diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000000..6ee8cfc06f --- /dev/null +++ b/.gitattributes @@ -0,0 +1,6 @@ +* text eol=lf + +*.jar binary +*.jpg binary +*.pdf binary +*.png binary diff --git a/.github/ISSUE_TEMPLATE/bug.md b/.github/ISSUE_TEMPLATE/bug.md new file mode 100644 index 0000000000..d85ac7999c --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug.md @@ -0,0 +1,43 @@ +--- +name: Bug report +about: Encountered an issue with Querydsl? Report it here. +labels: 'bug' +--- + +## Observed vs. expected behavior + + + +## Steps to reproduce + + + +## Environment + + + +Querydsl version: + +Querydsl module: + +Database: + +JDK: + +## Additional details + + + + + diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000000..54867f9a34 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,11 @@ +blank_issues_enabled: false +contact_links: + - name: Querydsl's User Guide + url: https://querydsl.github.io/static/querydsl/latest/reference/html_single/ + about: Learn about Querydsl's features + - name: Querydsl's Google Group + url: https://groups.google.com/forum/#!forum/querydsl + about: Ask questions, suggest changes and provide feedback. + - name: Querydsl on Stackoverflow + url: https://stackoverflow.com/questions/tagged/querydsl + about: Seek help on setup and usage. diff --git a/.github/ISSUE_TEMPLATE/documentation.md b/.github/ISSUE_TEMPLATE/documentation.md new file mode 100644 index 0000000000..b40c19c578 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/documentation.md @@ -0,0 +1,11 @@ +--- +name: Documentation improvement +about: Encountered lacking or outdated documentation? Suggest improvements here. +labels: 'documentation' +--- + +## Description + + diff --git a/.github/ISSUE_TEMPLATE/feature.md b/.github/ISSUE_TEMPLATE/feature.md new file mode 100644 index 0000000000..c67e2078fe --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature.md @@ -0,0 +1,21 @@ +--- +name: Feature request +about: Missing a feature? Suggest it here. +labels: 'enhancement' +--- + +## Why the new feature should be added + + + +## How the new feature should work + + diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000000..83774e0f51 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,7 @@ +version: 2 +updates: +- package-ecosystem: maven + directory: "/" + schedule: + interval: daily + open-pull-requests-limit: 40 diff --git a/.github/stale.yml b/.github/stale.yml new file mode 100644 index 0000000000..f810c11c0c --- /dev/null +++ b/.github/stale.yml @@ -0,0 +1,17 @@ +# Number of days of inactivity before an issue becomes stale +daysUntilStale: 365 +# Number of days of inactivity before a stale issue is closed +daysUntilClose: 7 +# Issues with these labels will never be considered stale +exemptLabels: + - pinned + - security +# Label to use when marking an issue as stale +staleLabel: wontfix +# Comment to post when marking an issue as stale. Set to `false` to disable +markComment: > + This issue has been automatically marked as stale because it has not had + recent activity. It will be closed if no further activity occurs. Thank you + for your contributions. +# Comment to post when closing a stale issue. Set to `false` to disable +closeComment: false diff --git a/.github/touched-file-so-ci-runs b/.github/touched-file-so-ci-runs new file mode 100644 index 0000000000..e69de29bb2 diff --git a/.github/touched-file-so-ci-runs2 b/.github/touched-file-so-ci-runs2 new file mode 100644 index 0000000000..e69de29bb2 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000000..b6de806a82 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,89 @@ +name: querydsl + +on: + push: + branches: + - '*' + paths-ignore: + - README.md + + pull_request: + branches: + - '*' + paths-ignore: + - README.md + +env: + MAVEN_OPTS: -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn + +jobs: + check_duplicate: + runs-on: ubuntu-latest + outputs: + should_skip: ${{ steps.skip_check.outputs.should_skip }} + steps: + - id: skip_check + uses: fkirc/skip-duplicate-actions@master + with: + concurrent_skipping: 'same_content_newer' + + build: + needs: check_duplicate + if: ${{ needs.check_duplicate.outputs.should_skip != 'true' || github.ref == 'refs/heads/master' }} + + strategy: + matrix: + target: [test] + java: [1.8, 11, 17, 21] + include: + - target: test + containers: db2 mysql postgresql mongo sqlserver oracle cubrid firebird + + runs-on: ubuntu-latest + steps: + - name: Check out code + uses: actions/checkout@v2 + + - name: Set up JDK ${{ matrix.java }} + uses: actions/setup-java@v1 + with: + java-version: ${{ matrix.java }} + + - name: Start test databases + if: ${{ matrix.containers }} + run: | + docker-compose up --detach ${{ matrix.containers }} &&\ + time docker-compose up block-until-healthy &&\ + docker ps + + - name: Initialize cache + uses: actions/cache@v1 + with: + path: ~/.m2/repository + key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} + + - name: Run tests + run: mvn --batch-mode install -am jacoco:report --activate-profiles all,travis,examples -Duser.timezone=UTC + + - name: Upload test reports + uses: actions/upload-artifact@v2 + if: failure() + with: + name: test-reports + path: './**/target/surefire-reports/' + + - name: Report coverage + if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }} + env: + COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }} + run: mvn --batch-mode coveralls:report --activate-profiles all,travis + + - name: Deploy snapshot 🚀 + if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }} + env: + NEXUS_USERNAME: ${{ secrets.NEXUS_USERNAME }} + NEXUS_PASSWORD: ${{ secrets.NEXUS_PASSWORD }} + run: mvn --batch-mode clean deploy --settings deploy/.m2/settings.xml -DskipTests + + - name: Clean up before caching + run: rm -rf ~/.m2/repository/com/querydsl/ diff --git a/.gitignore b/.gitignore index e86640bd83..841de60045 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,4 @@ derby.log /devops/*.rpm.zip /devops/**/*.semaphore /devops/test-connection/.lein-repl-history +**/.flattened-pom.xml diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index b463661444..0000000000 --- a/.travis.yml +++ /dev/null @@ -1,29 +0,0 @@ -language: java -jdk: - - oraclejdk7 -services: - - mongodb -addons: - postgresql: "9.3" -install: - - sh -c 'cd querydsl-root && mvn -B -q install -Dmaven.javadoc.skip=true -DskipTests=true' -before_script: - - mysql -e "create database querydsl;" -u root - - mysql -e "create database querydsl2;" -u root - - mysql -e "create user 'querydsl'@'localhost' identified by 'querydsl';" -u root - - mysql -e "grant all privileges on querydsl.* to 'querydsl'@'localhost';" -u root - - mysql -e "grant all privileges on querydsl2.* to 'querydsl'@'localhost';" -u root - - psql -c 'create database querydsl;' -U postgres - - psql -c 'create database querydsl2;' -U postgres - - psql -c "create user querydsl with password 'querydsl';" -U postgres - - psql -c 'grant all privileges on database querydsl to querydsl;' -U postgres - - psql -c 'grant all privileges on database querydsl2 to querydsl;' -U postgres - - psql -c 'create extension postgis;' -d querydsl -U postgres - - echo 'yes' | sudo add-apt-repository ppa:cubrid/cubrid - - sudo apt-get update - - sudo apt-get install cubrid - - sudo apt-get install cubrid-demodb - - /etc/profile.d/cubrid.sh - - hostname | sed 's/^/127.0.0.1 /g' | cat - /etc/hosts > /tmp/etchoststemp && sudo mv /tmp/etchoststemp /etc/hosts --force -script: - - sh -c 'cd querydsl-root && mvn -B test -Pall,travis' diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000000..c121be66a6 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,126 @@ +# Changelog + +### 5.0.0 + +This release of QueryDSL targets Java 8 minimally and comes with various improvements to make QueryDSL ready for the modern Java ecosystem. +This version also removes `joda-time:joda-time`, `com.google.guava:guava` and `com.google.code.findbugs:jsr305` as required runtime dependencies for using QueryDSL. + +QueryDSL 5.0 is the long awaited major release after the QueryDSL project was left mostly unmaintained for over two years. +With this release the team worked hard on resolving the most pressing issues that have been requested repeatedly for a long time. + +A huge thanks goes out to all contributors that made this release possible in their free time: + +* **[@mp911de](https://github.com/mp911de)**, for working on the MongoDB Document API; +* **[@daniel-shuy](https://github.com/daniel-shuy)**, for working on decoupling `querydsl-sql` from `joda-time:joda-time`; +* **[@heesuk-ahn](https://github.com/heesuk-ahn)**, for working on improved Hibernate support and count query generation in `JPASQLQuery`; +* **[@harshtuna](https://github.com/harshtuna)**, for working on NullsLast ordering in `querydsl-collections`; +* **[@kherrala](https://github.com/kherrala)**, **[@ridoo](https://github.com/ridoo)** and **[@NikitaKochkurov](https://github.com/NikitaKochkurov)** for working on the JTS and GeoLatte upgrade for `querydsl-spatial`; +* **[@ridoo](https://github.com/ridoo)**, for working on Spatial support in `HibernateDomainExporter` and `JPADomainExporter`; +* **[@lpandzic](https://github.com/lpandzic)**, for working on codegen support for Java 15 records and general improvements; +* **[@F43nd1r](https://github.com/F43nd1r)**, for working on Kotlin Code generation, Java 11 support, general improvements and Continuous Integration; +* **[@jwgmeligmeyling](https://github.com/jwgmeligmeyling)**, **[@Shredder121](https://github.com/Shredder121)**, **[@johnktims](https://github.com/johnktims)**, **[@idosal](https://github.com/idosal)** and **[@robertandrewbain](https://github.com/robertandrewbain)**. + +#### New features + +* [#2672](https://github.com/querydsl/querydsl/pull/2672) - Various performance and code improvements possible by targeting Java 8 source level. +* [#2672](https://github.com/querydsl/querydsl/pull/2672) - Added `Fetchable#stream()` which returns a `Stream`. + Make sure that the returned stream is always closed to free up resources, for example using _try-with-resources_. + It does not suffice to rely on a terminating operation on the stream for this (i.e. `forEach`, `collect`). +* [#2324](https://github.com/querydsl/querydsl/issues/2324) - Removal of Guava as dependency. + Almost no required transitive dependencies to get started with QueryDSL. + And no more conflicts with Guava versions required by your other tools or own application. +* [#2025](https://github.com/querydsl/querydsl/issues/2025) - `joda-time:joda-time` is no longer a required dependency for `querydsl-sql`. + By default, the Java 8 date/time API is used for date/time operations. + The `joda-time:joda-time` types will still be registered automatically if they are on the classpath. +* [#2215](https://github.com/querydsl/querydsl/issues/2215) - MongoDB 4 support through the Document API +* [#2697](https://github.com/querydsl/querydsl/issues/2697) - Allow `com.querydsl.core.alias.Alias.*` to be used on a JRE by relying on ECJ as compiler +* [#2479](https://github.com/querydsl/querydsl/issues/2479) - Swap out JSR305 for Jetbrains Annotations. + Because the Jetbrains Annotations, contrary to the JSR305 annotations, use a Class retention level, Jetbrains Annotations + does not have to be available at runtime and is not a transitive dependency. +* [#658](https://github.com/querydsl/querydsl/issues/658) - Added `JPAExpressions#treat` which can be used to generate JPA 2.1 Treated path expressions. +* [#2666](https://github.com/querydsl/querydsl/issues/2666) - More descriptive error message when using unsupported query features in JPA. +* [#2106](https://github.com/querydsl/querydsl/issues/2106) - Support NullsLast ordering in `querydsl-collections`. +* [#2404](https://github.com/querydsl/querydsl/issues/2404) - Upgrade of JTS / Geolatte in `querydsl-spatial` +* [#2320](https://github.com/querydsl/querydsl/issues/2320) - Make Spatial support available to `HibernateDomainExporter` and `JPADomainExporter`. +* [#2612](https://github.com/querydsl/querydsl/issues/2612) - Support jakarta.* packages for new Jakarta EE releases (available through the`jakarta` classifiers for Maven) +* [#1376](https://github.com/querydsl/querydsl/issues/1376) - Return typed expression from `nullif` and `coalesce` methods. +* [#1828](https://github.com/querydsl/querydsl/issues/1828) - Kotlin Codegen support +* [#2798](https://github.com/querydsl/querydsl/pull/2798) - Java Record support + +#### Bugfixes + +* [#2579](https://github.com/querydsl/querydsl/issues/2579) - Count query generation in `JPASQLQuery` +* [#2671](https://github.com/querydsl/querydsl/issues/2671) - Fixed a concurrency issue in `Alias.*`. `Alias.*` is now Thread safe. +* [#2053](https://github.com/querydsl/querydsl/issues/2053) - Work around issues with `AbstractJPAQuery#fetchResults` and `AbstractJPAQuery#fetchCount` in a query with a having clause by using an in-memory calculation. +* [#2504](https://github.com/querydsl/querydsl/issues/2504) - Work around issues with `AbstractJPAQuery#fetchResults` and `AbstractJPAQuery#fetchCount` in a query with multiple group by expressions by using an in-memory calculation. +* [#2663](https://github.com/querydsl/querydsl/issues/2663) - Fix issues with the JPA implementation of `InsertClause`. +* [#2706](https://github.com/querydsl/querydsl/pull/2706) - Fix a memory leak in `TemplateFactory`. +* [#2467](https://github.com/querydsl/querydsl/issues/2467) - Prevent `ExtendedBeanSerializer` from generating `toString` method twice +* [#2326](https://github.com/querydsl/querydsl/issues/2326) - Use JPA indexed parameters instead of HQL's legacy positional parameters +* [#2816](https://github.com/querydsl/querydsl/issues/2816) - Generated JPA query with incorrect argument binding indexes +* [#1413](https://github.com/querydsl/querydsl/issues/1413) - Incorrect parameter values with Hibernate custom types +* [#1429](https://github.com/querydsl/querydsl/issues/1429) - Reusing of constants in JPQL generation causes issues with hibernate query caching + +#### Breaking changes + +* Java 8 minimal requirement. If you still rely on Java <7, please use the latest 4.x.x version. +* `JavaSE6SQLExceptionWrapper` and other parts regarding pre-Java 7 exception handling are removed. +* Removed bridge method that were in place for backwards compatibility of legacy API's. This may lead to some breaking API changes. +* Removed Guava as a dependency. If your application relies on Guava, make sure to add it as a direct dependency for your project and not rely on QueryDSL shipping it transitively. +* In order for Guava to be removed Mysema Codegen had to be rereleased as QueryDSL Codegen Utils. + Therefore, the classes in this module moved to a different package: `com.mysema.codegen` is now `com.querydsl.codegen.utils`. + This for example affects `com.mysema.codegen.model.SimpleType`. + Although many applications won't touch the codgen internal classes, custom APT extensions might be affected by this. +* Due to the removal of Guava, any method that received an `ImmutableList` as parameter, now accepts any `List` instead. + Normal code should handle this signature just fine. + However, make sure to check any reflective uses of these parameters. +* The `querydsl.variableNameFunctionClass` property for the `DefaultConfiguration` should now be provided as a `java.util.function.Function` instead of a `com.google.common.base.Function`. +* `CodeWriter#beginStaticMethod` now takes a `java.util.function.Function` instead of a `com.google.common.base.Function`. +* `AbstractLuceneQuery` now takes a `java.util.function.Function` instead of a `com.google.common.base.Function`. +* `AbstractMongodbQuery` now takes a `java.util.function.Function` instead of a `com.google.common.base.Function`. +* `com.querydsl.codegen.NamingFunction`, `EvaluatorFunction`, `DefaultVariableFunction` now extend `java.util.function.Function` instead of `com.google.common.base.Function`. +* Any constructor that received a `javax.inject.Provider`, now takes a `java.util.function.Supplier` instead. In most cases you can replace the argument with `provider::get`. +* This release targets Hibernate 5.2 in the Hibernate integration. If you need Hibernate 4 dialect specific workarounds, use the `HQLTemplates` instead of the `Hibernate5Templates`. +* Removal of various deprecated methods. +* `joda-time:joda-time` is now an optional dependency. If your application relies on `joda-time:joda-time` make sure to specify it as a direct dependency rather than relying on QueryDSL to include it transitively. +* `com.google.code.findbugs:jsr305` is no longer a dependency. If your application currently relies on QueryDSL shipping JSR305 transitively, you should add JSR305 as a direct dependency to your project. +* MDC keys now use an underscore instead of a dot as separator: ` querydsl.query` now is `querydsl_query` and `querydsl.parameters` is `querydsl_parameters`. +* Removal of `PolyHedralSurface` in `querydsl-spatial` and `querydsl-sql-spatial` due to the upgrade of `geolatte-geom`. +* `com.querydsl.apt.Extension` moved to `com.querydsl.codegen` and now resides in the `querydsl-codegen` module. +* `com.querydsl.apt.SpatialSupport` moved to `com.querydsl.spatial.apt.SpatialSupport` and now resides in the `querydsl-spatial` module. +* `com.querydsl.sql.codegen.SpatialSupport` moved to `com.querydsl.sql.spatial.SpatialSupport` and now resides in the `querydsl-sql-spatial` module. +* `SQLServerGeometryReader` in `querydsl-sql-spatial` is removed in favour of `org.geolatte.geom.codec.db.sqlserver.*`. +* `PGgeometryConverter` in `querydsl-sql-spatial` is removed in favour of `org.geolatte.geom.codec.Wkt`. +* `JGeometryConverter` in `querydsl-sql-spatial` is removed in favour of `org.geolatte.geom.codec.db.oracle.*`. +* Removal of `HibernateDomainExporter` in `querysql-jpa-codegen`. `HibernateDomainExporter` only supported Hibernate 4, which QueryDSL no longer actively supports. Instead, use the `JPADomainExporter` with Hibernate. +* `ComparableExpression#coalesce` (and subtypes) no longer return a mutable `Coalesce` expression, but instead return a typed expression. + If you need the Coalesce builder, use `new Coalesce().add(expression)` instead. +* `getConstantToNamedLabel`, `getConstantToNumberedLabel` and `getConstantToAllLabels` that were temporarily introduced to `SerializerBase` and `JPQLSerializer` + in QueryDSL 4.3.0 to eventually replace `getConstantToLabel` are now removed in favor of `getConstants`. + +#### Deprecations +* `AbstractJPAQuery#fetchResults` and `AbstractJPAQuery#fetchCount` are now deprecated for queries that have multiple group by + expressions or a having clause, because these scenarios cannot be supported by pure JPA and are instead computed in-memory. + If the total count of results is not necessary, we recommend to always use `AbstractJPAQuery#fetch` instead. + If you want a reliable way of computing the result count for a paginated result for even the most complicated queries, + we recommend using the [Blaze-Persistence QueryDSL integration](https://persistence.blazebit.com/documentation/1.5/core/manual/en_US/#querydsl-integration). + `BlazeJPAQuery` properly implements both `fetchResults` and `fetchCount` and even comes with a `page` method. +* `getConstantToLabel` which was deprecated in QueryDSL 4.3.0 is no longer deprecated. + +#### Dependency updates + +* `cglib:cglib` to 3.3.0 for Java 8+ support +* `org.eclipse.jdt.core.compiler:ecj` to 4.6.1 for Java 8+ support +* `joda-time:joda-time` to 2.10.10 for better interoperability with other frameworks that use more recent versions than QueryDSL. + `joda-time:joda-time` is also no longer a required dependency and as such is no longer provided transitively to your application. + If your application relies on `joda-time:joda-time` being available, make sure to add the dependency to your project. +* `org.geolatte:geolatte-geom` to 1.8.1 for better interopability with Hibernate Spatial. + `querydsl-spatial` is still backwards compatible with older versions of Geolatte, however, `querydsl-sql-spatial` is not and requires 1.4.0 or newer. +* `com.vividsolutions:jts` to `org.locationtech:jts` for better interopability with Hibernate Spatial. + `com.vividsolutions:jts` is still supported for `querydsl-spatial` if an older version of `org.geolatte:geolatte-geom` is provided. +* DataNucleus 5.2.x for Java 8+ support + * JDO now uses `org.datanucleus:javax.jdo` instead of `javax.jdo:jdo-api` +* `com.google.guava:guava` is no longer a dependency of QueryDSL and as such is no longer provided transitively to your application. + If your application relies on `com.google.guava:guava` being available, make sure to add the dependency to your project. +* `com.google.code.findbugs:jsr305` is no longer a dependency of QueryDSL and as such is no longer provided transitively to your application. + If your application relies on `com.google.code.findbugs:jsr305` being available, make sure to add the dependency to your project. \ No newline at end of file diff --git a/querydsl-root/LICENSE.txt b/LICENSE.txt similarity index 98% rename from querydsl-root/LICENSE.txt rename to LICENSE.txt index 29f81d812f..261eeb9e9f 100644 --- a/querydsl-root/LICENSE.txt +++ b/LICENSE.txt @@ -1,201 +1,201 @@ - 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 [yyyy] [name of copyright owner] - - 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. + 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 [yyyy] [name of copyright owner] + + 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. diff --git a/README.md b/README.md index c048b52dab..7284d11e2f 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,11 @@ Querydsl is a framework which enables the construction of type-safe SQL-like que Instead of writing queries as inline strings or externalizing them into XML files they are constructed via a fluent API. -[![Build Status](https://travis-ci.org/querydsl/querydsl.svg?branch=master)](https://travis-ci.org/querydsl/querydsl) +[![Website shields.io](https://img.shields.io/website-up-down-green-red/http/querydsl.github.io.svg)](https://querydsl.github.io/) +[![Build Status](https://github.com/querydsl/querydsl/workflows/querydsl/badge.svg)](https://github.com/querydsl/querydsl/actions) +[![Coverage Status](https://coveralls.io/repos/github/querydsl/querydsl/badge.svg?branch=master)](https://coveralls.io/github/querydsl/querydsl?branch=master) +[![Stackoverflow](https://img.shields.io/badge/StackOverflow-querydsl-yellow.svg)](https://stackoverflow.com/questions/tagged/querydsl) +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.querydsl/querydsl-core/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.querydsl/querydsl-core/) **Getting started** @@ -12,55 +16,50 @@ Use these tutorials to get started * [Querying JPA](http://www.querydsl.com/static/querydsl/latest/reference/html/ch02.html#jpa_integration) * [Querying SQL](http://www.querydsl.com/static/querydsl/latest/reference/html/ch02s03.html) -* [Querying Mongodb](http://www.querydsl.com/static/querydsl/latest/reference/html/ch02s06.html) -* [Querying Lucene](http://www.querydsl.com/static/querydsl/latest/reference/html/ch02s04.html) -* [Querying Collections](http://www.querydsl.com/static/querydsl/latest/reference/html/ch02s07.html) +* [Querying Mongodb](http://www.querydsl.com/static/querydsl/latest/reference/html/ch02s07.html) +* [Querying Lucene](http://www.querydsl.com/static/querydsl/latest/reference/html/ch02s05.html) +* [Querying Collections](http://www.querydsl.com/static/querydsl/latest/reference/html/ch02s08.html) * [Querydsl Spatial](http://www.querydsl.com/static/querydsl/latest/reference/html/ch02s04.html) * [Querying JDO](http://www.querydsl.com/static/querydsl/latest/reference/html/ch02s02.html) **Examples** -Querydsl example projects - -* [Querydsl JPA example](https://github.com/querydsl/querydsl-jpa-example) -* [Querydsl SQL example](https://github.com/querydsl/querydsl-sql-example) -* [Querydsl Customer DAO](https://github.com/querydsl/querydsl-customer-dao) +[Querydsl example projects](https://github.com/querydsl/querydsl/tree/master/querydsl-examples) **Support** -Free support is provided in the Querydsl Google Group https://groups.google.com/forum/#!forum/querydsl +Free support is provided in the [Discussion Section](https://github.com/querydsl/querydsl/discussions) and on [StackOverflow](http://stackoverflow.com/questions/tagged/querydsl). +Please do not post questions as issue. Such issues will be closed immediately. **How to build** -Querydsl provides releases via public Maven repositories, but you can build the sources also yourself like this +Querydsl provides releases via public Maven repositories, but you can also build the sources yourself like this - cd querydsl-root - mvn -DskipTests=true clean install +```BASH +$ mvn -Pquickbuild,{projectname} clean install +``` +Where projectname is one of the Maven profiles (e.g. `jpa`, `sql`, `mongodb`, etc. or `all`) -For more information visit the project homepage at http://www.querydsl.com/. +For more information visit the project homepage at https://querydsl.github.io. -**Vagrant/Puppet setup** +**Docker Compose setup** -For running tests, a Vagrant/Puppet setup is provided. It is based on Ubuntu 12.04 and comes with the following databases: +For running tests, a Docker Compose setup is provided. It comes with the following databases: * Oracle Express Edition 11g * PostgreSQL 9.1.10 * MySQL 5.5.34 * Cubrid 9.2 -You will need to install [VirtualBox], [Puppet], [Vagrant], the [vagrant-vbguest] plugin and [librarian-puppet]. You will also need to -download the Oracle XE 11g installer file (```oracle-xe-11.2.0-1.0.x86_64.rpm.zip```) manually and -place it in the ```devops``` directory. +You will need to install [Docker] and [docker-compose]. -To launch the virtual machine: +To launch the database containers: -``` -$> cd devops -devops$> librarian-puppet install -devops$> vagrant up +```BASH +$ docker-compose up -d ``` -All of the databases' default ports are forwarded to the host machine. See the Vagrantfile for details. +All of the databases' default ports are forwarded to the host machine. **How to contribute** @@ -69,18 +68,9 @@ GitHub pull requests are the way to contribute to Querydsl. If you are unsure about the details of a contribution, ask on the Querydsl Google Group or create a ticket on GitHub. -[VirtualBox]: https://www.virtualbox.org/ -[Vagrant]: http://www.vagrantup.com/ -[Puppet]: http://puppetlabs.com/ -[vagrant-vbguest]: https://github.com/dotless-de/vagrant-vbguest -[librarian-puppet]: http://librarian-puppet.com/ - -**Continuous integration** - -Querydsl uses Cloudbees for Jenkins based CI - -[![CloudBees](http://www.cloudbees.com/sites/default/files/Button-Built-on-CB-1.png)](https://querydsl.ci.cloudbees.com) +[Docker]: https://www.docker.com/products/docker-desktop +[docker-compose]: https://docs.docker.com/compose/ -As well as Travis CI for pull request validation +### Slack -[![Build Status](https://travis-ci.org/querydsl/querydsl.svg?branch=master)](https://travis-ci.org/querydsl/querydsl) +If you want to join Slack workspace for Querydsl contributors join by following [this link](https://join.slack.com/t/querydsl/shared_invite/zt-r7ufzz6q-zxIHgpOSSMFvoU3YU4SclQ). diff --git a/db/mysql.sh b/db/mysql.sh new file mode 100644 index 0000000000..b6a038e9ac --- /dev/null +++ b/db/mysql.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +mysql -uroot -p$MYSQL_ROOT_PASSWORD -e "CREATE SCHEMA querydsl" +mysql -uroot -p$MYSQL_ROOT_PASSWORD -e "CREATE SCHEMA querydsl2" + +mysql -uroot -p$MYSQL_ROOT_PASSWORD -e "GRANT ALL PRIVILEGES ON *.* TO 'querydsl'@'%'" diff --git a/db/postgresql.sql b/db/postgresql.sql new file mode 100644 index 0000000000..34de9ea9fa --- /dev/null +++ b/db/postgresql.sql @@ -0,0 +1,2 @@ +create database querydsl2; +grant all privileges on database querydsl2 to querydsl; diff --git a/deploy/.m2/settings.xml b/deploy/.m2/settings.xml new file mode 100644 index 0000000000..005d2529d8 --- /dev/null +++ b/deploy/.m2/settings.xml @@ -0,0 +1,16 @@ + + + + sonatype-nexus-staging + ${env.NEXUS_USERNAME} + ${env.NEXUS_PASSWORD} + + + sonatype-nexus-snapshots + ${env.NEXUS_USERNAME} + ${env.NEXUS_PASSWORD} + + + \ No newline at end of file diff --git a/devops/test-connection/src/test_connection/core.clj b/devops/test-connection/src/test_connection/core.clj index 9fc1721aad..5f6d1eb0a9 100644 --- a/devops/test-connection/src/test_connection/core.clj +++ b/devops/test-connection/src/test_connection/core.clj @@ -22,7 +22,7 @@ (def cubrid-db {:classname "cubrid.jdbc.driver.CUBRIDDriver" :subprotocol "cubrid" - :subname "localhost:30000:demodb:public::"}) + :subname "localhost:30000:demodb:dba::"}) (count (j/query oracle-db (s/select * :all_tables))) (count (j/query postgres-db (s/select * :pg_catalog.pg_tables))) diff --git a/dist.sh b/dist.sh new file mode 100755 index 0000000000..0dead02a00 --- /dev/null +++ b/dist.sh @@ -0,0 +1,13 @@ +#!/bin/sh +rm -rf target/dist +mkdir -p target/dist +mvn javadoc:aggregate + +for module in apt collections hibernate-search jpa jdo lucene3 lucene4 sql sql-codegen +do + mvn -pl querydsl-$module -Dtest=X clean assembly:assembly +done + +mkdir -p target/dist/reference +mvn -f querydsl-docs/pom.xml -Dxslthl.config=http://docbook.sourceforge.net/release/xsl/current/highlighting/xslthl-config.xml clean package +cp -R querydsl-docs/target/docbook/publish/en-US/* target/dist/reference/ diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000000..035354a772 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,103 @@ +version: "2.4" +services: + # Provides an easy way to ensure slow-starting databases are ready when the tests run + block-until-healthy: + image: alpine:latest + depends_on: + cubrid: + condition: service_healthy + db2: + condition: service_healthy + sqlserver: + condition: service_healthy + + mysql: + image: mysql:5.6.38 + ports: + - "3306:3306" + volumes: + - ./db/mysql.sh:/docker-entrypoint-initdb.d/mysql.sh + environment: + - MYSQL_ROOT_PASSWORD=querydsl + - MYSQL_USER=querydsl + - MYSQL_PASSWORD=querydsl + + postgresql: + image: mdillon/postgis:9.3-alpine + ports: + - "5433:5432" + volumes: + - ./db/postgresql.sql:/docker-entrypoint-initdb.d/postgresql.sql + environment: + - POSTGRES_USER=querydsl + - POSTGRES_PASSWORD=querydsl + - POSTGRES_DB=querydsl + + oracle: + image: wnameless/oracle-xe-11g-r2:latest + ports: + - "1521:1521" + volumes: + - "./devops/sql-snippets/oracle.sql:/docker-entrypoint-initdb.d/oracle.sql" + + cubrid: + image: lighthopper/cubrid:9.2.26.0004 + command: "./create-start-demodb.sh" + ports: + - "33000:33000" + - "30000:30000" + - "8001:8001" + - "8002:8002" + - "1523:1523" + healthcheck: + test: csql demodb -c "SELECT 1" + interval: 5s + timeout: 60s + start_period: 60s + + mongo: + image: mongo:3.6.1 + ports: + - "27017:27017" + + db2: + image: ibmcom/db2:11.5.0.0 + privileged: true + ports: + - "50000:50000" + environment: + - DB2INST1_PASSWORD=a3sd!fDj + - DB2INSTANCE=db2inst1 + - DBNAME=sample + - LICENSE=accept + - ARCHIVE_LOGS=false + - AUTOCONFIG=false + healthcheck: + test: /opt/ibm/db2/V11.5/bin/db2 CONNECT TO $$DBNAME + interval: 5s + timeout: 240s + start_period: 240s + + sqlserver: + image: mcr.microsoft.com/mssql/server:2017-latest-ubuntu + environment: + - ACCEPT_EULA=Y + - SA_PASSWORD=Password1! + - MSSQL_PID=Express + ports: + - "1433:1433" + healthcheck: + test: /opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P "$$SA_PASSWORD" -Q "SELECT 1" || exit 1 + interval: 5s + timeout: 60s + start_period: 60s + + firebird: + image: jacobalberty/firebird:v4 + ports: + - "3050:3050" + environment: + - ISC_PASSWORD=masterkey + - FIREBIRD_DATABASE=querydsl.fdb + - FIREBIRD_USER=querydsl + - FIREBIRD_PASSWORD=querydsl diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000000..36a93c514f --- /dev/null +++ b/pom.xml @@ -0,0 +1,981 @@ + + + + 4.0.0 + com.querydsl + querydsl-root + 5.1.0 + Querydsl + parent project for Querydsl modules + https://querydsl.github.io/ + + + com.querydsl + querydsl-parent + 0.1.0 + + + pom + + 2007 + + + false + UTF-8 + http://www.querydsl.com + http://github.com/querydsl/querydsl + scm:git:git@github.com:querydsl/querydsl.git + + + + com.querydsl.core.testutil.ExternalDatabase, + com.querydsl.core.testutil.SlowTest, + com.querydsl.core.testutil.Performance, + com.querydsl.core.testutil.ReportingOnly + + + + + + -Xms256m -Xmx512m + + + 11.5.7.0 + 10.15.2.0 + 2.6.0 + 1.4.197 + 42.3.4 + 21.7.0.0 + 8.0.29 + 11.2.1.jre8 + 9.3.9.0002 + 3.36.0.3 + 13.10.00.35 + 4.0.6.java8 + + + 5.4.8.Final + 7.0.4.Final + 2.7.8 + + 31.1-jre + 0.6.8 + 0.2.4 + 3.3.0 + 9.6 + 1.7.35 + 3.2.2 + 1.20 + 2.10.14 + 1.5.0 + 1.3.2 + 1.35 + 2.2 + 2.0.0-Beta4 + 1.9.20 + + + + * + + ${osgi.import.package.root} + + + + + junit + junit + test + + + org.hamcrest + hamcrest + test + + + org.easymock + easymock + 4.3 + test + + + cglib + cglib-nodep + + + + + org.javassist + javassist + test + + + org.codehaus.mojo + animal-sniffer-annotations + ${animal-sniffer.version} + true + + + + + + + org.jetbrains + annotations + 23.0.0 + provided + + + jakarta.persistence + jakarta.persistence-api + 2.2.3 + + + org.datanucleus + javax.jdo + 3.2.0-release + + + com.vividsolutions + jts + 1.13 + + + com.h2database + h2 + ${h2.version} + + + javax.validation + validation-api + 2.0.1.Final + + + junit + junit + 4.13.2 + + + org.hamcrest + hamcrest + ${hamcrest.veresion} + test + + + org.hamcrest + hamcrest-core + ${hamcrest.veresion} + test + + + org.hamcrest + hamcrest-all + ${hamcrest.veresion} + test + + + org.eclipse.jdt.core.compiler + ecj + 4.6.1 + + + io.github.classgraph + classgraph + 4.8.146 + + + org.javassist + javassist + + + + + org.javassist + javassist + 3.28.0-GA + + + com.google.guava + guava + ${guava.version} + + + org.geolatte + geolatte-geom + 1.8.2 + + + org.jetbrains.kotlin + kotlin-bom + ${kotlin.version} + pom + import + + + org.jetbrains.kotlin + kotlin-scripting-jsr223 + ${kotlin.version} + + + com.fasterxml + classmate + 1.5.1 + + + org.jboss.logging + jboss-logging + 3.4.3.Final + + + + + + ${project.checkout} + ${project.checkout} + ${project.githubpage} + + + + + timowest + Timo Westkämper + Mysema Ltd + + Project Manager + Architect + + + + ssaarela + Samppa Saarela + Mysema Ltd + + Developer + + + + ponzao + Vesa Marttila + Mysema Ltd + + Developer + + + + mangolas + Lassi Immonen + Mysema Ltd + + Developer + + + + Shredder121 + Ruben Dijkstra + + Developer + + + + johnktims + John Tims + + Developer + + + + robertandrewbain + Robert Bain + + Developer + + + + jwgmeligmeyling + Jan-Willem Gmelig Meyling + + Developer + + + + + + + Apache License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + + + + + + + + org.apache.maven.plugins + maven-assembly-plugin + 3.3.0 + + + org.apache.maven.plugins + maven-compiler-plugin + 3.12.1 + + + org.apache.maven.plugins + maven-deploy-plugin + 2.8.2 + + + com.mysema.maven + apt-maven-plugin + 1.1.3 + + + org.apache.maven.plugins + maven-surefire-plugin + ${surefire.version} + + + org.apache.felix + maven-bundle-plugin + 5.1.4 + + + bundle-manifest + process-classes + + manifest + + true + + + + ${osgi.import.package} + + com.querydsl.* + + + + + + + org.jetbrains.dokka + dokka-maven-plugin + ${dokka.version} + + + prepare-package + + javadocJar + + + + + + org.jetbrains.kotlin + kotlin-maven-plugin + ${kotlin.version} + + 1.8 + + + + + + + + org.apache.maven.plugins + maven-enforcer-plugin + 1.4.1 + + + enforce-maven + validate + + enforce + + + + + + + + + enforce-banned-dependencies + validate + + enforce + + + + + + + org.jetbrains:annotations:*:*:compile + + com.google.code.findbugs:jsr305:*:*:compile + + org.hibernate:hibernate-core:*:*:compile + org.hibernate:hibernate-envers:*:*:compile + org.hibernate.validator:hibernate-validator:*:*:compile + org.eclipse.persistence:eclipselink:*:*:compile + javax.transaction:jta:*:*:compile + org.datanucleus:javax.jdo:*:*:compile + org.springframework.roo:org.springframework.roo.annotations:*:*:compile + org.mongodb.morphia:morphia:*:*:compile + joda-time:joda-time:*:*:compile + org.joda:joda-money:*:*:compile + javax.el:javax.el-api:*:*:compile + jakarta.persistence:jakarta.persistence-api:*:*:compile + org.batoo.jpa:batoo-jpa:*:*:compile + + org.hsqldb:hsqldb:*:*:compile + com.h2database:h2:*:*:compile + org.apche.derby:derby:*:*:compile + mysql:mysql-connector-java:*:*:compile + com.microsoft.sqlserver:mssql-jdbc:*:*:compile + com.oracle:ojdbc8:*:*:compile + org.postgresql:postgresql:*:*:compile + cubrid:cubrid-jdbc:*:*:compile + org.firebirdsql.jdbc:jaybird:*:*:compile + org.xerial:sqlite-jdbc:*:*:compile + + org.hibernate:hibernate-entitymanager + + org.slf4j:slf4j-api:*:*:compile + org.slf4j:slf4j-log4j12:*:*:compile + + false + + + + + + + + com.github.siom79.japicmp + japicmp-maven-plugin + 0.15.3 + + + true + true + true + true + + querydsl-maven-plugin + querydsl-example.* + + + + + + verify + + cmp + + + + + + maven-assembly-plugin + + + ../src/main/assembly.xml + + ../target/dist + + + + org.eluder.coveralls + coveralls-maven-plugin + 4.3.0 + + ${env.COVERALLS_REPO_TOKEN} + + + + org.jacoco + jacoco-maven-plugin + 0.8.11 + + + prepare-agent + + prepare-agent + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 3.4.0 + + 8 + com.querydsl.examples.kotlin.* + ${project.build.directory}/dist/apidocs + ${project.build.directory}/dist/apidocs + false + + + Core + com.querydsl.core* + + + Codegen + com.querydsl.codegen* + + + APT + com.querydsl.apt* + + + Maven + com.querydsl.maven* + + + Spatial + com.querydsl.spatial* + + + Collections + com.querydsl.collections* + + + JPA + com.querydsl.jpa* + + + JDO + com.querydsl.jdo* + + + SQL + com.querydsl.sql* + + + Lucene 3 + com.querydsl.lucene3* + + + Lucene 4 + com.querydsl.lucene4* + + + Lucene 5 + com.querydsl.lucene5* + + + Hibernate Search + com.querydsl.hibernate.search* + + + Mongodb + com.querydsl.mongodb* + + + + + + org.apache.maven.plugins + maven-pmd-plugin + 3.15.0 + + 1.6 + true + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + + + + org.apache.maven.plugins + maven-source-plugin + 3.2.1 + + + package + + jar + + + + + + org.apache.maven.plugins + maven-jar-plugin + 3.2.2 + + + org.apache.maven.plugins + maven-surefire-plugin + + ${excludedGroups} + ${includedGroups} + + + + org.apache.maven.surefire + surefire-junit47 + ${surefire.version} + + + + + org.codehaus.mojo + animal-sniffer-maven-plugin + ${animal-sniffer.version} + + + org.codehaus.mojo.signature + java18 + 1.0 + + + + + ensure-java-1.6-class-library + test + + check + + + + + + org.apache.maven.plugins + maven-checkstyle-plugin + 3.1.2 + + + checkstyle + validate + + check + + + src/main/resources/querydsl_checks_base.xml + true + true + + + + checkstyle-main + validate + + check + + + src/main/resources/querydsl_checks_main.xml + true + + + + + + com.puppycrawl.tools + checkstyle + 9.3 + + + + **/generated/**/*,**/jmh_generated/**/*,**/com/querydsl/codegen/utils/**/* + + + + + + + + + + all + true + + querydsl-core + querydsl-codegen + querydsl-codegen-utils + querydsl-spatial + querydsl-apt + querydsl-collections + querydsl-guava + querydsl-sql + querydsl-sql-spatial + querydsl-sql-codegen + querydsl-sql-spring + querydsl-maven-plugin + querydsl-jpa + querydsl-jpa-codegen + querydsl-jdo + querydsl-bom + querydsl-kotlin-codegen + + + querydsl-lucene3 + querydsl-lucene4 + querydsl-lucene5 + querydsl-hibernate-search + + + querydsl-mongodb + + + querydsl-scala + querydsl-kotlin + + + + + hibernate-search + + querydsl-core + querydsl-codegen + querydsl-codegen-utils + querydsl-lucene3 + querydsl-hibernate-search + + + + + jpa + + querydsl-core + querydsl-codegen + querydsl-codegen-utils + querydsl-spatial + querydsl-apt + querydsl-sql + querydsl-sql-spatial + querydsl-sql-codegen + querydsl-sql-spring + querydsl-maven-plugin + querydsl-jpa + querydsl-jpa-codegen + + + + + jdo + + querydsl-core + querydsl-codegen + querydsl-codegen-utils + querydsl-spatial + querydsl-apt + querydsl-sql + querydsl-sql-spatial + querydsl-sql-codegen + querydsl-sql-spring + querydsl-maven-plugin + querydsl-jdo + + + + + lucene + + querydsl-core + querydsl-codegen + querydsl-codegen-utils + querydsl-apt + querydsl-lucene3 + querydsl-lucene4 + querydsl-lucene5 + + + + + mongodb + + querydsl-core + querydsl-codegen + querydsl-codegen-utils + querydsl-apt + querydsl-mongodb + + + + + sql + + querydsl-core + querydsl-codegen + querydsl-codegen-utils + querydsl-spatial + querydsl-sql + querydsl-sql-spatial + querydsl-sql-codegen + querydsl-sql-spring + querydsl-maven-plugin + + + + + collections + + querydsl-core + querydsl-codegen + querydsl-codegen-utils + querydsl-apt + querydsl-collections + + + + + docs + + querydsl-docs + + + + + examples + + querydsl-examples + + + + + jenkins + + + com.querydsl.core.testutil.Performance, + + com.querydsl.core.testutil.DB2, + com.querydsl.core.testutil.SQLServer + + + + + + travis + + + com.querydsl.core.testutil.Performance, + com.querydsl.core.testutil.ReportingOnly, + + com.querydsl.core.testutil.Teradata + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + true + false + + + + + + + quickbuild + + true + true + true + true + true + + + + + java-8 + + 1.8 + + + 2.5.2 + 10.14.2.0 + + + + + java-11 + + [11,) + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 11 + + + + org.eluder.coveralls + coveralls-maven-plugin + + + jakarta.xml.bind + jakarta.xml.bind-api + 2.3.2 + + + org.glassfish.jaxb + jaxb-runtime + 2.3.2 + + + + + + + + + java-17 + + [17,) + + + + + + org.apache.maven.plugins + maven-surefire-plugin + ${surefire.version} + + + --add-opens=java.base/java.lang=ALL-UNNAMED + --add-opens=java.base/java.util=ALL-UNNAMED + + + + + + + + + + + + + org.codehaus.mojo + junit-report-maven-plugin + devel + + true + + + + org.apache.maven.plugins + maven-jxr-plugin + 3.2.0 + + true + + + + + + diff --git a/querydsl-ant-test/build.xml b/querydsl-ant-test/build.xml index b251dee1c9..2a0abd591a 100755 --- a/querydsl-ant-test/build.xml +++ b/querydsl-ant-test/build.xml @@ -1,55 +1,55 @@ - - - simple example build file - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + simple example build file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/querydsl-ant-test/src/test/Test.java b/querydsl-ant-test/src/test/Test.java index 02ee9ee8f9..1785678916 100755 --- a/querydsl-ant-test/src/test/Test.java +++ b/querydsl-ant-test/src/test/Test.java @@ -1,15 +1,15 @@ -package test; -import java.math.BigDecimal; - -import com.mysema.query.annotations.QueryEntity; - - -@QueryEntity -public class Test { - - private String property; - - private int intProperty; - - private BigDecimal bigDecimal; -} +package test; +import java.math.BigDecimal; + +import com.mysema.query.annotations.QueryEntity; + + +@QueryEntity +public class Test { + + private String property; + + private int intProperty; + + private BigDecimal bigDecimal; +} diff --git a/querydsl-apt/etc/META-INF/services/javax.annotation.processing.Processor b/querydsl-apt/etc/META-INF/services/javax.annotation.processing.Processor index 3c35a2e619..9a9230aef5 100644 --- a/querydsl-apt/etc/META-INF/services/javax.annotation.processing.Processor +++ b/querydsl-apt/etc/META-INF/services/javax.annotation.processing.Processor @@ -1 +1 @@ -com.mysema.query.apt.EntityAnnotationProcessor \ No newline at end of file +com.querydsl.apt.EntityAnnotationProcessor \ No newline at end of file diff --git a/querydsl-apt/etc/readme.txt b/querydsl-apt/etc/readme.txt deleted file mode 100644 index 3d27748804..0000000000 --- a/querydsl-apt/etc/readme.txt +++ /dev/null @@ -1 +0,0 @@ -* TODO : supertype references need to preserve type parameters \ No newline at end of file diff --git a/querydsl-apt/pom.xml b/querydsl-apt/pom.xml index b113fca31c..5cecb9ae2f 100644 --- a/querydsl-apt/pom.xml +++ b/querydsl-apt/pom.xml @@ -1,15 +1,15 @@ - + 4.0.0 - com.mysema.querydsl + com.querydsl querydsl-root - 3.4.1.BUILD-SNAPSHOT - ../querydsl-root/pom.xml + 5.1.0 + ../pom.xml - com.mysema.querydsl + com.querydsl querydsl-apt Querydsl - APT support APT based Source code generation for Querydsl @@ -22,15 +22,9 @@ ${project.githubpage} - - 4.2.0.Final - 2.3-eb - 0.105 - - - com.mysema.querydsl + com.querydsl querydsl-codegen ${project.version} @@ -40,24 +34,28 @@ - - - javax.jdo - jdo2-api - ${jdo.version} + org.jetbrains + annotations + provided + + + jakarta.persistence + jakarta.persistence-api + 2.2.3 provided - + + + - org.hibernate.javax.persistence - hibernate-jpa-2.0-api - 1.0.0.Final + org.datanucleus + javax.jdo provided org.springframework.roo org.springframework.roo.annotations - 1.2.3.RELEASE + 1.3.2.RELEASE provided @@ -85,7 +83,7 @@ joda-time joda-time - 1.6 + ${jodatime.version} test @@ -93,6 +91,12 @@ hibernate-core ${hibernate.version} test + + + javassist + org.javassist + + org.hibernate @@ -101,7 +105,7 @@ test - com.mysema.querydsl + com.querydsl querydsl-core ${project.version} test @@ -111,14 +115,13 @@ org.joda joda-money - 0.9 + 1.0.1 test org.eclipse.jdt.core.compiler ecj - 3.7.1 test @@ -128,21 +131,34 @@ + + + org.apache.maven.plugins + maven-jar-plugin + + + + com.querydsl.apt + + + + + - com.springsource.bundlor - com.springsource.bundlor.maven + org.apache.felix + maven-bundle-plugin @@ -150,7 +166,25 @@ false - + + + + org.eclipse.transformer + org.eclipse.transformer.maven + 0.2.0 + + + jakarta-ee + + run + + package + + jakarta + + + + maven-assembly-plugin @@ -167,6 +201,7 @@ src/main/hibernate.xml src/main/jdo.xml src/main/jpa.xml + src/main/jakarta.xml src/main/morphia.xml src/main/roo.xml src/main/onejar.xml @@ -176,7 +211,7 @@ - + com.mysema.maven apt-maven-plugin @@ -191,10 +226,10 @@ target/generated-test-sources/java true - com.mysema.query.apt.QuerydslAnnotationProcessor - com.mysema.query.apt.hibernate.HibernateAnnotationProcessor - com.mysema.query.apt.jdo.JDOAnnotationProcessor - com.mysema.query.apt.roo.RooAnnotationProcessor + com.querydsl.apt.QuerydslAnnotationProcessor + com.querydsl.apt.hibernate.HibernateAnnotationProcessor + com.querydsl.apt.jdo.JDOAnnotationProcessor + com.querydsl.apt.roo.RooAnnotationProcessor @@ -224,12 +259,6 @@ - - - - spring roo repository - http://spring-roo-repository.springsource.org/release - - + - + diff --git a/querydsl-apt/src/apt/general/META-INF/services/javax.annotation.processing.Processor b/querydsl-apt/src/apt/general/META-INF/services/javax.annotation.processing.Processor index 819d6cd88f..e31d641cff 100644 --- a/querydsl-apt/src/apt/general/META-INF/services/javax.annotation.processing.Processor +++ b/querydsl-apt/src/apt/general/META-INF/services/javax.annotation.processing.Processor @@ -1 +1 @@ -com.mysema.query.apt.QuerydslAnnotationProcessor \ No newline at end of file +com.querydsl.apt.QuerydslAnnotationProcessor \ No newline at end of file diff --git a/querydsl-apt/src/apt/hibernate/META-INF/services/javax.annotation.processing.Processor b/querydsl-apt/src/apt/hibernate/META-INF/services/javax.annotation.processing.Processor index 4f7291436b..bb12f8599e 100644 --- a/querydsl-apt/src/apt/hibernate/META-INF/services/javax.annotation.processing.Processor +++ b/querydsl-apt/src/apt/hibernate/META-INF/services/javax.annotation.processing.Processor @@ -1 +1 @@ -com.mysema.query.apt.hibernate.HibernateAnnotationProcessor \ No newline at end of file +com.querydsl.apt.hibernate.HibernateAnnotationProcessor \ No newline at end of file diff --git a/querydsl-apt/src/apt/jdo/META-INF/services/javax.annotation.processing.Processor b/querydsl-apt/src/apt/jdo/META-INF/services/javax.annotation.processing.Processor index 390c5f8f7f..ff511957d0 100644 --- a/querydsl-apt/src/apt/jdo/META-INF/services/javax.annotation.processing.Processor +++ b/querydsl-apt/src/apt/jdo/META-INF/services/javax.annotation.processing.Processor @@ -1 +1 @@ -com.mysema.query.apt.jdo.JDOAnnotationProcessor \ No newline at end of file +com.querydsl.apt.jdo.JDOAnnotationProcessor \ No newline at end of file diff --git a/querydsl-apt/src/apt/jpa/META-INF/gradle/incremental.annotation.processors b/querydsl-apt/src/apt/jpa/META-INF/gradle/incremental.annotation.processors new file mode 100644 index 0000000000..e6e3960816 --- /dev/null +++ b/querydsl-apt/src/apt/jpa/META-INF/gradle/incremental.annotation.processors @@ -0,0 +1 @@ +com.querydsl.apt.jpa.JPAAnnotationProcessor,isolating diff --git a/querydsl-apt/src/apt/jpa/META-INF/services/javax.annotation.processing.Processor b/querydsl-apt/src/apt/jpa/META-INF/services/javax.annotation.processing.Processor index 4774bfb506..720345c294 100644 --- a/querydsl-apt/src/apt/jpa/META-INF/services/javax.annotation.processing.Processor +++ b/querydsl-apt/src/apt/jpa/META-INF/services/javax.annotation.processing.Processor @@ -1 +1 @@ -com.mysema.query.apt.jpa.JPAAnnotationProcessor \ No newline at end of file +com.querydsl.apt.jpa.JPAAnnotationProcessor \ No newline at end of file diff --git a/querydsl-apt/src/apt/morphia/META-INF/services/javax.annotation.processing.Processor b/querydsl-apt/src/apt/morphia/META-INF/services/javax.annotation.processing.Processor index 7a4886bc1e..d0b82f8576 100644 --- a/querydsl-apt/src/apt/morphia/META-INF/services/javax.annotation.processing.Processor +++ b/querydsl-apt/src/apt/morphia/META-INF/services/javax.annotation.processing.Processor @@ -1 +1 @@ -com.mysema.query.apt.morphia.MorphiaAnnotationProcessor \ No newline at end of file +com.querydsl.apt.morphia.MorphiaAnnotationProcessor \ No newline at end of file diff --git a/querydsl-apt/src/apt/roo/META-INF/services/javax.annotation.processing.Processor b/querydsl-apt/src/apt/roo/META-INF/services/javax.annotation.processing.Processor index 689f34fa38..8ba591975e 100644 --- a/querydsl-apt/src/apt/roo/META-INF/services/javax.annotation.processing.Processor +++ b/querydsl-apt/src/apt/roo/META-INF/services/javax.annotation.processing.Processor @@ -1 +1 @@ -com.mysema.query.apt.roo.RooAnnotationProcessor \ No newline at end of file +com.querydsl.apt.roo.RooAnnotationProcessor \ No newline at end of file diff --git a/querydsl-apt/src/main/general.xml b/querydsl-apt/src/main/general.xml index 0ad441d8df..8c6293e7d1 100644 --- a/querydsl-apt/src/main/general.xml +++ b/querydsl-apt/src/main/general.xml @@ -8,12 +8,12 @@ false - src/apt/general - / - + src/apt/general + / + - ${project.build.outputDirectory} - / - + ${project.build.outputDirectory} + / + \ No newline at end of file diff --git a/querydsl-apt/src/main/hibernate.xml b/querydsl-apt/src/main/hibernate.xml index 98cb428ca2..4861280d03 100644 --- a/querydsl-apt/src/main/hibernate.xml +++ b/querydsl-apt/src/main/hibernate.xml @@ -8,12 +8,12 @@ false - src/apt/hibernate - / - + src/apt/hibernate + / + - ${project.build.outputDirectory} - / - + ${project.build.outputDirectory} + / + \ No newline at end of file diff --git a/querydsl-apt/src/main/jakarta.xml b/querydsl-apt/src/main/jakarta.xml new file mode 100644 index 0000000000..959d5d1cc9 --- /dev/null +++ b/querydsl-apt/src/main/jakarta.xml @@ -0,0 +1,29 @@ + + jakarta + + jar + + false + + + true + + ${project.groupId}:${project.artifactId} + + + true + false + jakarta + / + + + + + + src/apt/jpa + / + + + \ No newline at end of file diff --git a/querydsl-apt/src/main/java/com/mysema/query/apt/APTException.java b/querydsl-apt/src/main/java/com/mysema/query/apt/APTException.java deleted file mode 100644 index 066264e0fe..0000000000 --- a/querydsl-apt/src/main/java/com/mysema/query/apt/APTException.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.apt; - -/** - * Exception thrown on APT processing errors - * - * @author tiwe - * - */ -public class APTException extends RuntimeException { - - private static final long serialVersionUID = -8456970330509020462L; - - public APTException(String msg) { - super(msg); - } - - public APTException(String msg, Throwable t) { - super(msg, t); - } - - public APTException(Throwable t) { - super(t); - } - -} diff --git a/querydsl-apt/src/main/java/com/mysema/query/apt/APTOptions.java b/querydsl-apt/src/main/java/com/mysema/query/apt/APTOptions.java deleted file mode 100644 index f98bb65395..0000000000 --- a/querydsl-apt/src/main/java/com/mysema/query/apt/APTOptions.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.apt; - -/** - * APT options supported by Querydsl - * - * @author tiwe - * - */ -public final class APTOptions { - - public static final String QUERYDSL_CREATE_DEFAULT_VARIABLE = "querydsl.createDefaultVariable"; - - public static final String QUERYDSL_PREFIX = "querydsl.prefix"; - - public static final String QUERYDSL_SUFFIX = "querydsl.suffix"; - - public static final String QUERYDSL_PACKAGE_SUFFIX = "querydsl.packageSuffix"; - - public static final String QUERYDSL_MAP_ACCESSORS = "querydsl.mapAccessors"; - - public static final String QUERYDSL_LIST_ACCESSORS = "querydsl.listAccessors"; - - public static final String QUERYDSL_ENTITY_ACCESSORS = "querydsl.entityAccessors"; - - public static final String QUERYDSL_EXCLUDED_PACKAGES = "querydsl.excludedPackages"; - - public static final String QUERYDSL_EXCLUDED_CLASSES = "querydsl.excludedClasses"; - - public static final String QUERYDSL_INCLUDED_PACKAGES = "querydsl.includedPackages"; - - public static final String QUERYDSL_INCLUDED_CLASSES = "querydsl.includedClasses"; - - public static final String QUERYDSL_UNKNOWN_AS_EMBEDDABLE = "querydsl.unknownAsEmbeddable"; - - private APTOptions() {} - -} diff --git a/querydsl-apt/src/main/java/com/mysema/query/apt/Configuration.java b/querydsl-apt/src/main/java/com/mysema/query/apt/Configuration.java deleted file mode 100644 index 9a24f5f4b3..0000000000 --- a/querydsl-apt/src/main/java/com/mysema/query/apt/Configuration.java +++ /dev/null @@ -1,231 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.apt; - -import java.lang.annotation.Annotation; -import java.util.Collection; -import java.util.List; -import java.util.Set; - -import javax.annotation.Nullable; -import javax.lang.model.element.Element; -import javax.lang.model.element.ExecutableElement; -import javax.lang.model.element.TypeElement; -import javax.lang.model.element.VariableElement; -import javax.lang.model.type.TypeMirror; - -import com.mysema.query.codegen.EntityType; -import com.mysema.query.codegen.QueryTypeFactory; -import com.mysema.query.codegen.Serializer; -import com.mysema.query.codegen.SerializerConfig; -import com.mysema.query.codegen.TypeMappings; -import com.mysema.util.Annotations; - -/** - * Configuration defines the configuration options for APT based Querydsl code generation - * - * @author tiwe - * - */ -public interface Configuration { - - /** - * @return - */ - boolean isUnknownAsEmbedded(); - - /** - * @return - */ - TypeMappings getTypeMappings(); - - /** - * @param e - * @param elements - * @return - */ - VisitorConfig getConfig(TypeElement e, List elements); - - /** - * @return - */ - Serializer getDTOSerializer(); - - /** - * @return - */ - @Nullable - Class getEntitiesAnnotation(); - - /** - * @return - */ - @Nullable - Class getEmbeddedAnnotation(); - - /** - * @return - */ - @Nullable - Class getEmbeddableAnnotation(); - - /** - * @return - */ - Serializer getEmbeddableSerializer(); - - /** - * @return - */ - Class getEntityAnnotation(); - - /** - * @return - */ - Class getAlternativeEntityAnnotation(); - - /** - * @return - */ - Set> getEntityAnnotations(); - - /** - * @return - */ - Serializer getEntitySerializer(); - - /** - * @return - */ - String getNamePrefix(); - - /** - * @return - */ - String getNameSuffix(); - - /** - * @param entityType - * @return - */ - SerializerConfig getSerializerConfig(EntityType entityType); - - /** - * @return - */ - @Nullable - Class getSkipAnnotation(); - - /** - * @return - */ - @Nullable - Class getSuperTypeAnnotation(); - - /** - * @return - */ - Serializer getSupertypeSerializer(); - - /** - * @param field - * @return - */ - boolean isBlockedField(VariableElement field); - - /** - * @param getter - * @return - */ - boolean isBlockedGetter(ExecutableElement getter); - - /** - * @return - */ - boolean isUseFields(); - - /** - * @return - */ - boolean isUseGetters(); - - /** - * @param constructor - * @return - */ - boolean isValidConstructor(ExecutableElement constructor); - - /** - * @param field - * @return - */ - boolean isValidField(VariableElement field); - - /** - * @param getter - * @return - */ - boolean isValidGetter(ExecutableElement getter); - - /** - * @return - */ - Collection getKeywords(); - - /** - * @return - */ - QueryTypeFactory getQueryTypeFactory(); - - /** - * @param packageName - */ - void addExcludedPackage(String packageName); - - /** - * @param className - */ - void addExcludedClass(String className); - - /** - * @param method - * @return - */ - TypeMirror getRealType(ExecutableElement method); - - /** - * @param field - * @return - */ - TypeMirror getRealType(VariableElement field); - - /** - * @param packageName - * @return - */ - boolean isExcludedPackage(String packageName); - - /** - * @param className - * @return - */ - boolean isExcludedClass(String className); - - /** - * @param element - * @param annotations - */ - void inspect(Element element, Annotations annotations); - -} diff --git a/querydsl-apt/src/main/java/com/mysema/query/apt/Context.java b/querydsl-apt/src/main/java/com/mysema/query/apt/Context.java deleted file mode 100644 index 9af8e5ab22..0000000000 --- a/querydsl-apt/src/main/java/com/mysema/query/apt/Context.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.apt; - -import java.util.HashMap; -import java.util.Map; -import java.util.Set; - -import javax.lang.model.element.TypeElement; - -import com.mysema.query.codegen.EntityType; - -/** - * Context of handled types used by {@link AbstractQuerydslProcessor} - * - * @author tiwe - * - */ -public class Context { - - final Map supertypes = new HashMap(); - - final Map allTypes = new HashMap(); - - final Map projectionTypes = new HashMap(); - - final Map embeddableTypes = new HashMap(); - - final Map entityTypes = new HashMap(); - - final Map extensionTypes = new HashMap(); - - final Map> typeElements = new HashMap>(); - - public void clean() { - for (String key : supertypes.keySet()) { - entityTypes.remove(key); - extensionTypes.remove(key); - embeddableTypes.remove(key); - } - - for (String key : entityTypes.keySet()) { - supertypes.remove(key); - extensionTypes.remove(key); - embeddableTypes.remove(key); - } - } - -} diff --git a/querydsl-apt/src/main/java/com/mysema/query/apt/DefaultConfiguration.java b/querydsl-apt/src/main/java/com/mysema/query/apt/DefaultConfiguration.java deleted file mode 100644 index 02c48989b4..0000000000 --- a/querydsl-apt/src/main/java/com/mysema/query/apt/DefaultConfiguration.java +++ /dev/null @@ -1,485 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.apt; - -import static com.mysema.query.apt.APTOptions.QUERYDSL_CREATE_DEFAULT_VARIABLE; -import static com.mysema.query.apt.APTOptions.QUERYDSL_ENTITY_ACCESSORS; -import static com.mysema.query.apt.APTOptions.QUERYDSL_EXCLUDED_CLASSES; -import static com.mysema.query.apt.APTOptions.QUERYDSL_EXCLUDED_PACKAGES; -import static com.mysema.query.apt.APTOptions.QUERYDSL_INCLUDED_CLASSES; -import static com.mysema.query.apt.APTOptions.QUERYDSL_INCLUDED_PACKAGES; -import static com.mysema.query.apt.APTOptions.QUERYDSL_LIST_ACCESSORS; -import static com.mysema.query.apt.APTOptions.QUERYDSL_MAP_ACCESSORS; -import static com.mysema.query.apt.APTOptions.QUERYDSL_PACKAGE_SUFFIX; -import static com.mysema.query.apt.APTOptions.QUERYDSL_PREFIX; -import static com.mysema.query.apt.APTOptions.QUERYDSL_SUFFIX; -import static com.mysema.query.apt.APTOptions.QUERYDSL_UNKNOWN_AS_EMBEDDABLE; - -import java.lang.annotation.Annotation; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import javax.annotation.processing.RoundEnvironment; -import javax.lang.model.element.Element; -import javax.lang.model.element.ExecutableElement; -import javax.lang.model.element.Modifier; -import javax.lang.model.element.PackageElement; -import javax.lang.model.element.TypeElement; -import javax.lang.model.element.VariableElement; -import javax.lang.model.type.TypeMirror; - -import com.google.common.base.Strings; -import com.mysema.codegen.model.ClassType; -import com.mysema.query.annotations.Config; -import com.mysema.query.annotations.QueryProjection; -import com.mysema.query.annotations.QueryType; -import com.mysema.query.codegen.CodegenModule; -import com.mysema.query.codegen.EmbeddableSerializer; -import com.mysema.query.codegen.EntitySerializer; -import com.mysema.query.codegen.EntityType; -import com.mysema.query.codegen.ProjectionSerializer; -import com.mysema.query.codegen.QueryTypeFactory; -import com.mysema.query.codegen.Serializer; -import com.mysema.query.codegen.SerializerConfig; -import com.mysema.query.codegen.SimpleSerializerConfig; -import com.mysema.query.codegen.SupertypeSerializer; -import com.mysema.query.codegen.TypeMappings; -import com.mysema.query.types.Expression; -import com.mysema.util.Annotations; - -/** - * DefaultConfiguration is a simple implementation of the {@link Configuration} interface - * - * @author tiwe - * - */ -public class DefaultConfiguration implements Configuration { - - private static final String DEFAULT_SEPARATOR = ","; - - private boolean unknownAsEmbedded; - - private final CodegenModule module = new CodegenModule(); - - private final SerializerConfig defaultSerializerConfig; - - private final Map packageToConfig = new HashMap(); - - protected final Class entityAnn; - - @Nonnull - private final Set excludedPackages, excludedClasses; - - @Nonnull - private final Set includedPackages, includedClasses; - - @Nullable - protected final Class entitiesAnn, superTypeAnn, embeddedAnn, embeddableAnn, skipAnn; - - @Nullable - protected Class altEntityAnn; - - private final Set> entityAnnotations = new HashSet>(); - - private final Map typeToConfig = new HashMap(); - - private boolean useFields = true, useGetters = true; - - public DefaultConfiguration( - RoundEnvironment roundEnv, - Map options, - Collection keywords, - @Nullable Class entitiesAnn, - Class entityAnn, - @Nullable Class superTypeAnn, - @Nullable Class embeddableAnn, - @Nullable Class embeddedAnn, - @Nullable Class skipAnn) { - this.excludedClasses = new HashSet(); - this.excludedPackages = new HashSet(); - this.includedClasses = new HashSet(); - this.includedPackages = new HashSet(); - module.bind(RoundEnvironment.class, roundEnv); - module.bind(CodegenModule.KEYWORDS, keywords); - this.entitiesAnn = entitiesAnn; - this.entityAnn = entityAnn; - this.superTypeAnn = superTypeAnn; - this.embeddableAnn = embeddableAnn; - this.embeddedAnn = embeddedAnn; - this.skipAnn = skipAnn; - - entityAnnotations.add(entityAnn); - if (superTypeAnn != null) { - entityAnnotations.add(superTypeAnn); - } - if (embeddableAnn != null) { - entityAnnotations.add(embeddableAnn); - } - for (Element element : roundEnv.getElementsAnnotatedWith(Config.class)) { - Config querydslConfig = element.getAnnotation(Config.class); - SerializerConfig config = SimpleSerializerConfig.getConfig(querydslConfig); - if (element instanceof PackageElement) { - PackageElement packageElement = (PackageElement)element; - packageToConfig.put(packageElement.getQualifiedName().toString(), config); - } else if (element instanceof TypeElement) { - TypeElement typeElement = (TypeElement)element; - typeToConfig.put(typeElement.getQualifiedName().toString(), config); - } - } - boolean entityAccessors = false; - boolean listAccessors = false; - boolean mapAccessors = false; - boolean createDefaultVariable = true; - - if (options.containsKey(QUERYDSL_ENTITY_ACCESSORS)) { - entityAccessors = Boolean.valueOf(options.get(QUERYDSL_ENTITY_ACCESSORS)); - } - if (options.containsKey(QUERYDSL_LIST_ACCESSORS)) { - listAccessors = Boolean.valueOf(options.get(QUERYDSL_LIST_ACCESSORS)); - } - if (options.containsKey(QUERYDSL_MAP_ACCESSORS)) { - mapAccessors = Boolean.valueOf(options.get(QUERYDSL_MAP_ACCESSORS)); - } - if (options.containsKey(QUERYDSL_CREATE_DEFAULT_VARIABLE)) { - createDefaultVariable = Boolean.valueOf(options.get(QUERYDSL_CREATE_DEFAULT_VARIABLE)); - } - if (options.containsKey(QUERYDSL_PACKAGE_SUFFIX)) { - module.bind(CodegenModule.PACKAGE_SUFFIX, Strings.nullToEmpty(options.get(QUERYDSL_PACKAGE_SUFFIX))); - } - if (options.containsKey(QUERYDSL_PREFIX)) { - module.bind(CodegenModule.PREFIX, Strings.nullToEmpty(options.get(QUERYDSL_PREFIX))); - } - if (options.containsKey(QUERYDSL_SUFFIX)) { - module.bind(CodegenModule.SUFFIX, Strings.nullToEmpty(options.get(QUERYDSL_SUFFIX))); - } - if (options.containsKey(QUERYDSL_UNKNOWN_AS_EMBEDDABLE)) { - unknownAsEmbedded = Boolean.valueOf(options.get(QUERYDSL_UNKNOWN_AS_EMBEDDABLE)); - } - - if (options.containsKey(QUERYDSL_EXCLUDED_PACKAGES)) { - String packageString = options.get(QUERYDSL_EXCLUDED_PACKAGES); - if (!Strings.isNullOrEmpty(packageString)) { - for (String packageName : packageString.split(DEFAULT_SEPARATOR)) { - excludedPackages.add(packageName); - } - } - } - - if (options.containsKey(QUERYDSL_EXCLUDED_CLASSES)) { - String classString = options.get(QUERYDSL_EXCLUDED_CLASSES); - if (!Strings.isNullOrEmpty(classString)) { - for (String className : classString.split(DEFAULT_SEPARATOR)) { - excludedClasses.add(className); - } - } - } - - if (options.containsKey(QUERYDSL_INCLUDED_PACKAGES)) { - String packageString = options.get(QUERYDSL_INCLUDED_PACKAGES); - if (!Strings.isNullOrEmpty(packageString)) { - for (String packageName : packageString.split(DEFAULT_SEPARATOR)) { - includedPackages.add(packageName); - } - } - } - - if (options.containsKey(QUERYDSL_INCLUDED_CLASSES)) { - String classString = options.get(QUERYDSL_INCLUDED_CLASSES); - if (!Strings.isNullOrEmpty(classString)) { - for (String className : classString.split(DEFAULT_SEPARATOR)) { - includedClasses.add(className); - } - } - } - - defaultSerializerConfig = new SimpleSerializerConfig(entityAccessors, listAccessors, - mapAccessors, createDefaultVariable, ""); - - } - - @Override - public void addExcludedClass(String className) { - excludedClasses.add(className); - } - - @Override - public void addExcludedPackage(String packageName) { - excludedPackages.add(packageName); - } - - @Override - public VisitorConfig getConfig(TypeElement e, List elements) { - if (useFields) { - if (useGetters) { - return VisitorConfig.ALL; - } else { - return VisitorConfig.FIELDS_ONLY; - } - } else if (useGetters) { - return VisitorConfig.METHODS_ONLY; - } else { - return VisitorConfig.NONE; - } - } - - @Override - public Serializer getDTOSerializer() { - return module.get(ProjectionSerializer.class); - } - - @Override - @Nullable - public Class getEntitiesAnnotation() { - return entitiesAnn; - } - - @Override - @Nullable - public Class getEmbeddableAnnotation() { - return embeddableAnn; - } - - @Override - public Serializer getEmbeddableSerializer() { - return module.get(EmbeddableSerializer.class); - } - - @Override - public Class getEntityAnnotation() { - return entityAnn; - } - - @Override - public Class getAlternativeEntityAnnotation() { - return altEntityAnn; - } - - public void setAlternativeEntityAnnotation(Class ann) { - altEntityAnn = ann; - entityAnnotations.add(ann); - } - - @Override - @Nullable - public Class getEmbeddedAnnotation() { - return embeddedAnn; - } - - @Override - public Set> getEntityAnnotations() { - return entityAnnotations; - } - - @Override - public Serializer getEntitySerializer() { - return module.get(EntitySerializer.class); - } - - @Override - public String getNamePrefix() { - return module.get(String.class, "prefix"); - } - - @Override - public SerializerConfig getSerializerConfig(EntityType entityType) { - if (typeToConfig.containsKey(entityType.getFullName())) { - return typeToConfig.get(entityType.getFullName()); - } else if (packageToConfig.containsKey(entityType.getPackageName())) { - return packageToConfig.get(entityType.getPackageName()); - } else { - return defaultSerializerConfig; - } - } - - @Override - @Nullable - public Class getSkipAnnotation() { - return skipAnn; - } - - @Override - @Nullable - public Class getSuperTypeAnnotation() { - return superTypeAnn; - } - - @Override - public Serializer getSupertypeSerializer() { - return module.get(SupertypeSerializer.class); - } - - @Override - public void inspect(Element element, Annotations annotations) { - // do nothing - } - - @Override - public boolean isBlockedField(VariableElement field) { - if (field.getAnnotation(QueryType.class) != null) { - return false; - } else { - return field.getAnnotation(skipAnn) != null - || field.getModifiers().contains(Modifier.TRANSIENT) - || field.getModifiers().contains(Modifier.STATIC); - } - } - - @Override - public boolean isBlockedGetter(ExecutableElement getter) { - if (getter.getAnnotation(QueryType.class) != null) { - return false; - } else { - return getter.getAnnotation(skipAnn) != null - || getter.getModifiers().contains(Modifier.STATIC); - } - } - - @Override - public boolean isUseFields() { - return useFields; - } - - @Override - public boolean isUseGetters() { - return useGetters; - } - - @Override - public boolean isValidConstructor(ExecutableElement constructor) { - return constructor.getModifiers().contains(Modifier.PUBLIC) - && constructor.getAnnotation(QueryProjection.class) != null - && !constructor.getParameters().isEmpty(); - } - - @Override - public boolean isValidField(VariableElement field) { - if (field.getAnnotation(QueryType.class) != null) { - return true; - } else { - return field.getAnnotation(skipAnn) == null - && !field.getModifiers().contains(Modifier.TRANSIENT) - && !field.getModifiers().contains(Modifier.STATIC); - } - } - - @Override - public boolean isValidGetter(ExecutableElement getter) { - if (getter.getAnnotation(QueryType.class) != null) { - return true; - } else { - return getter.getAnnotation(skipAnn) == null - && !getter.getModifiers().contains(Modifier.STATIC); - } - } - - public void setNamePrefix(String namePrefix) { - module.bind(CodegenModule.PREFIX, namePrefix); - } - - public void setUseFields(boolean b) { - this.useFields = b; - } - - public void setUseGetters(boolean b) { - this.useGetters = b; - } - - @Override - public TypeMappings getTypeMappings() { - return module.get(TypeMappings.class); - } - - @SuppressWarnings("unchecked") - @Override - public Collection getKeywords() { - return module.get(Collection.class, CodegenModule.KEYWORDS); - } - - @Override - public String getNameSuffix() { - return module.get(String.class, CodegenModule.SUFFIX); - } - - public void setNameSuffix(String nameSuffix) { - module.bind(CodegenModule.SUFFIX, nameSuffix); - } - - public void addCustomType(Class type, Class> queryType) { - module.get(TypeMappings.class).register(new ClassType(type), new ClassType(queryType)); - } - - @Override - public QueryTypeFactory getQueryTypeFactory() { - return module.get(QueryTypeFactory.class); - } - - @Override - public boolean isExcludedPackage(@Nonnull String packageName) { - if (!includedPackages.isEmpty()) { - boolean included = false; - for (String includedPackage : includedPackages) { - if (packageName.startsWith(includedPackage)) { - included = true; - break; - } - } - if (!included) { - return true; - } - } - if (!excludedPackages.isEmpty()) { - for (String excludedPackage : excludedPackages) { - if (packageName.startsWith(excludedPackage)) { - return true; - } - } - } - return false; - } - - @Override - public boolean isExcludedClass(@Nonnull String className) { - if (!includedClasses.isEmpty() && !includedClasses.contains(className)) { - return true; - } else { - return excludedClasses.contains(className); - } - } - - @Override - public TypeMirror getRealType(ExecutableElement method) { - return null; - } - - @Override - public TypeMirror getRealType(VariableElement field) { - return null; - } - - @Override - public boolean isUnknownAsEmbedded() { - return unknownAsEmbedded; - } - - public void setUnknownAsEmbedded(boolean unknownAsEmbedded) { - this.unknownAsEmbedded = unknownAsEmbedded; - } - -} diff --git a/querydsl-apt/src/main/java/com/mysema/query/apt/QuerydslAnnotationProcessor.java b/querydsl-apt/src/main/java/com/mysema/query/apt/QuerydslAnnotationProcessor.java deleted file mode 100644 index bf25cbf9d4..0000000000 --- a/querydsl-apt/src/main/java/com/mysema/query/apt/QuerydslAnnotationProcessor.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.apt; - -import java.lang.annotation.Annotation; -import java.util.Collections; - -import javax.annotation.processing.RoundEnvironment; -import javax.annotation.processing.SupportedAnnotationTypes; - -import com.mysema.query.annotations.QueryEmbeddable; -import com.mysema.query.annotations.QueryEmbedded; -import com.mysema.query.annotations.QueryEntities; -import com.mysema.query.annotations.QueryEntity; -import com.mysema.query.annotations.QuerySupertype; -import com.mysema.query.annotations.QueryTransient; - -/** - * Default annotation processor for Querydsl which handles {@link QueryEntity}, {@link QuerySupertype}, - * {@link QueryEmbeddable}, {@link QueryEmbedded} and {@link QueryTransient} - * - * @author tiwe - * - */ -@SupportedAnnotationTypes({"com.mysema.query.annotations.*"}) -public class QuerydslAnnotationProcessor extends AbstractQuerydslProcessor { - - @Override - protected Configuration createConfiguration(RoundEnvironment roundEnv) { - Class entities = QueryEntities.class; - Class entity = QueryEntity.class; - Class superType = QuerySupertype.class; - Class embeddable = QueryEmbeddable.class; - Class embedded = QueryEmbedded.class; - Class skip = QueryTransient.class; - - return new DefaultConfiguration( - roundEnv, processingEnv.getOptions(), Collections.emptySet(), entities, - entity, superType, embeddable, embedded, skip); - } - -} diff --git a/querydsl-apt/src/main/java/com/mysema/query/apt/TypeExtractor.java b/querydsl-apt/src/main/java/com/mysema/query/apt/TypeExtractor.java deleted file mode 100644 index 6a36a5d3f9..0000000000 --- a/querydsl-apt/src/main/java/com/mysema/query/apt/TypeExtractor.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.apt; - -import javax.lang.model.element.TypeElement; -import javax.lang.model.type.ArrayType; -import javax.lang.model.type.DeclaredType; -import javax.lang.model.type.ErrorType; -import javax.lang.model.type.ExecutableType; -import javax.lang.model.type.NoType; -import javax.lang.model.type.NullType; -import javax.lang.model.type.PrimitiveType; -import javax.lang.model.type.TypeVariable; -import javax.lang.model.type.WildcardType; -import javax.lang.model.util.AbstractTypeVisitor6; - -/** - * TypeExtractor is a visitor implementation which a concrete type given a general {@link TypeElement} - * - * @author tiwe - * - */ -public class TypeExtractor extends AbstractTypeVisitor6 { - - private final boolean skipEnum; - - public TypeExtractor(boolean skipEnum) { - this.skipEnum = skipEnum; - } - - @Override - public TypeElement visitPrimitive(PrimitiveType t, Void p) { - return null; - } - - @Override - public TypeElement visitNull(NullType t, Void p) { - return null; - } - - @Override - public TypeElement visitArray(ArrayType t, Void p) { - return visit(t.getComponentType()); - } - - @Override - public TypeElement visitDeclared(DeclaredType t, Void p) { - if (t.asElement() instanceof TypeElement) { - TypeElement typeElement = (TypeElement)t.asElement(); - switch (typeElement.getKind()) { - case ENUM: return skipEnum ? null : typeElement; - case CLASS: return typeElement; - case INTERFACE: return visitInterface(t); - default: throw new IllegalArgumentException("Illegal type " + typeElement); - } - } else { - return null; - } - } - - private TypeElement visitInterface(DeclaredType t) { - if (t.getTypeArguments().isEmpty()) { - return (TypeElement)t.asElement(); - } else { - int count = t.getTypeArguments().size(); - if (t.asElement().toString().startsWith("java.util")) { - return t.getTypeArguments().get(count - 1).accept(this, null); - } else { - return (TypeElement)t.asElement(); - } - } - } - - @Override - public TypeElement visitError(ErrorType t, Void p) { - return visitDeclared(t, p); - } - - @Override - public TypeElement visitTypeVariable(TypeVariable t, Void p) { - if (t.getUpperBound() != null) { - return visit(t.getUpperBound()); - } else if (t.getLowerBound() != null) { - return visit(t.getLowerBound()); - } else { - return null; - } - } - - @Override - public TypeElement visitWildcard(WildcardType t, Void p) { - if (t.getExtendsBound() != null) { - return visit(t.getExtendsBound()); - } else if (t.getSuperBound() != null) { - return visit(t.getSuperBound()); - } else { - return null; - } - - } - - @Override - public TypeElement visitExecutable(ExecutableType t, Void p) { - return null; - } - - @Override - public TypeElement visitNoType(NoType t, Void p) { - return null; - } - - -} diff --git a/querydsl-apt/src/main/java/com/mysema/query/apt/UnsupportedTypeException.java b/querydsl-apt/src/main/java/com/mysema/query/apt/UnsupportedTypeException.java deleted file mode 100644 index b77a4f12e1..0000000000 --- a/querydsl-apt/src/main/java/com/mysema/query/apt/UnsupportedTypeException.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.apt; - -import javax.lang.model.type.TypeMirror; - -/** - * UnsupportedTypeException is thrown for unsupported types - * - * @author tiwe - * - */ -public class UnsupportedTypeException extends APTException { - - private static final long serialVersionUID = 1082936662325717262L; - - public UnsupportedTypeException(TypeMirror mirror) { - super("Unsupported type " + mirror); - } -} diff --git a/querydsl-apt/src/main/java/com/mysema/query/apt/hibernate/HibernateAnnotationProcessor.java b/querydsl-apt/src/main/java/com/mysema/query/apt/hibernate/HibernateAnnotationProcessor.java deleted file mode 100644 index f1b9b2e127..0000000000 --- a/querydsl-apt/src/main/java/com/mysema/query/apt/hibernate/HibernateAnnotationProcessor.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.apt.hibernate; - -import java.lang.annotation.Annotation; - -import javax.annotation.processing.RoundEnvironment; -import javax.annotation.processing.SupportedAnnotationTypes; -import javax.persistence.Embeddable; -import javax.persistence.Embedded; -import javax.persistence.Entity; -import javax.persistence.MappedSuperclass; -import javax.persistence.Transient; - -import com.mysema.query.apt.Configuration; -import com.mysema.query.apt.jpa.JPAAnnotationProcessor; - -/** - * HibernateAnnotationProcessor extends {@link JPAAnnotationProcessor} to take Hibernate specific - * annotations into account - * - * @author tiwe - * @see JPAAnnotationProcessor - */ -@SupportedAnnotationTypes({"com.mysema.query.annotations.*","javax.persistence.*", "org.hibernate.annotations.*"}) -public class HibernateAnnotationProcessor extends JPAAnnotationProcessor { - - @Override - protected Configuration createConfiguration(RoundEnvironment roundEnv) { - try { - Class entity = Entity.class; - Class superType = MappedSuperclass.class; - Class embeddable = Embeddable.class; - Class embedded = Embedded.class; - Class skip = Transient.class; - return new HibernateConfiguration(roundEnv, processingEnv.getOptions(), entity, superType, - embeddable, embedded, skip); - } catch (ClassNotFoundException e) { - throw new RuntimeException(e); - } - } - -} diff --git a/querydsl-apt/src/main/java/com/mysema/query/apt/hibernate/package-info.java b/querydsl-apt/src/main/java/com/mysema/query/apt/hibernate/package-info.java deleted file mode 100644 index 39a6940570..0000000000 --- a/querydsl-apt/src/main/java/com/mysema/query/apt/hibernate/package-info.java +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -/** - * APT Hibernate support - */ -package com.mysema.query.apt.hibernate; diff --git a/querydsl-apt/src/main/java/com/mysema/query/apt/jdo/JDOAnnotationProcessor.java b/querydsl-apt/src/main/java/com/mysema/query/apt/jdo/JDOAnnotationProcessor.java deleted file mode 100644 index 3e6674a6d6..0000000000 --- a/querydsl-apt/src/main/java/com/mysema/query/apt/jdo/JDOAnnotationProcessor.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.apt.jdo; - -import java.lang.annotation.Annotation; - -import javax.annotation.processing.RoundEnvironment; -import javax.annotation.processing.SupportedAnnotationTypes; -import javax.jdo.annotations.EmbeddedOnly; -import javax.jdo.annotations.NotPersistent; -import javax.jdo.annotations.PersistenceCapable; -import javax.persistence.Embedded; - -import com.mysema.query.annotations.QueryEntities; -import com.mysema.query.annotations.QuerySupertype; -import com.mysema.query.apt.AbstractQuerydslProcessor; -import com.mysema.query.apt.Configuration; -import com.mysema.query.apt.DefaultConfiguration; -import com.mysema.query.codegen.Keywords; - -/** - * AnnotationProcessor for JDO which takes {@link PersistenceCapable}, {@link EmbeddedOnly} and - * {@link NotPersistent} into account - * - * @author tiwe - * - */ -@SupportedAnnotationTypes({"com.mysema.query.annotations.*","javax.jdo.annotations.*"}) -public class JDOAnnotationProcessor extends AbstractQuerydslProcessor { - - @Override - protected Configuration createConfiguration(RoundEnvironment roundEnv) { - Class entities = QueryEntities.class; - Class entity = PersistenceCapable.class; - Class superType = QuerySupertype.class; - Class embeddable = EmbeddedOnly.class; - Class embedded = Embedded.class; - Class skip = NotPersistent.class; - return new DefaultConfiguration(roundEnv, processingEnv.getOptions(), Keywords.JDO, - entities, entity, superType, embeddable, embedded, skip); - } -} diff --git a/querydsl-apt/src/main/java/com/mysema/query/apt/jdo/package-info.java b/querydsl-apt/src/main/java/com/mysema/query/apt/jdo/package-info.java deleted file mode 100644 index e58068427e..0000000000 --- a/querydsl-apt/src/main/java/com/mysema/query/apt/jdo/package-info.java +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ - -/** - * APT JDO support - */ -package com.mysema.query.apt.jdo; diff --git a/querydsl-apt/src/main/java/com/mysema/query/apt/jpa/JPAAnnotationProcessor.java b/querydsl-apt/src/main/java/com/mysema/query/apt/jpa/JPAAnnotationProcessor.java deleted file mode 100644 index bfd3e44514..0000000000 --- a/querydsl-apt/src/main/java/com/mysema/query/apt/jpa/JPAAnnotationProcessor.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.apt.jpa; - -import java.lang.annotation.Annotation; - -import javax.annotation.processing.RoundEnvironment; -import javax.annotation.processing.SupportedAnnotationTypes; -import javax.persistence.Embeddable; -import javax.persistence.Embedded; -import javax.persistence.Entity; -import javax.persistence.MappedSuperclass; -import javax.persistence.Transient; - -import com.mysema.query.apt.AbstractQuerydslProcessor; -import com.mysema.query.apt.Configuration; - -/** - * AnnotationProcessor for JPA which takes {@link Entity}, {@link MappedSuperclass}, {@link Embeddable} - * and {@link Transient} into account - * - * @author tiwe - * - */ -@SupportedAnnotationTypes({"com.mysema.query.annotations.*","javax.persistence.*"}) -public class JPAAnnotationProcessor extends AbstractQuerydslProcessor { - - @Override - protected Configuration createConfiguration(RoundEnvironment roundEnv) { - Class entity = Entity.class; - Class superType = MappedSuperclass.class; - Class embeddable = Embeddable.class; - Class embedded = Embedded.class; - Class skip = Transient.class; - return new JPAConfiguration(roundEnv, processingEnv.getOptions(), - entity, superType, embeddable, embedded, skip); - } - -} diff --git a/querydsl-apt/src/main/java/com/mysema/query/apt/jpa/JPAConfiguration.java b/querydsl-apt/src/main/java/com/mysema/query/apt/jpa/JPAConfiguration.java deleted file mode 100644 index e8c57cc853..0000000000 --- a/querydsl-apt/src/main/java/com/mysema/query/apt/jpa/JPAConfiguration.java +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.apt.jpa; - -import javax.annotation.processing.RoundEnvironment; -import javax.lang.model.element.*; -import javax.lang.model.type.DeclaredType; -import javax.lang.model.type.TypeMirror; -import javax.lang.model.util.Types; -import javax.persistence.*; -import java.lang.annotation.Annotation; -import java.util.List; -import java.util.Map; - -import com.google.common.collect.ImmutableList; -import com.mysema.query.annotations.PropertyType; -import com.mysema.query.annotations.QueryEntities; -import com.mysema.query.annotations.QueryTransient; -import com.mysema.query.annotations.QueryType; -import com.mysema.query.apt.*; -import com.mysema.query.codegen.Keywords; -import com.mysema.util.Annotations; - -/** - * Configuration for {@link JPAAnnotationProcessor} - * - * @author tiwe - * @see JPAAnnotationProcessor - */ -public class JPAConfiguration extends DefaultConfiguration { - - private final List> annotations; - - private final Types types; - - public JPAConfiguration(RoundEnvironment roundEnv, - Map options, - Class entityAnn, - Class superTypeAnn, - Class embeddableAnn, - Class embeddedAnn, - Class skipAnn) { - super(roundEnv, options, Keywords.JPA, QueryEntities.class, entityAnn, superTypeAnn, - embeddableAnn, embeddedAnn, skipAnn); - this.annotations = getAnnotations(); - // TODO replace with proper injection in Querydsl 4.0.0 - this.types = AbstractQuerydslProcessor.TYPES; - } - - @SuppressWarnings("unchecked") - protected List> getAnnotations() { - return ImmutableList.of( - Access.class, Basic.class, Column.class, ElementCollection.class, - Embedded.class, EmbeddedId.class, Enumerated.class, GeneratedValue.class, Id.class, - JoinColumn.class, ManyToOne.class, ManyToMany.class, MapKeyEnumerated.class, - OneToOne.class, OneToMany.class, PrimaryKeyJoinColumn.class, QueryType.class, - QueryTransient.class, Temporal.class, Transient.class, Version.class); - } - - @Override - public VisitorConfig getConfig(TypeElement e, List elements) { - Access access = e.getAnnotation(Access.class); - if (access != null) { - if (access.value() == AccessType.FIELD) { - return VisitorConfig.FIELDS_ONLY; - } else { - return VisitorConfig.METHODS_ONLY; - } - } - boolean fields = false, methods = false; - for (Element element : elements) { - if (hasRelevantAnnotation(element)) { - fields |= element.getKind().equals(ElementKind.FIELD); - methods |= element.getKind().equals(ElementKind.METHOD); - } - } - return VisitorConfig.get(fields, methods); - } - - @Override - public TypeMirror getRealType(ExecutableElement method) { - return getRealElementType(method); - } - - @Override - public TypeMirror getRealType(VariableElement field) { - return getRealElementType(field); - } - - private TypeMirror getRealElementType(Element element) { - AnnotationMirror mirror = TypeUtils.getAnnotationMirrorOfType(element, ManyToOne.class); - if (mirror == null) { - mirror = TypeUtils.getAnnotationMirrorOfType(element, OneToOne.class); - } - if (mirror != null) { - return TypeUtils.getAnnotationValueAsTypeMirror(mirror, "targetEntity"); - } - - mirror = TypeUtils.getAnnotationMirrorOfType(element, OneToMany.class); - if (mirror == null) { - mirror = TypeUtils.getAnnotationMirrorOfType(element, ManyToMany.class); - } - if (mirror != null) { - TypeMirror typeArg = TypeUtils.getAnnotationValueAsTypeMirror(mirror, "targetEntity"); - TypeMirror erasure = types.erasure(element.asType()); - TypeElement typeElement = (TypeElement) types.asElement(erasure); - if (typeElement != null && typeArg != null) { - if (typeElement.getTypeParameters().size() == 1) { - return types.getDeclaredType(typeElement, typeArg); - } else if (typeElement.getTypeParameters().size() == 2) { - if (element.asType() instanceof DeclaredType) { - TypeMirror first = ((DeclaredType)element.asType()).getTypeArguments().get(0); - return types.getDeclaredType(typeElement, first, typeArg); - } - } - } - } - - return null; - } - - @Override - public void inspect(Element element, Annotations annotations) { - Temporal temporal = element.getAnnotation(Temporal.class); - if (temporal != null && element.getAnnotation(ElementCollection.class) == null) { - PropertyType propertyType = null; - switch (temporal.value()) { - case DATE: propertyType = PropertyType.DATE; break; - case TIME: propertyType = PropertyType.TIME; break; - case TIMESTAMP: propertyType = PropertyType.DATETIME; - } - annotations.addAnnotation(new QueryTypeImpl(propertyType)); - } - } - - private boolean hasRelevantAnnotation(Element element) { - for (Class annotation : annotations) { - if (element.getAnnotation(annotation) != null) { - return true; - } - } - return false; - } - -} diff --git a/querydsl-apt/src/main/java/com/mysema/query/apt/jpa/package-info.java b/querydsl-apt/src/main/java/com/mysema/query/apt/jpa/package-info.java deleted file mode 100644 index 00bb6e6401..0000000000 --- a/querydsl-apt/src/main/java/com/mysema/query/apt/jpa/package-info.java +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ - -/** - * APT JPA support - */ -package com.mysema.query.apt.jpa; diff --git a/querydsl-apt/src/main/java/com/mysema/query/apt/morphia/MorphiaAnnotationProcessor.java b/querydsl-apt/src/main/java/com/mysema/query/apt/morphia/MorphiaAnnotationProcessor.java deleted file mode 100644 index a53c20ac49..0000000000 --- a/querydsl-apt/src/main/java/com/mysema/query/apt/morphia/MorphiaAnnotationProcessor.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.apt.morphia; - -import java.lang.annotation.Annotation; -import java.util.Collections; - -import javax.annotation.processing.RoundEnvironment; -import javax.annotation.processing.SupportedAnnotationTypes; - -import org.mongodb.morphia.annotations.Embedded; -import org.mongodb.morphia.annotations.Entity; -import org.mongodb.morphia.annotations.Transient; - -import com.mysema.query.annotations.QueryEntities; -import com.mysema.query.annotations.QuerySupertype; -import com.mysema.query.apt.AbstractQuerydslProcessor; -import com.mysema.query.apt.Configuration; -import com.mysema.query.apt.DefaultConfiguration; - -/** - * Annotation processor to create Querydsl query types for Morphia annotated classes - * - * @author tiwe - * - */ -@SupportedAnnotationTypes({"com.mysema.query.annotations.*","org.mongodb.morphia.annotations.*"}) -public class MorphiaAnnotationProcessor extends AbstractQuerydslProcessor { - - @Override - protected Configuration createConfiguration(RoundEnvironment roundEnv) { - Class entities = QueryEntities.class; - Class entity = Entity.class; - Class superType = QuerySupertype.class; - Class embedded = Embedded.class; - Class skip = Transient.class; - DefaultConfiguration conf = new DefaultConfiguration(roundEnv, - processingEnv.getOptions(), Collections.emptySet(), - entities, entity, superType, null, embedded, skip); - try { - Class cl = Class.forName("com.mysema.query.mongodb.Point"); - conf.addCustomType(Double[].class, cl); - } catch (ClassNotFoundException e) { - throw new IllegalStateException(e); - } - return conf; - } - -} diff --git a/querydsl-apt/src/main/java/com/mysema/query/apt/morphia/package-info.java b/querydsl-apt/src/main/java/com/mysema/query/apt/morphia/package-info.java deleted file mode 100644 index ff7202df51..0000000000 --- a/querydsl-apt/src/main/java/com/mysema/query/apt/morphia/package-info.java +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ - -/** - * APT Morphia support - */ -package com.mysema.query.apt.morphia; diff --git a/querydsl-apt/src/main/java/com/mysema/query/apt/package-info.java b/querydsl-apt/src/main/java/com/mysema/query/apt/package-info.java deleted file mode 100644 index 043294e3e5..0000000000 --- a/querydsl-apt/src/main/java/com/mysema/query/apt/package-info.java +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ - -/** - * APT related classes - */ -package com.mysema.query.apt; diff --git a/querydsl-apt/src/main/java/com/querydsl/apt/APTOptions.java b/querydsl-apt/src/main/java/com/querydsl/apt/APTOptions.java new file mode 100644 index 0000000000..cae2e4018c --- /dev/null +++ b/querydsl-apt/src/main/java/com/querydsl/apt/APTOptions.java @@ -0,0 +1,113 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt; + +/** + * APT options supported by Querydsl + * + * @author tiwe + * + */ +public final class APTOptions { + + /** + * set whether default variables are created (default: true) + */ + public static final String QUERYDSL_CREATE_DEFAULT_VARIABLE = "querydsl.createDefaultVariable"; + + /** + * set the prefix for query types (default: Q) + */ + public static final String QUERYDSL_PREFIX = "querydsl.prefix"; + + /** + * set a suffix for query types (default: empty) + */ + public static final String QUERYDSL_SUFFIX = "querydsl.suffix"; + + /** + * set a suffix for query type packages (default: empty) + */ + public static final String QUERYDSL_PACKAGE_SUFFIX = "querydsl.packageSuffix"; + + /** + * enable accessors for direct key based map access (default: false) + */ + public static final String QUERYDSL_MAP_ACCESSORS = "querydsl.mapAccessors"; + + /** + * enable accessors for direct indexed list access (default: false) + */ + public static final String QUERYDSL_LIST_ACCESSORS = "querydsl.listAccessors"; + + /** + * enable reference field accessors (default: false) + */ + public static final String QUERYDSL_ENTITY_ACCESSORS = "querydsl.entityAccessors"; + + /** + * Set whether fields are used as metadata source (default: true) + */ + public static final String QUERYDSL_USE_FIELDS = "querydsl.useFields"; + + /** + * Set whether accessors are used as metadata source (default: true) + */ + public static final String QUERYDSL_USE_GETTERS = "querydsl.useGetters"; + + /** + * comma separated list of packages to be excluded from code generation (default: none) + */ + public static final String QUERYDSL_EXCLUDED_PACKAGES = "querydsl.excludedPackages"; + + /** + * comma separated list of class names to be excluded from code generation (default: none) + */ + public static final String QUERYDSL_EXCLUDED_CLASSES = "querydsl.excludedClasses"; + + /** + * comma separated list of packages to be included into code generation (default: all) + */ + public static final String QUERYDSL_INCLUDED_PACKAGES = "querydsl.includedPackages"; + + /** + * comma separated list of class names to be included into code generation (default: all) + */ + public static final String QUERYDSL_INCLUDED_CLASSES = "querydsl.includedClasses"; + + /** + * set whether unknown non-annotated classes should be treated as embeddable (default: false) + */ + public static final String QUERYDSL_UNKNOWN_AS_EMBEDDABLE = "querydsl.unknownAsEmbeddable"; + + /** + * set the variable name function class + */ + public static final String QUERYDSL_VARIABLE_NAME_FUNCTION_CLASS = "querydsl.variableNameFunctionClass"; + + /** + * set whether info level messages should be written to stdout (default: false) + */ + public static final String QUERYDSL_LOG_INFO = "querydsl.logInfo"; + + /** + * the class instance of the Single-Element Annotation (with {@code String} element) to be used on the generated classes. + * (default: depending on java version: javax.annotation.Generated or javax.annotation.processing.Generated) + * @see Single-Element Annotation + */ + public static final String QUERYDSL_GENERATED_ANNOTATION_CLASS = "querydsl.generatedAnnotationClass"; + + private APTOptions() { } + +} diff --git a/querydsl-apt/src/main/java/com/mysema/query/apt/AbstractQuerydslProcessor.java b/querydsl-apt/src/main/java/com/querydsl/apt/AbstractQuerydslProcessor.java similarity index 78% rename from querydsl-apt/src/main/java/com/mysema/query/apt/AbstractQuerydslProcessor.java rename to querydsl-apt/src/main/java/com/querydsl/apt/AbstractQuerydslProcessor.java index 022adc17df..920eae2518 100644 --- a/querydsl-apt/src/main/java/com/mysema/query/apt/AbstractQuerydslProcessor.java +++ b/querydsl-apt/src/main/java/com/querydsl/apt/AbstractQuerydslProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2011, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,7 +11,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.apt; +package com.querydsl.apt; + +import static com.querydsl.apt.APTOptions.*; + +import java.io.IOException; +import java.io.Writer; +import java.lang.annotation.Annotation; +import java.util.*; +import java.util.stream.Stream; import javax.annotation.processing.AbstractProcessor; import javax.annotation.processing.RoundEnvironment; @@ -21,41 +29,26 @@ import javax.lang.model.type.NoType; import javax.lang.model.type.TypeMirror; import javax.lang.model.util.ElementFilter; -import javax.lang.model.util.Elements; -import javax.lang.model.util.Types; -import javax.tools.Diagnostic; import javax.tools.Diagnostic.Kind; -import javax.tools.JavaFileObject; -import java.io.IOException; -import java.io.Writer; -import java.lang.annotation.Annotation; -import java.util.*; -import com.mysema.codegen.JavaWriter; -import com.mysema.codegen.model.Parameter; -import com.mysema.codegen.model.Type; -import com.mysema.codegen.model.TypeCategory; -import com.mysema.query.annotations.QueryDelegate; -import com.mysema.query.annotations.QueryExclude; -import com.mysema.query.annotations.QueryProjection; -import com.mysema.query.codegen.*; +import com.querydsl.codegen.utils.JavaWriter; +import com.querydsl.codegen.utils.model.Parameter; +import com.querydsl.codegen.utils.model.Type; +import com.querydsl.codegen.utils.model.TypeCategory; +import com.querydsl.codegen.*; +import com.querydsl.core.annotations.QueryDelegate; +import com.querydsl.core.annotations.QueryExclude; +import com.querydsl.core.annotations.QueryProjection; /** - * Base class for Querydsl annotation processors, contains the main processing logic. The subclasses - * just provide the configuration. + * {@code AbstractQuerydslProcessor} is the base class for Querydsl annotation processors and + * contains the main processing logic. The subclasses just provide the configuration. * * @author tiwe * */ public abstract class AbstractQuerydslProcessor extends AbstractProcessor { - // TODO replace with proper injections in Querydsl 4.0.0 - public static Types TYPES; - - public static Elements ELEMENTS; - - private static final Set DELEGATE_METHODS = new HashSet(); - public static final Boolean ALLOW_OTHER_PROCESSORS_TO_CLAIM_ANNOTATIONS = Boolean.FALSE; private final TypeExtractor typeExtractor = new TypeExtractor(true); @@ -70,19 +63,19 @@ public abstract class AbstractQuerydslProcessor extends AbstractProcessor { private Context context; + private boolean shouldLogInfo; + @Override public boolean process(Set annotations, RoundEnvironment roundEnv) { - TYPES = processingEnv.getTypeUtils(); - ELEMENTS = processingEnv.getElementUtils(); - - processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "Running " + getClass().getSimpleName()); + setLogInfo(); + logInfo("Running " + getClass().getSimpleName()); if (roundEnv.processingOver() || annotations.size() == 0) { return ALLOW_OTHER_PROCESSORS_TO_CLAIM_ANNOTATIONS; } if (roundEnv.getRootElements() == null || roundEnv.getRootElements().isEmpty()) { - processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "No sources to process"); + logInfo("No sources to process"); return ALLOW_OTHER_PROCESSORS_TO_CLAIM_ANNOTATIONS; } @@ -91,8 +84,8 @@ public boolean process(Set annotations, RoundEnvironment Set> entityAnnotations = conf.getEntityAnnotations(); TypeMappings typeMappings = conf.getTypeMappings(); QueryTypeFactory queryTypeFactory = conf.getQueryTypeFactory(); - this.typeFactory = new ExtendedTypeFactory(processingEnv, conf, entityAnnotations, typeMappings, queryTypeFactory); - elementHandler = new TypeElementHandler(conf, typeFactory, typeMappings, queryTypeFactory); + this.typeFactory = createTypeFactory(entityAnnotations, typeMappings, queryTypeFactory); + elementHandler = createElementHandler(typeMappings, queryTypeFactory); this.roundEnv = roundEnv; // process annotations @@ -106,7 +99,16 @@ public boolean process(Set annotations, RoundEnvironment return ALLOW_OTHER_PROCESSORS_TO_CLAIM_ANNOTATIONS; } - private void processAnnotations() { + protected TypeElementHandler createElementHandler(TypeMappings typeMappings, QueryTypeFactory queryTypeFactory) { + return new TypeElementHandler(conf, typeFactory, typeMappings, queryTypeFactory); + } + + protected ExtendedTypeFactory createTypeFactory(Set> entityAnnotations, + TypeMappings typeMappings, QueryTypeFactory queryTypeFactory) { + return new ExtendedTypeFactory(processingEnv, entityAnnotations, typeMappings, queryTypeFactory, conf.getVariableNameFunction()); + } + + protected void processAnnotations() { processExclusions(); Set elements = collectElements(); @@ -126,11 +128,11 @@ private void processAnnotations() { for (TypeElement element : elements) { EntityType entityType = elementHandler.handleEntityType(element); registerTypeElement(entityType.getFullName(), element); - if (element.getAnnotation(conf.getEntityAnnotation()) != null) { + if (typeFactory.isSimpleTypeEntity(element, conf.getEntityAnnotation())) { context.entityTypes.put(entityType.getFullName(), entityType); } else if (altEntityAnn && element.getAnnotation(conf.getAlternativeEntityAnnotation()) != null) { context.entityTypes.put(entityType.getFullName(), entityType); - } else if (embeddableAnn && element.getAnnotation(conf.getEmbeddableAnnotation()) != null ) { + } else if (embeddableAnn && element.getAnnotation(conf.getEmbeddableAnnotation()) != null) { context.embeddableTypes.put(entityType.getFullName(), entityType); } else if (superAnn && element.getAnnotation(conf.getSuperTypeAnnotation()) != null) { context.supertypes.put(entityType.getFullName(), entityType); @@ -146,7 +148,6 @@ private void processAnnotations() { for (EntityType entityType : new ArrayList(typeFactory.getEntityTypes())) { String fullName = entityType.getFullName(); if (!context.allTypes.keySet().contains(fullName)) { - //System.err.println(fullName); TypeElement element = processingEnv.getElementUtils().getTypeElement(fullName); if (element != null) { elementHandler.handleEntityType(element); @@ -188,6 +189,9 @@ private void addExternalParents(EntityType entityType) { if (typeElement == null) { throw new IllegalStateException("Found no type for " + superType.getFullName()); } + if (conf.isStrictMode() && !TypeUtils.hasAnnotationOfType(typeElement, conf.getEntityAnnotations())) { + continue; + } EntityType superEntityType = elementHandler.handleEntityType(typeElement); if (superEntityType.getSuperType() != null) { superTypes.push(superEntityType.getSuperType().getType()); @@ -199,10 +203,9 @@ private void addExternalParents(EntityType entityType) { } protected Set collectElements() { - Set elements = new HashSet(); // from delegate methods - elements.addAll(processDelegateMethods()); + Set elements = new HashSet(processDelegateMethods()); // from class annotations for (Class annotation : conf.getEntityAnnotations()) { @@ -232,7 +235,9 @@ protected Set collectElements() { } // from annotation less supertypes - elements.addAll(getAnnotationlessSupertypes(elements)); + if (!conf.isStrictMode()) { + elements.addAll(getAnnotationlessSupertypes(elements)); + } // register possible embedded types of non-tracked supertypes if (conf.getEmbeddedAnnotation() != null) { @@ -294,11 +299,7 @@ private Set getAnnotationlessSupertypes(Set elements) } private void registerTypeElement(String entityName, TypeElement element) { - Set elements = context.typeElements.get(entityName); - if (elements == null) { - elements = new HashSet(); - context.typeElements.put(entityName, elements); - } + Set elements = context.typeElements.computeIfAbsent(entityName, k -> new HashSet()); elements.add(element); } @@ -307,8 +308,8 @@ private void processProjectionTypes(Set elements) { for (Element element : getElements(QueryProjection.class)) { Element parent = element.getEnclosingElement(); if (!elements.contains(parent) && !visited.contains(parent)) { - EntityType model = elementHandler.handleProjectionType((TypeElement)parent); - registerTypeElement(model.getFullName(), (TypeElement)parent); + EntityType model = elementHandler.handleProjectionType((TypeElement) parent); + registerTypeElement(model.getFullName(), (TypeElement) parent); context.projectionTypes.put(model.getFullName(), model); visited.add(parent); } @@ -327,17 +328,17 @@ private Set getEmbeddedTypes() { private void handleEmbeddedType(Element element, Set elements) { TypeMirror type = element.asType(); if (element.getKind() == ElementKind.METHOD) { - type = ((ExecutableElement)element).getReturnType(); + type = ((ExecutableElement) element).getReturnType(); } String typeName = type.toString(); if (typeName.startsWith(Collection.class.getName()) || typeName.startsWith(List.class.getName()) || typeName.startsWith(Set.class.getName())) { - type = ((DeclaredType)type).getTypeArguments().get(0); + type = ((DeclaredType) type).getTypeArguments().get(0); } else if (typeName.startsWith(Map.class.getName())) { - type = ((DeclaredType)type).getTypeArguments().get(1); + type = ((DeclaredType) type).getTypeArguments().get(1); } TypeElement typeElement = typeExtractor.visit(type); @@ -353,7 +354,7 @@ private Set getTypeFromProperties(Set parents) { Set elements = new HashSet(); for (Element element : parents) { if (element instanceof TypeElement) { - processFromProperties((TypeElement)element, elements); + processFromProperties((TypeElement) element, elements); } } @@ -421,9 +422,9 @@ private void addSupertypeFields(EntityType model, Set handled) { private void processExclusions() { for (Element element : getElements(QueryExclude.class)) { if (element instanceof PackageElement) { - conf.addExcludedPackage(((PackageElement)element).getQualifiedName().toString()); + conf.addExcludedPackage(((PackageElement) element).getQualifiedName().toString()); } else if (element instanceof TypeElement) { - conf.addExcludedClass(((TypeElement)element).getQualifiedName().toString()); + conf.addExcludedClass(((TypeElement) element).getQualifiedName().toString()); } else { throw new IllegalArgumentException(element.toString()); } @@ -431,27 +432,11 @@ private void processExclusions() { } private Set processDelegateMethods() { - Set delegateMethods = new HashSet(); - delegateMethods.addAll(getElements(QueryDelegate.class)); - for (Element element : DELEGATE_METHODS) { - TypeElement parent = (TypeElement)element.getEnclosingElement(); - // replace with element from current session - parent = processingEnv.getElementUtils().getTypeElement(parent.getQualifiedName().toString()); - if (parent != null) { - for (Element child : parent.getEnclosedElements()) { - if (child.getKind() == element.getKind() && child.getSimpleName().equals(element.getSimpleName())) { - delegateMethods.add(child); - } - } - } - } - DELEGATE_METHODS.clear(); - DELEGATE_METHODS.addAll(delegateMethods); - + Set delegateMethods = getElements(QueryDelegate.class); Set typeElements = new HashSet(); for (Element delegateMethod : delegateMethods) { - ExecutableElement method = (ExecutableElement)delegateMethod; + ExecutableElement method = (ExecutableElement) delegateMethod; Element element = delegateMethod.getEnclosingElement(); String name = method.getSimpleName().toString(); Type delegateType = typeFactory.getType(element.asType(), true); @@ -471,7 +456,7 @@ private Set processDelegateMethods() { } if (entityType != null) { - registerTypeElement(entityType.getFullName(), (TypeElement)element); + registerTypeElement(entityType.getFullName(), (TypeElement) element); entityType.addDelegate(new Delegate(entityType, delegateType, name, parameters, returnType)); TypeElement typeElement = processingEnv.getElementUtils().getTypeElement(entityType.getFullName()); boolean isAnnotated = false; @@ -495,58 +480,54 @@ private Set processDelegateMethods() { } private void validateMetaTypes() { - for (Collection entityTypes : Arrays.asList( + Stream.of( context.supertypes.values(), context.entityTypes.values(), context.extensionTypes.values(), context.embeddableTypes.values(), - context.projectionTypes.values())) { - for (EntityType entityType : entityTypes) { - for (Property property : entityType.getProperties()) { - if (property.getInits() != null && property.getInits().size() > 0) { - validateInits(entityType, property); - } - } - } - } + context.projectionTypes.values() + ).flatMap(Collection::stream).forEach(entityType -> + entityType.getProperties().stream() + .filter(property -> property.getInits() != null && property.getInits().size() > 0) + .forEach(property -> validateInits(entityType, property))); } protected void validateInits(EntityType entityType, Property property) { for (String init : property.getInits()) { if (!init.startsWith("*") && property.getType() instanceof EntityType) { String initProperty = init.contains(".") ? init.substring(0, init.indexOf('.')) : init; - if (!((EntityType)property.getType()).getPropertyNames().contains(initProperty)) { + Set propertyNames = ((EntityType) property.getType()).getPropertyNames(); + if (!propertyNames.contains(initProperty)) { processingEnv.getMessager().printMessage(Kind.ERROR, - "Illegal inits of " + entityType.getFullName()+ "." + property.getName() + ": " + - initProperty + " not found"); + "Illegal inits of " + entityType.getFullName() + "." + property.getName() + ": " + + initProperty + " not found in " + propertyNames); } } } } - private void serializeMetaTypes() { if (!context.supertypes.isEmpty()) { - processingEnv.getMessager().printMessage(Kind.NOTE, "Serializing Supertypes"); + logInfo("Serializing Supertypes"); serialize(conf.getSupertypeSerializer(), context.supertypes.values()); } if (!context.entityTypes.isEmpty()) { - processingEnv.getMessager().printMessage(Kind.NOTE, "Serializing Entity types"); + logInfo("Serializing Entity types"); serialize(conf.getEntitySerializer(), context.entityTypes.values()); } if (!context.extensionTypes.isEmpty()) { - processingEnv.getMessager().printMessage(Kind.NOTE, "Serializing Extension types"); + logInfo("Serializing Extension types"); serialize(conf.getEmbeddableSerializer(), context.extensionTypes.values()); } if (!context.embeddableTypes.isEmpty()) { - processingEnv.getMessager().printMessage(Kind.NOTE, "Serializing Embeddable types"); + logInfo("Serializing Embeddable types"); serialize(conf.getEmbeddableSerializer(), context.embeddableTypes.values()); } if (!context.projectionTypes.isEmpty()) { - processingEnv.getMessager().printMessage(Kind.NOTE, "Serializing Projection types"); + logInfo("Serializing Projection types"); serialize(conf.getDTOSerializer(), context.projectionTypes.values()); } @@ -558,15 +539,49 @@ private Set getElements(Class a) { @Override public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); + return SourceVersion.latestSupported(); + } + + @Override + public Set getSupportedOptions() { + return new HashSet<>(Arrays.asList( + QUERYDSL_CREATE_DEFAULT_VARIABLE, + QUERYDSL_PREFIX, + QUERYDSL_SUFFIX, + QUERYDSL_PACKAGE_SUFFIX, + QUERYDSL_MAP_ACCESSORS, + QUERYDSL_LIST_ACCESSORS, + QUERYDSL_ENTITY_ACCESSORS, + QUERYDSL_USE_FIELDS, + QUERYDSL_USE_GETTERS, + QUERYDSL_EXCLUDED_PACKAGES, + QUERYDSL_EXCLUDED_CLASSES, + QUERYDSL_INCLUDED_PACKAGES, + QUERYDSL_INCLUDED_CLASSES, + QUERYDSL_UNKNOWN_AS_EMBEDDABLE, + QUERYDSL_VARIABLE_NAME_FUNCTION_CLASS, + QUERYDSL_LOG_INFO, + QUERYDSL_GENERATED_ANNOTATION_CLASS)); + } + + private void setLogInfo() { + boolean hasProperty = processingEnv.getOptions().containsKey(QUERYDSL_LOG_INFO); + if (hasProperty) { + String val = processingEnv.getOptions().get(QUERYDSL_LOG_INFO); + shouldLogInfo = Boolean.parseBoolean(val); + } + } + + private void logInfo(String message) { + if (shouldLogInfo) { + processingEnv.getMessager().printMessage(Kind.NOTE, message); + } } private void serialize(Serializer serializer, Collection models) { for (EntityType model : models) { try { - Type type = conf.getTypeMappings().getPathType(model, model, true); - String packageName = type.getPackageName(); - String className = !packageName.isEmpty() ? (packageName + "." + type.getSimpleName()) : type.getSimpleName(); + String className = getClassName(model); // skip if type is excluded class or in excluded package if (conf.isExcludedPackage(model.getPackageName()) || conf.isExcludedClass(model.getFullName())) { @@ -587,17 +602,10 @@ private void serialize(Serializer serializer, Collection models) { } } - processingEnv.getMessager().printMessage(Kind.NOTE, "Generating " + className + " for " + elements); - JavaFileObject fileObject = processingEnv.getFiler().createSourceFile(className, - elements.toArray(new Element[elements.size()])); - Writer writer = fileObject.openWriter(); - try { + logInfo("Generating " + className + " for " + elements); + try (Writer writer = conf.getFiler().createFile(processingEnv, className, elements)) { SerializerConfig serializerConfig = conf.getSerializerConfig(model); serializer.serialize(model, serializerConfig, new JavaWriter(writer)); - } finally { - if (writer != null) { - writer.close(); - } } } catch (IOException e) { @@ -607,6 +615,11 @@ private void serialize(Serializer serializer, Collection models) { } } + protected String getClassName(EntityType model) { + Type type = conf.getTypeMappings().getPathType(model, model, true); + String packageName = type.getPackageName(); + return packageName.isEmpty() ? type.getSimpleName() : (packageName + "." + type.getSimpleName()); + } protected abstract Configuration createConfiguration(RoundEnvironment roundEnv); diff --git a/querydsl-apt/src/main/java/com/querydsl/apt/Configuration.java b/querydsl-apt/src/main/java/com/querydsl/apt/Configuration.java new file mode 100644 index 0000000000..affc5a4e3b --- /dev/null +++ b/querydsl-apt/src/main/java/com/querydsl/apt/Configuration.java @@ -0,0 +1,117 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt; + +import com.querydsl.codegen.*; +import com.querydsl.core.util.Annotations; + +import org.jetbrains.annotations.Nullable; +import javax.lang.model.element.Element; +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.TypeElement; +import javax.lang.model.element.VariableElement; +import javax.lang.model.type.TypeMirror; +import java.lang.annotation.Annotation; +import java.util.Collection; +import java.util.List; +import java.util.Set; +import java.util.function.Function; + +/** + * {@code Configuration} defines the configuration options for APT-based Querydsl code generation + * + * @author tiwe + * + */ +public interface Configuration { + + boolean isUnknownAsEmbedded(); + + TypeMappings getTypeMappings(); + + VisitorConfig getConfig(TypeElement e, List elements); + + Serializer getDTOSerializer(); + + @Nullable + Class getEntitiesAnnotation(); + + @Nullable + Class getEmbeddedAnnotation(); + + @Nullable + Class getEmbeddableAnnotation(); + + Serializer getEmbeddableSerializer(); + + Class getEntityAnnotation(); + + Class getAlternativeEntityAnnotation(); + + Set> getEntityAnnotations(); + + Serializer getEntitySerializer(); + + String getNamePrefix(); + + String getNameSuffix(); + + SerializerConfig getSerializerConfig(EntityType entityType); + + @Nullable + Class getSkipAnnotation(); + + @Nullable + Class getSuperTypeAnnotation(); + + Serializer getSupertypeSerializer(); + + boolean isBlockedField(VariableElement field); + + boolean isBlockedGetter(ExecutableElement getter); + + boolean isUseFields(); + + boolean isUseGetters(); + + boolean isValidConstructor(ExecutableElement constructor); + + boolean isValidField(VariableElement field); + + boolean isValidGetter(ExecutableElement getter); + + Collection getKeywords(); + + QueryTypeFactory getQueryTypeFactory(); + + void addExcludedPackage(String packageName); + + void addExcludedClass(String className); + + TypeMirror getRealType(ExecutableElement method); + + TypeMirror getRealType(VariableElement field); + + boolean isExcludedPackage(String packageName); + + boolean isExcludedClass(String className); + + void inspect(Element element, Annotations annotations); + + boolean isStrictMode(); + + Function getVariableNameFunction(); + + Filer getFiler(); +} diff --git a/querydsl-apt/src/main/java/com/querydsl/apt/Context.java b/querydsl-apt/src/main/java/com/querydsl/apt/Context.java new file mode 100644 index 0000000000..3707f6f8fe --- /dev/null +++ b/querydsl-apt/src/main/java/com/querydsl/apt/Context.java @@ -0,0 +1,60 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import javax.lang.model.element.TypeElement; + +import com.querydsl.codegen.EntityType; + +/** + * Context of handled types used by {@link AbstractQuerydslProcessor} + * + * @author tiwe + * + */ +class Context { + + final Map supertypes = new HashMap(); + + final Map allTypes = new HashMap(); + + final Map projectionTypes = new HashMap(); + + final Map embeddableTypes = new HashMap(); + + final Map entityTypes = new HashMap(); + + final Map extensionTypes = new HashMap(); + + final Map> typeElements = new HashMap>(); + + public void clean() { + for (String key : supertypes.keySet()) { + entityTypes.remove(key); + extensionTypes.remove(key); + embeddableTypes.remove(key); + } + + for (String key : entityTypes.keySet()) { + supertypes.remove(key); + extensionTypes.remove(key); + embeddableTypes.remove(key); + } + } + +} diff --git a/querydsl-apt/src/main/java/com/querydsl/apt/DefaultConfiguration.java b/querydsl-apt/src/main/java/com/querydsl/apt/DefaultConfiguration.java new file mode 100644 index 0000000000..ca24d2a5a8 --- /dev/null +++ b/querydsl-apt/src/main/java/com/querydsl/apt/DefaultConfiguration.java @@ -0,0 +1,577 @@ +/* + * Copyright 2016, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt; + +import com.querydsl.codegen.*; +import com.querydsl.codegen.utils.model.ClassType; +import com.querydsl.core.annotations.Config; +import com.querydsl.core.annotations.QueryProjection; +import com.querydsl.core.annotations.QueryType; +import com.querydsl.core.types.Expression; +import com.querydsl.core.util.Annotations; +import com.querydsl.core.util.StringUtils; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import javax.annotation.processing.ProcessingEnvironment; +import javax.annotation.processing.RoundEnvironment; +import javax.lang.model.element.Element; +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.Modifier; +import javax.lang.model.element.PackageElement; +import javax.lang.model.element.TypeElement; +import javax.lang.model.element.VariableElement; +import javax.lang.model.type.TypeMirror; +import java.lang.annotation.Annotation; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Function; + +import static com.querydsl.apt.APTOptions.QUERYDSL_CREATE_DEFAULT_VARIABLE; +import static com.querydsl.apt.APTOptions.QUERYDSL_ENTITY_ACCESSORS; +import static com.querydsl.apt.APTOptions.QUERYDSL_EXCLUDED_CLASSES; +import static com.querydsl.apt.APTOptions.QUERYDSL_EXCLUDED_PACKAGES; +import static com.querydsl.apt.APTOptions.QUERYDSL_GENERATED_ANNOTATION_CLASS; +import static com.querydsl.apt.APTOptions.QUERYDSL_INCLUDED_CLASSES; +import static com.querydsl.apt.APTOptions.QUERYDSL_INCLUDED_PACKAGES; +import static com.querydsl.apt.APTOptions.QUERYDSL_LIST_ACCESSORS; +import static com.querydsl.apt.APTOptions.QUERYDSL_MAP_ACCESSORS; +import static com.querydsl.apt.APTOptions.QUERYDSL_PACKAGE_SUFFIX; +import static com.querydsl.apt.APTOptions.QUERYDSL_PREFIX; +import static com.querydsl.apt.APTOptions.QUERYDSL_SUFFIX; +import static com.querydsl.apt.APTOptions.QUERYDSL_UNKNOWN_AS_EMBEDDABLE; +import static com.querydsl.apt.APTOptions.QUERYDSL_USE_FIELDS; +import static com.querydsl.apt.APTOptions.QUERYDSL_USE_GETTERS; +import static com.querydsl.apt.APTOptions.QUERYDSL_VARIABLE_NAME_FUNCTION_CLASS; + +/** + * {@code DefaultConfiguration} is a simple implementation of the {@link Configuration} interface. + * + * @author tiwe + * + */ +public class DefaultConfiguration implements Configuration { + + private boolean unknownAsEmbedded; + + private final CodegenModule module; + + private final SerializerConfig defaultSerializerConfig; + + private final Map packageToConfig = new HashMap(); + + protected final Class entityAnn; + + @NotNull + private final Set excludedPackages, excludedClasses; + + @NotNull + private final Set includedPackages, includedClasses; + + @Nullable + protected final Class entitiesAnn, superTypeAnn, embeddedAnn, embeddableAnn, skipAnn; + + @Nullable + protected Class altEntityAnn; + + private final Set> entityAnnotations = new HashSet>(); + + private final Map typeToConfig = new HashMap(); + + private boolean useFields = true, useGetters = true; + + private boolean strictMode; + + private Function variableNameFunction; + + public DefaultConfiguration( + ProcessingEnvironment processingEnvironment, + RoundEnvironment roundEnv, + Collection keywords, + @Nullable Class entitiesAnn, + Class entityAnn, + @Nullable Class superTypeAnn, + @Nullable Class embeddableAnn, + @Nullable Class embeddedAnn, + @Nullable Class skipAnn + ) { + this(processingEnvironment, roundEnv, processingEnvironment.getOptions(), keywords, entitiesAnn, entityAnn, superTypeAnn, embeddableAnn, + embeddedAnn, skipAnn, new CodegenModule()); + } + + @Deprecated + public DefaultConfiguration( + RoundEnvironment roundEnv, + Map options, + Collection keywords, + @Nullable Class entitiesAnn, + Class entityAnn, + @Nullable Class superTypeAnn, + @Nullable Class embeddableAnn, + @Nullable Class embeddedAnn, + @Nullable Class skipAnn + ) { + this(null, roundEnv, options, keywords, entitiesAnn, entityAnn, superTypeAnn, embeddableAnn, + embeddedAnn, skipAnn, new CodegenModule()); + } + + @Deprecated + public DefaultConfiguration( + ProcessingEnvironment processingEnvironment, + RoundEnvironment roundEnv, + Collection keywords, + @Nullable Class entitiesAnn, + Class entityAnn, + @Nullable Class superTypeAnn, + @Nullable Class embeddableAnn, + @Nullable Class embeddedAnn, + @Nullable Class skipAnn, + CodegenModule codegenModule) { + this(processingEnvironment, roundEnv, processingEnvironment.getOptions(), keywords, entitiesAnn, entityAnn, superTypeAnn, embeddableAnn, + embeddedAnn, skipAnn, codegenModule); + } + + public DefaultConfiguration( + ProcessingEnvironment processingEnvironment, + RoundEnvironment roundEnv, + Map options, + Collection keywords, + @Nullable Class entitiesAnn, + Class entityAnn, + @Nullable Class superTypeAnn, + @Nullable Class embeddableAnn, + @Nullable Class embeddedAnn, + @Nullable Class skipAnn, + CodegenModule codegenModule) { + this.excludedClasses = new HashSet(); + this.excludedPackages = new HashSet(); + this.includedClasses = new HashSet(); + this.includedPackages = new HashSet(); + module = codegenModule; + module.bind(ProcessingEnvironment.class, processingEnvironment); + module.bind(RoundEnvironment.class, roundEnv); + module.bind(CodegenModule.KEYWORDS, keywords); + this.entitiesAnn = entitiesAnn; + this.entityAnn = entityAnn; + this.superTypeAnn = superTypeAnn; + this.embeddableAnn = embeddableAnn; + this.embeddedAnn = embeddedAnn; + this.skipAnn = skipAnn; + + entityAnnotations.add(entityAnn); + if (superTypeAnn != null) { + entityAnnotations.add(superTypeAnn); + } + if (embeddableAnn != null) { + entityAnnotations.add(embeddableAnn); + } + for (Element element : roundEnv.getElementsAnnotatedWith(Config.class)) { + Config querydslConfig = element.getAnnotation(Config.class); + SerializerConfig config = SimpleSerializerConfig.getConfig(querydslConfig); + if (element instanceof PackageElement) { + PackageElement packageElement = (PackageElement) element; + packageToConfig.put(packageElement.getQualifiedName().toString(), config); + } else if (element instanceof TypeElement) { + TypeElement typeElement = (TypeElement) element; + typeToConfig.put(typeElement.getQualifiedName().toString(), config); + } + } + boolean entityAccessors = false; + boolean listAccessors = false; + boolean mapAccessors = false; + boolean createDefaultVariable = true; + + if (options.containsKey(QUERYDSL_ENTITY_ACCESSORS)) { + entityAccessors = Boolean.parseBoolean(options.get(QUERYDSL_ENTITY_ACCESSORS)); + } + if (options.containsKey(QUERYDSL_LIST_ACCESSORS)) { + listAccessors = Boolean.parseBoolean(options.get(QUERYDSL_LIST_ACCESSORS)); + } + if (options.containsKey(QUERYDSL_MAP_ACCESSORS)) { + mapAccessors = Boolean.parseBoolean(options.get(QUERYDSL_MAP_ACCESSORS)); + } + if (options.containsKey(QUERYDSL_CREATE_DEFAULT_VARIABLE)) { + createDefaultVariable = Boolean.parseBoolean(options.get(QUERYDSL_CREATE_DEFAULT_VARIABLE)); + } + if (options.containsKey(QUERYDSL_PACKAGE_SUFFIX)) { + module.bind(CodegenModule.PACKAGE_SUFFIX, StringUtils.nullToEmpty(options.get(QUERYDSL_PACKAGE_SUFFIX))); + } + if (options.containsKey(QUERYDSL_PREFIX)) { + module.bind(CodegenModule.PREFIX, StringUtils.nullToEmpty(options.get(QUERYDSL_PREFIX))); + } + if (options.containsKey(QUERYDSL_SUFFIX)) { + module.bind(CodegenModule.SUFFIX, StringUtils.nullToEmpty(options.get(QUERYDSL_SUFFIX))); + } + if (options.containsKey(QUERYDSL_UNKNOWN_AS_EMBEDDABLE)) { + unknownAsEmbedded = Boolean.parseBoolean(options.get(QUERYDSL_UNKNOWN_AS_EMBEDDABLE)); + } + + if (options.containsKey(QUERYDSL_EXCLUDED_PACKAGES)) { + String packageString = options.get(QUERYDSL_EXCLUDED_PACKAGES); + if (!StringUtils.isNullOrEmpty(packageString)) { + List packages = Arrays.asList(packageString.split(",")); + excludedPackages.addAll(packages); + } + } + + if (options.containsKey(QUERYDSL_EXCLUDED_CLASSES)) { + String classString = options.get(QUERYDSL_EXCLUDED_CLASSES); + if (!StringUtils.isNullOrEmpty(classString)) { + List classes = Arrays.asList(classString.split(",")); + excludedClasses.addAll(classes); + } + } + + if (options.containsKey(QUERYDSL_INCLUDED_PACKAGES)) { + String packageString = options.get(QUERYDSL_INCLUDED_PACKAGES); + if (!StringUtils.isNullOrEmpty(packageString)) { + List packages = Arrays.asList(packageString.split(",")); + includedPackages.addAll(packages); + } + } + + if (options.containsKey(QUERYDSL_INCLUDED_CLASSES)) { + String classString = options.get(QUERYDSL_INCLUDED_CLASSES); + if (!StringUtils.isNullOrEmpty(classString)) { + List classes = Arrays.asList(classString.split(",")); + includedClasses.addAll(classes); + } + } + + if (options.containsKey(QUERYDSL_USE_FIELDS)) { + useFields = Boolean.parseBoolean(options.get(QUERYDSL_USE_FIELDS)); + } + + if (options.containsKey(QUERYDSL_USE_GETTERS)) { + useGetters = Boolean.parseBoolean(options.get(QUERYDSL_USE_GETTERS)); + } + + if (options.containsKey(QUERYDSL_VARIABLE_NAME_FUNCTION_CLASS)) { + try { + @SuppressWarnings("unchecked") + Class> variableNameFunctionClass = (Class>) Class.forName(options.get(QUERYDSL_VARIABLE_NAME_FUNCTION_CLASS)); + variableNameFunction = variableNameFunctionClass.newInstance(); + } catch (RuntimeException e) { + throw e; + } catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } catch (Exception e) { + variableNameFunction = DefaultVariableNameFunction.INSTANCE; + } + } else { + variableNameFunction = DefaultVariableNameFunction.INSTANCE; + } + + module.bind(CodegenModule.VARIABLE_NAME_FUNCTION_CLASS, variableNameFunction); + + module.loadExtensions(); + + Class generatedAnnotationClass = GeneratedAnnotationResolver.resolve(options.get(QUERYDSL_GENERATED_ANNOTATION_CLASS)); + module.bindInstance(CodegenModule.GENERATED_ANNOTATION_CLASS, generatedAnnotationClass); + + defaultSerializerConfig = new SimpleSerializerConfig(entityAccessors, listAccessors, + mapAccessors, createDefaultVariable, ""); + + } + + @Override + public void addExcludedClass(String className) { + excludedClasses.add(className); + } + + @Override + public void addExcludedPackage(String packageName) { + excludedPackages.add(packageName); + } + + @Override + public VisitorConfig getConfig(TypeElement e, List elements) { + if (useFields) { + if (useGetters) { + return VisitorConfig.ALL; + } else { + return VisitorConfig.FIELDS_ONLY; + } + } else if (useGetters) { + return VisitorConfig.METHODS_ONLY; + } else { + return VisitorConfig.NONE; + } + } + + @Override + public Serializer getDTOSerializer() { + return module.get(ProjectionSerializer.class); + } + + @Override + @Nullable + public Class getEntitiesAnnotation() { + return entitiesAnn; + } + + @Override + @Nullable + public Class getEmbeddableAnnotation() { + return embeddableAnn; + } + + @Override + public Serializer getEmbeddableSerializer() { + return module.get(EmbeddableSerializer.class); + } + + @Override + public Class getEntityAnnotation() { + return entityAnn; + } + + @Override + public Class getAlternativeEntityAnnotation() { + return altEntityAnn; + } + + public void setAlternativeEntityAnnotation(Class ann) { + altEntityAnn = ann; + entityAnnotations.add(ann); + } + + @Override + @Nullable + public Class getEmbeddedAnnotation() { + return embeddedAnn; + } + + @Override + public Set> getEntityAnnotations() { + return entityAnnotations; + } + + @Override + public Serializer getEntitySerializer() { + return module.get(EntitySerializer.class); + } + + @Override + public String getNamePrefix() { + return module.get(String.class, "prefix"); + } + + @Override + public SerializerConfig getSerializerConfig(EntityType entityType) { + if (typeToConfig.containsKey(entityType.getFullName())) { + return typeToConfig.get(entityType.getFullName()); + } else { + return packageToConfig.getOrDefault(entityType.getPackageName(), defaultSerializerConfig); + } + } + + @Override + @Nullable + public Class getSkipAnnotation() { + return skipAnn; + } + + @Override + @Nullable + public Class getSuperTypeAnnotation() { + return superTypeAnn; + } + + @Override + public Serializer getSupertypeSerializer() { + return module.get(SupertypeSerializer.class); + } + + @Override + public void inspect(Element element, Annotations annotations) { + // do nothing + } + + @Override + public boolean isBlockedField(VariableElement field) { + if (field.getAnnotation(QueryType.class) != null) { + return false; + } else { + return field.getAnnotation(skipAnn) != null + || field.getModifiers().contains(Modifier.TRANSIENT) + || field.getModifiers().contains(Modifier.STATIC); + } + } + + @Override + public boolean isBlockedGetter(ExecutableElement getter) { + if (getter.getAnnotation(QueryType.class) != null) { + return false; + } else { + return getter.getAnnotation(skipAnn) != null + || getter.getModifiers().contains(Modifier.STATIC); + } + } + + @Override + public boolean isUseFields() { + return useFields; + } + + @Override + public boolean isUseGetters() { + return useGetters; + } + + @Override + public boolean isValidConstructor(ExecutableElement constructor) { + return constructor.getModifiers().contains(Modifier.PUBLIC) + && constructor.getAnnotation(QueryProjection.class) != null + && !constructor.getParameters().isEmpty(); + } + + @Override + public boolean isValidField(VariableElement field) { + if (field.getAnnotation(QueryType.class) != null) { + return true; + } else { + return field.getAnnotation(skipAnn) == null + && !field.getModifiers().contains(Modifier.TRANSIENT) + && !field.getModifiers().contains(Modifier.STATIC); + } + } + + @Override + public boolean isValidGetter(ExecutableElement getter) { + if (getter.getAnnotation(QueryType.class) != null) { + return true; + } else { + return getter.getAnnotation(skipAnn) == null + && !getter.getModifiers().contains(Modifier.STATIC); + } + } + + public void setNamePrefix(String namePrefix) { + module.bind(CodegenModule.PREFIX, namePrefix); + } + + public void setUseFields(boolean b) { + this.useFields = b; + } + + public void setUseGetters(boolean b) { + this.useGetters = b; + } + + @Override + public TypeMappings getTypeMappings() { + return module.get(TypeMappings.class); + } + + @SuppressWarnings("unchecked") + @Override + public Collection getKeywords() { + return module.get(Collection.class, CodegenModule.KEYWORDS); + } + + @Override + public String getNameSuffix() { + return module.get(String.class, CodegenModule.SUFFIX); + } + + public void setNameSuffix(String nameSuffix) { + module.bind(CodegenModule.SUFFIX, nameSuffix); + } + + public void addCustomType(Class type, Class> queryType) { + module.get(TypeMappings.class).register(new ClassType(type), new ClassType(queryType)); + } + + @Override + public QueryTypeFactory getQueryTypeFactory() { + return module.get(QueryTypeFactory.class); + } + + @Override + public boolean isExcludedPackage(@NotNull String packageName) { + if (!includedPackages.isEmpty()) { + boolean included = false; + for (String includedPackage : includedPackages) { + if (packageName.startsWith(includedPackage)) { + included = true; + break; + } + } + if (!included) { + return true; + } + } + if (!excludedPackages.isEmpty()) { + for (String excludedPackage : excludedPackages) { + if (packageName.startsWith(excludedPackage)) { + return true; + } + } + } + return false; + } + + @Override + public boolean isExcludedClass(@NotNull String className) { + if (!includedClasses.isEmpty() && !includedClasses.contains(className)) { + return true; + } else { + return excludedClasses.contains(className); + } + } + + @Override + public TypeMirror getRealType(ExecutableElement method) { + return null; + } + + @Override + public TypeMirror getRealType(VariableElement field) { + return null; + } + + @Override + public boolean isUnknownAsEmbedded() { + return unknownAsEmbedded; + } + + @Override + public boolean isStrictMode() { + return strictMode; + } + + public void setStrictMode(boolean s) { + strictMode = s; + } + + public void setUnknownAsEmbedded(boolean unknownAsEmbedded) { + this.unknownAsEmbedded = unknownAsEmbedded; + } + + @Override + public Function getVariableNameFunction() { + return variableNameFunction; + } + + @Override + public Filer getFiler() { + return module.get(Filer.class); + } +} diff --git a/querydsl-apt/src/main/java/com/mysema/query/apt/ExtendedTypeFactory.java b/querydsl-apt/src/main/java/com/querydsl/apt/ExtendedTypeFactory.java similarity index 79% rename from querydsl-apt/src/main/java/com/mysema/query/apt/ExtendedTypeFactory.java rename to querydsl-apt/src/main/java/com/querydsl/apt/ExtendedTypeFactory.java index 689ca6f0ea..9a5cd04b02 100644 --- a/querydsl-apt/src/main/java/com/mysema/query/apt/ExtendedTypeFactory.java +++ b/querydsl-apt/src/main/java/com/querydsl/apt/ExtendedTypeFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2011, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,20 +11,22 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.apt; - -import java.lang.annotation.Annotation; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import javax.annotation.Nullable; +package com.querydsl.apt; + +import com.querydsl.codegen.utils.model.SimpleType; +import com.querydsl.codegen.utils.model.Type; +import com.querydsl.codegen.utils.model.TypeCategory; +import com.querydsl.codegen.utils.model.TypeExtends; +import com.querydsl.codegen.utils.model.TypeSuper; +import com.querydsl.codegen.utils.model.Types; +import com.querydsl.codegen.EntityType; +import com.querydsl.codegen.Property; +import com.querydsl.codegen.QueryTypeFactory; +import com.querydsl.codegen.Supertype; +import com.querydsl.codegen.TypeMappings; +import com.querydsl.core.annotations.QueryExclude; + +import org.jetbrains.annotations.Nullable; import javax.annotation.processing.ProcessingEnvironment; import javax.lang.model.element.ElementKind; import javax.lang.model.element.Modifier; @@ -41,28 +43,25 @@ import javax.lang.model.type.TypeVariable; import javax.lang.model.type.TypeVisitor; import javax.lang.model.type.WildcardType; -import javax.lang.model.util.AbstractTypeVisitor6; - -import com.mysema.codegen.model.SimpleType; -import com.mysema.codegen.model.Type; -import com.mysema.codegen.model.TypeCategory; -import com.mysema.codegen.model.TypeExtends; -import com.mysema.codegen.model.TypeSuper; -import com.mysema.codegen.model.Types; -import com.mysema.query.annotations.QueryExclude; -import com.mysema.query.codegen.EntityType; -import com.mysema.query.codegen.Property; -import com.mysema.query.codegen.QueryTypeFactory; -import com.mysema.query.codegen.Supertype; -import com.mysema.query.codegen.TypeMappings; +import java.lang.annotation.Annotation; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Function; /** - * ExtendedTypeFactory is a factory for APT inspection based Type creation + * {@code ExtendedTypeFactory} is a factory for APT-based inspection {@link Type} creation * * @author tiwe * */ -public final class ExtendedTypeFactory { +public class ExtendedTypeFactory { private final Map, Type> typeCache = new HashMap, Type>(); @@ -82,7 +81,9 @@ public final class ExtendedTypeFactory { private boolean doubleIndexEntities = true; - private final TypeVisitor visitor = new AbstractTypeVisitor6() { + private Function variableNameFunction; + + private final TypeVisitor visitor = new SimpleTypeVisitorAdapter() { @Override public Type visitPrimitive(PrimitiveType primitiveType, Boolean p) { @@ -132,13 +133,19 @@ public Type visitArray(ArrayType arrayType, Boolean p) { @Override public Type visitDeclared(DeclaredType declaredType, Boolean p) { if (declaredType.asElement() instanceof TypeElement) { - TypeElement typeElement = (TypeElement)declaredType.asElement(); - switch(typeElement.getKind()) { - case ENUM: return createEnumType(declaredType, typeElement, p); - case ANNOTATION_TYPE: - case CLASS: return createClassType(declaredType, typeElement, p); - case INTERFACE: return createInterfaceType(declaredType, typeElement, p); - default: throw new IllegalArgumentException("Illegal type " + typeElement); + TypeElement typeElement = (TypeElement) declaredType.asElement(); + switch (typeElement.getKind()) { + case ENUM: return createEnumType(declaredType, typeElement, p); + case ANNOTATION_TYPE: + case CLASS: return createClassType(declaredType, typeElement, p); + case INTERFACE: return createInterfaceType(declaredType, typeElement, p); + default: { + if (typeElement.getKind().name().equals("RECORD")) { + return createClassType(declaredType, typeElement, p); + } + + throw new IllegalArgumentException("Illegal type " + typeElement); + } } } else { throw new IllegalArgumentException("Unsupported element type " + declaredType.asElement()); @@ -165,12 +172,12 @@ public Type visitTypeVariable(TypeVariable typeVariable, Boolean p) { } @Override - public Type visitWildcard(WildcardType wildardType, Boolean p) { - if (wildardType.getExtendsBound() != null) { - Type type = visit(wildardType.getExtendsBound(), p); + public Type visitWildcard(WildcardType wildcardType, Boolean p) { + if (wildcardType.getExtendsBound() != null) { + Type type = visit(wildcardType.getExtendsBound(), p); return new TypeExtends(type); - } else if (wildardType.getSuperBound() != null) { - Type type = visit(wildardType.getSuperBound(), p); + } else if (wildcardType.getSuperBound() != null) { + Type type = visit(wildcardType.getSuperBound(), p); return new TypeSuper(type); } else { return null; @@ -187,16 +194,13 @@ public Type visitNoType(NoType t, Boolean p) { return defaultType; } - @Override - public Type visitUnknown(TypeMirror t, Boolean p) { - return defaultType; - } - }; // TODO : return TypeMirror instead ?!? - private final TypeVisitor, Boolean> keyBuilder = new AbstractTypeVisitor6, Boolean>() { + private final TypeVisitor, Boolean> keyBuilder = new SimpleTypeVisitorAdapter, Boolean>() { + + private final List defaultValue = Collections.singletonList("Object"); private List visitBase(TypeMirror t) { List rv = new ArrayList(); @@ -215,7 +219,7 @@ public List visitPrimitive(PrimitiveType t, Boolean p) { @Override public List visitNull(NullType t, Boolean p) { - return Collections.singletonList("Object"); + return defaultValue; } @Override @@ -274,17 +278,18 @@ public List visitExecutable(ExecutableType t, Boolean p) { @Override public List visitNoType(NoType t, Boolean p) { - return Collections.singletonList("Object"); + return defaultValue; } }; public ExtendedTypeFactory( ProcessingEnvironment env, - Configuration configuration, Set> annotations, TypeMappings typeMappings, - QueryTypeFactory queryTypeFactory) { + QueryTypeFactory queryTypeFactory, + Function variableNameFunction) { this.env = env; this.defaultType = new TypeExtends(Types.OBJECT); this.entityAnnotations = annotations; @@ -297,13 +302,14 @@ public ExtendedTypeFactory( this.mapType = getErasedType(Map.class); this.typeMappings = typeMappings; this.queryTypeFactory = queryTypeFactory; + this.variableNameFunction = variableNameFunction; } private TypeMirror getErasedType(Class clazz) { return env.getTypeUtils().erasure(env.getElementUtils().getTypeElement(clazz.getName()).asType()); } - private Type createType(TypeElement typeElement, TypeCategory category, + protected Type createType(TypeElement typeElement, TypeCategory category, List typeArgs, boolean deep) { String name = typeElement.getQualifiedName().toString(); String simpleName = typeElement.getSimpleName().toString(); @@ -350,6 +356,24 @@ private Type createType(TypeMirror typeMirror, List key, boolean deep) { private Type createClassType(DeclaredType declaredType, TypeElement typeElement, boolean deep) { // other String name = typeElement.getQualifiedName().toString(); + + if (name.startsWith("java.")) { + Iterator i = declaredType.getTypeArguments().iterator(); + + if (isAssignable(declaredType, mapType)) { + return createMapType(i, deep); + + } else if (isAssignable(declaredType, listType)) { + return createCollectionType(Types.LIST, i, deep); + + } else if (isAssignable(declaredType, setType)) { + return createCollectionType(Types.SET, i, deep); + + } else if (isAssignable(declaredType, collectionType)) { + return createCollectionType(Types.COLLECTION, i, deep); + } + } + TypeCategory typeCategory = TypeCategory.get(name); if (typeCategory != TypeCategory.NUMERIC @@ -361,11 +385,11 @@ && isSubType(typeElement.asType(), numberType)) { && isAssignable(typeElement.asType(), comparableType)) { typeCategory = TypeCategory.COMPARABLE; - } if (typeCategory == TypeCategory.SIMPLE) { - for (Class entityAnn : entityAnnotations) { - if (typeElement.getAnnotation(entityAnn) != null) { - typeCategory = TypeCategory.ENTITY; - } + } + + for (Class entityAnn : entityAnnotations) { + if (isSimpleTypeEntity(typeElement, entityAnn)) { + typeCategory = TypeCategory.ENTITY; } } @@ -384,9 +408,9 @@ && isAssignable(typeElement.asType(), comparableType)) { type = superType; } } - typeElement = (TypeElement)env.getTypeUtils().asElement(type); + typeElement = (TypeElement) env.getTypeUtils().asElement(type); if (type instanceof DeclaredType) { - arguments = ((DeclaredType)type).getTypeArguments(); + arguments = ((DeclaredType) type).getTypeArguments(); } } @@ -395,14 +419,14 @@ && isAssignable(typeElement.asType(), comparableType)) { TypeMirror superType = typeElement.getSuperclass(); TypeElement superTypeElement = null; if (superType instanceof DeclaredType) { - superTypeElement = (TypeElement) ((DeclaredType)superType).asElement(); + superTypeElement = (TypeElement) ((DeclaredType) superType).asElement(); } // entity type for (Class entityAnn : entityAnnotations) { if (typeElement.getAnnotation(entityAnn) != null || (superTypeElement != null && superTypeElement.getAnnotation(entityAnn) != null)) { - EntityType entityType = new EntityType(type); + EntityType entityType = new EntityType(type, variableNameFunction); typeMappings.register(entityType, queryTypeFactory.create(entityType)); return entityType; } @@ -410,7 +434,11 @@ && isAssignable(typeElement.asType(), comparableType)) { return type; } - private Type createMapType(String simpleName, Iterator typeMirrors, boolean deep) { + public boolean isSimpleTypeEntity(TypeElement typeElement, Class entityAnn) { + return typeElement.getAnnotation(entityAnn) != null; + } + + protected Type createMapType(Iterator typeMirrors, boolean deep) { if (!typeMirrors.hasNext()) { return new SimpleType(Types.MAP, defaultType, defaultType); } @@ -435,8 +463,8 @@ private Type createMapType(String simpleName, Iterator typ return new SimpleType(Types.MAP, keyType, valueType); } - private Type createCollectionType(Type baseType, String simpleName, - Iterator typeMirrors, boolean deep) { + private Type createCollectionType(Type baseType, + Iterator typeMirrors, boolean deep) { if (!typeMirrors.hasNext()) { return new SimpleType(baseType, defaultType); } @@ -463,7 +491,7 @@ public EntityType getEntityType(TypeMirror typeMirror, boolean deep) { if (entityTypeCache.containsKey(key)) { EntityType entityType = entityTypeCache.get(key); if (deep && entityType.getSuperTypes().isEmpty()) { - for (Type superType : getSupertypes(typeMirror, entityType, deep)) { + for (Type superType : getSupertypes(typeMirror, deep)) { entityType.addSupertype(new Supertype(superType)); } } @@ -483,15 +511,15 @@ private EntityType createEntityType(TypeMirror typeMirror, List key, boo if (value != null) { EntityType entityType = null; if (value instanceof EntityType) { - entityType = (EntityType)value; + entityType = (EntityType) value; } else { - entityType = new EntityType(value); + entityType = new EntityType(value, variableNameFunction); typeMappings.register(entityType, queryTypeFactory.create(entityType)); } entityTypeCache.put(key, entityType); if (deep) { - for (Type superType : getSupertypes(typeMirror, value, deep)) { + for (Type superType : getSupertypes(typeMirror, deep)) { entityType.addSupertype(new Supertype(superType)); } } @@ -508,7 +536,7 @@ private Type createEnumType(DeclaredType declaredType, TypeElement typeElement, for (Class entityAnn : entityAnnotations) { if (typeElement.getAnnotation(entityAnn) != null) { - EntityType entityType = new EntityType(enumType); + EntityType entityType = new EntityType(enumType, variableNameFunction); typeMappings.register(entityType, queryTypeFactory.create(entityType)); return entityType; } @@ -524,20 +552,19 @@ private Type createInterfaceType(DeclaredType declaredType, TypeElement typeElem } } - String simpleName = typeElement.getSimpleName().toString(); Iterator i = declaredType.getTypeArguments().iterator(); if (isAssignable(declaredType, mapType)) { - return createMapType(simpleName, i, deep); + return createMapType(i, deep); } else if (isAssignable(declaredType, listType)) { - return createCollectionType(Types.LIST, simpleName, i, deep); + return createCollectionType(Types.LIST, i, deep); } else if (isAssignable(declaredType, setType)) { - return createCollectionType(Types.SET, simpleName, i, deep); + return createCollectionType(Types.SET, i, deep); } else if (isAssignable(declaredType, collectionType)) { - return createCollectionType(Types.COLLECTION, simpleName, i, deep); + return createCollectionType(Types.COLLECTION, i, deep); } else { String name = typeElement.getQualifiedName().toString(); @@ -545,20 +572,20 @@ private Type createInterfaceType(DeclaredType declaredType, TypeElement typeElem } } - private Set getSupertypes(TypeMirror typeMirror, Type type, boolean deep) { + private Set getSupertypes(TypeMirror typeMirror, boolean deep) { boolean doubleIndex = doubleIndexEntities; doubleIndexEntities = false; Set superTypes = Collections.emptySet(); typeMirror = normalize(typeMirror); if (typeMirror.getKind() == TypeKind.DECLARED) { - DeclaredType declaredType = (DeclaredType)typeMirror; - TypeElement e = (TypeElement)declaredType.asElement(); + DeclaredType declaredType = (DeclaredType) typeMirror; + TypeElement e = (TypeElement) declaredType.asElement(); // class if (e.getKind() == ElementKind.CLASS) { if (e.getSuperclass().getKind() != TypeKind.NONE) { TypeMirror supertype = normalize(e.getSuperclass()); if (supertype instanceof DeclaredType - && ((DeclaredType)supertype).asElement().getAnnotation(QueryExclude.class) != null) { + && ((DeclaredType) supertype).asElement().getAnnotation(QueryExclude.class) != null) { return Collections.emptySet(); } else { Type superClass = getType(supertype, deep); @@ -572,7 +599,7 @@ private Set getSupertypes(TypeMirror typeMirror, Type type, boolean deep) } // interface } else { - superTypes = new HashSet(e.getInterfaces().size()); + superTypes = new LinkedHashSet(e.getInterfaces().size()); for (TypeMirror mirror : e.getInterfaces()) { Type iface = getType(mirror, deep); if (!iface.getFullName().startsWith("java")) { @@ -602,12 +629,12 @@ private boolean isSubType(TypeMirror type1, TypeMirror clazz) { private TypeMirror normalize(TypeMirror type) { if (type.getKind() == TypeKind.TYPEVAR) { - TypeVariable typeVar = (TypeVariable)type; + TypeVariable typeVar = (TypeVariable) type; if (typeVar.getUpperBound() != null) { return typeVar.getUpperBound(); } } else if (type.getKind() == TypeKind.WILDCARD) { - WildcardType wildcard = (WildcardType)type; + WildcardType wildcard = (WildcardType) type; if (wildcard.getExtendsBound() != null) { return wildcard.getExtendsBound(); } diff --git a/querydsl-apt/src/main/java/com/mysema/query/apt/QueryTypeImpl.java b/querydsl-apt/src/main/java/com/querydsl/apt/QueryTypeImpl.java similarity index 79% rename from querydsl-apt/src/main/java/com/mysema/query/apt/QueryTypeImpl.java rename to querydsl-apt/src/main/java/com/querydsl/apt/QueryTypeImpl.java index a41f04eddf..3f0ba17ffd 100644 --- a/querydsl-apt/src/main/java/com/mysema/query/apt/QueryTypeImpl.java +++ b/querydsl-apt/src/main/java/com/querydsl/apt/QueryTypeImpl.java @@ -1,6 +1,6 @@ /* - * Copyright 2013, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,14 +11,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.apt; +package com.querydsl.apt; import java.lang.annotation.Annotation; -import com.mysema.query.annotations.PropertyType; -import com.mysema.query.annotations.QueryType; +import com.querydsl.core.annotations.PropertyType; +import com.querydsl.core.annotations.QueryType; /** + * Implementation of the {@link QueryType} annotation + * * @author tiwe * */ @@ -26,11 +28,11 @@ public class QueryTypeImpl implements QueryType { private final PropertyType value; - + public QueryTypeImpl(PropertyType value) { this.value = value; } - + @Override public Class annotationType() { return QueryType.class; diff --git a/querydsl-apt/src/main/java/com/querydsl/apt/QuerydslAnnotationProcessor.java b/querydsl-apt/src/main/java/com/querydsl/apt/QuerydslAnnotationProcessor.java new file mode 100644 index 0000000000..ea9384ba19 --- /dev/null +++ b/querydsl-apt/src/main/java/com/querydsl/apt/QuerydslAnnotationProcessor.java @@ -0,0 +1,48 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt; + +import java.lang.annotation.Annotation; +import java.util.Collections; + +import javax.annotation.processing.RoundEnvironment; +import javax.annotation.processing.SupportedAnnotationTypes; + +import com.querydsl.core.annotations.*; + +/** + * Default annotation processor for Querydsl which handles {@link QueryEntity}, {@link QuerySupertype}, + * {@link QueryEmbeddable}, {@link QueryEmbedded} and {@link QueryTransient} + * + * @author tiwe + * + */ +@SupportedAnnotationTypes({"com.querydsl.core.annotations.*"}) +public class QuerydslAnnotationProcessor extends AbstractQuerydslProcessor { + + @Override + protected Configuration createConfiguration(RoundEnvironment roundEnv) { + Class entities = QueryEntities.class; + Class entity = QueryEntity.class; + Class superType = QuerySupertype.class; + Class embeddable = QueryEmbeddable.class; + Class embedded = QueryEmbedded.class; + Class skip = QueryTransient.class; + + return new DefaultConfiguration( + processingEnv, roundEnv, Collections.emptySet(), entities, + entity, superType, embeddable, embedded, skip); + } + +} diff --git a/querydsl-apt/src/main/java/com/querydsl/apt/SimpleTypeVisitorAdapter.java b/querydsl-apt/src/main/java/com/querydsl/apt/SimpleTypeVisitorAdapter.java new file mode 100644 index 0000000000..35f3dfd06c --- /dev/null +++ b/querydsl-apt/src/main/java/com/querydsl/apt/SimpleTypeVisitorAdapter.java @@ -0,0 +1,65 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.List; + +import javax.lang.model.type.TypeMirror; +import javax.lang.model.util.SimpleTypeVisitor6; + +/** + * Converts Java 8 {@link javax.lang.model.type.IntersectionType IntersectionType} instances into their first bound when visiting + * + * @param + * @param

+ */ +class SimpleTypeVisitorAdapter extends SimpleTypeVisitor6 { + + private static final Class intersectionTypeClass; + + private static final Method getBoundsMethod; + + static { + Class availableClass; + Method availableMethod; + try { + availableClass = Class.forName("javax.lang.model.type.IntersectionType"); + availableMethod = availableClass.getMethod("getBounds"); + } catch (Exception e) { + // Not using Java 8 + availableClass = null; + availableMethod = null; + } + intersectionTypeClass = availableClass; + getBoundsMethod = availableMethod; + } + + @SuppressWarnings("unchecked") + @Override + public R visitUnknown(TypeMirror t, P p) { + if (intersectionTypeClass != null && intersectionTypeClass.isInstance(t)) { + try { + List bounds = (List) getBoundsMethod.invoke(t); + return bounds.get(0).accept(this, p); + } catch (IllegalAccessException | InvocationTargetException e) { + throw new RuntimeException(e.getMessage(), e); + } + } else { + return super.visitUnknown(t, p); + } + } + +} diff --git a/querydsl-apt/src/main/java/com/mysema/query/apt/TypeElementHandler.java b/querydsl-apt/src/main/java/com/querydsl/apt/TypeElementHandler.java similarity index 88% rename from querydsl-apt/src/main/java/com/mysema/query/apt/TypeElementHandler.java rename to querydsl-apt/src/main/java/com/querydsl/apt/TypeElementHandler.java index 37a6082bff..93a06f811a 100644 --- a/querydsl-apt/src/main/java/com/mysema/query/apt/TypeElementHandler.java +++ b/querydsl-apt/src/main/java/com/querydsl/apt/TypeElementHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2011, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,9 +11,30 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.apt; +package com.querydsl.apt; + +import com.querydsl.codegen.utils.model.Constructor; +import com.querydsl.codegen.utils.model.Parameter; +import com.querydsl.codegen.utils.model.Type; +import com.querydsl.codegen.utils.model.TypeCategory; +import com.querydsl.codegen.EntityType; +import com.querydsl.codegen.Property; +import com.querydsl.codegen.QueryTypeFactory; +import com.querydsl.codegen.TypeMappings; +import com.querydsl.core.annotations.PropertyType; +import com.querydsl.core.annotations.QueryInit; +import com.querydsl.core.annotations.QueryType; +import com.querydsl.core.util.Annotations; +import com.querydsl.core.util.BeanUtils; +import javax.lang.model.element.Element; +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.TypeElement; +import javax.lang.model.element.VariableElement; +import javax.lang.model.type.TypeMirror; +import javax.lang.model.util.ElementFilter; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; @@ -21,35 +42,13 @@ import java.util.Map; import java.util.Set; -import javax.lang.model.element.Element; -import javax.lang.model.element.ExecutableElement; -import javax.lang.model.element.TypeElement; -import javax.lang.model.element.VariableElement; -import javax.lang.model.type.TypeMirror; -import javax.lang.model.util.ElementFilter; - -import com.google.common.collect.ImmutableList; -import com.mysema.codegen.model.Constructor; -import com.mysema.codegen.model.Parameter; -import com.mysema.codegen.model.Type; -import com.mysema.codegen.model.TypeCategory; -import com.mysema.query.annotations.PropertyType; -import com.mysema.query.annotations.QueryInit; -import com.mysema.query.annotations.QueryType; -import com.mysema.query.codegen.EntityType; -import com.mysema.query.codegen.Property; -import com.mysema.query.codegen.QueryTypeFactory; -import com.mysema.query.codegen.TypeMappings; -import com.mysema.util.Annotations; -import com.mysema.util.BeanUtils; - /** - * TypeElementHandler is a an APT visitor for entity types + * {@code TypeElementHandler} is an APT visitor for entity types * * @author tiwe * */ -public final class TypeElementHandler { +public class TypeElementHandler { private final TypeMappings typeMappings; @@ -165,9 +164,9 @@ private Property toProperty(EntityType entityType, String name, TypeMirror type, } // inits - List inits = Collections.emptyList(); + List inits = Collections.emptyList(); if (annotations.isAnnotationPresent(QueryInit.class)) { - inits = ImmutableList.copyOf(annotations.getAnnotation(QueryInit.class).value()); + inits = Arrays.asList(annotations.getAnnotation(QueryInit.class).value()); } return new Property(entityType, name, propertyType, inits); @@ -176,7 +175,7 @@ private Property toProperty(EntityType entityType, String name, TypeMirror type, public EntityType handleProjectionType(TypeElement e) { Type c = typeFactory.getType(e.asType(), true); - EntityType entityType = new EntityType(c.as(TypeCategory.ENTITY)); + EntityType entityType = new EntityType(c.as(TypeCategory.ENTITY), configuration.getVariableNameFunction()); typeMappings.register(entityType, queryTypeFactory.create(entityType)); List elements = e.getEnclosedElements(); handleConstructors(entityType, elements); diff --git a/querydsl-apt/src/main/java/com/querydsl/apt/TypeExtractor.java b/querydsl-apt/src/main/java/com/querydsl/apt/TypeExtractor.java new file mode 100644 index 0000000000..12f7229773 --- /dev/null +++ b/querydsl-apt/src/main/java/com/querydsl/apt/TypeExtractor.java @@ -0,0 +1,114 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt; + +import javax.lang.model.element.TypeElement; +import javax.lang.model.type.*; + +/** + * {@code TypeExtractor} is a visitor implementation which extracts a concrete type from a generic {@link TypeElement} + * + * @author tiwe + * + */ +class TypeExtractor extends SimpleTypeVisitorAdapter { + + private final boolean skipEnum; + + TypeExtractor(boolean skipEnum) { + this.skipEnum = skipEnum; + } + + @Override + public TypeElement visitPrimitive(PrimitiveType t, Void p) { + return null; + } + + @Override + public TypeElement visitNull(NullType t, Void p) { + return null; + } + + @Override + public TypeElement visitArray(ArrayType t, Void p) { + return visit(t.getComponentType()); + } + + @Override + public TypeElement visitDeclared(DeclaredType t, Void p) { + if (t.asElement() instanceof TypeElement) { + TypeElement typeElement = (TypeElement) t.asElement(); + switch (typeElement.getKind()) { + case ENUM: return skipEnum ? null : typeElement; + case CLASS: return typeElement; + case INTERFACE: return visitInterface(t); + default: throw new IllegalArgumentException("Illegal type: " + typeElement); + } + } else { + return null; + } + } + + private TypeElement visitInterface(DeclaredType t) { + if (t.getTypeArguments().isEmpty()) { + return (TypeElement) t.asElement(); + } else { + int count = t.getTypeArguments().size(); + if (t.asElement().toString().startsWith("java.util")) { + return t.getTypeArguments().get(count - 1).accept(this, null); + } else { + return (TypeElement) t.asElement(); + } + } + } + + @Override + public TypeElement visitError(ErrorType t, Void p) { + return visitDeclared(t, p); + } + + @Override + public TypeElement visitTypeVariable(TypeVariable t, Void p) { + if (t.getUpperBound() != null) { + return visit(t.getUpperBound()); + } else if (t.getLowerBound() != null) { + return visit(t.getLowerBound()); + } else { + return null; + } + } + + @Override + public TypeElement visitWildcard(WildcardType t, Void p) { + if (t.getExtendsBound() != null) { + return visit(t.getExtendsBound()); + } else if (t.getSuperBound() != null) { + return visit(t.getSuperBound()); + } else { + return null; + } + + } + + @Override + public TypeElement visitExecutable(ExecutableType t, Void p) { + return null; + } + + @Override + public TypeElement visitNoType(NoType t, Void p) { + return null; + } + +} diff --git a/querydsl-apt/src/main/java/com/mysema/query/apt/TypeUtils.java b/querydsl-apt/src/main/java/com/querydsl/apt/TypeUtils.java similarity index 91% rename from querydsl-apt/src/main/java/com/mysema/query/apt/TypeUtils.java rename to querydsl-apt/src/main/java/com/querydsl/apt/TypeUtils.java index 020eab9087..79ce91dc1c 100644 --- a/querydsl-apt/src/main/java/com/mysema/query/apt/TypeUtils.java +++ b/querydsl-apt/src/main/java/com/querydsl/apt/TypeUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2011, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.apt; +package com.querydsl.apt; import java.lang.annotation.Annotation; import java.util.HashSet; @@ -19,11 +19,7 @@ import java.util.Map; import java.util.Set; -import javax.lang.model.element.AnnotationMirror; -import javax.lang.model.element.AnnotationValue; -import javax.lang.model.element.Element; -import javax.lang.model.element.ExecutableElement; -import javax.lang.model.element.TypeElement; +import javax.lang.model.element.*; import javax.lang.model.type.DeclaredType; import javax.lang.model.type.TypeMirror; @@ -66,6 +62,7 @@ public static boolean isAnnotationMirrorOfType(AnnotationMirror annotationMirror return annotationClassName.equals(className); } + @SuppressWarnings("unchecked") public static Set getAnnotationValuesAsElements(AnnotationMirror mirror, String method) { Set elements = new HashSet(); for (Map.Entry entry : mirror.getElementValues().entrySet()) { @@ -89,6 +86,6 @@ public static TypeMirror getAnnotationValueAsTypeMirror(AnnotationMirror mirror, return null; } - private TypeUtils() {} + private TypeUtils() { } } diff --git a/querydsl-apt/src/main/java/com/mysema/query/apt/VisitorConfig.java b/querydsl-apt/src/main/java/com/querydsl/apt/VisitorConfig.java similarity index 76% rename from querydsl-apt/src/main/java/com/mysema/query/apt/VisitorConfig.java rename to querydsl-apt/src/main/java/com/querydsl/apt/VisitorConfig.java index 48994e6d98..860df21860 100644 --- a/querydsl-apt/src/main/java/com/mysema/query/apt/VisitorConfig.java +++ b/querydsl-apt/src/main/java/com/querydsl/apt/VisitorConfig.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,10 +11,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.apt; +package com.querydsl.apt; + +import com.querydsl.codegen.EntityType; /** - * VisitorConfig defines the entity type specific visiting configuration + * {@code VisitorConfig} defines the {@link EntityType}-specific visiting configuration * * @author tiwe * @@ -43,21 +45,27 @@ public enum VisitorConfig { private final boolean visitFieldProperties, visitMethodProperties, visitConstructors; public static VisitorConfig get(boolean fields, boolean methods) { - if (fields && !methods) { + return get(fields, methods, VisitorConfig.ALL); + } + + public static VisitorConfig get(boolean fields, boolean methods, VisitorConfig defaultConfig) { + if (fields && methods) { + return VisitorConfig.ALL; + } else if (fields) { return VisitorConfig.FIELDS_ONLY; - } else if (methods && !fields) { + } else if (methods) { return VisitorConfig.METHODS_ONLY; } else { - return VisitorConfig.ALL; + return defaultConfig; } } - + VisitorConfig(boolean fields, boolean methods, boolean constructors) { this.visitFieldProperties = fields; this.visitMethodProperties = methods; this.visitConstructors = constructors; } - + public boolean visitConstructors() { return visitConstructors; } diff --git a/querydsl-apt/src/main/java/com/querydsl/apt/hibernate/HibernateAnnotationProcessor.java b/querydsl-apt/src/main/java/com/querydsl/apt/hibernate/HibernateAnnotationProcessor.java new file mode 100644 index 0000000000..a59c7f417b --- /dev/null +++ b/querydsl-apt/src/main/java/com/querydsl/apt/hibernate/HibernateAnnotationProcessor.java @@ -0,0 +1,50 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt.hibernate; + +import java.lang.annotation.Annotation; + +import javax.annotation.processing.RoundEnvironment; +import javax.annotation.processing.SupportedAnnotationTypes; +import javax.persistence.*; + +import com.querydsl.apt.Configuration; +import com.querydsl.apt.jpa.JPAAnnotationProcessor; + +/** + * {@code HibernateAnnotationProcessor} extends {@link JPAAnnotationProcessor} to take Hibernate-specific + * annotations into account + * + * @author tiwe + * @see JPAAnnotationProcessor + */ +@SupportedAnnotationTypes({"com.querydsl.core.annotations.*", "javax.persistence.*", "jakarta.persistence.*", "org.hibernate.annotations.*"}) +public class HibernateAnnotationProcessor extends JPAAnnotationProcessor { + + @Override + protected Configuration createConfiguration(RoundEnvironment roundEnv) { + try { + Class entity = Entity.class; + Class superType = MappedSuperclass.class; + Class embeddable = Embeddable.class; + Class embedded = Embedded.class; + Class skip = Transient.class; + return new HibernateConfiguration(roundEnv, processingEnv, entity, superType, + embeddable, embedded, skip); + } catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } + } + +} diff --git a/querydsl-apt/src/main/java/com/mysema/query/apt/hibernate/HibernateConfiguration.java b/querydsl-apt/src/main/java/com/querydsl/apt/hibernate/HibernateConfiguration.java similarity index 76% rename from querydsl-apt/src/main/java/com/mysema/query/apt/hibernate/HibernateConfiguration.java rename to querydsl-apt/src/main/java/com/querydsl/apt/hibernate/HibernateConfiguration.java index cf99086e7c..077d5df54a 100644 --- a/querydsl-apt/src/main/java/com/mysema/query/apt/hibernate/HibernateConfiguration.java +++ b/querydsl-apt/src/main/java/com/querydsl/apt/hibernate/HibernateConfiguration.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,21 +11,21 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.apt.hibernate; +package com.querydsl.apt.hibernate; import java.lang.annotation.Annotation; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import java.util.Map; +import javax.annotation.processing.ProcessingEnvironment; import javax.annotation.processing.RoundEnvironment; -import com.mysema.query.apt.jpa.JPAConfiguration; +import com.querydsl.apt.jpa.JPAConfiguration; /** * Configuration for {@link HibernateAnnotationProcessor} - * + * * @author tiwe * @see HibernateAnnotationProcessor * @see JPAConfiguration @@ -34,28 +34,27 @@ public class HibernateConfiguration extends JPAConfiguration { public HibernateConfiguration( RoundEnvironment roundEnv, - Map options, + ProcessingEnvironment processingEnv, Class entityAnn, Class superTypeAnn, Class embeddableAnn, Class embeddedAnn, Class skipAnn) throws ClassNotFoundException { - super(roundEnv, options, entityAnn, superTypeAnn, embeddableAnn, embeddedAnn, skipAnn); + super(roundEnv, processingEnv, entityAnn, superTypeAnn, embeddableAnn, embeddedAnn, skipAnn); } @SuppressWarnings("unchecked") @Override protected List> getAnnotations() { - try { - List> annotations = new ArrayList>(); - annotations.addAll(super.getAnnotations()); + try { + List> annotations = new ArrayList>(super.getAnnotations()); for (String simpleName : Arrays.asList("Type", "Cascade", "LazyCollection", "OnDelete")) { - annotations.add((Class) Class.forName("org.hibernate.annotations."+simpleName)); + annotations.add((Class) Class.forName("org.hibernate.annotations." + simpleName)); } - return annotations; + return annotations; } catch (ClassNotFoundException e) { throw new RuntimeException(e); } } - + } diff --git a/querydsl-apt/src/main/java/com/querydsl/apt/hibernate/package-info.java b/querydsl-apt/src/main/java/com/querydsl/apt/hibernate/package-info.java new file mode 100644 index 0000000000..4b648f3150 --- /dev/null +++ b/querydsl-apt/src/main/java/com/querydsl/apt/hibernate/package-info.java @@ -0,0 +1,18 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ + +/** + * APT Hibernate support + */ +package com.querydsl.apt.hibernate; diff --git a/querydsl-apt/src/main/java/com/querydsl/apt/jdo/JDOAnnotationProcessor.java b/querydsl-apt/src/main/java/com/querydsl/apt/jdo/JDOAnnotationProcessor.java new file mode 100644 index 0000000000..190d7a5c12 --- /dev/null +++ b/querydsl-apt/src/main/java/com/querydsl/apt/jdo/JDOAnnotationProcessor.java @@ -0,0 +1,51 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt.jdo; + +import java.lang.annotation.Annotation; + +import javax.annotation.processing.RoundEnvironment; +import javax.annotation.processing.SupportedAnnotationTypes; +import javax.jdo.annotations.EmbeddedOnly; +import javax.jdo.annotations.NotPersistent; +import javax.jdo.annotations.PersistenceCapable; + +import com.querydsl.apt.AbstractQuerydslProcessor; +import com.querydsl.apt.Configuration; +import com.querydsl.core.annotations.QueryEmbedded; +import com.querydsl.core.annotations.QueryEntities; +import com.querydsl.core.annotations.QuerySupertype; + +/** + * AnnotationProcessor for JDO which takes {@link PersistenceCapable}, {@link EmbeddedOnly} and + * {@link NotPersistent} into account + * + * @author tiwe + * + */ +@SupportedAnnotationTypes({"com.querydsl.core.annotations.*","javax.jdo.annotations.*"}) +public class JDOAnnotationProcessor extends AbstractQuerydslProcessor { + + @Override + protected Configuration createConfiguration(RoundEnvironment roundEnv) { + Class entities = QueryEntities.class; + Class entity = PersistenceCapable.class; + Class superType = QuerySupertype.class; + Class embeddable = EmbeddedOnly.class; + Class embedded = QueryEmbedded.class; + Class skip = NotPersistent.class; + return new JDOConfiguration(processingEnv, roundEnv, + entities, entity, superType, embeddable, embedded, skip); + } +} diff --git a/querydsl-apt/src/main/java/com/querydsl/apt/jdo/JDOConfiguration.java b/querydsl-apt/src/main/java/com/querydsl/apt/jdo/JDOConfiguration.java new file mode 100644 index 0000000000..edac3b9587 --- /dev/null +++ b/querydsl-apt/src/main/java/com/querydsl/apt/jdo/JDOConfiguration.java @@ -0,0 +1,103 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt.jdo; + +import com.querydsl.apt.DefaultConfiguration; +import com.querydsl.apt.VisitorConfig; +import com.querydsl.codegen.Keywords; +import com.querydsl.core.annotations.QueryInit; +import com.querydsl.core.annotations.QueryTransient; +import com.querydsl.core.annotations.QueryType; + +import javax.annotation.processing.ProcessingEnvironment; +import javax.annotation.processing.RoundEnvironment; +import javax.jdo.annotations.Cacheable; +import javax.jdo.annotations.Column; +import javax.jdo.annotations.Columns; +import javax.jdo.annotations.Embedded; +import javax.jdo.annotations.Extension; +import javax.jdo.annotations.Extensions; +import javax.jdo.annotations.ForeignKey; +import javax.jdo.annotations.Index; +import javax.jdo.annotations.Join; +import javax.jdo.annotations.Key; +import javax.jdo.annotations.NotPersistent; +import javax.jdo.annotations.Order; +import javax.jdo.annotations.Persistent; +import javax.jdo.annotations.PrimaryKey; +import javax.jdo.annotations.Serialized; +import javax.jdo.annotations.Transactional; +import javax.jdo.annotations.Unique; +import javax.jdo.annotations.Value; +import javax.lang.model.element.Element; +import javax.lang.model.element.ElementKind; +import javax.lang.model.element.TypeElement; +import java.lang.annotation.Annotation; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +/** + * Configuration for {@link JDOAnnotationProcessor} + * + * @author tiwe + * @see JDOAnnotationProcessor + */ +public class JDOConfiguration extends DefaultConfiguration { + + @SuppressWarnings("unchecked") + private static final Iterable> relevantAnnotations + = Collections.unmodifiableList(Arrays.asList( + Cacheable.class, Column.class, Columns.class, + javax.jdo.annotations.Element.class, Embedded.class, + Extension.class, Extensions.class, ForeignKey.class, + Index.class, Join.class, Key.class, NotPersistent.class, + Order.class, Persistent.class, PrimaryKey.class, QueryType.class, QueryInit.class, + QueryTransient.class, Serialized.class, Transactional.class, Unique.class, Value.class)); + + public JDOConfiguration(ProcessingEnvironment processingEnvironment, + RoundEnvironment roundEnv, + Class entitiesAnn, + Class entityAnn, + Class superTypeAnn, + Class embeddableAnn, + Class embeddedAnn, Class skipAnn) { + super(processingEnvironment, roundEnv, Keywords.JDO, entitiesAnn, entityAnn, superTypeAnn, + embeddableAnn, embeddedAnn, skipAnn); + } + + @Override + public VisitorConfig getConfig(TypeElement e, List elements) { + boolean fields = false, methods = false; + for (Element element : elements) { + if (hasRelevantAnnotation(element)) { + fields |= element.getKind().equals(ElementKind.FIELD); + methods |= element.getKind().equals(ElementKind.METHOD); + } + } + return VisitorConfig.get(fields, methods, VisitorConfig.FIELDS_ONLY); + } + + private boolean hasRelevantAnnotation(Element element) { + for (Class relevantAnnotation : relevantAnnotations) { + if (element.getAnnotation(relevantAnnotation) != null) { + return true; + } + } + return false; + } + +} diff --git a/querydsl-apt/src/main/java/com/querydsl/apt/jdo/package-info.java b/querydsl-apt/src/main/java/com/querydsl/apt/jdo/package-info.java new file mode 100644 index 0000000000..6ec2d627bb --- /dev/null +++ b/querydsl-apt/src/main/java/com/querydsl/apt/jdo/package-info.java @@ -0,0 +1,18 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ + +/** + * APT JDO support + */ +package com.querydsl.apt.jdo; diff --git a/querydsl-apt/src/main/java/com/querydsl/apt/jpa/JPAAnnotationProcessor.java b/querydsl-apt/src/main/java/com/querydsl/apt/jpa/JPAAnnotationProcessor.java new file mode 100644 index 0000000000..3292354126 --- /dev/null +++ b/querydsl-apt/src/main/java/com/querydsl/apt/jpa/JPAAnnotationProcessor.java @@ -0,0 +1,46 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt.jpa; + +import java.lang.annotation.Annotation; + +import javax.annotation.processing.RoundEnvironment; +import javax.annotation.processing.SupportedAnnotationTypes; +import javax.persistence.*; + +import com.querydsl.apt.AbstractQuerydslProcessor; +import com.querydsl.apt.Configuration; + +/** + * AnnotationProcessor for JPA which takes {@link Entity}, {@link MappedSuperclass}, {@link Embeddable} + * and {@link Transient} into account + * + * @author tiwe + * + */ +@SupportedAnnotationTypes({"com.querydsl.core.annotations.*", "jakarta.persistence.*", "javax.persistence.*"}) +public class JPAAnnotationProcessor extends AbstractQuerydslProcessor { + + @Override + protected Configuration createConfiguration(RoundEnvironment roundEnv) { + Class entity = Entity.class; + Class superType = MappedSuperclass.class; + Class embeddable = Embeddable.class; + Class embedded = Embedded.class; + Class skip = Transient.class; + return new JPAConfiguration(roundEnv, processingEnv, + entity, superType, embeddable, embedded, skip); + } + +} diff --git a/querydsl-apt/src/main/java/com/querydsl/apt/jpa/JPAConfiguration.java b/querydsl-apt/src/main/java/com/querydsl/apt/jpa/JPAConfiguration.java new file mode 100644 index 0000000000..f8f147e616 --- /dev/null +++ b/querydsl-apt/src/main/java/com/querydsl/apt/jpa/JPAConfiguration.java @@ -0,0 +1,190 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt.jpa; + +import com.querydsl.apt.DefaultConfiguration; +import com.querydsl.apt.QueryTypeImpl; +import com.querydsl.apt.TypeUtils; +import com.querydsl.apt.VisitorConfig; +import com.querydsl.codegen.Keywords; +import com.querydsl.core.annotations.PropertyType; +import com.querydsl.core.annotations.QueryEntities; +import com.querydsl.core.annotations.QueryInit; +import com.querydsl.core.annotations.QueryTransient; +import com.querydsl.core.annotations.QueryType; +import com.querydsl.core.util.Annotations; + +import javax.annotation.processing.ProcessingEnvironment; +import javax.annotation.processing.RoundEnvironment; +import javax.lang.model.element.AnnotationMirror; +import javax.lang.model.element.Element; +import javax.lang.model.element.ElementKind; +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.TypeElement; +import javax.lang.model.element.VariableElement; +import javax.lang.model.type.DeclaredType; +import javax.lang.model.type.TypeMirror; +import javax.lang.model.util.Types; +import javax.persistence.Access; +import javax.persistence.AccessType; +import javax.persistence.Basic; +import javax.persistence.Column; +import javax.persistence.ElementCollection; +import javax.persistence.Embedded; +import javax.persistence.EmbeddedId; +import javax.persistence.Enumerated; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToMany; +import javax.persistence.ManyToOne; +import javax.persistence.MapKeyEnumerated; +import javax.persistence.OneToMany; +import javax.persistence.OneToOne; +import javax.persistence.PrimaryKeyJoinColumn; +import javax.persistence.Temporal; +import javax.persistence.Transient; +import javax.persistence.Version; +import java.lang.annotation.Annotation; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +/** + * Configuration for {@link JPAAnnotationProcessor} + * + * @author tiwe + * @see JPAAnnotationProcessor + */ +public class JPAConfiguration extends DefaultConfiguration { + + private final List> annotations; + + private final Types types; + + public JPAConfiguration(RoundEnvironment roundEnv, + ProcessingEnvironment processingEnv, + Class entityAnn, + Class superTypeAnn, + Class embeddableAnn, + Class embeddedAnn, + Class skipAnn) { + super(processingEnv, roundEnv, Keywords.JPA, QueryEntities.class, entityAnn, superTypeAnn, + embeddableAnn, embeddedAnn, skipAnn); + this.annotations = getAnnotations(); + this.types = processingEnv.getTypeUtils(); + setStrictMode(true); + } + + @SuppressWarnings("unchecked") + protected List> getAnnotations() { + return Collections.unmodifiableList(Arrays.asList( + Access.class, Basic.class, Column.class, ElementCollection.class, + Embedded.class, EmbeddedId.class, Enumerated.class, GeneratedValue.class, Id.class, + JoinColumn.class, ManyToOne.class, ManyToMany.class, MapKeyEnumerated.class, + OneToOne.class, OneToMany.class, PrimaryKeyJoinColumn.class, QueryType.class, QueryInit.class, + QueryTransient.class, Temporal.class, Transient.class, Version.class)); + } + + @Override + public VisitorConfig getConfig(TypeElement e, List elements) { + Access access = e.getAnnotation(Access.class); + if (access != null) { + if (access.value() == AccessType.FIELD) { + return VisitorConfig.FIELDS_ONLY; + } else { + return VisitorConfig.METHODS_ONLY; + } + } + boolean fields = false, methods = false; + for (Element element : elements) { + if (hasRelevantAnnotation(element)) { + fields |= element.getKind().equals(ElementKind.FIELD); + methods |= element.getKind().equals(ElementKind.METHOD); + } + } + return VisitorConfig.get(fields, methods, VisitorConfig.ALL); + } + + @Override + public TypeMirror getRealType(ExecutableElement method) { + return getRealElementType(method); + } + + @Override + public TypeMirror getRealType(VariableElement field) { + return getRealElementType(field); + } + + private TypeMirror getRealElementType(Element element) { + AnnotationMirror mirror = TypeUtils.getAnnotationMirrorOfType(element, ManyToOne.class); + if (mirror == null) { + mirror = TypeUtils.getAnnotationMirrorOfType(element, OneToOne.class); + } + if (mirror != null) { + return TypeUtils.getAnnotationValueAsTypeMirror(mirror, "targetEntity"); + } + + mirror = TypeUtils.getAnnotationMirrorOfType(element, OneToMany.class); + if (mirror == null) { + mirror = TypeUtils.getAnnotationMirrorOfType(element, ManyToMany.class); + } + if (mirror != null) { + TypeMirror typeArg = TypeUtils.getAnnotationValueAsTypeMirror(mirror, "targetEntity"); + TypeMirror erasure; + if (element instanceof ExecutableElement) { + erasure = ((ExecutableElement) element).getReturnType(); + } else { + erasure = types.erasure(element.asType()); + } + TypeElement typeElement = (TypeElement) types.asElement(erasure); + if (typeElement != null && typeArg != null) { + if (typeElement.getTypeParameters().size() == 1) { + return types.getDeclaredType(typeElement, typeArg); + } else if (typeElement.getTypeParameters().size() == 2) { + if (element.asType() instanceof DeclaredType) { + TypeMirror first = ((DeclaredType) element.asType()).getTypeArguments().get(0); + return types.getDeclaredType(typeElement, first, typeArg); + } + } + } + } + + return null; + } + + @Override + public void inspect(Element element, Annotations annotations) { + Temporal temporal = element.getAnnotation(Temporal.class); + if (temporal != null && element.getAnnotation(ElementCollection.class) == null) { + PropertyType propertyType = null; + switch (temporal.value()) { + case DATE: propertyType = PropertyType.DATE; break; + case TIME: propertyType = PropertyType.TIME; break; + case TIMESTAMP: propertyType = PropertyType.DATETIME; + } + annotations.addAnnotation(new QueryTypeImpl(propertyType)); + } + } + + private boolean hasRelevantAnnotation(Element element) { + for (Class annotation : annotations) { + if (element.getAnnotation(annotation) != null) { + return true; + } + } + return false; + } + +} diff --git a/querydsl-apt/src/main/java/com/querydsl/apt/jpa/package-info.java b/querydsl-apt/src/main/java/com/querydsl/apt/jpa/package-info.java new file mode 100644 index 0000000000..3cab073449 --- /dev/null +++ b/querydsl-apt/src/main/java/com/querydsl/apt/jpa/package-info.java @@ -0,0 +1,18 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ + +/** + * APT JPA support + */ +package com.querydsl.apt.jpa; diff --git a/querydsl-apt/src/main/java/com/querydsl/apt/morphia/MorphiaAnnotationProcessor.java b/querydsl-apt/src/main/java/com/querydsl/apt/morphia/MorphiaAnnotationProcessor.java new file mode 100644 index 0000000000..1d7d41bbdf --- /dev/null +++ b/querydsl-apt/src/main/java/com/querydsl/apt/morphia/MorphiaAnnotationProcessor.java @@ -0,0 +1,63 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt.morphia; + +import java.lang.annotation.Annotation; +import java.util.Collections; + +import javax.annotation.processing.RoundEnvironment; +import javax.annotation.processing.SupportedAnnotationTypes; + +import org.mongodb.morphia.annotations.Embedded; +import org.mongodb.morphia.annotations.Entity; +import org.mongodb.morphia.annotations.Transient; + +import com.querydsl.apt.AbstractQuerydslProcessor; +import com.querydsl.apt.Configuration; +import com.querydsl.apt.DefaultConfiguration; +import com.querydsl.core.annotations.QueryEntities; +import com.querydsl.core.annotations.QuerySupertype; +import com.querydsl.core.types.Expression; + +/** + * Annotation processor to create Querydsl query types for Morphia annotated classes + * + * @author tiwe + * + */ +@SupportedAnnotationTypes({"com.querydsl.core.annotations.*","org.mongodb.morphia.annotations.*"}) +public class MorphiaAnnotationProcessor extends AbstractQuerydslProcessor { + + @Override + protected Configuration createConfiguration(RoundEnvironment roundEnv) { + Class entities = QueryEntities.class; + Class entity = Entity.class; + Class superType = QuerySupertype.class; + Class embedded = Embedded.class; + Class skip = Transient.class; + DefaultConfiguration conf = new DefaultConfiguration(processingEnv, roundEnv, + Collections.emptySet(), + entities, entity, superType, null, embedded, skip); + try { + @SuppressWarnings("unchecked") // Point is an Expression + Class> cl = + (Class>) Class.forName("com.querydsl.mongodb.Point"); + conf.addCustomType(Double[].class, cl); + } catch (ClassNotFoundException e) { + throw new IllegalStateException(e); + } + return conf; + } + +} diff --git a/querydsl-apt/src/main/java/com/querydsl/apt/morphia/package-info.java b/querydsl-apt/src/main/java/com/querydsl/apt/morphia/package-info.java new file mode 100644 index 0000000000..16b717272f --- /dev/null +++ b/querydsl-apt/src/main/java/com/querydsl/apt/morphia/package-info.java @@ -0,0 +1,18 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ + +/** + * APT Morphia support + */ +package com.querydsl.apt.morphia; diff --git a/querydsl-apt/src/main/java/com/querydsl/apt/package-info.java b/querydsl-apt/src/main/java/com/querydsl/apt/package-info.java new file mode 100644 index 0000000000..87460624f3 --- /dev/null +++ b/querydsl-apt/src/main/java/com/querydsl/apt/package-info.java @@ -0,0 +1,18 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ + +/** + * APT-related classes + */ +package com.querydsl.apt; diff --git a/querydsl-apt/src/main/java/com/mysema/query/apt/roo/RooAnnotationProcessor.java b/querydsl-apt/src/main/java/com/querydsl/apt/roo/RooAnnotationProcessor.java similarity index 81% rename from querydsl-apt/src/main/java/com/mysema/query/apt/roo/RooAnnotationProcessor.java rename to querydsl-apt/src/main/java/com/querydsl/apt/roo/RooAnnotationProcessor.java index 6c75dd3576..bdfba58cf4 100644 --- a/querydsl-apt/src/main/java/com/mysema/query/apt/roo/RooAnnotationProcessor.java +++ b/querydsl-apt/src/main/java/com/querydsl/apt/roo/RooAnnotationProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2013, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.apt.roo; +package com.querydsl.apt.roo; import java.lang.annotation.Annotation; @@ -25,10 +25,10 @@ import org.springframework.roo.addon.jpa.activerecord.RooJpaActiveRecord; import org.springframework.roo.addon.jpa.entity.RooJpaEntity; -import com.mysema.query.apt.AbstractQuerydslProcessor; -import com.mysema.query.apt.Configuration; -import com.mysema.query.apt.DefaultConfiguration; -import com.mysema.query.apt.jpa.JPAConfiguration; +import com.querydsl.apt.AbstractQuerydslProcessor; +import com.querydsl.apt.Configuration; +import com.querydsl.apt.DefaultConfiguration; +import com.querydsl.apt.jpa.JPAConfiguration; /** * AnnotationProcessor for Spring Roo which takes {@link RooJpaEntity}, {@link RooJpaActiveRecord}, @@ -37,7 +37,7 @@ * @author tiwe * */ -@SupportedAnnotationTypes({"com.mysema.query.annotations.*","javax.persistence.*","org.springframework.roo.addon.jpa.entity.*"}) +@SupportedAnnotationTypes({"com.querydsl.core.annotations.*","javax.persistence.*","org.springframework.roo.addon.jpa.entity.*"}) public class RooAnnotationProcessor extends AbstractQuerydslProcessor { @Override @@ -47,7 +47,7 @@ protected Configuration createConfiguration(RoundEnvironment roundEnv) { Class embeddable = Embeddable.class; Class embedded = Embedded.class; Class skip = Transient.class; - DefaultConfiguration conf = new JPAConfiguration(roundEnv, processingEnv.getOptions(), + DefaultConfiguration conf = new JPAConfiguration(roundEnv, processingEnv, entity, superType, embeddable, embedded, skip); conf.setAlternativeEntityAnnotation(RooJpaActiveRecord.class); return conf; diff --git a/querydsl-apt/src/main/java/com/querydsl/apt/roo/package-info.java b/querydsl-apt/src/main/java/com/querydsl/apt/roo/package-info.java new file mode 100644 index 0000000000..1901efb011 --- /dev/null +++ b/querydsl-apt/src/main/java/com/querydsl/apt/roo/package-info.java @@ -0,0 +1,18 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ + +/** + * APT Roo support + */ +package com.querydsl.apt.roo; diff --git a/querydsl-apt/src/main/jdo.xml b/querydsl-apt/src/main/jdo.xml index ca16f117c0..016a08ac4d 100644 --- a/querydsl-apt/src/main/jdo.xml +++ b/querydsl-apt/src/main/jdo.xml @@ -8,12 +8,12 @@ false - src/apt/jdo - / - + src/apt/jdo + / + - ${project.build.outputDirectory} - / - + ${project.build.outputDirectory} + / + \ No newline at end of file diff --git a/querydsl-apt/src/main/jpa.xml b/querydsl-apt/src/main/jpa.xml index 9680191b55..6c9fa68af9 100644 --- a/querydsl-apt/src/main/jpa.xml +++ b/querydsl-apt/src/main/jpa.xml @@ -8,12 +8,12 @@ false - src/apt/jpa - / - + src/apt/jpa + / + - ${project.build.outputDirectory} - / - + ${project.build.outputDirectory} + / + \ No newline at end of file diff --git a/querydsl-apt/src/main/onejar.xml b/querydsl-apt/src/main/onejar.xml index c77d705e49..120779d545 100644 --- a/querydsl-apt/src/main/onejar.xml +++ b/querydsl-apt/src/main/onejar.xml @@ -27,16 +27,13 @@ true cglib:cglib - org.slf4j:slf4j-api - org.slf4j:slf4j-log4j12 true provided - com.mysema.querydsl:* - com.mysema.codegen:* + com.querydsl:* diff --git a/querydsl-apt/src/main/roo.xml b/querydsl-apt/src/main/roo.xml index 5d3a20c379..6e56b67f02 100644 --- a/querydsl-apt/src/main/roo.xml +++ b/querydsl-apt/src/main/roo.xml @@ -8,12 +8,12 @@ false - src/apt/roo - / - + src/apt/roo + / + - ${project.build.outputDirectory} - / - + ${project.build.outputDirectory} + / + \ No newline at end of file diff --git a/querydsl-apt/src/test/apt/com/mysema/query/BooleanExtensions.java b/querydsl-apt/src/test/apt/com/mysema/query/BooleanExtensions.java deleted file mode 100644 index 7f5232919b..0000000000 --- a/querydsl-apt/src/test/apt/com/mysema/query/BooleanExtensions.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.mysema.query; - -import com.mysema.query.annotations.*; -import com.mysema.query.types.*; -import com.mysema.query.types.path.*; - -public class BooleanExtensions { - - @QueryDelegate(Boolean.class) - public static Predicate isFalse(BooleanPath path) { - return path.isNotNull().or(path.eq(false)); - } - - @QueryDelegate(Boolean.class) - public static Predicate isTrue(BooleanPath path) { - return path.eq(true); - } - -} diff --git a/querydsl-apt/src/test/apt/com/mysema/query/BooleanExtensions2.java b/querydsl-apt/src/test/apt/com/mysema/query/BooleanExtensions2.java deleted file mode 100644 index 6708d17b95..0000000000 --- a/querydsl-apt/src/test/apt/com/mysema/query/BooleanExtensions2.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.mysema.query; - -import com.mysema.query.annotations.*; -import com.mysema.query.types.*; -import com.mysema.query.types.path.*; - -public class BooleanExtensions2 { - - @QueryDelegate(boolean.class) - public static Predicate isFalse(BooleanPath path) { - return path.isNotNull().or(path.eq(false)); - } - - @QueryDelegate(boolean.class) - public static Predicate isTrue(BooleanPath path) { - return path.eq(true); - } - -} diff --git a/querydsl-apt/src/test/apt/com/mysema/query/ExampleEntity.java b/querydsl-apt/src/test/apt/com/mysema/query/ExampleEntity.java deleted file mode 100644 index 09ba0b4ea9..0000000000 --- a/querydsl-apt/src/test/apt/com/mysema/query/ExampleEntity.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.mysema.query; - -import java.math.BigDecimal; - -import com.mysema.query.annotations.QueryEntity; - -@QueryEntity -public class ExampleEntity { - - private boolean booleanProp; - - private Boolean booleanProp2; - - - -} diff --git a/querydsl-apt/src/test/apt/com/querydsl/BooleanExtensions.java b/querydsl-apt/src/test/apt/com/querydsl/BooleanExtensions.java new file mode 100644 index 0000000000..d6675ad459 --- /dev/null +++ b/querydsl-apt/src/test/apt/com/querydsl/BooleanExtensions.java @@ -0,0 +1,19 @@ +package com.querydsl; + +import com.querydsl.core.annotations.QueryDelegate; +import com.querydsl.core.types.Predicate; +import com.querydsl.core.types.dsl.BooleanPath; + +public class BooleanExtensions { + + @QueryDelegate(Boolean.class) + public static Predicate isFalse(BooleanPath path) { + return path.isNotNull().or(path.eq(false)); + } + + @QueryDelegate(Boolean.class) + public static Predicate isTrue(BooleanPath path) { + return path.eq(true); + } + +} diff --git a/querydsl-apt/src/test/apt/com/querydsl/BooleanExtensions2.java b/querydsl-apt/src/test/apt/com/querydsl/BooleanExtensions2.java new file mode 100644 index 0000000000..2ab0bb0eb9 --- /dev/null +++ b/querydsl-apt/src/test/apt/com/querydsl/BooleanExtensions2.java @@ -0,0 +1,19 @@ +package com.querydsl; + +import com.querydsl.core.annotations.QueryDelegate; +import com.querydsl.core.types.Predicate; +import com.querydsl.core.types.dsl.BooleanPath; + +public class BooleanExtensions2 { + + @QueryDelegate(boolean.class) + public static Predicate isFalse(BooleanPath path) { + return path.isNotNull().or(path.eq(false)); + } + + @QueryDelegate(boolean.class) + public static Predicate isTrue(BooleanPath path) { + return path.eq(true); + } + +} diff --git a/querydsl-apt/src/test/apt/com/querydsl/ExampleEntity.java b/querydsl-apt/src/test/apt/com/querydsl/ExampleEntity.java new file mode 100644 index 0000000000..82793204eb --- /dev/null +++ b/querydsl-apt/src/test/apt/com/querydsl/ExampleEntity.java @@ -0,0 +1,14 @@ +package com.querydsl; + +import com.querydsl.core.annotations.QueryEntity; + +@QueryEntity +public class ExampleEntity { + + private boolean booleanProp; + + private Boolean booleanProp2; + + + +} diff --git a/querydsl-apt/src/test/apt/com/querydsl/ExampleEntity2.java b/querydsl-apt/src/test/apt/com/querydsl/ExampleEntity2.java new file mode 100644 index 0000000000..55fbb9db11 --- /dev/null +++ b/querydsl-apt/src/test/apt/com/querydsl/ExampleEntity2.java @@ -0,0 +1,9 @@ +package com.querydsl; + +import com.querydsl.core.annotations.QueryEntity; +import com.querydsl.core.domain.AbstractEntity; + +@QueryEntity +public class ExampleEntity2 extends AbstractEntity { +// id inherited +} diff --git a/querydsl-apt/src/test/apt/com/querydsl/InnerExtensions.java b/querydsl-apt/src/test/apt/com/querydsl/InnerExtensions.java new file mode 100644 index 0000000000..46ecd3916d --- /dev/null +++ b/querydsl-apt/src/test/apt/com/querydsl/InnerExtensions.java @@ -0,0 +1,15 @@ +package com.querydsl; + +import com.querydsl.core.annotations.QueryDelegate; +import com.querydsl.core.types.dsl.BooleanExpression; + +public class InnerExtensions { + + public static class ExampleEntity2Extensions { + + @QueryDelegate(ExampleEntity2.class) + public static BooleanExpression isZero(QExampleEntity2 left) { + return left.id.eq(0); + } + } +} diff --git a/querydsl-apt/src/test/apt/com/querydsl/IntegerExtensions.java b/querydsl-apt/src/test/apt/com/querydsl/IntegerExtensions.java new file mode 100644 index 0000000000..96b96a985f --- /dev/null +++ b/querydsl-apt/src/test/apt/com/querydsl/IntegerExtensions.java @@ -0,0 +1,13 @@ +package com.querydsl; + +import com.querydsl.core.annotations.QueryDelegate; +import com.querydsl.core.types.dsl.NumberExpression; +import com.querydsl.core.types.dsl.NumberPath; + +public class IntegerExtensions { + + @QueryDelegate(Integer.class) + public static NumberExpression difference(NumberPath left, NumberExpression right) { + return right.subtract(left); + } +} diff --git a/querydsl-apt/src/test/apt/com/mysema/query/eclipse/SimpleEntity.java b/querydsl-apt/src/test/apt/com/querydsl/eclipse/SimpleEntity.java similarity index 87% rename from querydsl-apt/src/test/apt/com/mysema/query/eclipse/SimpleEntity.java rename to querydsl-apt/src/test/apt/com/querydsl/eclipse/SimpleEntity.java index dcb62f74df..5be697627b 100644 --- a/querydsl-apt/src/test/apt/com/mysema/query/eclipse/SimpleEntity.java +++ b/querydsl-apt/src/test/apt/com/querydsl/eclipse/SimpleEntity.java @@ -1,24 +1,24 @@ -package com.mysema.query.eclipse; +package com.querydsl.eclipse; import java.math.BigDecimal; -import com.mysema.query.annotations.QueryEntity; +import com.querydsl.core.annotations.QueryEntity; @QueryEntity public class SimpleEntity { - + CustomComparable comparableProp; - + CustomNumber customNumber; - + int intProp; - + Integer integerProp; - + BigDecimal bigDecimalProp; - + String stringProp; - + SimpleEntity entityProp; } @@ -29,7 +29,7 @@ class CustomComparable implements Comparable { public int compareTo(CustomComparable o) { return 0; } - + } class CustomNumber extends Number implements Comparable { @@ -60,6 +60,6 @@ public long longValue() { public int compareTo(CustomNumber o) { return 0; } - - + + } \ No newline at end of file diff --git a/querydsl-apt/src/test/java/Entity.java b/querydsl-apt/src/test/java/Entity.java index 6e734ac557..88246f2d3b 100644 --- a/querydsl-apt/src/test/java/Entity.java +++ b/querydsl-apt/src/test/java/Entity.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,10 +11,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import com.mysema.query.annotations.QueryEntity; +import com.querydsl.core.annotations.QueryEntity; @QueryEntity -public class Entity { +public final class Entity { + + private Entity() { } static final QEntity entity = QEntity.entity; diff --git a/querydsl-apt/src/test/java/com/mysema/query/apt/BooleanExtensionsTest.java b/querydsl-apt/src/test/java/com/mysema/query/apt/BooleanExtensionsTest.java deleted file mode 100644 index 7d2f12cbc0..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/apt/BooleanExtensionsTest.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.apt; - -import static org.junit.Assert.assertTrue; - -import java.io.File; -import java.io.IOException; -import java.util.Arrays; -import java.util.List; - -import org.junit.Test; - -import com.google.common.base.Charsets; -import com.google.common.io.Files; - -public class BooleanExtensionsTest extends AbstractProcessorTest { - - private static final String packagePath = "src/test/apt/com/mysema/query/"; - - @Test - public void Process() throws IOException { - List sources = Arrays.asList( - new File(packagePath, "BooleanExtensions.java").getPath(), - new File(packagePath, "ExampleEntity.java").getPath()); - process(QuerydslAnnotationProcessor.class, sources,"booleanExtensions"); - String qtypeContent = Files.toString(new File("target/booleanExtensions/com/mysema/query/QExampleEntity.java"), Charsets.UTF_8); - assertTrue(qtypeContent.contains("ext.java.lang.QBoolean booleanProp")); - assertTrue(qtypeContent.contains("ext.java.lang.QBoolean booleanProp2")); - } - - @Test - public void Process2() throws IOException { - List sources = Arrays.asList( - new File(packagePath, "BooleanExtensions2.java").getPath(), - new File(packagePath, "ExampleEntity.java").getPath()); - process(QuerydslAnnotationProcessor.class, sources,"booleanExtensions2"); - String qtypeContent = Files.toString(new File("target/booleanExtensions2/com/mysema/query/QExampleEntity.java"), Charsets.UTF_8); - assertTrue(qtypeContent.contains("ext.java.lang.QBoolean booleanProp")); - assertTrue(qtypeContent.contains("ext.java.lang.QBoolean booleanProp2")); - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/apt/DateExtensions.java b/querydsl-apt/src/test/java/com/mysema/query/apt/DateExtensions.java deleted file mode 100644 index f14802eb66..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/apt/DateExtensions.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.apt; - -import java.sql.Date; - -import com.mysema.query.annotations.QueryDelegate; -import com.mysema.query.types.Predicate; -import com.mysema.query.types.expr.DateExpression; -import com.mysema.query.types.path.BooleanPath; - -public class DateExtensions { - - @QueryDelegate(Date.class) - public static Predicate extension(DateExpression date) { - return new BooleanPath("b"); - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/apt/DateExtensionsTest.java b/querydsl-apt/src/test/java/com/mysema/query/apt/DateExtensionsTest.java deleted file mode 100644 index 45a8569173..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/apt/DateExtensionsTest.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.apt; - -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertTrue; - -import java.io.File; -import java.io.IOException; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; - -import org.junit.Ignore; -import org.junit.Test; - -import com.google.common.base.Charsets; -import com.google.common.io.Files; - -@Ignore -public class DateExtensionsTest extends AbstractProcessorTest { - - private static final String packagePath = "src/test/java/com/mysema/query/apt/"; - - @Test - public void Handles_Date_Extensions_Correctly() throws IOException, InterruptedException { - File source = new File(packagePath, "EntityWithExtensions.java"); - File source2 = new File(packagePath, "DateExtensions.java"); - List sources = Arrays.asList(source.getPath(), source2.getPath()); - File qType = new File("target/overwrite3/com/mysema/query/apt/QEntityWithExtensions.java"); - - // QEntityWithExtensions is generated - process(QuerydslAnnotationProcessor.class, sources, "overwrite3"); - assertTrue(qType.exists()); - long modified = qType.lastModified(); - Thread.sleep(1000); - System.out.println(Files.toString(qType, Charsets.UTF_8).contains("QDate")); - - // EntityWithExtensions has not changed, QEntityWithExtensions is not overwritten - compile(QuerydslAnnotationProcessor.class, sources, "overwrite3"); - assertEquals(modified, qType.lastModified()); - - // EntityWithExtensions is updated, QEntityWithExtensions is overwritten - Files.touch(source); - compile(QuerydslAnnotationProcessor.class, sources, "overwrite3"); - assertTrue("" + modified + " >= " + qType.lastModified(), modified < qType.lastModified()); - assertTrue(Files.toString(qType, Charsets.UTF_8).contains("QDate")); - - // QEntityWithExtensions is deleted and regenerated - assertTrue(qType.delete()); - compile(QuerydslAnnotationProcessor.class, sources, "overwrite3"); - assertTrue(qType.exists()); - assertTrue(Files.toString(qType, Charsets.UTF_8).contains("QDate")); - } - - @Override - protected Collection getAPTOptions() { - return Arrays.asList("-AdefaultOverwrite=true"); - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/apt/EmbeddableTest.java b/querydsl-apt/src/test/java/com/mysema/query/apt/EmbeddableTest.java deleted file mode 100644 index 46e2168a47..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/apt/EmbeddableTest.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.apt; - -import java.io.IOException; -import java.util.Collections; -import java.util.List; - -import org.junit.Test; - -public class EmbeddableTest extends AbstractProcessorTest { - - @Test - public void Process() throws IOException { - List classes = Collections.singletonList("src/test/java/com/mysema/query/domain/Embeddable2Test.java"); - process(QuerydslAnnotationProcessor.class, classes,"embeddable"); - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/apt/EntityExtensions.java b/querydsl-apt/src/test/java/com/mysema/query/apt/EntityExtensions.java deleted file mode 100644 index ecb6431f13..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/apt/EntityExtensions.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.apt; - -import com.mysema.query.annotations.QueryDelegate; -import com.mysema.query.types.Predicate; -import com.mysema.query.types.path.BooleanPath; - -public class EntityExtensions { - - @QueryDelegate(EntityWithExtensions.class) - public static Predicate extension(QEntityWithExtensions entity) { - return new BooleanPath("b"); - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/apt/EntityExtensionsTest.java b/querydsl-apt/src/test/java/com/mysema/query/apt/EntityExtensionsTest.java deleted file mode 100644 index 0cded84adb..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/apt/EntityExtensionsTest.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.apt; - -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertTrue; - -import java.io.File; -import java.io.IOException; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; - -import org.junit.Ignore; -import org.junit.Test; - -import com.google.common.base.Charsets; -import com.google.common.io.Files; - -@Ignore -public class EntityExtensionsTest extends AbstractProcessorTest { - - private static final String packagePath = "src/test/java/com/mysema/query/apt/"; - - @Test - public void Handles_Entity_Extensions_Correctly() throws IOException, InterruptedException { - File source = new File(packagePath, "EntityWithExtensions.java"); - File source2 = new File(packagePath, "EntityExtensions.java"); - List sources = Arrays.asList(source.getPath(), source2.getPath()); - File qType = new File("target/overwrite2/com/mysema/query/apt/QEntityWithExtensions.java"); - - // QEntityWithExtensions is generated - process(QuerydslAnnotationProcessor.class, sources, "overwrite2"); - assertTrue(qType.exists()); - long modified = qType.lastModified(); - Thread.sleep(1000); - System.out.println(Files.toString(qType, Charsets.UTF_8).contains("extension()")); - - // EntityWithExtensions has not changed, QEntityWithExtensions is not overwritten - compile(QuerydslAnnotationProcessor.class, sources, "overwrite2"); - assertEquals(modified, qType.lastModified()); - - // EntityWithExtensions is updated, QEntityWithExtensions is overwritten - Files.touch(source); - compile(QuerydslAnnotationProcessor.class, sources, "overwrite2"); - assertTrue("" + modified + " >= " + qType.lastModified(), modified < qType.lastModified()); - assertTrue(Files.toString(qType, Charsets.UTF_8).contains("extension()")); - - // QEntityWithExtensions is deleted and regenerated - assertTrue(qType.delete()); - compile(QuerydslAnnotationProcessor.class, sources, "overwrite2"); - assertTrue(qType.exists()); - assertTrue(Files.toString(qType, Charsets.UTF_8).contains("extension()")); - } - - @Override - protected Collection getAPTOptions() { - return Arrays.asList("-AdefaultOverwrite=true"); - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/apt/ExcludedClassesTest.java b/querydsl-apt/src/test/java/com/mysema/query/apt/ExcludedClassesTest.java deleted file mode 100644 index d7dea48a1c..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/apt/ExcludedClassesTest.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.apt; - -import static org.junit.Assert.assertFalse; - -import java.io.File; -import java.io.IOException; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; - -import org.junit.Test; - -public class ExcludedClassesTest extends AbstractProcessorTest { - - private static final String packagePath = "src/test/java/com/mysema/query/"; - - @Test - public void Process() throws IOException { - List classes = getFiles(packagePath); - process(QuerydslAnnotationProcessor.class, classes, "excludedClasses"); - - assertFalse(new File("target/excludedClasses/com/mysema/query/domain/QArrayTest_ArrayTestEntity.java").exists()); - } - - @Override - protected Collection getAPTOptions() { - return Arrays.asList("-Aquerydsl.excludedClasses=com.mysema.query.domain.ArrayTest.ArrayTestEntity"); - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/apt/ExcludedPackagesTest.java b/querydsl-apt/src/test/java/com/mysema/query/apt/ExcludedPackagesTest.java deleted file mode 100644 index c99d29c045..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/apt/ExcludedPackagesTest.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.apt; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import java.io.File; -import java.io.IOException; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; - -import org.junit.Test; - -public class ExcludedPackagesTest extends AbstractProcessorTest { - - private static final String packagePath = "src/test/java/com/mysema/query/"; - - @Test - public void Process() throws IOException { - List classes = getFiles(packagePath); - process(QuerydslAnnotationProcessor.class, classes, "excludedPackages"); - - assertFalse(new File("target/excludedPackages/com/mysema/query/domain/p1").exists()); - assertTrue(new File("target/excludedPackages/com/mysema/query/domain/p2").exists()); - } - - @Override - protected Collection getAPTOptions() { - return Arrays.asList("-Aquerydsl.excludedPackages=com.mysema.query.domain.p1"); - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/apt/GenericExporterTest.java b/querydsl-apt/src/test/java/com/mysema/query/apt/GenericExporterTest.java deleted file mode 100644 index 6f2ed002c6..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/apt/GenericExporterTest.java +++ /dev/null @@ -1,152 +0,0 @@ -package com.mysema.query.apt; - -import javax.persistence.*; -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import com.google.common.base.Charsets; -import com.google.common.collect.ForwardingSet; -import com.google.common.io.Files; -import com.mysema.query.apt.hibernate.HibernateAnnotationProcessor; -import com.mysema.query.codegen.GenericExporter; -import com.mysema.query.codegen.Keywords; -import com.mysema.query.domain.AbstractEntityTest; -import com.mysema.query.domain.CustomCollection; -import com.mysema.query.domain.Generic2Test; -import org.junit.Test; -import static org.junit.Assert.fail; - -public class GenericExporterTest extends AbstractProcessorTest { - - private static final String PACKAGE_PATH = "src/test/java/com/mysema/query/domain/"; - - private static final List CLASSES = getFiles(PACKAGE_PATH); - - @Test - public void Execute() throws IOException { - // via APT - process(QuerydslAnnotationProcessor.class, CLASSES, "QuerydslAnnotationProcessor"); - - // via GenericExporter - GenericExporter exporter = new GenericExporter(); - exporter.setTargetFolder(new File("target/GenericExporterTest")); - exporter.export(AbstractEntityTest.class.getPackage()); - - List expected = new ArrayList(); - // delegates are not supported - expected.add("QDelegateTest_SimpleUser.java"); - expected.add("QDelegateTest_SimpleUser2.java"); - expected.add("QDelegateTest_User.java"); - expected.add("QDelegate2Test_Entity.java"); - expected.add("QExampleEntity.java"); - - expected.add("QQueryProjectionTest_DTOWithProjection.java"); - - // FIXME - expected.add("QExternalEntityTest_MyEntity.java"); - expected.add("QQueryEmbedded4Test_User.java"); - - execute(expected, "GenericExporterTest", "QuerydslAnnotationProcessor"); - } - - @Test - public void Execute2() throws IOException { - // via APT - process(HibernateAnnotationProcessor.class, CLASSES, "HibernateAnnotationProcessor"); - - // via GenericExporter - GenericExporter exporter = new GenericExporter(); - exporter.setKeywords(Keywords.JPA); - exporter.setEntityAnnotation(Entity.class); - exporter.setEmbeddableAnnotation(Embeddable.class); - exporter.setEmbeddedAnnotation(Embedded.class); - exporter.setSupertypeAnnotation(MappedSuperclass.class); - exporter.setSkipAnnotation(Transient.class); - exporter.setTargetFolder(new File("target/GenericExporterTest2")); - exporter.addStopClass(ForwardingSet.class); - exporter.export(AbstractEntityTest.class.getPackage()); - - List expected = new ArrayList(); - // GenericExporter doesn't include field/method selection - expected.add("QFileAttachment.java"); - expected.add("QJodaTest_BaseEntity.java"); - expected.add("QEnum3Test_Entity1.java"); - expected.add("QCustomCollection_MyCustomCollection.java"); - expected.add("QCustomCollection_MyCustomCollection2.java"); - - expected.add("QTemporalTest_MyEntity.java"); - - expected.add("QTemporal2Test_Cheque.java"); - expected.add("QQueryProjectionTest_DTOWithProjection.java"); - - // FIXME - expected.add("QGeneric4Test_HidaBez.java"); - expected.add("QGeneric4Test_HidaBezGruppe.java"); - expected.add("QInterfaceType2Test_UserImpl.java"); - expected.add("QOrderTest_Order.java"); - expected.add("QManagedEmailTest_ManagedEmails.java"); - expected.add("QGeneric12Test_ChannelRole.java"); - expected.add("QManyToManyTest_Person.java"); - expected.add("QOneToOneTest_Person.java"); - - execute(expected, "GenericExporterTest2", "HibernateAnnotationProcessor"); - } - - @Test - public void Execute3() { - GenericExporter exporter = new GenericExporter(); - exporter.setKeywords(Keywords.JPA); - exporter.setEntityAnnotation(Entity.class); - exporter.setEmbeddableAnnotation(Embeddable.class); - exporter.setEmbeddedAnnotation(Embedded.class); - exporter.setSupertypeAnnotation(MappedSuperclass.class); - exporter.setSkipAnnotation(Transient.class); - exporter.setTargetFolder(new File("target/GenericExporterTest3")); - //exporter.addStopClass(ForwardingSet.class); - exporter.export(CustomCollection.MyCustomCollection.class, - CustomCollection.MyCustomCollection2.class, - CustomCollection.MyEntity.class); - } - - @Test - public void Execute4() throws IOException { - GenericExporter exporter = new GenericExporter(); - exporter.setKeywords(Keywords.JPA); - exporter.setEntityAnnotation(Entity.class); - exporter.setEmbeddableAnnotation(Embeddable.class); - exporter.setEmbeddedAnnotation(Embedded.class); - exporter.setSupertypeAnnotation(MappedSuperclass.class); - exporter.setSkipAnnotation(Transient.class); - exporter.setTargetFolder(new File("target/GenericExporterTest4")); - exporter.addStopClass(ForwardingSet.class); - exporter.export(Generic2Test.class.getClasses()); - } - - private void execute(List expected, String genericExporterFolder, String aptFolder) throws IOException { - List failures = new ArrayList(); - int successes = 0; - for (File file : new File("target/"+genericExporterFolder+"/com/mysema/query/domain").listFiles()) { - File other = new File("target/"+aptFolder+"/com/mysema/query/domain", file.getName()); - if (!other.exists() || !other.isFile()) continue; - String result1 = Files.toString(file, Charsets.UTF_8); - String result2 = Files.toString(other, Charsets.UTF_8); - if (!result1.equals(result2)) { - if (!expected.contains(file.getName())) { - System.err.println(file.getName()); - failures.add(file.getName()); - } - } else { - successes++; - } - } - if (!failures.isEmpty()) { - for (String failure : failures) { - System.err.println(failure); - } - fail("Failed with " + failures.size() + " failures, " + successes + " succeeded"); - } - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/apt/GenericTest.java b/querydsl-apt/src/test/java/com/mysema/query/apt/GenericTest.java deleted file mode 100644 index 3971cbb3c1..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/apt/GenericTest.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.mysema.query.apt; - -import java.io.IOException; -import java.util.Collections; -import java.util.List; - -import org.junit.Test; - -import com.mysema.query.apt.jpa.JPAAnnotationProcessor; - -public class GenericTest extends AbstractProcessorTest { - - @Test - public void test() throws IOException { - List classes = Collections.singletonList("src/test/java/com/mysema/query/domain/Generic7Test.java"); - process(QuerydslAnnotationProcessor.class, classes,"GenericTest"); - } - - @Test - public void test2() throws IOException { - List classes = Collections.singletonList("src/test/java/com/mysema/query/domain/Generic9Test.java"); - process(JPAAnnotationProcessor.class, classes,"GenericTest2"); - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/apt/IncludedClassesTest.java b/querydsl-apt/src/test/java/com/mysema/query/apt/IncludedClassesTest.java deleted file mode 100644 index a192b28fba..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/apt/IncludedClassesTest.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.apt; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import java.io.File; -import java.io.IOException; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; - -import org.junit.Test; - -public class IncludedClassesTest extends AbstractProcessorTest { - - private static final String packagePath = "src/test/java/com/mysema/query/"; - - @Test - public void Process() throws IOException { - List classes = getFiles(packagePath); - process(QuerydslAnnotationProcessor.class, classes, "includedClasses"); - - assertTrue(new File("target/includedClasses/com/mysema/query/domain/QArrayTest_ArrayTestEntity.java").exists()); - assertFalse(new File("target/includedClasses/com/mysema/query/domain/QArray2Test_Example.java").exists()); - } - - @Override - protected Collection getAPTOptions() { - return Arrays.asList("-Aquerydsl.includedClasses=com.mysema.query.domain.ArrayTest.ArrayTestEntity"); - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/apt/IncludedPackagesTest.java b/querydsl-apt/src/test/java/com/mysema/query/apt/IncludedPackagesTest.java deleted file mode 100644 index 196c09b224..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/apt/IncludedPackagesTest.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.apt; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import java.io.File; -import java.io.IOException; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; - -import org.junit.Test; - -public class IncludedPackagesTest extends AbstractProcessorTest { - - private static final String packagePath = "src/test/java/com/mysema/query/"; - - @Test - public void Process() throws IOException { - List classes = getFiles(packagePath); - process(QuerydslAnnotationProcessor.class, classes, "includedPackages"); - - assertFalse(new File("target/includedPackages/com/mysema/query/domain/p1").exists()); - assertTrue(new File("target/includedPackages/com/mysema/query/domain/p2").exists()); - } - - @Override - protected Collection getAPTOptions() { - return Arrays.asList("-Aquerydsl.includedPackages=com.mysema.query.domain.p2"); - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/apt/NamePrefixTest.java b/querydsl-apt/src/test/java/com/mysema/query/apt/NamePrefixTest.java deleted file mode 100644 index 80b5276185..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/apt/NamePrefixTest.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.apt; - -import static org.junit.Assert.*; - -import java.io.File; -import java.io.IOException; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; - -import org.junit.Test; - -public class NamePrefixTest extends AbstractProcessorTest { - - private static final String packagePath = "src/test/java/com/mysema/query/domain/"; - - @Test - public void ProcessAll() throws IOException { - // works only in Eclipse for the moment - List classes = getFiles(packagePath); - - // default Processor - process(QuerydslAnnotationProcessor.class, classes,"prefix"); - - assertTrue(new File("target/prefix/com/mysema/query/domain/QTAnimalTest_Animal.java").exists()); - } - - @Override - protected Collection getAPTOptions() { - return Arrays.asList("-Aquerydsl.prefix=QT"); - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/apt/PackageSuffixTest.java b/querydsl-apt/src/test/java/com/mysema/query/apt/PackageSuffixTest.java deleted file mode 100644 index 051a368769..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/apt/PackageSuffixTest.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.apt; - -import static org.junit.Assert.assertTrue; - -import java.io.File; -import java.io.IOException; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; - -import org.junit.Test; - -public class PackageSuffixTest extends AbstractProcessorTest { - - private static final String packagePath = "src/test/java/com/mysema/query/domain/"; - - @Test - public void ProcessAll() throws IOException { - // works only in Eclipse for the moment - List classes = getFiles(packagePath); - - // default Processor - process(QuerydslAnnotationProcessor.class, classes,"packageSuffix"); - - assertTrue(new File("target/packageSuffix/com/mysema/query/domain/query/QAnimalTest_Animal.java").exists()); - } - - @Override - protected Collection getAPTOptions() { - return Arrays.asList("-Aquerydsl.packageSuffix=.query"); - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/apt/QuerydslAnnotationProcessorTest.java b/querydsl-apt/src/test/java/com/mysema/query/apt/QuerydslAnnotationProcessorTest.java deleted file mode 100644 index aa1fbdd643..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/apt/QuerydslAnnotationProcessorTest.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.apt; - -import static org.junit.Assert.assertTrue; - -import java.io.File; -import java.io.IOException; -import java.util.Collections; -import java.util.List; - -import org.junit.Test; - -import com.mysema.query.apt.hibernate.HibernateAnnotationProcessor; -import com.mysema.query.apt.jdo.JDOAnnotationProcessor; -import com.mysema.query.apt.jpa.JPAAnnotationProcessor; -import com.mysema.query.apt.roo.RooAnnotationProcessor; - -public class QuerydslAnnotationProcessorTest extends AbstractProcessorTest { - - private static final String PACKAGE_PATH = "src/test/java/com/mysema/query/domain/"; - - private static final List CLASSES = getFiles(PACKAGE_PATH); - - @Test - public void Process() throws IOException { - File file = new File(PACKAGE_PATH, "AbstractEntityTest.java"); - process(QuerydslAnnotationProcessor.class, Collections.singletonList(file.getPath()),"qdsl"); - } - - @Test - public void Process_MonitoredCompany() throws IOException { - String path = new File(PACKAGE_PATH, "MonitoredCompany.java").getPath(); - process(QuerydslAnnotationProcessor.class, Collections.singletonList(path),"MonitoredCompany"); - } - - @Test - public void Process_Inheritance3() throws IOException { - String path = new File("src/test/java/com/mysema/query/inheritance/Inheritance3Test.java").getPath(); - process(QuerydslAnnotationProcessor.class, Collections.singletonList(path),"Inheritance3Test"); - } - - @Test - public void Process_Inheritance8() throws IOException { - String path = new File("src/test/java/com/mysema/query/inheritance/Inheritance8Test.java").getPath(); - process(QuerydslAnnotationProcessor.class, Collections.singletonList(path),"Inheritance8Test"); - } - - @Test - public void Process_QueryEmbedded3() throws IOException { - String path = new File("src/test/java/com/mysema/query/domain/QueryEmbedded3Test.java").getPath(); - process(QuerydslAnnotationProcessor.class, Collections.singletonList(path),"QueryEmbedded3Test"); - } - - @Test - public void Process_QueryEmbedded4() throws IOException { - String path = new File("src/test/java/com/mysema/query/domain/QueryEmbedded4Test.java").getPath(); - process(QuerydslAnnotationProcessor.class, Collections.singletonList(path),"QueryEmbedded4Test"); - } - - @Test - public void Process_Delegate() throws IOException { - String path = new File("src/test/java/com/mysema/query/domain/DelegateTest.java").getPath(); - process(QuerydslAnnotationProcessor.class, Collections.singletonList(path),"DelegateTest"); - } - - @Test - public void Process_AbstractClasses() throws IOException { - String path = new File("src/test/java/com/mysema/query/domain/AbstractClassesTest.java").getPath(); - process(JPAAnnotationProcessor.class, Collections.singletonList(path),"AbstractClassesTest"); - } - - @Test - public void Process_AbstractClasses2() throws IOException { - String path = new File("src/test/java/com/mysema/query/domain/AbstractClasses2Test.java").getPath(); - process(JPAAnnotationProcessor.class, Collections.singletonList(path),"abstractClasses2"); - } - - @Test - public void Process_GenericSignature() throws IOException { - String path = new File("src/test/java/com/mysema/query/domain/GenericSignatureTest.java").getPath(); - process(QuerydslAnnotationProcessor.class, Collections.singletonList(path),"GenericSignatureTest"); - } - - @Test - public void Process_AbstractProperties2Test() throws IOException { - String path = new File("src/test/java/com/mysema/query/domain/AbstractProperties2Test.java").getPath(); - process(QuerydslAnnotationProcessor.class, Collections.singletonList(path),"AbstractProperties2Test"); - } - - @Test - public void Process_Inheritance2Test() throws IOException { - String path = new File("src/test/java/com/mysema/query/inheritance/Inheritance2Test.java").getPath(); - process(QuerydslAnnotationProcessor.class, Collections.singletonList(path),"InheritanceTest2"); - } - - @Test - public void Process_EntityInheritanceTest() throws IOException { - String path = new File("src/test/java/com/mysema/query/domain/EntityInheritanceTest.java").getPath(); - process(JPAAnnotationProcessor.class, Collections.singletonList(path),"EntityInheritanceTest"); - } - - @Test - public void Process_Enum2Test() throws IOException { - String path = new File("src/test/java/com/mysema/query/domain/Enum2Test.java").getPath(); - process(QuerydslAnnotationProcessor.class, Collections.singletonList(path),"Enum2Test"); - } - - @Test - public void Process_ExternalEntityTest() throws IOException { - String path = new File("src/test/java/com/mysema/query/domain/ExternalEntityTest.java").getPath(); - process(QuerydslAnnotationProcessor.class, Collections.singletonList(path),"ExternalEntityTest"); - } - - @Test - public void Process_Generic13Test() throws IOException { - String path = new File("src/test/java/com/mysema/query/domain/Generic13Test.java").getPath(); - process(QuerydslAnnotationProcessor.class, Collections.singletonList(path),"Generic13Test"); - } - - @Test - public void QuerydslAnnotationProcessor() throws IOException { - process(QuerydslAnnotationProcessor.class, CLASSES, "querydsl"); - } - - @Test - public void JPAAnnotationProcessor() throws IOException { - process(JPAAnnotationProcessor.class, CLASSES, "jpa"); - } - - @Test - public void HibernateAnnotationProcessor() throws IOException { - process(HibernateAnnotationProcessor.class, CLASSES, "hibernate"); - } - - @Test - public void JDOAnnotationProcessor() throws IOException { - process(JDOAnnotationProcessor.class, CLASSES, "jdo"); - } - - @Test - public void RooAnnotationProcessor() throws IOException { - process(RooAnnotationProcessor.class, CLASSES, "roo"); - - assertTrue(new File("target/roo/com/mysema/query/domain/QRooEntities_MyEntity.java").exists()); - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/apt/UnknownAsEmbeddableTest.java b/querydsl-apt/src/test/java/com/mysema/query/apt/UnknownAsEmbeddableTest.java deleted file mode 100644 index 282bca063a..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/apt/UnknownAsEmbeddableTest.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.apt; - -import static org.junit.Assert.assertTrue; - -import java.io.File; -import java.io.IOException; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; - -import org.junit.Test; - -public class UnknownAsEmbeddableTest extends AbstractProcessorTest { - - private static final String packagePath = "src/test/java/com/mysema/query/domain"; - - @Test - public void Process() throws IOException { - List classes = getFiles(packagePath); - process(QuerydslAnnotationProcessor.class, classes,"unknownAsEmbeddable"); - - assertTrue(new File("target/unknownAsEmbeddable/com/mysema/query/domain/custom/QEntity.java").exists()); - assertTrue(new File("target/unknownAsEmbeddable/com/mysema/query/domain/custom/QEmbeddedType.java").exists()); - assertTrue(new File("target/unknownAsEmbeddable/com/mysema/query/domain/custom/QEmbeddedType2.java").exists()); - assertTrue(new File("target/unknownAsEmbeddable/com/mysema/query/domain/custom/QEmbeddedType3.java").exists()); - } - - @Override - protected Collection getAPTOptions() { - return Arrays.asList("-Aquerydsl.unknownAsEmbeddable=true"); - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/AbstractEntityTest.java b/querydsl-apt/src/test/java/com/mysema/query/domain/AbstractEntityTest.java deleted file mode 100644 index 79512a22b1..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/AbstractEntityTest.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.domain; - -import static org.junit.Assert.*; - -import org.junit.Test; - -import com.mysema.query.annotations.QueryEntity; -import com.mysema.query.annotations.QueryInit; - -public class AbstractEntityTest { - - @QueryEntity - public static abstract class Category> { - - public Category defaultChild; - - } - - @QueryEntity - public static class CategoryReference { - - @QueryInit("defaultChild") - public Category category; - - } - - @Test - public void Path_Is_Available() { - QAbstractEntityTest_CategoryReference categoryReference = QAbstractEntityTest_CategoryReference.categoryReference; - assertNotNull(categoryReference.category.defaultChild); - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/AbstractProperties2Test.java b/querydsl-apt/src/test/java/com/mysema/query/domain/AbstractProperties2Test.java deleted file mode 100644 index ee35257715..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/AbstractProperties2Test.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.domain; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -import java.io.Serializable; - -import org.junit.Test; - -import com.mysema.query.annotations.QueryEntity; - -public class AbstractProperties2Test { - - public static abstract class GenericEntity, E extends GenericEntity> { - - public abstract K getId(); - - public abstract void setId(K id); - - } - - public static abstract class AbstractEntity

> extends GenericEntity { - - private Integer id; - - @Override - public Integer getId() { - return id; - } - - @Override - public void setId(Integer id) { - this.id = id; - } - - } - - @QueryEntity - public static class User extends AbstractEntity { - - } - - @Test - public void GenericEntity_id_Is_Available() { - assertNotNull(QAbstractProperties2Test_GenericEntity.genericEntity.id); - } - - @Test - public void AbstractEntity_Is_Available() { - assertNotNull(QAbstractProperties2Test_AbstractEntity.abstractEntity.id); - } - - @Test - public void AbstractEntity_Super_Is_Available() { - assertEquals(QAbstractProperties2Test_GenericEntity.class, QAbstractProperties2Test_AbstractEntity.abstractEntity._super.getClass()); - } - - @Test - public void User_Is_Available() { - assertNotNull(QAbstractProperties2Test_User.user.id); - } - - @Test - public void User_Super_Is_Available() { - assertEquals(QAbstractProperties2Test_AbstractEntity.class, QAbstractProperties2Test_User.user._super.getClass()); - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/AbstractProperties3Test.java b/querydsl-apt/src/test/java/com/mysema/query/domain/AbstractProperties3Test.java deleted file mode 100644 index af92b64733..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/AbstractProperties3Test.java +++ /dev/null @@ -1,78 +0,0 @@ -package com.mysema.query.domain; - -import java.io.Serializable; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.Inheritance; -import javax.persistence.InheritanceType; -import javax.persistence.JoinColumn; -import javax.persistence.MappedSuperclass; -import javax.persistence.OneToOne; -import javax.persistence.SequenceGenerator; - -import org.hibernate.annotations.Cache; -import org.hibernate.annotations.CacheConcurrencyStrategy; -import org.junit.Ignore; -import org.junit.Test; - -import com.mysema.query.annotations.PropertyType; -import com.mysema.query.annotations.QueryType; - -@Ignore -public class AbstractProperties3Test { - - @MappedSuperclass - public static class BaseEntity { - - } - - @Entity - public static class Compound extends BaseEntity { - - String name; - - } - - @Entity - @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) - public static abstract class Containable extends BaseEntity implements Serializable { - - @Id - @GeneratedValue(strategy = GenerationType.AUTO, generator = "containable_seq_gen") - @SequenceGenerator(name = "containable_seq_gen", sequenceName = "seq_containable") - @Column(name = "id") - Long id; - - @QueryType(PropertyType.ENTITY) - public abstract Compound getCompound(); - - } - - @MappedSuperclass - @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) - @Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL) - public static abstract class CompoundContainer extends BaseEntity implements Serializable { - - @Id - @GeneratedValue(strategy = GenerationType.AUTO, generator = "compound_container_seq_gen") - @SequenceGenerator(name = "compound_container_seq_gen", sequenceName = "seq_compound_container", allocationSize = 1000) - @Column(name = "compound_container_id") - Long id; - - @JoinColumn(name = "containable_id") - @OneToOne(fetch = FetchType.EAGER) - Containable containable; - - } - - @Test - public void test() { - QAbstractProperties3Test_CompoundContainer.compoundContainer.containable.compound.name.isNotNull(); - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/AbstractTest.java b/querydsl-apt/src/test/java/com/mysema/query/domain/AbstractTest.java deleted file mode 100644 index d3aefdbc86..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/AbstractTest.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.domain; - -import static org.junit.Assert.*; -import junit.framework.Assert; - -public abstract class AbstractTest { - - public Class cl; - - protected void match(Class expectedType, String name) throws SecurityException, NoSuchFieldException { - assertTrue(cl.getSimpleName()+"."+name + " failed", expectedType.isAssignableFrom(cl.getField(name).getType())); - } - - protected void assertMissing(String name) { - try { - cl.getField(name); - Assert.fail("Expected missing field : " + cl.getSimpleName() + "." + name); - } catch (NoSuchFieldException e) { - // expected - } - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/Address.java b/querydsl-apt/src/test/java/com/mysema/query/domain/Address.java deleted file mode 100644 index 7e07594a55..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/Address.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.mysema.query.domain; - -import com.mysema.query.annotations.QueryEmbeddable; -import com.mysema.query.annotations.QueryEmbedded; - -@QueryEmbeddable -public final class Address { - - public Address() { - - } - - public Address(String street, String postCode, City city) { - this.street = street; this.postCode = postCode; this.city = city; - } - - public String street; - - public String postCode; - - @QueryEmbedded - public City city; - -} \ No newline at end of file diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/AnimalTest.java b/querydsl-apt/src/test/java/com/mysema/query/domain/AnimalTest.java deleted file mode 100644 index c5134cffc2..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/AnimalTest.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.domain; - -import static org.junit.Assert.assertTrue; - -import org.junit.Test; - -import com.mysema.query.annotations.QueryEntity; -import com.mysema.query.annotations.QueryInit; - -public class AnimalTest { - - @QueryEntity - public static class Animal { - - public String name; - - } - - @QueryEntity - public static class Cat extends Animal { - - @QueryInit("name") - public Cat mate; - - } - - @Test - public void Properties_Are_Copied_From_Super() { - assertTrue("direct copy of StringPath field failed", QAnimalTest_Cat.cat.name == QAnimalTest_Cat.cat._super.name); - - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/AnnotationTypeTest.java b/querydsl-apt/src/test/java/com/mysema/query/domain/AnnotationTypeTest.java deleted file mode 100644 index 326503f43e..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/AnnotationTypeTest.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.mysema.query.domain; - -import java.lang.annotation.Annotation; - -import javax.persistence.Embeddable; -import javax.persistence.EmbeddedId; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.MappedSuperclass; - -import org.junit.Ignore; - -@Ignore -public class AnnotationTypeTest { - - @MappedSuperclass - public static abstract class BaseObject { - - } - - @Entity - public static class Person extends BaseObject { - @Id - private Long id; - } - - @Embeddable - public static class Address extends BaseObject { - @EmbeddedId - private String street; - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/AnyPathTest.java b/querydsl-apt/src/test/java/com/mysema/query/domain/AnyPathTest.java deleted file mode 100644 index f35c888d79..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/AnyPathTest.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.mysema.query.domain; - -import static org.junit.Assert.assertNotNull; - -import java.util.HashSet; -import java.util.Set; - -import javax.persistence.Embeddable; -import javax.persistence.EmbeddedId; -import javax.persistence.Entity; -import javax.persistence.ManyToOne; -import javax.persistence.OneToMany; - -import org.junit.Test; - -import com.mysema.query.annotations.QueryInit; -import com.mysema.query.types.expr.BooleanExpression; - -public class AnyPathTest { - @Entity - public static class Foo { - - @OneToMany(mappedBy = "key.foo") - @QueryInit("key.student") - private Set bars = new HashSet(); - - } - - @Entity - public static class Bar { - - @EmbeddedId - @QueryInit("student") - private BarId key = new BarId(); - - } - - @Embeddable - public static class BarId { - - @ManyToOne - private Student student; - - @ManyToOne - private Foo foo; - - } - - @Entity - public static class Student { - - } - - private BooleanExpression authorFilter(Student student){ - //return QFoo.foo.bars.any().key.student.eq(Student student); - return QAnyPathTest_Foo.foo.bars.any().key.student.eq(student); - } - - @Test - public void AnyPath() { - assertNotNull(authorFilter(new Student())); - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/AnyUsageTest.java b/querydsl-apt/src/test/java/com/mysema/query/domain/AnyUsageTest.java deleted file mode 100644 index 5bc1e6c9c3..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/AnyUsageTest.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.domain; - -import static org.junit.Assert.assertNotNull; - -import java.io.Serializable; -import java.util.LinkedList; -import java.util.List; -import java.util.Set; - -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import javax.persistence.ManyToOne; -import javax.persistence.OneToMany; - -import org.junit.Test; - -import com.mysema.query.types.expr.BooleanExpression; - -public class AnyUsageTest { - - @Entity - public static class DealerGroup implements Serializable { - private static final long serialVersionUID = 8001287260658920066L; - - @Id - @GeneratedValue - public Long id; - - @OneToMany(mappedBy = "dealerGroup") - public Set dealers; - - } - - @Entity - public static class Dealer implements Serializable { - private static final long serialVersionUID = -6832045219902674887L; - - @Id - @GeneratedValue - public Long id; - - @ManyToOne - public DealerGroup dealerGroup; - - @ManyToOne - public Company company; - - } - - @Entity - public static class Company implements Serializable { - private static final long serialVersionUID = -5369301332567282659L; - - @Id - @GeneratedValue - public Long id; - - } - - @Test - public void test() { - QAnyUsageTest_Dealer dealer = QAnyUsageTest_DealerGroup.dealerGroup.dealers.any(); - assertNotNull(dealer); - assertNotNull(dealer.company); - } - - @Test - public void WithQDealer() { - List companies = new LinkedList(); - companies.add( new Company() ); - QAnyUsageTest_Dealer qDealer = QAnyUsageTest_Dealer.dealer; - BooleanExpression expression = qDealer.company.in( companies ); - assertNotNull(expression); - } - - @Test - public void WithQDealerGroup() { - List companies = new LinkedList(); - companies.add( new Company() ); - QAnyUsageTest_Dealer qDealer = QAnyUsageTest_DealerGroup.dealerGroup.dealers.any(); - BooleanExpression expression = qDealer.company.in( companies ); - assertNotNull(expression); - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/Array2Test.java b/querydsl-apt/src/test/java/com/mysema/query/domain/Array2Test.java deleted file mode 100644 index 431303713c..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/Array2Test.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.mysema.query.domain; - -import org.junit.Test; - -import com.mysema.query.annotations.QueryProjection; -import com.mysema.query.types.path.SimplePath; - -public class Array2Test { - - public static class Example { - - byte[] imageData; - - @QueryProjection - public Example(byte[] param0) { - this.imageData = param0; - } - } - - @Test - public void test() { - new QArray2Test_Example(new SimplePath(byte[].class, "bytes")).newInstance(new byte[0]); - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/Array3Test.java b/querydsl-apt/src/test/java/com/mysema/query/domain/Array3Test.java deleted file mode 100644 index e5e24eec4b..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/Array3Test.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.mysema.query.domain; - -import static org.junit.Assert.assertEquals; - -import org.junit.Test; - -import com.mysema.query.annotations.QueryEntity; - -public class Array3Test { - - @QueryEntity - public static class Domain { - - byte[] bytes; - - Byte[] bytes2; - } - - @QueryEntity - public static class Domain2 { - - byte[] bytes; - } - - @QueryEntity - public static class Domain3 { - - Byte[] bytes; - } - - @Test - public void Domain() { - assertEquals(byte[].class, QArray3Test_Domain.domain.bytes.getType()); - assertEquals(Byte[].class, QArray3Test_Domain.domain.bytes2.getType()); - } - - @Test - public void Domain2() { - assertEquals(byte[].class, QArray3Test_Domain2.domain2.bytes.getType()); - } - - @Test - public void Domain3() { - assertEquals(Byte[].class, QArray3Test_Domain3.domain3.bytes.getType()); - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/B.java b/querydsl-apt/src/test/java/com/mysema/query/domain/B.java deleted file mode 100644 index 96f40d06d2..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/B.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.mysema.query.domain; - -import com.mysema.query.annotations.QueryEntity; - -@QueryEntity -public class B extends A { - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/BlockingTest.java b/querydsl-apt/src/test/java/com/mysema/query/domain/BlockingTest.java deleted file mode 100644 index ddf8958f11..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/BlockingTest.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.domain; - -import static org.junit.Assert.assertTrue; - -import org.junit.Test; - -import com.mysema.query.annotations.PropertyType; -import com.mysema.query.annotations.QueryEntity; -import com.mysema.query.annotations.QueryTransient; -import com.mysema.query.annotations.QueryType; - -public class BlockingTest extends AbstractTest { - - @QueryEntity - public static class Entity { - - Entity field1; - - @QueryTransient - @QueryType(PropertyType.ENTITY) - Entity field2; - - @QueryTransient - Entity blockedField; - } - - @QueryEntity - public static abstract class Entity2 { - - @QueryTransient - @QueryType(PropertyType.ENTITY) - public abstract Entity getField2(); - - @QueryTransient - public abstract Entity getBlockedField(); - } - - @Test - public void Entity_Fields_are_available() { - assertTrue(QBlockingTest_Entity.entity.field1 != null); - - cl = QBlockingTest_Entity.class; - assertMissing("blockedField"); - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/City.java b/querydsl-apt/src/test/java/com/mysema/query/domain/City.java deleted file mode 100644 index 20d0d5204c..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/City.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.domain; - - -public final class City { - - public City() {} - - public City(String name, Double latitude, Double longitude) { - this.name = name; - this.latitude = latitude; - this.longitude = longitude; - } - - public String name; - - public Double latitude; - - public Double longitude; - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/CollectionTest.java b/querydsl-apt/src/test/java/com/mysema/query/domain/CollectionTest.java deleted file mode 100644 index ece0949574..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/CollectionTest.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.domain; - -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.junit.Test; - -import com.mysema.query.annotations.QueryEntity; - -public class CollectionTest { - - @QueryEntity - public static class Person { - - Map map1; - - Map map2; - - Map map3; - - Map map4; - - List list1; - - List list2; - - Collection collection1; - - Collection collection2; - - Collection> collectionOfCOllection; - - Collection> collectionOfSet; - - Set set1; - - Set set2; - } - - @Test - public void test() { -// assertEquals(String.class, QMapWithUndefinedValueTest_Person.person.appData.getParameter(1)); -// assertEquals(Object.class, QMapWithUndefinedValueTest_Person.person.appData.getParameter(1)); - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/ComparableTest.java b/querydsl-apt/src/test/java/com/mysema/query/domain/ComparableTest.java deleted file mode 100644 index 1d5b0c8e21..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/ComparableTest.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.domain; - -import static org.junit.Assert.*; - -import org.junit.Test; - -import com.mysema.query.annotations.QueryEmbeddable; -import com.mysema.query.annotations.QueryEntity; - -public class ComparableTest { - - @QueryEntity - public static class CustomComparable implements Comparable{ - - @Override - public int compareTo(CustomComparable o) { - return 0; - } - - public boolean equals(Object o) { - return o == this; - } - - } - - @QueryEmbeddable - public static class CustomComparable2 implements Comparable{ - - @Override - public int compareTo(CustomComparable2 o) { - return 0; - } - - public boolean equals(Object o) { - return o == this; - } - - } - - @Test - public void CustomComparable_is_Properly_Handled() { - assertNotNull(QComparableTest_CustomComparable.customComparable.asc()); - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/ConstructorTest.java b/querydsl-apt/src/test/java/com/mysema/query/domain/ConstructorTest.java deleted file mode 100644 index 33b528d2f9..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/ConstructorTest.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.domain; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -import org.junit.Test; - -import com.mysema.query.annotations.QueryEntity; -import com.mysema.query.annotations.QuerySupertype; - -public class ConstructorTest { - - @QuerySupertype - public static class CategorySuperclass { - - } - - @QueryEntity - public static class Category> extends CategorySuperclass { - - public Category(int i) {} - - } - - @QueryEntity - public static class ClassWithConstructor { - - public ClassWithConstructor() {} - - } - - @Test - public void Classes_are_available() { - assertNotNull(QConstructorTest_CategorySuperclass.class); - assertNotNull(QConstructorTest_Category.class); - assertNotNull(QConstructorTest_ClassWithConstructor.class); - } - - @Test - public void Category_Super_Reference_is_Correct() { - assertEquals(QConstructorTest_CategorySuperclass.class, QConstructorTest_Category.category._super.getClass()); - assertEquals(Category.class, QConstructorTest_Category.category._super.getType()); - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/CustomCollection.java b/querydsl-apt/src/test/java/com/mysema/query/domain/CustomCollection.java deleted file mode 100644 index 674139f19c..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/CustomCollection.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.mysema.query.domain; - -import java.util.Set; - -import javax.persistence.Entity; - -import com.google.common.collect.ForwardingSet; - -public class CustomCollection { - - @Entity - public static class MyCustomCollection extends ForwardingSet { - - @Override - protected Set delegate() { - return null; - } - - } - - @Entity - public static class MyCustomCollection2 extends ForwardingSet { - - @Override - protected Set delegate() { - return null; - } - - } - - @Entity - public static class MyEntity { - - MyCustomCollection strings; - - MyCustomCollection2 strings2; - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/DeepInitializationTest.java b/querydsl-apt/src/test/java/com/mysema/query/domain/DeepInitializationTest.java deleted file mode 100644 index 2f1a160e8c..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/DeepInitializationTest.java +++ /dev/null @@ -1,122 +0,0 @@ -package com.mysema.query.domain; - -import java.util.Collection; - -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Embeddable; -import javax.persistence.Embedded; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.MappedSuperclass; -import javax.persistence.OneToMany; -import javax.persistence.OneToOne; -import javax.persistence.SequenceGenerator; - -import org.junit.Test; - -import com.mysema.query.annotations.QueryInit; - -public class DeepInitializationTest { - - @MappedSuperclass - public static abstract class AbstractEntity implements Cloneable { - - @Id - @Column(name = "ID") - @GeneratedValue(generator="SEQUENCE") - private long id; - - public long getId() { - return id; - } - - @Override - protected Object clone() throws CloneNotSupportedException { - return super.clone(); - } - } - - @Entity - @SequenceGenerator(name = "SEQUENCE", sequenceName = "PARENT_SEQUENCE") - public static class Parent extends AbstractEntity { - @JoinColumn(name = "FK_PARENT_ID", nullable = false) - @OneToMany(cascade = CascadeType.PERSIST) - @QueryInit("subChild.*") - private Collection children; - - public Parent() { - } - - public Collection getChildren() { - return children; - } - - public void setChildren(Collection children) { - this.children = children; - } - } - - @Entity - @SequenceGenerator(name = "SEQUENCE", sequenceName = "CHILD_SEQUENCE") - public static class Child extends AbstractEntity { - @OneToOne - @JoinColumn(name = "FK_SUBCHILD_ID", referencedColumnName = "ID") - private SubChild subChild; - - public Child() { - } - - public SubChild getSubChild() { - return subChild; - } - - public void setSubChild(SubChild subChild) { - this.subChild = subChild; - } - } - - @Entity - @SequenceGenerator(name = "SEQUENCE", sequenceName = "SUBCHILD_SEQUENCE") - public static class SubChild extends AbstractEntity { - @Embedded - private MyEmbeddable myEmbeddable; - - public SubChild() { - } - - public MyEmbeddable getMyEmbeddable() { - return myEmbeddable; - } - - public void setMyEmbeddable(MyEmbeddable myEmbeddable) { - this.myEmbeddable = myEmbeddable; - } - } - - @Embeddable - public static class MyEmbeddable { - - private String nummer; - - public MyEmbeddable() { - } - - public String getNummer() { - return nummer; - } - - public void setNummer(String nummer) { - this.nummer = nummer; - } - } - - @Test - public void Init_Via_Parent() { - QDeepInitializationTest_Parent parent = QDeepInitializationTest_Parent.parent; - parent.children.any().subChild.myEmbeddable.nummer.eq("Test"); - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/Delegate2Test.java b/querydsl-apt/src/test/java/com/mysema/query/domain/Delegate2Test.java deleted file mode 100644 index 8382d64ad4..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/Delegate2Test.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.domain; - -import static org.junit.Assert.assertNotNull; - -import org.junit.Test; - -import com.mysema.query.annotations.QueryDelegate; -import com.mysema.query.annotations.QueryEntity; -import com.mysema.query.types.ConstantImpl; -import com.mysema.query.types.Path; -import com.mysema.query.types.expr.NumberExpression; -import com.mysema.query.types.template.NumberTemplate; - -public class Delegate2Test { - - @QueryEntity - public static class Entity { - - Point point; - } - - public static class Point { - - } - - @QueryDelegate(Point.class) - public static NumberExpression geoDistance(Path point, Point other) { - return NumberTemplate.create(Integer.class, "geo_distance({0},{1})", point, ConstantImpl.create(other)); - } - - @Test - public void test() { - QDelegate2Test_Entity entity = QDelegate2Test_Entity.entity; - assertNotNull(entity.point.geoDistance(new Point())); - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/Delegate3Test.java b/querydsl-apt/src/test/java/com/mysema/query/domain/Delegate3Test.java deleted file mode 100644 index 5773ed8fb9..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/Delegate3Test.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.mysema.query.domain; - -import org.junit.Test; - -import com.mysema.query.annotations.QueryDelegate; -import com.mysema.query.types.expr.BooleanExpression; -import com.mysema.query.types.path.ComparablePath; -import com.mysema.query.types.template.BooleanTemplate; - -public class Delegate3Test { - - public static class Geometry implements Comparable { - - @Override - public int compareTo(Geometry o) { - return 0; - } - - } - - public static class Point extends Geometry { - - } - - public static class Polygon extends Geometry { - - } - - @QueryDelegate(Geometry.class) - public static BooleanExpression isWithin( ComparablePath geo1, ComparablePath geo2){ - return BooleanTemplate.TRUE; - } - - @Test - public void test() { - QDelegate3Test_Geometry.geometry.isWithin(null); - QDelegate3Test_Point.point.isWithin(null); - QDelegate3Test_Polygon.polygon.isWithin(null); - } -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/DelegateTest.java b/querydsl-apt/src/test/java/com/mysema/query/domain/DelegateTest.java deleted file mode 100644 index eb9a57d30b..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/DelegateTest.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.domain; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -import org.junit.Test; - -import com.mysema.query.annotations.QueryDelegate; -import com.mysema.query.annotations.QueryEntity; -import com.mysema.query.annotations.QuerySupertype; -import com.mysema.query.types.ConstantImpl; -import com.mysema.query.types.Expression; -import com.mysema.query.types.path.StringPath; - -public class DelegateTest { - - @QuerySupertype - public static class Identifiable { - - long id; - - } - - @QueryEntity - public static class User extends Identifiable { - - String name; - - User managedBy; - - } - - @QueryEntity - public static class SimpleUser extends User { - - } - - @QueryEntity - public static class SimpleUser2 extends SimpleUser { - - } - - @QueryDelegate(User.class) - public static Expression isManagedBy(QDelegateTest_User user, User other) { - return ConstantImpl.create(true); - } - - @QueryDelegate(User.class) - public static Expression isManagedBy(QDelegateTest_User user, QDelegateTest_User other) { - return ConstantImpl.create(true); - } - - @QueryDelegate(User.class) - public static Expression simpleMethod(QDelegateTest_User user) { - return ConstantImpl.create(true); - } - - @QueryDelegate(DelegateTest.User.class) - public static StringPath getName(QDelegateTest_User user) { - return user.name; - } - - @Test - public void User() { - QDelegateTest_User user = QDelegateTest_User.user; - assertNotNull(user.isManagedBy(new User())); - assertNotNull(user.isManagedBy(user)); - assertNotNull(user.simpleMethod()); - assertEquals(user.name, user.getName()); - } - - @Test - public void SimpleUser() { - QDelegateTest_SimpleUser user = QDelegateTest_SimpleUser.simpleUser; - assertNotNull(user.isManagedBy(new User())); - assertNotNull(user.isManagedBy(user._super)); - assertEquals(user.name, user.getName()); - } - - @Test - public void SimpleUser2() { - QDelegateTest_SimpleUser2 user = QDelegateTest_SimpleUser2.simpleUser2; - assertNotNull(user.isManagedBy(new User())); - assertNotNull(user.isManagedBy(user._super._super)); - assertEquals(user.name, user.getName()); - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/Embeddable2Test.java b/querydsl-apt/src/test/java/com/mysema/query/domain/Embeddable2Test.java deleted file mode 100644 index f39fe95b39..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/Embeddable2Test.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.domain; - -import static org.junit.Assert.assertNotNull; - -import org.junit.Ignore; -import org.junit.Test; - -import com.mysema.query.annotations.QueryEmbedded; -import com.mysema.query.annotations.QueryEntity; -import com.mysema.query.annotations.QuerySupertype; -import com.mysema.query.types.PathMetadata; -import com.mysema.query.types.path.PathInits; - -public class Embeddable2Test { - - @QuerySupertype - public static abstract class SomeMappedSuperClassHavingMyEmbeddable { - - @QueryEmbedded - MyEmbeddable embeddable; - } - - @QueryEntity - public static abstract class SomeEntityClassHavingMyEmbeddable { - - @QueryEmbedded - MyEmbeddable embeddable; - - } - - @QueryEntity - public static class SomeEntity extends SomeMappedSuperClassHavingMyEmbeddable { - - } - - @Test - @Ignore - public void MappedSuperClassConstructors() throws SecurityException, NoSuchMethodException { - assertNotNull(QEmbeddable2Test_SomeMappedSuperClassHavingMyEmbeddable.class.getConstructor( - Class.class, PathMetadata.class, PathInits.class)); - } - - @Test - @Ignore - public void EntityConstructors() throws SecurityException, NoSuchMethodException { - assertNotNull(QEmbeddable2Test_SomeEntityClassHavingMyEmbeddable.class.getConstructor( - Class.class, PathMetadata.class, PathInits.class)); - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/EmbeddableInterfaceTest.java b/querydsl-apt/src/test/java/com/mysema/query/domain/EmbeddableInterfaceTest.java deleted file mode 100644 index fd10783b64..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/EmbeddableInterfaceTest.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.domain; - -import static org.junit.Assert.*; - -import java.util.Collection; - -import javax.persistence.ElementCollection; -import javax.persistence.Embeddable; -import javax.persistence.Entity; - -import org.junit.Test; - -public class EmbeddableInterfaceTest { - - @Entity - public static class EntityClass { - - @ElementCollection(targetClass=EmbeddableClass.class) - Collection children; - - } - - @Embeddable - public interface EmbeddableInterface { - - String getName(); - } - - @Embeddable - public static class EmbeddableClass implements EmbeddableInterface { - - @Override - public String getName() { - return null; - } - - } - - @Test - public void Type() { - assertEquals( - QEmbeddableInterfaceTest_EmbeddableInterface.class, - QEmbeddableInterfaceTest_EntityClass.entityClass.children.any().getClass()); - } - - @Test - public void Properties() { - assertNotNull(QEmbeddableInterfaceTest_EmbeddableInterface.embeddableInterface.name); - assertNotNull(QEmbeddableInterfaceTest_EmbeddableClass.embeddableClass.name); - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/EmbeddableTest.java b/querydsl-apt/src/test/java/com/mysema/query/domain/EmbeddableTest.java deleted file mode 100644 index a350ab1c1f..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/EmbeddableTest.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.domain; - -import java.util.List; - -import org.junit.Ignore; - -import com.mysema.query.annotations.QueryEmbeddable; -import com.mysema.query.annotations.QueryEntity; -import com.mysema.query.annotations.QuerySupertype; -import com.mysema.query.domain.AnimalTest.Cat; - -@Ignore -public class EmbeddableTest { - - @QueryEntity - public static class EntityWithEmbedded { - - public WithEntityRef e1; - - public WithStringProp e2; - - public WithEntityAndString e3; - - public WithList e4; - } - - @QueryEmbeddable - public static class WithEntityRef { - - public Cat cat; - - } - - @QueryEmbeddable - public static class WithStringProp { - - public String str; - } - - @QueryEmbeddable - public static class WithEntityAndString extends WithEntityRef { - - public String str2; - - } - - @QueryEmbeddable - public static class WithList extends WithStringProp { - - public List cats; - - public String str3; - - } - - @QueryEntity - @QueryEmbeddable - public static class EntityAndEmbeddable { - - } - - @QuerySupertype - @QueryEmbeddable - public static class SuperclassAndEmbeddable { - - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/Embedded2Test.java b/querydsl-apt/src/test/java/com/mysema/query/domain/Embedded2Test.java deleted file mode 100644 index 48aabbd764..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/Embedded2Test.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.domain; - -import java.io.Serializable; - -import javax.persistence.Column; -import javax.persistence.Embeddable; -import javax.persistence.Embedded; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.MappedSuperclass; - -import org.junit.Test; - -public class Embedded2Test { - - @MappedSuperclass - public static class EntityCode { - - @Column(name = "code", unique = true) - String code; - - } - - @MappedSuperclass - public static abstract class AbstractEntity { - - @Embedded - @Column(name = "code", nullable = false, unique = true) - C code; - - } - - @MappedSuperclass - public static class AbstractMultilingualEntity extends AbstractEntity { - - } - - @MappedSuperclass - public static abstract class AbstractNamedEntity extends AbstractMultilingualEntity { - - @Column(name = "name_en", nullable = false) - String nameEn; - - @Column(name = "name_nl") - String nameNl; - - } - - @javax.persistence.Entity - public static class Brand extends AbstractNamedEntity { - - @Id - @GeneratedValue(strategy = GenerationType.AUTO) - @Column(name = "brand_id") - Long id; - - } - - public interface Entity extends Serializable { - - boolean sameIdentityAs(T other); - - } - - @Embeddable - public static class BrandCode extends EntityCode { - - } - - @Test - public void test() { - // TODO - } - - - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/EmbeddedTest.java b/querydsl-apt/src/test/java/com/mysema/query/domain/EmbeddedTest.java deleted file mode 100644 index 37f5a3bc41..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/EmbeddedTest.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.domain; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -import javax.persistence.Column; -import javax.persistence.Embeddable; -import javax.persistence.Embedded; -import javax.persistence.Entity; -import javax.persistence.MappedSuperclass; - -import org.junit.Test; - -public class EmbeddedTest { - - @Entity - public static class EntityClass extends AbstractEntity { - - } - - @MappedSuperclass - public static abstract class AbstractEntity { - - @Embedded - @Column(name = "code", nullable = false, unique = true) - C code; - } - - @MappedSuperclass - public static class EntityCode { - - @Column(name = "code", unique = true) - String code; - - } - - @Embeddable - public static class SubEntityCode extends EntityCode { - - String property; - - } - - @Test - public void EntityClass() { - assertNotNull(QEmbeddedTest_EntityClass.entityClass.code.property); - assertEquals(SubEntityCode.class, QEmbeddedTest_EntityClass.entityClass.code.getType()); - } - - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/EntityInheritanceTest.java b/querydsl-apt/src/test/java/com/mysema/query/domain/EntityInheritanceTest.java deleted file mode 100644 index 3d2c36e056..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/EntityInheritanceTest.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.domain; - -import static org.junit.Assert.assertEquals; - -import javax.persistence.Entity; -import javax.persistence.MappedSuperclass; - -import org.junit.Test; - -public class EntityInheritanceTest { - - @MappedSuperclass - public static class TreeEntity> { - - Integer id; - - T parent; - - } - - @Entity - public static class TestEntity extends TreeEntity { - - String name; - - } - - @Test - public void test() { - assertEquals( - QEntityInheritanceTest_TestEntity.class, - QEntityInheritanceTest_TestEntity.testEntity.parent.getClass()); - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/Enum2Test.java b/querydsl-apt/src/test/java/com/mysema/query/domain/Enum2Test.java deleted file mode 100644 index 0f1fe905e2..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/Enum2Test.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.domain; - -import org.junit.Ignore; - -import com.mysema.query.annotations.QueryEntity; - -@Ignore -public class Enum2Test { - - @QueryEntity - public static abstract class EnumPermissions

& Permission> extends EntityImpl implements Permissions

{ - - } - - @QueryEntity - public static abstract class EntityImpl { - - } - - public interface Permission { - - } - - public interface Permissions

{ - - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/EnumTest.java b/querydsl-apt/src/test/java/com/mysema/query/domain/EnumTest.java deleted file mode 100644 index 93677a72b5..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/EnumTest.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.domain; - -import static org.junit.Assert.*; - -import org.junit.Test; - -import com.mysema.query.annotations.QueryEmbeddable; -import com.mysema.query.annotations.QueryEntity; - -public class EnumTest { - - @QueryEntity - public enum Gender { - MALE, - FEMALE - } - - @QueryEmbeddable - public enum Gender2 { - MALE, - FEMALE - } - - @QueryEntity - public static class Bean { - Gender gender; - } - - @Test - public void Enum_as_Comparable() { - assertNotNull(QEnumTest_Gender.gender.asc()); - } - - @Test - public void EnumOrdinal_as_Comparable() { - assertNotNull(QEnumTest_Gender.gender.ordinal().asc()); - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/ExampleEntity.java b/querydsl-apt/src/test/java/com/mysema/query/domain/ExampleEntity.java deleted file mode 100644 index 58a13839cd..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/ExampleEntity.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.domain; - -import com.mysema.query.annotations.QueryEntity; - -@QueryEntity -public class ExampleEntity { - - String name; - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/Examples.java b/querydsl-apt/src/test/java/com/mysema/query/domain/Examples.java deleted file mode 100644 index d65c0308ff..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/Examples.java +++ /dev/null @@ -1,77 +0,0 @@ -package com.mysema.query.domain; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import com.mysema.query.annotations.QueryEmbedded; -import com.mysema.query.annotations.QueryEntity; -import com.mysema.query.types.OrderSpecifier; - -public class Examples { - - public static class Supertype { - - String supertypeProperty; - } - - @QueryEntity - public static class SimpleEntity extends Supertype { - - } - - @QueryEntity - public static abstract class AbstractEntity { - - Id id; - - String first; - - } - - @QueryEntity - public static class SubEntity extends AbstractEntity { - - String second; - - } - - @QueryEntity - public static class ComplexCollections { - - @QueryEmbedded - List> list; - - @QueryEmbedded - Map> map; - - @QueryEmbedded - Map> map2; - - @QueryEmbedded - Map> map3; - - } - - public static class Complex> implements Comparable> { - - T a; - - @Override - public int compareTo(Complex arg0) { - return 0; - } - - public boolean equals(Object o) { - return o == this; - } - } - - @QueryEntity - public static class OrderBys { - - @QueryEmbedded - List> orderBy = new ArrayList>(); - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/ExcludedClassTest.java b/querydsl-apt/src/test/java/com/mysema/query/domain/ExcludedClassTest.java deleted file mode 100644 index fdb3be10e0..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/ExcludedClassTest.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.domain; - -import org.junit.Test; - -import com.mysema.query.annotations.QueryEntity; -import com.mysema.query.annotations.QueryExclude; - -@QueryExclude -@QueryEntity -public class ExcludedClassTest { - - @QueryExclude - @QueryEntity - public static class InnerClass { - - } - - @Test(expected=ClassNotFoundException.class) - public void OuterClass() throws ClassNotFoundException { - Class.forName(getClass().getPackage().getName() + ".Q" + getClass().getSimpleName()); - } - - @Test(expected=ClassNotFoundException.class) - public void InnerClass() throws ClassNotFoundException { - Class.forName(getClass().getPackage().getName() + ".QExcludedClassTest_InnerClass"); - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/Expression.java b/querydsl-apt/src/test/java/com/mysema/query/domain/Expression.java deleted file mode 100644 index f9bcef6ce6..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/Expression.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.mysema.query.domain; - -import javax.persistence.Entity; - -@Entity -public class Expression { - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/ExternalEmbeddableTest.java b/querydsl-apt/src/test/java/com/mysema/query/domain/ExternalEmbeddableTest.java deleted file mode 100644 index f5a7333d24..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/ExternalEmbeddableTest.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.domain; - -import javax.persistence.Embedded; -import javax.persistence.Entity; - -import org.junit.Ignore; - -@Ignore -public class ExternalEmbeddableTest { - - @Entity - public static class EntityWithExternalEmbeddable { - - @Embedded - EmbeddableWithoutQType embeddable; - - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/Generic10Test.java b/querydsl-apt/src/test/java/com/mysema/query/domain/Generic10Test.java deleted file mode 100644 index ed9302b9c2..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/Generic10Test.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.mysema.query.domain; - -import javax.persistence.Entity; -import javax.persistence.MappedSuperclass; -import javax.persistence.OneToOne; - -import org.junit.Ignore; - -@Ignore -public class Generic10Test { - - public interface Tradable {} - - public interface Market {} - - @Entity - public static class FutureTrade implements Tradable {} - - @MappedSuperclass - public static abstract class AbstractTradingMarket implements Market{ - - // XXX - @OneToOne - private TradingMarketLedger> ledger; - } - - @Entity - public static abstract class AbstractFuturesMarket extends AbstractTradingMarket {} - - // XXX - @Entity - public static class CommonFuturesMarket extends AbstractFuturesMarket {} - - @Entity - public static class TradingMarketLedger> {} - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/Generic13Test.java b/querydsl-apt/src/test/java/com/mysema/query/domain/Generic13Test.java deleted file mode 100644 index 468d3dd4a1..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/Generic13Test.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.mysema.query.domain; - -import org.junit.Ignore; - -import com.mysema.query.annotations.QueryEntity; - -@Ignore -public class Generic13Test { - - @QueryEntity - public static class GenericBase { - T t; - } - - @QueryEntity - public static class GenericBaseSubclass

extends GenericBase { - P p; - } - - @QueryEntity - public static class Subclass extends GenericBaseSubclass { - } - - public static class AnotherClass { - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/Generic14Test.java b/querydsl-apt/src/test/java/com/mysema/query/domain/Generic14Test.java deleted file mode 100644 index fc01b201b1..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/Generic14Test.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.mysema.query.domain; - -import javax.persistence.Entity; -import javax.persistence.MappedSuperclass; -import java.io.Serializable; - -import org.junit.Test; -import static org.junit.Assert.assertNotNull; - -public class Generic14Test { - - @Entity - public static class UserAccount extends BaseReferencablePersistable { - - } - - @MappedSuperclass - public static abstract class BaseReferencablePersistable extends BasePersistable { - - } - - @MappedSuperclass - public static class BasePersistable extends AbstractPersistable implements UpdateInfo { - - } - - @MappedSuperclass - public static abstract class AbstractPersistable implements Persistable { - - } - - public interface Persistable { - - } - - public interface UpdateInfo { - - } - - @Test - public void test() { - assertNotNull(QGeneric14Test_UserAccount.userAccount); - assertNotNull(QGeneric14Test_BaseReferencablePersistable.baseReferencablePersistable); - assertNotNull(QGeneric14Test_BasePersistable.basePersistable); - assertNotNull(QGeneric14Test_AbstractPersistable.abstractPersistable); - } -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/Generic2Test.java b/querydsl-apt/src/test/java/com/mysema/query/domain/Generic2Test.java deleted file mode 100644 index 5271e7fb55..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/Generic2Test.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.mysema.query.domain; - -import java.io.Serializable; - -import javax.persistence.Embedded; -import javax.persistence.Entity; -import javax.persistence.MappedSuperclass; - -import org.junit.Test; - -public class Generic2Test { - - public static class Range> { - private T min; - private T max; - - public T getMin() { - return min; - } - - public void setMin(T min) { - this.min = min; - } - - public T getMax() { - return max; - } - - public void setMax(T max) { - this.max = max; - } - } - - @MappedSuperclass - public static abstract class BaseEntity> implements - Serializable { - @Embedded - private Range range; - - public Range getRange() { - return range; - } - - public void setRange(Range range) { - this.range = range; - } - } - - @Entity - public static class Foo extends BaseEntity { - - } - - @Test - public void test() { - - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/Generic3Test.java b/querydsl-apt/src/test/java/com/mysema/query/domain/Generic3Test.java deleted file mode 100644 index a64c9b2287..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/Generic3Test.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.mysema.query.domain; - -import javax.persistence.Entity; -import javax.persistence.MappedSuperclass; - -import org.junit.Test; - -public class Generic3Test { - - @MappedSuperclass - public static abstract class BaseEntity> { - - } - - @MappedSuperclass - public static abstract class Order> extends BaseEntity implements Cloneable { - - String property1; - } - - @Entity - public static class MyOrder> extends Order { - - String property2; - } - - @Test - public void test() { - - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/Generic4Test.java b/querydsl-apt/src/test/java/com/mysema/query/domain/Generic4Test.java deleted file mode 100644 index bb8de62b16..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/Generic4Test.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.mysema.query.domain; - -import javax.persistence.MappedSuperclass; - -import org.junit.Test; - -public class Generic4Test { - - @MappedSuperclass - public static abstract class CapiBCKeyedByGrundstueck { - - } - - @MappedSuperclass - public static abstract class HidaBez, G extends HidaBezGruppe> extends CapiBCKeyedByGrundstueck { - - } - - @MappedSuperclass - public static abstract class HidaBezGruppe, B extends HidaBez> extends - CapiBCKeyedByGrundstueck { - - } - - @Test - public void test() { - - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/Generic8Test.java b/querydsl-apt/src/test/java/com/mysema/query/domain/Generic8Test.java deleted file mode 100644 index 322c4e8e50..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/Generic8Test.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.mysema.query.domain; - -import java.util.List; - -import org.junit.Test; - -import com.mysema.query.annotations.QueryEntity; -import com.mysema.query.annotations.QuerySupertype; - -public class Generic8Test { - - @QuerySupertype - public static class Superclass { - - Long id; - - List values; - - List values2; - - } - - @QueryEntity - public static class Entity extends Superclass { - - } - - - @QueryEntity - public static class Entity2 extends Superclass { - - } - - @Test - public void test() { - - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/Generic9Test.java b/querydsl-apt/src/test/java/com/mysema/query/domain/Generic9Test.java deleted file mode 100644 index 98aac2a5e1..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/Generic9Test.java +++ /dev/null @@ -1,70 +0,0 @@ -package com.mysema.query.domain; - -import java.io.Serializable; - -import javax.persistence.DiscriminatorColumn; -import javax.persistence.DiscriminatorType; -import javax.persistence.Entity; -import javax.persistence.MappedSuperclass; -import javax.persistence.Table; - -import org.junit.Test; - -public class Generic9Test { - - @MappedSuperclass - public static abstract class CommonOrganizationalUnit> extends - LocalizableEntity implements Serializable, Comparable> { - - P parent; - -// CommonOrganizationalUnit parent2; -// -// CommonOrganizationalUnit parent3; - - } - - @MappedSuperclass - public static abstract class ProductionSurface> extends - CommonOrganizationalUnit implements Serializable { - - } - -// @Entity -// public class Building extends ProductionSurface { -// -// } - - @MappedSuperclass - public static abstract class EntityLocalized extends CommonEntity { - - } - - @Entity - public static class Preference { - - } - - @Entity - @Table(name = "preference") - @DiscriminatorColumn(name = "discriminator", discriminatorType = DiscriminatorType.STRING) - public static abstract class TenantPreference extends Preference { - - } - - @MappedSuperclass - public static abstract class CommonEntity { - - } - - @MappedSuperclass - public static abstract class LocalizableEntity extends CommonEntity { - - } - - @Test - public void test() { - new QGeneric9Test_CommonOrganizationalUnit("test"); - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/GenericTest.java b/querydsl-apt/src/test/java/com/mysema/query/domain/GenericTest.java deleted file mode 100644 index 1f73665565..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/GenericTest.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.domain; - -import java.util.Date; - -import org.junit.Ignore; - -import com.mysema.query.annotations.QueryEntity; -import com.mysema.query.annotations.QueryTransient; -import com.mysema.query.domain.rel.SimpleType; -import com.mysema.query.domain.rel.SimpleType2; - -@Ignore -public class GenericTest { - - @QueryEntity - public static class GenericType { - T itemType; - } - - @QueryEntity - @SuppressWarnings("unchecked") - public static class GenericType2 { - T itemType; - - // simple - GenericSimpleType prop1; - GenericSimpleType prop2; - GenericSimpleType> prop3; - - // comparable - GenericComparableType comp1; - GenericComparableType comp2; - GenericComparableType comp3; - - // number - - @QueryTransient - GenericNumberType num1; // NOTE : doesn't work! - - GenericNumberType num2; - GenericNumberType num3; - } - - public static class GenericSimpleType>{ - - } - - @SuppressWarnings("unchecked") - public static class GenericComparableType implements Comparable>{ - @Override - public int compareTo(GenericComparableType o) { - return 0; - } - - @Override - public boolean equals(Object o) { - return o instanceof GenericComparableType; - } - } - - @SuppressWarnings({ "unchecked", "serial" }) - public static class GenericNumberType extends Number implements Comparable>{ - @Override - public double doubleValue() { - return 0; - } - @Override - public float floatValue() { - return 0; - } - @Override - public int intValue() { - return 0; - } - @Override - public long longValue() { - return 0; - } - @Override - public int compareTo(GenericNumberType o) { - return 0; - } - - @Override - public int hashCode() { - return super.hashCode(); - } - - @Override - public boolean equals(Object o) { - return o instanceof GenericNumberType; - } - } - - @QueryEntity - @SuppressWarnings("unchecked") - public static class ItemType { - Amount prop; - SimpleType2> prop2; - SimpleType2 prop3; - SimpleType2 prop4; - } - - public static class Amount{ - - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/InterfaceTypeTest.java b/querydsl-apt/src/test/java/com/mysema/query/domain/InterfaceTypeTest.java deleted file mode 100644 index 5f8581d3ef..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/InterfaceTypeTest.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.domain; - -import java.util.List; - -import org.junit.Test; - -import com.mysema.query.annotations.QueryEntity; -import com.mysema.query.types.path.ListPath; -import com.mysema.query.types.path.NumberPath; - -public class InterfaceTypeTest extends AbstractTest { - - @QueryEntity - public interface InterfaceType { - InterfaceType getRelation(); - - List getRelation2(); - - List getRelation3(); - - int getRelation4(); - - String getProp(); - } - - @QueryEntity - public interface InterfaceType2 { - - public String getProp2(); - - } - - @QueryEntity - public interface InterfaceType3 extends InterfaceType, InterfaceType2 { - - public String getProp3(); - - } - - @QueryEntity - public interface InterfaceType4 { - - public String getProp4(); - - } - - @QueryEntity - public interface InterfaceType5 extends InterfaceType3, InterfaceType4 { - - public String getProp5(); - - } - - @Test - public void QInterfaceType_relation() throws SecurityException, NoSuchFieldException { - cl = QInterfaceTypeTest_InterfaceType.class; - match(QInterfaceTypeTest_InterfaceType.class, "relation"); - } - - @Test - public void QInterfaceType_relation2() throws SecurityException, NoSuchFieldException { - cl = QInterfaceTypeTest_InterfaceType.class; - match(ListPath.class, "relation2"); - } - - @Test - public void QInterfaceType_relation3() throws SecurityException, NoSuchFieldException { - cl = QInterfaceTypeTest_InterfaceType.class; - match(ListPath.class, "relation3"); - } - - @Test - public void QInterfaceType_relation4() throws SecurityException, NoSuchFieldException { - cl = QInterfaceTypeTest_InterfaceType.class; - match(NumberPath.class, "relation4"); - } - - @Test - public void QInterfaceType3() throws SecurityException, NoSuchFieldException { - Class cl = QInterfaceTypeTest_InterfaceType3.class; - cl.getField("prop"); - cl.getField("prop2"); - cl.getField("prop3"); - } - - @Test - public void QInterfaceType5() throws SecurityException, NoSuchFieldException{ - Class cl = QInterfaceTypeTest_InterfaceType5.class; - cl.getField("prop"); - cl.getField("prop2"); - cl.getField("prop3"); - cl.getField("prop4"); - cl.getField("prop5"); - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/JDOTest.java b/querydsl-apt/src/test/java/com/mysema/query/domain/JDOTest.java deleted file mode 100644 index c74a9b3f2a..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/JDOTest.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.domain; - -import javax.jdo.annotations.NotPersistent; -import javax.jdo.annotations.PersistenceCapable; - -import org.junit.Test; - -import com.mysema.query.types.path.StringPath; - -public class JDOTest extends AbstractTest { - - @PersistenceCapable - public static class JDOEntity { - - String prop; - - @NotPersistent - String skipped; - - @NotPersistent - JDOEntity skippedEntity; - } - - @PersistenceCapable - public static class JDOEntity2 { - - @SuppressWarnings("unused") - private String stringField1; - - private String stringField2; - - public String getStringField2() { - return stringField2; - } - } - - @Test - public void test() throws SecurityException, NoSuchFieldException { - cl = QJDOTest_JDOEntity.class; - match(StringPath.class, "prop"); - assertMissing("skipped"); - assertMissing("skippedEntity"); - - cl = QJDOTest_JDOEntity2.class; - match(StringPath.class, "stringField1"); - match(StringPath.class, "stringField2"); - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/JPATest.java b/querydsl-apt/src/test/java/com/mysema/query/domain/JPATest.java deleted file mode 100644 index a744b37389..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/JPATest.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.domain; - -import javax.persistence.Entity; -import javax.persistence.Transient; - -import org.junit.Test; - -import com.mysema.query.domain.JDOTest.JDOEntity; -import com.mysema.query.types.path.StringPath; - -public class JPATest extends AbstractTest { - - @Entity - public static class JPAEntity { - - String prop; - - @Transient - String skipped; - - @Transient - JDOEntity skippedEntity; - } - - @Test - public void test() throws SecurityException, NoSuchFieldException { - cl = QJPATest_JPAEntity.class; - match(StringPath.class, "prop"); - assertMissing("skipped"); - assertMissing("skippedEntity"); - } -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/JodaMoneyHelpers.java b/querydsl-apt/src/test/java/com/mysema/query/domain/JodaMoneyHelpers.java deleted file mode 100644 index 592c07c425..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/JodaMoneyHelpers.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.mysema.query.domain; - -import java.math.BigDecimal; - -import org.joda.money.Money; -import org.joda.money.QMoney; - -import com.mysema.query.annotations.QueryDelegate; -import com.mysema.query.types.Ops; -import com.mysema.query.types.expr.NumberExpression; -import com.mysema.query.types.expr.NumberOperation; - -public class JodaMoneyHelpers { - - @QueryDelegate(Money.class) - public static NumberExpression sum(QMoney money) { - return NumberOperation.create(BigDecimal.class, Ops.AggOps.SUM_AGG, money); - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/JodaTest.java b/querydsl-apt/src/test/java/com/mysema/query/domain/JodaTest.java deleted file mode 100644 index 560c8eb62a..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/JodaTest.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.mysema.query.domain; - -import static org.junit.Assert.*; - -import java.util.Date; - -import javax.persistence.Access; -import javax.persistence.AccessType; -import javax.persistence.MappedSuperclass; -import javax.persistence.Temporal; -import javax.persistence.TemporalType; - -import org.joda.time.DateTime; -import org.junit.Test; - -public class JodaTest { - - @MappedSuperclass - @Access(AccessType.FIELD) - public abstract class BaseEntity { - - public abstract Long getId(); - - @Temporal(TemporalType.TIMESTAMP) - private Date createdDate; - - public boolean isNew() { - return null == getId(); - } - - public DateTime getCreatedDate() { - return null == createdDate ? null : new DateTime(createdDate); - } - - public void setCreatedDate(DateTime creationDate) { - this.createdDate = null == creationDate ? null : creationDate.toDate(); - } - } - - @Test - public void test() { - assertEquals(Date.class, QJodaTest_BaseEntity.baseEntity.createdDate.getType()); - } -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/JodaTimeSupportTest.java b/querydsl-apt/src/test/java/com/mysema/query/domain/JodaTimeSupportTest.java deleted file mode 100644 index 02e1af7691..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/JodaTimeSupportTest.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.domain; - -import org.joda.time.DateMidnight; -import org.joda.time.DateTime; -import org.joda.time.Instant; -import org.joda.time.LocalDate; -import org.joda.time.LocalDateTime; -import org.joda.time.LocalTime; -import org.joda.time.Partial; -import org.junit.Test; - -import com.mysema.query.annotations.QueryEntity; -import com.mysema.query.types.path.ComparablePath; -import com.mysema.query.types.path.DatePath; -import com.mysema.query.types.path.DateTimePath; -import com.mysema.query.types.path.TimePath; - -public class JodaTimeSupportTest extends AbstractTest { - - @QueryEntity - public static class JodaTimeSupport { - - DateMidnight dateMidnight; - - DateTime dateTime; - - Instant instant; - - LocalDate localDate; - - LocalDateTime localDateTime; - - LocalTime localTime; - - Partial partial; - - } - - @Test - public void test() throws SecurityException, NoSuchFieldException { - cl = QJodaTimeSupportTest_JodaTimeSupport.class; - match(DateTimePath.class, "dateMidnight"); - match(DateTimePath.class, "dateTime"); - match(DateTimePath.class, "instant"); - match(DatePath.class, "localDate"); - match(DateTimePath.class, "localDateTime"); - match(TimePath.class, "localTime"); - match(ComparablePath.class, "partial"); - } -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/Location.java b/querydsl-apt/src/test/java/com/mysema/query/domain/Location.java deleted file mode 100644 index 46bf140afe..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/Location.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.mysema.query.domain; - -import java.util.Set; - -import javax.persistence.Entity; - -@Entity -public class Location { - - public Set paths; -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/ManyToManyTest.java b/querydsl-apt/src/test/java/com/mysema/query/domain/ManyToManyTest.java deleted file mode 100644 index 49753dfe23..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/ManyToManyTest.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.mysema.query.domain; - -import static org.junit.Assert.assertEquals; - -import java.util.Set; - -import javax.persistence.Entity; -import javax.persistence.ManyToMany; - -import org.junit.Test; - -public class ManyToManyTest { - - public interface PhoneNumber { - - } - - @Entity - public static class PhoneNumberImpl { - - } - - @Entity - public static class Person { - - @ManyToMany(targetEntity=PhoneNumberImpl.class) - Set phones; - } - - @Test - public void test() { - assertEquals(PhoneNumberImpl.class, QManyToManyTest_Person.person.phones.getElementType()); - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/MonitoredCompany.java b/querydsl-apt/src/test/java/com/mysema/query/domain/MonitoredCompany.java deleted file mode 100644 index 5dc4c69d31..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/MonitoredCompany.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.mysema.query.domain; - -import com.mysema.query.annotations.QueryEntity; -import com.mysema.query.annotations.QueryInit; - -@QueryEntity -public class MonitoredCompany { - - private Long key; - - @QueryInit("mainCompany") - private CompanyGroup companyGroup; - - public Long getKey() { - return key; - } - - public void setKey(final Long aKey) { - this.key = aKey; - } - - public CompanyGroup getCompanyGroup() { - return companyGroup; - } - - public void setCompanyGroup(CompanyGroup aCompanyGroup) { - this.companyGroup = aCompanyGroup; - } - -} \ No newline at end of file diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/MonitoredCompanyTest.java b/querydsl-apt/src/test/java/com/mysema/query/domain/MonitoredCompanyTest.java deleted file mode 100644 index e27310cd1a..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/MonitoredCompanyTest.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.mysema.query.domain; - -import static org.junit.Assert.*; - -import org.junit.Test; - -public class MonitoredCompanyTest { - - @Test - public void test() { - QMonitoredCompany monitoredCompany = QMonitoredCompany.monitoredCompany; - assertNotNull(monitoredCompany.companyGroup); - assertNotNull(monitoredCompany.companyGroup.mainCompany); - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/NumberTest.java b/querydsl-apt/src/test/java/com/mysema/query/domain/NumberTest.java deleted file mode 100644 index 9c506b269b..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/NumberTest.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.mysema.query.domain; - -import org.junit.Ignore; - -import com.mysema.query.annotations.QueryEntity; -import com.mysema.query.domain.custom.CustomNumber; - -@Ignore -public class NumberTest { - - @QueryEntity - public static class Entity { - - CustomNumber customNumber; - - } -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/OneToOneTest.java b/querydsl-apt/src/test/java/com/mysema/query/domain/OneToOneTest.java deleted file mode 100644 index a69b00a897..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/OneToOneTest.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.mysema.query.domain; - -import javax.persistence.Entity; -import javax.persistence.OneToOne; - -import org.junit.Test; -import static org.junit.Assert.assertEquals; - -public class OneToOneTest { - - public interface PhoneNumber { - - } - - @Entity - public static class PhoneNumberImpl { - - } - - @Entity - public static class Person { - - @OneToOne(targetEntity=PhoneNumberImpl.class) - PhoneNumber phone; - } - - @Test - public void test() { - assertEquals(PhoneNumberImpl.class, QOneToOneTest_Person.person.phone.getType()); - } -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/OrderTest.java b/querydsl-apt/src/test/java/com/mysema/query/domain/OrderTest.java deleted file mode 100644 index 1b9fc1a976..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/OrderTest.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.mysema.query.domain; - -import static org.junit.Assert.assertEquals; - -import java.util.List; - -import javax.persistence.Entity; -import javax.persistence.OneToMany; - -import org.junit.Test; - -public class OrderTest { - - @Entity - public static class Order { - @OneToMany(targetEntity = OrderItemImpl.class) - List orderItems; - } - - @Entity - public interface OrderItem { } - - @Entity - public static class OrderItemImpl implements OrderItem { } - - @Test - public void test() { - assertEquals(QOrderTest_OrderItemImpl.class, - QOrderTest_Order.order.orderItems.any().getClass()); - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/Path.java b/querydsl-apt/src/test/java/com/mysema/query/domain/Path.java deleted file mode 100644 index f2884af7fb..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/Path.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.mysema.query.domain; - -import javax.persistence.Entity; - -@Entity -public class Path { - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/PathInits.java b/querydsl-apt/src/test/java/com/mysema/query/domain/PathInits.java deleted file mode 100644 index 9276736a55..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/PathInits.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.mysema.query.domain; - -public class PathInits { - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/PathMetadata.java b/querydsl-apt/src/test/java/com/mysema/query/domain/PathMetadata.java deleted file mode 100644 index c239e009b1..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/PathMetadata.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.mysema.query.domain; - -public class PathMetadata { - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/PathTest.java b/querydsl-apt/src/test/java/com/mysema/query/domain/PathTest.java deleted file mode 100644 index d6c82ce594..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/PathTest.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.mysema.query.domain; - -import static org.junit.Assert.*; - -import org.junit.Test; - -public class PathTest { - - @Test - public void test() { - assertEquals(Path.class, QPath.path.getType()); - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/Person.java b/querydsl-apt/src/test/java/com/mysema/query/domain/Person.java deleted file mode 100644 index 349325ea7c..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/Person.java +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.domain; - -import java.io.Serializable; -import javax.persistence.Basic; -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.NamedQueries; -import javax.persistence.NamedQuery; -import javax.persistence.OneToOne; -import javax.persistence.Table; -import javax.xml.bind.annotation.XmlRootElement; - -/** - * - * @author Arash - */ -@Entity -@Table(name = "Person", catalog = "TestDB", schema = "dbo") -@XmlRootElement -@NamedQueries({ - @NamedQuery(name = "Person.findAll", query = "SELECT p FROM Person p"), - @NamedQuery(name = "Person.findByPersonId", query = "SELECT p FROM Person p WHERE p.personId = :personId"), - @NamedQuery(name = "Person.findByPersonName", query = "SELECT p FROM Person p WHERE p.personName = :personName"), - @NamedQuery(name = "Person.findByPersonFamily", query = "SELECT p FROM Person p WHERE p.personFamily = :personFamily"), - @NamedQuery(name = "Person.findByPersonReference", query = "SELECT p FROM Person p WHERE p.personReference = :personReference")}) -public class Person implements Serializable { - private static final long serialVersionUID = 1L; - @Id - @Basic(optional = false) - @Column(name = "person_id", nullable = false) - private Integer personId; - - @Column(name = "person_name", length = 50) - private String personName; - - @Column(name = "person_family", length = 50) - private String personFamily; - - @Column(name = "person_reference") - - private Integer personReference; - @OneToOne(cascade = CascadeType.ALL, mappedBy = "person1", fetch = FetchType.LAZY) - - private Person person; - @JoinColumn(name = "person_id", referencedColumnName = "person_id", nullable = false, insertable = false, updatable = false) - @OneToOne(optional = false, fetch = FetchType.LAZY) - - private Person person1; - - public Person() { - } - - public Person(Integer personId) { - this.personId = personId; - } - - public Integer getPersonId() { - return personId; - } - - public void setPersonId(Integer personId) { - this.personId = personId; - } - - public String getPersonName() { - return personName; - } - - public void setPersonName(String personName) { - this.personName = personName; - } - - public String getPersonFamily() { - return personFamily; - } - - public void setPersonFamily(String personFamily) { - this.personFamily = personFamily; - } - - public Integer getPersonReference() { - return personReference; - } - - public void setPersonReference(Integer personReference) { - this.personReference = personReference; - } - - public Person getPerson() { - return person; - } - - public void setPerson(Person person) { - this.person = person; - } - - public Person getPerson1() { - return person1; - } - - public void setPerson1(Person person1) { - this.person1 = person1; - } - - @Override - public int hashCode() { - int hash = 0; - hash += (personId != null ? personId.hashCode() : 0); - return hash; - } - - @Override - public boolean equals(Object object) { - // TODO: Warning - this method won't work in the case the id fields are not set - if (!(object instanceof Person)) { - return false; - } - Person other = (Person) object; - if ((this.personId == null && other.personId != null) || (this.personId != null && !this.personId.equals(other.personId))) { - return false; - } - return true; - } - - @Override - public String toString() { - return "newpackage.Person[ personId=" + personId + " ]"; - } - - - -} \ No newline at end of file diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/PropertiesTest.java b/querydsl-apt/src/test/java/com/mysema/query/domain/PropertiesTest.java deleted file mode 100644 index 0679950e3c..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/PropertiesTest.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.domain; - -import static org.junit.Assert.*; - -import java.util.ArrayList; -import java.util.Date; -import java.util.List; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.OneToMany; -import javax.persistence.Table; -import javax.persistence.Temporal; -import javax.persistence.TemporalType; - -import org.junit.Test; - -public class PropertiesTest { - - @Entity - public static abstract class AbstractEntity { - - } - - @Entity - @Table(name = "Customer") - public static class Customer extends AbstractEntity { - - private String name; - private List pizzas = new ArrayList(0); - - @Column - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - @OneToMany(mappedBy = "customer") - public List getPizzas() { - return pizzas; - } - - public void setPizzas(List pizzas) { - this.pizzas = pizzas; - } - } - - @Entity - @Table(name = "Pizza") - public static class Pizza extends AbstractEntity { - - private Date orderTime; - private Customer customer; - private List toppings = new ArrayList(0); - - @Column @Temporal(TemporalType.TIMESTAMP) - public Date getOrderTime() { - return new Date(orderTime.getTime()); - } - - public void setOrderTime(Date orderTime) { - this.orderTime = new Date(orderTime.getTime()); - } - - @ManyToOne - @JoinColumn(name = "customerId") - public Customer getCustomer() { - return customer; - } - - public void setCustomer(Customer customer) { - this.customer = customer; - } - - @OneToMany(mappedBy = "pizza") - public List getToppings() { - return toppings; - } - - public void setToppings(List toppings) { - this.toppings = toppings; - } - } - - @Entity - public static class Topping { - - } - - @Test - public void Customer() { - assertNotNull(QPropertiesTest_Customer.customer.name); - assertNotNull(QPropertiesTest_Customer.customer.pizzas); - } - - @Test - public void Pizza() { - assertNotNull(QPropertiesTest_Pizza.pizza.orderTime); - assertNotNull(QPropertiesTest_Pizza.pizza.customer); - assertNotNull(QPropertiesTest_Pizza.pizza.toppings); - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/PropertyTypeTest.java b/querydsl-apt/src/test/java/com/mysema/query/domain/PropertyTypeTest.java deleted file mode 100644 index 6e419f0b61..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/PropertyTypeTest.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.domain; - -import org.junit.Ignore; -import org.junit.Test; - -import com.mysema.query.annotations.PropertyType; -import com.mysema.query.annotations.QueryEntity; -import com.mysema.query.annotations.QueryType; - -@Ignore -public class PropertyTypeTest { - - @QueryEntity - public static class Entity { - - @QueryType(PropertyType.STRING) - Integer numberAsString; - - } - - @Test - public void NumberAsString_Like() { - QPropertyTypeTest_Entity.entity.numberAsString.like("a"); - } -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/QueryByExampleTest.java b/querydsl-apt/src/test/java/com/mysema/query/domain/QueryByExampleTest.java deleted file mode 100644 index 4c3df131cb..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/QueryByExampleTest.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.mysema.query.domain; - -import static org.junit.Assert.*; - -import org.junit.Test; - -import com.mysema.query.annotations.QueryDelegate; -import com.mysema.query.types.Predicate; - - -public class QueryByExampleTest { - - @QueryDelegate(ExampleEntity.class) - public static Predicate like(QExampleEntity qtype, ExampleEntity example) { - return example.name != null ? qtype.name.eq(example.name) : null; - } - - @Test - public void Name_Not_Set() { - ExampleEntity entity = new ExampleEntity(); - Predicate qbe = QExampleEntity.exampleEntity.like(entity); - assertNull(qbe); - } - - @Test - public void Name_Set() { - ExampleEntity entity = new ExampleEntity(); - entity.name = "XXX"; - Predicate qbe = QExampleEntity.exampleEntity.like(entity); - assertEquals("exampleEntity.name = XXX", qbe.toString()); - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/QueryEmbeddable2Test.java b/querydsl-apt/src/test/java/com/mysema/query/domain/QueryEmbeddable2Test.java deleted file mode 100644 index 297dd9a182..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/QueryEmbeddable2Test.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.domain; - -import static org.junit.Assert.assertNotNull; - -import org.junit.Test; - -import com.mysema.query.annotations.QueryEmbeddable; -import com.mysema.query.annotations.QueryEntity; - -public class QueryEmbeddable2Test { - - @QueryEntity - public static class User { - - Complex complex; - } - - @QueryEmbeddable - public static class Complex> implements Comparable> { - - T a; - - @Override - public int compareTo(Complex arg0) { - return 0; - } - - public boolean equals(Object o) { - return o == this; - } - - } - - @Test - public void User_Complex_a() { - assertNotNull(QQueryEmbeddable2Test_User.user.complex.a); - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/QueryEmbedded6Test.java b/querydsl-apt/src/test/java/com/mysema/query/domain/QueryEmbedded6Test.java deleted file mode 100644 index deee753cce..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/QueryEmbedded6Test.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.domain; - -import static org.junit.Assert.assertEquals; - -import java.util.List; - -import org.junit.Test; - -import com.mysema.query.annotations.QueryEmbedded; -import com.mysema.query.annotations.QueryEntity; -import com.mysema.query.types.path.EntityPathBase; - -public class QueryEmbedded6Test { - - @QueryEntity - public static class User { - - @QueryEmbedded - List list; - - } - - @Test - public void EntityPathBase_is_SuperClass() { - assertEquals(EntityPathBase.class, QQueryEmbedded6Test_User.class.getSuperclass()); - } - - @Test - public void User_list_any() { - assertEquals(QQueryEmbedded6Test_User.class, QQueryEmbedded6Test_User.user.list.any().getClass()); - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/QueryEmbedded7Test.java b/querydsl-apt/src/test/java/com/mysema/query/domain/QueryEmbedded7Test.java deleted file mode 100644 index de19c6efc1..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/QueryEmbedded7Test.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.mysema.query.domain; - -import static org.junit.Assert.assertEquals; - -import java.util.Collection; -import java.util.Locale; -import java.util.Set; - -import org.junit.Test; - -import com.mysema.query.annotations.QueryEmbedded; -import com.mysema.query.annotations.QueryEntity; -import com.mysema.query.types.path.NumberPath; -import com.mysema.query.types.path.StringPath; - -public class QueryEmbedded7Test { - - @QueryEntity - static class Entity { - - @QueryEmbedded - Collection users; - - @QueryEmbedded - Set productRoles; - - // misuse, but shouldn't cause problems - @QueryEmbedded - Locale locale; - - // misuse, but shouldn't cause problems - @QueryEmbedded - String string; - - } - - @Test - public void test() { - assertEquals(StringPath.class, QQueryEmbedded7Test_Entity.entity.users.any().getClass()); - assertEquals(NumberPath.class, QQueryEmbedded7Test_Entity.entity.productRoles.any().getClass()); - } -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/QueryExcludeTest.java b/querydsl-apt/src/test/java/com/mysema/query/domain/QueryExcludeTest.java deleted file mode 100644 index c085f9af9a..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/QueryExcludeTest.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.domain; - -import static org.junit.Assert.*; - -import org.junit.Test; - -import com.mysema.query.annotations.QueryEntity; -import com.mysema.query.annotations.QueryExclude; -import com.mysema.query.types.path.EntityPathBase; - -public class QueryExcludeTest { - - @QueryExclude - @QueryEntity - public static class Entity { - - } - - @QueryEntity - public static class SubEntity extends Entity { - - } - - @Test - public void SubEntity() { - assertEquals(EntityPathBase.class, QQueryExcludeTest_SubEntity.class.getSuperclass()); - } - - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/QueryTypeOverTransientTest.java b/querydsl-apt/src/test/java/com/mysema/query/domain/QueryTypeOverTransientTest.java deleted file mode 100644 index 00dc7a7c64..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/QueryTypeOverTransientTest.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.domain; - -import static org.junit.Assert.assertNotNull; - -import org.junit.Test; - -import com.mysema.query.annotations.PropertyType; -import com.mysema.query.annotations.QueryEntity; -import com.mysema.query.annotations.QueryTransient; -import com.mysema.query.annotations.QueryType; - -public class QueryTypeOverTransientTest { - - @QueryEntity - public static class Entity { - - @QueryType(PropertyType.ENTITY) - @QueryTransient - Entity reference; - - } - - @QueryEntity - public static abstract class Entity2 { - - @QueryType(PropertyType.ENTITY) - @QueryTransient - public abstract Entity getReference(); - - } - - @Test - public void Entity_Reference_Is_Available() { - assertNotNull(QQueryTypeOverTransientTest_Entity.entity.reference); - } - - @Test - public void Entity2_Reference_Is_Available() { - assertNotNull(QQueryTypeOverTransientTest_Entity2.entity2.reference); - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/QueryTypeTest.java b/querydsl-apt/src/test/java/com/mysema/query/domain/QueryTypeTest.java deleted file mode 100644 index 162f8e4bc6..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/QueryTypeTest.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.domain; - -import org.junit.Test; - -import com.mysema.query.annotations.PropertyType; -import com.mysema.query.annotations.QueryEntity; -import com.mysema.query.annotations.QueryType; -import com.mysema.query.types.path.ComparablePath; -import com.mysema.query.types.path.DatePath; -import com.mysema.query.types.path.DateTimePath; -import com.mysema.query.types.path.SimplePath; -import com.mysema.query.types.path.TimePath; - -public class QueryTypeTest extends AbstractTest { - - @QueryEntity - public static class QueryTypeEntity { - @QueryType(PropertyType.SIMPLE) - public String stringAsSimple; - - @QueryType(PropertyType.COMPARABLE) - public String stringAsComparable; - - @QueryType(PropertyType.DATE) - public String stringAsDate; - - @QueryType(PropertyType.DATETIME) - public String stringAsDateTime; - - @QueryType(PropertyType.TIME) - public String stringAsTime; - - @QueryType(PropertyType.NONE) - public String stringNotInQuerydsl; - - } - - @Test - public void test() throws SecurityException, NoSuchFieldException{ - cl = QQueryTypeTest_QueryTypeEntity.class; - match(SimplePath.class, "stringAsSimple"); - match(ComparablePath.class, "stringAsComparable"); - match(DatePath.class, "stringAsDate"); - match(DateTimePath.class, "stringAsDateTime"); - match(TimePath.class, "stringAsTime"); - } -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/QuerydslConfig2Test.java b/querydsl-apt/src/test/java/com/mysema/query/domain/QuerydslConfig2Test.java deleted file mode 100644 index a90cf6c678..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/QuerydslConfig2Test.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.domain; - -import static org.junit.Assert.assertNotNull; - -import org.junit.Test; - -import com.mysema.query.annotations.QueryEntity; -import com.mysema.query.annotations.Config; - -public class QuerydslConfig2Test { - - @Config(entityAccessors=true) - @QueryEntity - public static class Entity extends Superclass { - - Entity prop1; - - } - - @Config(createDefaultVariable=false) - @QueryEntity - public static class Entity2 extends Superclass2 { - - Entity prop1; - - } - - @QueryEntity - public static class Superclass { - - Entity prop2; - } - - @Config(entityAccessors=true) - @QueryEntity - public static class Superclass2 { - - Entity prop2; - } - - @Test - public void test() { - assertNotNull(QQuerydslConfig2Test_Entity.entity); - } - - @Test(expected=NoSuchFieldException.class) - public void Create_Default_Variable() throws SecurityException, NoSuchFieldException { - QQuerydslConfig2Test_Entity2.class.getField("entity2"); - } -} - diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/RawTest.java b/querydsl-apt/src/test/java/com/mysema/query/domain/RawTest.java deleted file mode 100644 index 18724f8ef4..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/RawTest.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.mysema.query.domain; - -import org.junit.Test; - -import com.mysema.query.annotations.QueryEntity; -import com.mysema.query.annotations.QuerySupertype; - -public class RawTest { - - @QuerySupertype - public static class SuperClass> { - - public String property; - - } - - @SuppressWarnings("rawtypes") - @QueryEntity - public static class Entity extends SuperClass { - - public String property2; - } - - @Test - public void test() { - - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/RooEntitiesTest.java b/querydsl-apt/src/test/java/com/mysema/query/domain/RooEntitiesTest.java deleted file mode 100644 index cafdf99011..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/RooEntitiesTest.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.mysema.query.domain; - -import static org.junit.Assert.assertNotNull; - -import org.junit.Test; - -public class RooEntitiesTest { - - @Test - public void RooJpaEntity() { - assertNotNull(QRooEntities_MyEntity.myEntity); - } - - @Test - public void RooJpaActiveRecord() { - assertNotNull(QRooEntities_MyEntity2.myEntity2); - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/SecurableEntity.java b/querydsl-apt/src/test/java/com/mysema/query/domain/SecurableEntity.java deleted file mode 100644 index 143ecc4cf2..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/SecurableEntity.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.mysema.query.domain; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.TableGenerator; - -/** - * This is an example of using system ACL function. Note, field id is must, - * abstract function getId must also implemented. - */ -@Entity -public class SecurableEntity extends AbstractSecurable { - - private static final long serialVersionUID = 3197097608363811501L; - - @Id - @TableGenerator(name = "SECUREENTITY_SEQ", allocationSize = 1) - @GeneratedValue(strategy = GenerationType.TABLE, generator = "SECUREENTITY_SEQ") - private Long securableEntityId; - - @Column(length = 50) - private String name; - - // public Long getId() { - // return getSecurableEntityId(); - // } - -} \ No newline at end of file diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/SignatureTest.java b/querydsl-apt/src/test/java/com/mysema/query/domain/SignatureTest.java deleted file mode 100644 index 54bee4f463..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/SignatureTest.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.domain; - -import static org.junit.Assert.*; - -import java.io.Serializable; - -import org.junit.Test; - -import com.mysema.query.annotations.QuerySupertype; -import com.mysema.query.types.path.ComparablePath; - -public class SignatureTest { - - @QuerySupertype - public static abstract class APropertyChangeSupported implements Comparable, Cloneable, Serializable { - - } - - @QuerySupertype - public static abstract class AValueObject extends APropertyChangeSupported implements Comparable, Cloneable, Serializable { - - } - - @Test - public void APropertyChangeSupported() { - assertEquals(ComparablePath.class, QSignatureTest_APropertyChangeSupported.class.getSuperclass()); - } - - @Test - public void AValueObject() { - assertEquals(ComparablePath.class, QSignatureTest_AValueObject.class.getSuperclass()); - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/SimpleTypesTest.java b/querydsl-apt/src/test/java/com/mysema/query/domain/SimpleTypesTest.java deleted file mode 100644 index e4faa94e3b..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/SimpleTypesTest.java +++ /dev/null @@ -1,339 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.domain; - -import java.io.Serializable; -import java.math.BigDecimal; -import java.math.BigInteger; -import java.sql.Time; -import java.util.Calendar; -import java.util.Date; -import java.util.List; -import java.util.Locale; - -import org.junit.Test; - -import com.mysema.query.annotations.Config; -import com.mysema.query.annotations.PropertyType; -import com.mysema.query.annotations.QueryEntity; -import com.mysema.query.annotations.QueryTransient; -import com.mysema.query.annotations.QueryType; -import com.mysema.query.types.path.ComparablePath; -import com.mysema.query.types.path.DateTimePath; -import com.mysema.query.types.path.EnumPath; -import com.mysema.query.types.path.NumberPath; -import com.mysema.query.types.path.SimplePath; -import com.mysema.query.types.path.StringPath; -import com.mysema.query.types.path.TimePath; - -public class SimpleTypesTest extends AbstractTest { - - public enum MyEnum { - VAL1, - VAL2 - } - - public static class CustomLiteral { - - } - - @SuppressWarnings("serial") - public static class CustomNumber extends Number { - - @Override - public double doubleValue() { - return 0; - } - - @Override - public float floatValue() { - return 0; - } - - @Override - public int intValue() { - return 0; - } - - @Override - public long longValue() { - return 0; - } - - } - - public static class CustomComparableNumber extends CustomNumber implements Comparable { - - private static final long serialVersionUID = 4398583038967396133L; - - @Override - public int compareTo(CustomComparableNumber o) { - return 0; - } - - @Override - public int hashCode() { - return super.hashCode(); - } - - @Override - public boolean equals(Object o) { - return o instanceof CustomComparableNumber; - } - } - - public static class CustomComparableLiteral implements Comparable { - - @Override - public int compareTo(CustomComparableLiteral o) { - return 0; - } - - @Override - public int hashCode() { - return super.hashCode(); - } - - @Override - public boolean equals(Object o) { - return o instanceof CustomComparableLiteral; - } - } - - public static class CustomGenericComparableLiteral implements Comparable { - - @Override - public int compareTo(CustomComparableLiteral o) { - return 0; - } - - @Override - public int hashCode() { - return super.hashCode(); - } - - @Override - public boolean equals(Object o) { - return o instanceof CustomGenericComparableLiteral; - } - } - - @QueryEntity - @Config(listAccessors=true) - public static class SimpleTypes { - transient int test; - List testList; - - Calendar calendar; - List calendarList; - - long id; - List idList; - - BigDecimal bigDecimal; - List bigDecimalList; - - Byte bbyte; - List bbyteList; - byte bbyte2; - - Short sshort; - List sshortList; - short sshort2; - - Character cchar; - List ccharList; - char cchar2; - - Double ddouble; - List ddoubleList; - double ddouble2; - - Float ffloat; - List ffloatList; - float ffloat2; - - Integer iint; - List iintList; - int iint2; - - Locale llocale; - List llocaleList; - - Long llong; - List llongList; - long llong2; - - BigInteger bigInteger; - - String sstring; - List sstringList; - - Date date; - List dateList; - - java.sql.Time time; - List timeList; - - java.sql.Timestamp timestamp; - List timestampList; - - Serializable serializable; - List serializableList; - - Object object; - List objectList; - - Class clazz; - List classList2; - List> classList3; - List> classList4; - List> classList5; - - Package packageAsLiteral; - List packageAsLiteralList; - - CustomLiteral customLiteral; - List customLiteralList; - - CustomComparableLiteral customComparableLiteral; - List customComparableLiteralList; - - CustomNumber customNumber; - List customNumberList; - - CustomComparableNumber customComparableNumber; - List customComparableNumber2; - - CustomGenericComparableLiteral customComparableLiteral2; - List customComparableLiteral2List; - - CustomGenericComparableLiteral customComparableLiteral3; - List> customComparableLiteral3List; - - java.sql.Clob clob; - List clobList; - - java.sql.Blob blob; - List blobList; - - @QueryTransient - String skipMe; - - MyEnum myEnum; - - int[] intArray; - byte[] byteArray; - long[] longArray; - float[] floatArray; - double[] doubleArray; - short[] shortArray; - - @QueryType(PropertyType.SIMPLE) - byte[] byteArrayAsSimple; - } - - @Test - public void List_Access() { - // date / time - QSimpleTypesTest_SimpleTypes.simpleTypes.dateList.get(0).after(new Date()); - QSimpleTypesTest_SimpleTypes.simpleTypes.timeList.get(0).after(new Time(0l)); - QSimpleTypesTest_SimpleTypes.simpleTypes.calendarList.get(0).before(Calendar.getInstance()); - - // numeric - QSimpleTypesTest_SimpleTypes.simpleTypes.bbyteList.get(0).abs(); - - // string - QSimpleTypesTest_SimpleTypes.simpleTypes.sstringList.get(0).toLowerCase(); - - // boolean -// QSimpleTypes.simpleTypes.b - - } - - @Test - public void Simple_Types() throws SecurityException, NoSuchFieldException { - cl = QSimpleTypesTest_SimpleTypes.class; - match(NumberPath.class, "id"); - match(NumberPath.class, "bigDecimal"); - match(NumberPath.class, "bigInteger"); -// match(PNumber.class, "bbyte"); - match(NumberPath.class, "bbyte2"); - match(NumberPath.class, "ddouble"); - match(NumberPath.class, "ddouble2"); - match(NumberPath.class, "ffloat"); - match(NumberPath.class, "ffloat2"); -// match(PNumber.class, "iint"); - match(NumberPath.class, "iint2"); - match(NumberPath.class, "llong"); - match(NumberPath.class, "llong2"); - - match(ComparablePath.class, "cchar"); - match(ComparablePath.class, "cchar2"); - - match(StringPath.class, "sstring"); - - match(DateTimePath.class, "date"); - match(DateTimePath.class, "calendar"); -// match(PDateTime.class, "timestamp"); - - match(TimePath.class, "time"); - - match(SimplePath.class, "llocale"); - match(SimplePath.class, "serializable"); - match(SimplePath.class, "object"); - match(SimplePath.class, "clazz"); - match(SimplePath.class, "packageAsLiteral"); - - match(SimplePath.class, "clob"); - match(SimplePath.class, "blob"); - - match(EnumPath.class, "myEnum"); - } - - @Test - public void Custom_Literal() throws SecurityException, NoSuchFieldException { - cl = QSimpleTypesTest_SimpleTypes.class; - match(SimplePath.class, "customLiteral"); - } - - @Test - public void Custom_ComparableLiteral() throws SecurityException, NoSuchFieldException { - cl = QSimpleTypesTest_SimpleTypes.class; - match(ComparablePath.class, "customComparableLiteral"); - } - - @Test - public void Custom_Number() throws SecurityException, NoSuchFieldException { - cl = QSimpleTypesTest_SimpleTypes.class; - match(SimplePath.class, "customNumber"); - } - - @Test - public void Custom_ComparableNumber() throws SecurityException, NoSuchFieldException { - cl = QSimpleTypesTest_SimpleTypes.class; - match(NumberPath.class, "customComparableNumber"); - } - - @Test(expected=NoSuchFieldException.class) - public void Skipped_Field1() throws SecurityException, NoSuchFieldException { - QSimpleTypesTest_SimpleTypes.class.getField("skipMe"); - } - - @Test(expected=NoSuchFieldException.class) - public void Skipped_Field2() throws SecurityException, NoSuchFieldException { - QSimpleTypesTest_SimpleTypes.class.getField("test"); - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/SubCat.java b/querydsl-apt/src/test/java/com/mysema/query/domain/SubCat.java deleted file mode 100644 index 31dadb8a15..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/SubCat.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.mysema.query.domain; - -public class SubCat { - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/Subclass.java b/querydsl-apt/src/test/java/com/mysema/query/domain/Subclass.java deleted file mode 100644 index a779d0b6d2..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/Subclass.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.mysema.query.domain; - -import com.mysema.query.annotations.QueryEntity; - -@QueryEntity -public class Subclass extends com.mysema.query.domain.Superclass { - - private int number; - - public int getNumber() { - return number; - } - - public void setNumber(int number) { - this.number = number; - } - - -} \ No newline at end of file diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/Temporal2Test.java b/querydsl-apt/src/test/java/com/mysema/query/domain/Temporal2Test.java deleted file mode 100644 index 489d5d0275..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/Temporal2Test.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.mysema.query.domain; - -import java.math.BigDecimal; -import java.util.Date; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Temporal; -import javax.persistence.TemporalType; - -import org.junit.Test; - -import com.mysema.query.annotations.QueryProjection; -import com.mysema.query.types.path.DatePath; -import com.mysema.query.types.path.NumberPath; - -public class Temporal2Test { - - @Entity - public static class Cheque { - @Temporal(TemporalType.DATE) - private Date dataVencimento; - - @Column(precision=15, scale=2) - private BigDecimal valor; - - @QueryProjection - public Cheque(Date param0, BigDecimal param1) { - this.dataVencimento = param0; - this.valor = param1; - } - - } - - @Test - public void test() { - DatePath datePath = new DatePath(Date.class, "date"); - NumberPath numberPath = new NumberPath(BigDecimal.class, "num"); - new QTemporal2Test_Cheque(datePath, numberPath); - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/TemporalTest.java b/querydsl-apt/src/test/java/com/mysema/query/domain/TemporalTest.java deleted file mode 100644 index d9190c7b73..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/TemporalTest.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.mysema.query.domain; - -import static org.junit.Assert.*; - -import java.util.Date; - -import javax.persistence.Entity; -import javax.persistence.Temporal; -import javax.persistence.TemporalType; - -import org.junit.Test; - -import com.mysema.query.types.path.DatePath; -import com.mysema.query.types.path.TimePath; - -public class TemporalTest { - - @Entity - public static class MyEntity { - - @Temporal(value=TemporalType.DATE) - private Date date; - - @Temporal(value=TemporalType.TIME) - private Date time; - } - - @Test - public void test() { - assertEquals(DatePath.class, QTemporalTest_MyEntity.myEntity.date.getClass()); - assertEquals(TimePath.class, QTemporalTest_MyEntity.myEntity.time.getClass()); - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/custom/EmbeddedType.java b/querydsl-apt/src/test/java/com/mysema/query/domain/custom/EmbeddedType.java deleted file mode 100644 index a454a1b3a3..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/custom/EmbeddedType.java +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.domain.custom; - -public class EmbeddedType { - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/custom/Entity.java b/querydsl-apt/src/test/java/com/mysema/query/domain/custom/Entity.java deleted file mode 100644 index b29b4d4020..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/custom/Entity.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.domain.custom; - -import java.util.List; -import java.util.Map; - -import com.mysema.query.annotations.QueryEntity; - -@QueryEntity -public class Entity { - - List list; - - EmbeddedType2 embedded; - - Map map; - - String stringProperty; - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/p1/SEntity1.java b/querydsl-apt/src/test/java/com/mysema/query/domain/p1/SEntity1.java deleted file mode 100644 index b2595329d6..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/p1/SEntity1.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.domain.p1; - -import com.mysema.query.annotations.QueryEntity; - -@QueryEntity -public class SEntity1 { - - String entity1Field; -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/p10/Persistable.java b/querydsl-apt/src/test/java/com/mysema/query/domain/p10/Persistable.java deleted file mode 100644 index ddf50c046a..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/p10/Persistable.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.mysema.query.domain.p10; - -public interface Persistable { - -} \ No newline at end of file diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/p10/UpdateInfo.java b/querydsl-apt/src/test/java/com/mysema/query/domain/p10/UpdateInfo.java deleted file mode 100644 index 6dd02e6089..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/p10/UpdateInfo.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.mysema.query.domain.p10; - -public interface UpdateInfo { - -} \ No newline at end of file diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/p6/TypeTest.java b/querydsl-apt/src/test/java/com/mysema/query/domain/p6/TypeTest.java deleted file mode 100644 index 622b18fecf..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/p6/TypeTest.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.domain.p6; - -import static org.junit.Assert.*; - -import org.junit.Test; - -public class TypeTest { - - @Test - public void test() { - QType1 type1 = QType1.type1; - QType2 type2 = QType2.type2; - assertEquals(type2.getType(), type1.property.getType()); - assertEquals(type2.getClass(), type1.property.getClass()); - } -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/p6/package-info.java b/querydsl-apt/src/test/java/com/mysema/query/domain/p6/package-info.java deleted file mode 100644 index 86ebd83346..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/p6/package-info.java +++ /dev/null @@ -1,5 +0,0 @@ -@QueryEntities({Type1.class, Type2.class}) -package com.mysema.query.domain.p6; - - -import com.mysema.query.annotations.*; \ No newline at end of file diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/p7/MyEntity.java b/querydsl-apt/src/test/java/com/mysema/query/domain/p7/MyEntity.java deleted file mode 100644 index a7953bc120..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/p7/MyEntity.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.mysema.query.domain.p7; - -import javax.persistence.Entity; - -@Entity -public class MyEntity { - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/p8/Custom.java b/querydsl-apt/src/test/java/com/mysema/query/domain/p8/Custom.java deleted file mode 100644 index 821c7a8bef..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/p8/Custom.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.mysema.query.domain.p8; - -public class Custom { - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/p8/Entity.java b/querydsl-apt/src/test/java/com/mysema/query/domain/p8/Entity.java deleted file mode 100644 index 662939f914..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/p8/Entity.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.mysema.query.domain.p8; - -import com.mysema.query.annotations.QueryEntity; - -@QueryEntity -public class Entity { - - private Long id; - - private Custom custom; - - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public Custom getCustom() { - return custom; - } - - public void setCustom(Custom custom) { - this.custom = custom; - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/p9/Article.java b/querydsl-apt/src/test/java/com/mysema/query/domain/p9/Article.java deleted file mode 100644 index d8b9384e9c..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/p9/Article.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.mysema.query.domain.p9; - -import javax.persistence.Entity; - -@Entity -public class Article { - - String name; - - Content content; - - Person author; - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/p9/Content.java b/querydsl-apt/src/test/java/com/mysema/query/domain/p9/Content.java deleted file mode 100644 index ed9a566a02..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/p9/Content.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.mysema.query.domain.p9; - -import javax.persistence.Embeddable; - -@Embeddable -public class Content { - - Article article; - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/p9/Person.java b/querydsl-apt/src/test/java/com/mysema/query/domain/p9/Person.java deleted file mode 100644 index 1c05c44e24..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/p9/Person.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.mysema.query.domain.p9; - -import javax.persistence.Entity; - -@Entity -public class Person { - - String firstName, lastName; -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/package-info.java b/querydsl-apt/src/test/java/com/mysema/query/domain/package-info.java deleted file mode 100644 index 06be2c671d..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/package-info.java +++ /dev/null @@ -1,7 +0,0 @@ -@QueryEntities({A.class, Tenant.class, DefaultRevisionEntity.class, Delegate3Test.Point.class, Delegate3Test.Polygon.class}) -package com.mysema.query.domain; - -import org.hibernate.envers.DefaultRevisionEntity; - -import com.mysema.query.annotations.QueryEntities; - diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/rel/SimpleType.java b/querydsl-apt/src/test/java/com/mysema/query/domain/rel/SimpleType.java deleted file mode 100644 index 9bca2db8de..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/rel/SimpleType.java +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.domain.rel; - -public class SimpleType { - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain2/BImpl.java b/querydsl-apt/src/test/java/com/mysema/query/domain2/BImpl.java deleted file mode 100644 index b68b2af8f9..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/domain2/BImpl.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.mysema.query.domain2; - -import com.mysema.query.annotations.QueryEntity; - -@QueryEntity -public class BImpl extends AImpl { - -} \ No newline at end of file diff --git a/querydsl-apt/src/test/java/com/mysema/query/inheritance/Inheritance2Test.java b/querydsl-apt/src/test/java/com/mysema/query/inheritance/Inheritance2Test.java deleted file mode 100644 index 10b32348f5..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/inheritance/Inheritance2Test.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.inheritance; - -import org.junit.Ignore; - -import com.mysema.query.annotations.QueryEntity; - -@Ignore -public class Inheritance2Test { - - @QueryEntity - public abstract class Base> { - @SuppressWarnings("unchecked") - Base2 base; - Base2 base2; - } - - @QueryEntity - public abstract class Base2,U extends IFace> { - - } - - @QueryEntity - public abstract class BaseSub extends Base { - - } - - @QueryEntity - public abstract class BaseSub2> extends Base { - - } - - @QueryEntity - public abstract class Base2Sub extends Base2,T> { - - } - - public interface IFace { - - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/inheritance/Inheritance3Test.java b/querydsl-apt/src/test/java/com/mysema/query/inheritance/Inheritance3Test.java deleted file mode 100644 index aa8c35fd1d..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/inheritance/Inheritance3Test.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.inheritance; - -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.junit.Test; - -import com.mysema.query.annotations.QueryEntity; -import com.mysema.query.domain.AbstractTest; -import com.mysema.query.types.path.SimplePath; -import com.mysema.query.types.path.StringPath; - -public class Inheritance3Test extends AbstractTest { - - /* - * TODO : map type variables to BeanModels - */ - - @QueryEntity - public class GenericSupertype{ - A field; - Collection fieldCol; - Set fieldSet; - List fieldList; - Map fieldMap1; - Map fieldMap2; - - String stringField; - } - - @QueryEntity - public class GenericSupertypeC> extends GenericSupertype{ - - } - - @QueryEntity - public class GenericSupertypeS extends GenericSupertypeC{ - - } - - @QueryEntity - public class GenericSupertypeS2 extends GenericSupertype{ - - } - - @Test - public void GenericSupertype() throws SecurityException, NoSuchFieldException { - cl = QInheritance3Test_GenericSupertype.class; - match(SimplePath.class, "field"); - } - - @Test - public void GenericSupertypeC() throws SecurityException, NoSuchFieldException { - cl = QInheritance3Test_GenericSupertypeC.class; - match(SimplePath.class, "field"); - } - - @Test - public void GenericSupertypeS() throws SecurityException, NoSuchFieldException { - cl = QInheritance3Test_GenericSupertypeS.class; - match(StringPath.class, "field"); - } - - @Test - public void GenericSupertypeS2() throws SecurityException, NoSuchFieldException { - cl = QInheritance3Test_GenericSupertypeS2.class; - match(StringPath.class, "field"); - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/inheritance/Inheritance4Test.java b/querydsl-apt/src/test/java/com/mysema/query/inheritance/Inheritance4Test.java deleted file mode 100644 index f16cdc65c6..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/inheritance/Inheritance4Test.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.inheritance; - -import org.junit.Test; - -import com.mysema.query.annotations.QueryEntity; -import com.mysema.query.domain.AbstractTest; -import com.mysema.query.types.path.NumberPath; -import com.mysema.query.types.path.SimplePath; -import com.mysema.query.types.path.StringPath; - -public class Inheritance4Test extends AbstractTest { - - @QueryEntity - public class EntityWithComparable { - private Comparable field; - - public Comparable getField() { - return field; - } - - } - - @QueryEntity - public class EntityWithNumber extends EntityWithComparable { - private Long field; - - public Long getField() { - return field; - } - - } - - @QueryEntity - public class EntityWithString extends EntityWithComparable{ - private String field; - - public String getField() { - return field; - } - - } - - @Test - public void test() throws SecurityException, NoSuchFieldException{ - cl = QInheritance4Test_EntityWithComparable.class; - match(SimplePath.class, "field"); - - cl = QInheritance4Test_EntityWithNumber.class; - match(NumberPath.class, "field"); - - cl = QInheritance4Test_EntityWithString.class; - match(StringPath.class, "field"); - - } -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/inheritance/Inheritance8Test.java b/querydsl-apt/src/test/java/com/mysema/query/inheritance/Inheritance8Test.java deleted file mode 100644 index 02bd9a5d65..0000000000 --- a/querydsl-apt/src/test/java/com/mysema/query/inheritance/Inheritance8Test.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.inheritance; - -import static org.junit.Assert.assertEquals; - -import org.junit.Test; - -import com.mysema.query.annotations.QueryEntity; -import com.mysema.query.domain.CommonIdentifiable; -import com.mysema.query.domain.CommonPersistence; -import com.mysema.query.types.path.NumberPath; - -public class Inheritance8Test { - - @QueryEntity - public static class SimpleSubclass extends CommonPersistence { - } - - @QueryEntity - public static class GenericSubclass extends CommonIdentifiable { - } - - @Test - public void Simple_subclass_should_contain_fields_from_external_superclass() { - assertEquals(NumberPath.class, QInheritance8Test_SimpleSubclass.simpleSubclass.version.getClass()); - } - - @Test - public void Generic_subclass_should_contain_fields_from_external_superclass() { - assertEquals(NumberPath.class, QInheritance8Test_GenericSubclass.genericSubclass.version.getClass()); - } - -} diff --git a/querydsl-apt/src/test/java/com/mysema/query/apt/AbstractProcessorTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/AbstractProcessorTest.java similarity index 80% rename from querydsl-apt/src/test/java/com/mysema/query/apt/AbstractProcessorTest.java rename to querydsl-apt/src/test/java/com/querydsl/apt/AbstractProcessorTest.java index 748cc5a89f..f2013c28bf 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/apt/AbstractProcessorTest.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/AbstractProcessorTest.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,10 +11,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.apt; +package com.querydsl.apt; -import javax.annotation.processing.AbstractProcessor; -import javax.tools.JavaCompiler; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; @@ -23,9 +21,13 @@ import java.util.Collections; import java.util.List; -import com.mysema.codegen.SimpleCompiler; -import com.mysema.util.FileUtils; -import junit.framework.Assert; +import javax.annotation.processing.AbstractProcessor; +import javax.tools.JavaCompiler; + +import org.junit.Assert; + +import com.querydsl.codegen.utils.SimpleCompiler; +import com.querydsl.core.util.FileUtils; public abstract class AbstractProcessorTest { @@ -50,8 +52,8 @@ protected void process(Class processorClass, List processorClass, List classes, String target) throws IOException { List options = new ArrayList(classes.size() + 3); options.add("-s"); @@ -63,18 +65,26 @@ protected void compile(Class processorClass, List getAPTOptions() { return Collections.emptyList(); } diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/BooleanExtensionsTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/BooleanExtensionsTest.java new file mode 100644 index 0000000000..2ffa88b031 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/BooleanExtensionsTest.java @@ -0,0 +1,55 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt; + +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.Arrays; +import java.util.List; + +import org.junit.Test; + +public class BooleanExtensionsTest extends AbstractProcessorTest { + + private static final String packagePath = "src/test/apt/com/querydsl/"; + + @Test + public void process() throws IOException { + List sources = Arrays.asList( + new File(packagePath, "BooleanExtensions.java").getPath(), + new File(packagePath, "ExampleEntity.java").getPath()); + process(QuerydslAnnotationProcessor.class, sources,"booleanExtensions"); + + String qtypeContent = new String(Files.readAllBytes(Paths.get("target", "booleanExtensions", "com", "querydsl", "QExampleEntity.java")), StandardCharsets.UTF_8); + assertTrue(qtypeContent.contains("ext.java.lang.QBoolean booleanProp")); + assertTrue(qtypeContent.contains("ext.java.lang.QBoolean booleanProp2")); + } + + @Test + public void process2() throws IOException { + List sources = Arrays.asList( + new File(packagePath, "BooleanExtensions2.java").getPath(), + new File(packagePath, "ExampleEntity.java").getPath()); + process(QuerydslAnnotationProcessor.class, sources,"booleanExtensions2"); + String qtypeContent = new String(Files.readAllBytes(Paths.get("target", "booleanExtensions2", "com", "querydsl", "QExampleEntity.java")), StandardCharsets.UTF_8); + assertTrue(qtypeContent.contains("ext.java.lang.QBoolean booleanProp")); + assertTrue(qtypeContent.contains("ext.java.lang.QBoolean booleanProp2")); + } + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/DateExtensions.java b/querydsl-apt/src/test/java/com/querydsl/apt/DateExtensions.java new file mode 100644 index 0000000000..bc296923bb --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/DateExtensions.java @@ -0,0 +1,32 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt; + +import java.sql.Date; + +import com.querydsl.core.annotations.QueryDelegate; +import com.querydsl.core.types.Predicate; +import com.querydsl.core.types.dsl.DateExpression; +import com.querydsl.core.types.dsl.Expressions; + +public final class DateExtensions { + + private DateExtensions() { } + + @QueryDelegate(Date.class) + public static Predicate extension(DateExpression date) { + return Expressions.booleanPath("b"); + } + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/DateExtensionsTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/DateExtensionsTest.java new file mode 100644 index 0000000000..e354eaacfe --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/DateExtensionsTest.java @@ -0,0 +1,72 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import org.junit.Ignore; +import org.junit.Test; + +@Ignore +public class DateExtensionsTest extends AbstractProcessorTest { + + private static final String packagePath = "src/test/java/com/querydsl/apt/"; + + @Test + public void handles_date_extensions_correctly() throws IOException, InterruptedException { + File source = new File(packagePath, "EntityWithExtensions.java"); + File source2 = new File(packagePath, "DateExtensions.java"); + List sources = Arrays.asList(source.getPath(), source2.getPath()); + File qType = new File("target/overwrite3/com/querydsl/apt/QEntityWithExtensions.java"); + + // QEntityWithExtensions is generated + process(QuerydslAnnotationProcessor.class, sources, "overwrite3"); + assertTrue(qType.exists()); + long modified = qType.lastModified(); + Thread.sleep(1000); + assertTrue(new String(Files.readAllBytes(qType.toPath()), StandardCharsets.UTF_8).contains("QDate")); + + // EntityWithExtensions has not changed, QEntityWithExtensions is not overwritten + compile(QuerydslAnnotationProcessor.class, sources, "overwrite3"); + assertEquals(modified, qType.lastModified()); + + // EntityWithExtensions is updated, QEntityWithExtensions is overwritten + Files.createFile(source.toPath()); + compile(QuerydslAnnotationProcessor.class, sources, "overwrite3"); + assertTrue("" + modified + " >= " + qType.lastModified(), modified < qType.lastModified()); + assertTrue(new String(Files.readAllBytes(qType.toPath()), StandardCharsets.UTF_8).contains("QDate")); + + // QEntityWithExtensions is deleted and regenerated + assertTrue(qType.delete()); + compile(QuerydslAnnotationProcessor.class, sources, "overwrite3"); + assertTrue(qType.exists()); + assertTrue(new String(Files.readAllBytes(qType.toPath()), StandardCharsets.UTF_8).contains("QDate")); + } + + @Override + protected Collection getAPTOptions() { + return Collections.singletonList("-AdefaultOverwrite=true"); + } + +} diff --git a/querydsl-apt/src/test/java/com/mysema/query/apt/EclipseCompilationTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/EclipseCompilationTest.java similarity index 83% rename from querydsl-apt/src/test/java/com/mysema/query/apt/EclipseCompilationTest.java rename to querydsl-apt/src/test/java/com/querydsl/apt/EclipseCompilationTest.java index 85839086ac..46ae72b1c9 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/apt/EclipseCompilationTest.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/EclipseCompilationTest.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,32 +11,31 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.apt; +package com.querydsl.apt; import static org.junit.Assert.assertTrue; import java.io.File; import java.io.IOException; import java.net.URLClassLoader; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; import java.util.ArrayList; import java.util.List; import javax.tools.JavaCompiler; -import junit.framework.Assert; - import org.eclipse.jdt.internal.compiler.tool.EclipseCompiler; +import org.junit.Assert; import org.junit.Ignore; import org.junit.Test; -import com.google.common.base.Charsets; -import com.google.common.io.Files; -import com.mysema.codegen.SimpleCompiler; -import com.mysema.util.FileUtils; +import com.querydsl.codegen.utils.SimpleCompiler; +import com.querydsl.core.util.FileUtils; public class EclipseCompilationTest { - private static final String packagePath = "src/test/apt/com/mysema/query/eclipse/"; + private static final String packagePath = "src/test/apt/com/querydsl/eclipse/"; @Test @Ignore @@ -73,16 +72,16 @@ public void test() throws IOException { options.add("-verbose"); options.addAll(classes); - int compilationResult = compiler.run(null, System.out, System.err, options.toArray(new String[options.size()])); + int compilationResult = compiler.run(null, System.out, System.err, options.toArray(new String[0])); if (compilationResult == 0) { System.out.println("Compilation is successful"); } else { Assert.fail("Compilation Failed"); } - File resultFile = new File("target/out-eclipse/com/mysema/query/eclipse/QSimpleEntity.java"); + File resultFile = new File("target/out-eclipse/com/querydsl/eclipse/QSimpleEntity.java"); assertTrue(resultFile.exists()); - String result = Files.toString(resultFile, Charsets.UTF_8); + String result = new String(Files.readAllBytes(resultFile.toPath()), StandardCharsets.UTF_8); assertTrue(result.contains("NumberPath bigDecimalProp")); assertTrue(result.contains("NumberPath integerProp")); assertTrue(result.contains("NumberPath intProp")); diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/EmbeddableTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/EmbeddableTest.java new file mode 100644 index 0000000000..d76d1bc6f3 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/EmbeddableTest.java @@ -0,0 +1,30 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt; + +import java.io.IOException; +import java.util.Collections; +import java.util.List; + +import org.junit.Test; + +public class EmbeddableTest extends AbstractProcessorTest { + + @Test + public void process() throws IOException { + List classes = Collections.singletonList("src/test/java/com/querydsl/apt/domain/Embeddable2Test.java"); + process(QuerydslAnnotationProcessor.class, classes,"embeddable"); + } + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/EntityExtensions.java b/querydsl-apt/src/test/java/com/querydsl/apt/EntityExtensions.java new file mode 100644 index 0000000000..0a7222de62 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/EntityExtensions.java @@ -0,0 +1,29 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt; + +import com.querydsl.core.annotations.QueryDelegate; +import com.querydsl.core.types.Predicate; +import com.querydsl.core.types.dsl.Expressions; + +public final class EntityExtensions { + + private EntityExtensions() { } + + @QueryDelegate(EntityWithExtensions.class) + public static Predicate extension(QEntityWithExtensions entity) { + return Expressions.booleanPath("b"); + } + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/EntityExtensionsTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/EntityExtensionsTest.java new file mode 100644 index 0000000000..100e37eeb7 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/EntityExtensionsTest.java @@ -0,0 +1,72 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import org.junit.Ignore; +import org.junit.Test; + +@Ignore +public class EntityExtensionsTest extends AbstractProcessorTest { + + private static final String packagePath = "src/test/java/com/querydsl/apt/"; + + @Test + public void handles_entity_extensions_correctly() throws IOException, InterruptedException { + File source = new File(packagePath, "EntityWithExtensions.java"); + File source2 = new File(packagePath, "EntityExtensions.java"); + List sources = Arrays.asList(source.getPath(), source2.getPath()); + File qType = new File("target/overwrite2/com/querydsl/apt/QEntityWithExtensions.java"); + + // QEntityWithExtensions is generated + process(QuerydslAnnotationProcessor.class, sources, "overwrite2"); + assertTrue(qType.exists()); + long modified = qType.lastModified(); + Thread.sleep(1000); + assertTrue(new String(Files.readAllBytes(qType.toPath()), StandardCharsets.UTF_8).contains("extension()")); + + // EntityWithExtensions has not changed, QEntityWithExtensions is not overwritten + compile(QuerydslAnnotationProcessor.class, sources, "overwrite2"); + assertEquals(modified, qType.lastModified()); + + // EntityWithExtensions is updated, QEntityWithExtensions is overwritten + Files.createFile(source.toPath()); + compile(QuerydslAnnotationProcessor.class, sources, "overwrite2"); + assertTrue("" + modified + " >= " + qType.lastModified(), modified < qType.lastModified()); + assertTrue(new String(Files.readAllBytes(qType.toPath()), StandardCharsets.UTF_8).contains("extension()")); + + // QEntityWithExtensions is deleted and regenerated + assertTrue(qType.delete()); + compile(QuerydslAnnotationProcessor.class, sources, "overwrite2"); + assertTrue(qType.exists()); + assertTrue(new String(Files.readAllBytes(qType.toPath()), StandardCharsets.UTF_8).contains("extension()")); + } + + @Override + protected Collection getAPTOptions() { + return Collections.singletonList("-AdefaultOverwrite=true"); + } + +} diff --git a/querydsl-apt/src/test/java/com/mysema/query/apt/EntityWithExtensions.java b/querydsl-apt/src/test/java/com/querydsl/apt/EntityWithExtensions.java similarity index 81% rename from querydsl-apt/src/test/java/com/mysema/query/apt/EntityWithExtensions.java rename to querydsl-apt/src/test/java/com/querydsl/apt/EntityWithExtensions.java index 2e7a72d5de..eea62a8dcd 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/apt/EntityWithExtensions.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/EntityWithExtensions.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,17 +11,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.apt; +package com.querydsl.apt; import java.sql.Date; -import com.mysema.query.annotations.QueryEntity; +import com.querydsl.core.annotations.QueryEntity; @QueryEntity public class EntityWithExtensions { String id; - + Date date; - + } diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/ExcludedClassesTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/ExcludedClassesTest.java new file mode 100644 index 0000000000..25f6f79db9 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/ExcludedClassesTest.java @@ -0,0 +1,43 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt; + +import static org.junit.Assert.assertFalse; + +import java.io.File; +import java.io.IOException; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import org.junit.Test; + +public class ExcludedClassesTest extends AbstractProcessorTest { + + private static final String packagePath = "src/test/java/com/querydsl/"; + + @Test + public void process() throws IOException { + List classes = getFiles(packagePath); + process(QuerydslAnnotationProcessor.class, classes, "excludedClasses"); + + assertFalse(new File("target/excludedClasses/com/querydsl/apt/domain/QArrayTest_ArrayTestEntity.java").exists()); + } + + @Override + protected Collection getAPTOptions() { + return Collections.singletonList("-Aquerydsl.excludedClasses=com.querydsl.apt.domain.ArrayTest.ArrayTestEntity"); + } + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/ExcludedPackagesTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/ExcludedPackagesTest.java new file mode 100644 index 0000000000..7fdc5e4268 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/ExcludedPackagesTest.java @@ -0,0 +1,45 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.io.IOException; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import org.junit.Test; + +public class ExcludedPackagesTest extends AbstractProcessorTest { + + private static final String packagePath = "src/test/java/com/querydsl/"; + + @Test + public void process() throws IOException { + List classes = getFiles(packagePath); + process(QuerydslAnnotationProcessor.class, classes, "excludedPackages"); + + assertFalse(new File("target/excludedPackages/com/querydsl/apt/domain/p1").exists()); + assertTrue(new File("target/excludedPackages/com/querydsl/apt/domain/p2").exists()); + } + + @Override + protected Collection getAPTOptions() { + return Collections.singletonList("-Aquerydsl.excludedPackages=com.querydsl.apt.domain.p1"); + } + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/GenericExporterTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/GenericExporterTest.java new file mode 100644 index 0000000000..bb319e0f60 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/GenericExporterTest.java @@ -0,0 +1,162 @@ +package com.querydsl.apt; + +import static org.junit.Assert.fail; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.util.ArrayList; +import java.util.List; + +import javax.persistence.*; + +import org.junit.Test; + +import com.querydsl.apt.domain.AbstractEntityTest; +import com.querydsl.apt.domain.CustomCollection; +import com.querydsl.apt.domain.Generic2Test; +import com.querydsl.apt.hibernate.HibernateAnnotationProcessor; +import com.querydsl.codegen.GenericExporter; +import com.querydsl.codegen.Keywords; +import com.querydsl.codegen.PropertyHandling; +import com.querydsl.core.domain.A; + +public class GenericExporterTest extends AbstractProcessorTest { + + private static final String PACKAGE_PATH = "src/test/java/com/querydsl/apt/domain/"; + + private static final List CLASSES = getFiles(PACKAGE_PATH); + + @Test + public void execute() throws IOException { + // via APT + process(QuerydslAnnotationProcessor.class, CLASSES, "QuerydslAnnotationProcessor"); + + // via GenericExporter + GenericExporter exporter = new GenericExporter(); + exporter.setTargetFolder(new File("target/GenericExporterTest")); + exporter.export(AbstractEntityTest.class.getPackage(), A.class.getPackage()); + + List expected = new ArrayList(); + // delegates are not supported + expected.add("QDelegateTest_SimpleUser.java"); + expected.add("QDelegateTest_SimpleUser2.java"); + expected.add("QDelegateTest_User.java"); + expected.add("QDelegate2Test_Entity.java"); + expected.add("QExampleEntity.java"); + expected.add("QQueryProjectionTest_DTOWithProjection.java"); + expected.add("QQueryProjectionTest_EntityWithProjection.java"); + expected.add("QEmbeddable3Test_EmbeddableClass.java"); + expected.add("QQueryEmbedded4Test_User.java"); + + execute(expected, "GenericExporterTest", "QuerydslAnnotationProcessor"); + } + + @Test + public void execute2() throws IOException { + // via APT + process(HibernateAnnotationProcessor.class, CLASSES, "HibernateAnnotationProcessor"); + + // via GenericExporter + GenericExporter exporter = new GenericExporter(); + exporter.setKeywords(Keywords.JPA); + exporter.setEntityAnnotation(Entity.class); + exporter.setEmbeddableAnnotation(Embeddable.class); + exporter.setEmbeddedAnnotation(Embedded.class); + exporter.setSupertypeAnnotation(MappedSuperclass.class); + exporter.setSkipAnnotation(Transient.class); + exporter.setTargetFolder(new File("target/GenericExporterTest2")); + exporter.setStrictMode(true); + exporter.setPropertyHandling(PropertyHandling.JPA); + exporter.export(AbstractEntityTest.class.getPackage(), A.class.getPackage()); + + List expected = new ArrayList(); + // GenericExporter doesn't include field/method selection + expected.add("QTemporalTest_MyEntity.java"); + expected.add("QTemporal2Test_Cheque.java"); + expected.add("QQueryProjectionTest_DTOWithProjection.java"); + expected.add("QQueryProjectionTest_EntityWithProjection.java"); + expected.add("QEmbeddable3Test_EmbeddableClass.java"); + expected.add("QGeneric4Test_HidaBez.java"); + expected.add("QGeneric4Test_HidaBezGruppe.java"); + expected.add("QInterfaceType2Test_UserImpl.java"); + expected.add("QOrderTest_Order.java"); + expected.add("QManagedEmailTest_ManagedEmails.java"); + expected.add("QGeneric12Test_ChannelRole.java"); + expected.add("QManyToManyTest_Person.java"); + expected.add("QOneToOneTest_Person.java"); + expected.add("QGeneric16Test_HidaBez.java"); + expected.add("QGeneric16Test_HidaBezGruppe.java"); + + execute(expected, "GenericExporterTest2", "HibernateAnnotationProcessor"); + } + + @Test + public void execute3() { + GenericExporter exporter = new GenericExporter(); + exporter.setKeywords(Keywords.JPA); + exporter.setEntityAnnotation(Entity.class); + exporter.setEmbeddableAnnotation(Embeddable.class); + exporter.setEmbeddedAnnotation(Embedded.class); + exporter.setSupertypeAnnotation(MappedSuperclass.class); + exporter.setSkipAnnotation(Transient.class); + exporter.setTargetFolder(new File("target/GenericExporterTest3")); + exporter.setPropertyHandling(PropertyHandling.JPA); + exporter.export(CustomCollection.MyCustomCollection.class, + CustomCollection.MyCustomCollection2.class, + CustomCollection.MyEntity.class); + } + + @Test + public void execute4() throws IOException { + GenericExporter exporter = new GenericExporter(); + exporter.setKeywords(Keywords.JPA); + exporter.setEntityAnnotation(Entity.class); + exporter.setEmbeddableAnnotation(Embeddable.class); + exporter.setEmbeddedAnnotation(Embedded.class); + exporter.setSupertypeAnnotation(MappedSuperclass.class); + exporter.setSkipAnnotation(Transient.class); + exporter.setTargetFolder(new File("target/GenericExporterTest4")); + exporter.setPropertyHandling(PropertyHandling.JPA); + exporter.export(Generic2Test.class.getClasses()); + } + + private void execute(List expected, String genericExporterFolder, String aptFolder) throws IOException { + List failures = new ArrayList(); + int successes = 0; + for (File file : new File("target/" + genericExporterFolder + "/com/querydsl/apt/domain").listFiles()) { + File other = new File("target/" + aptFolder + "/com/querydsl/apt/domain", file.getName()); + if (!other.exists() || !other.isFile()) { + continue; + } + String result1 = new String(Files.readAllBytes(file.toPath()), StandardCharsets.UTF_8); + String result2 = new String(Files.readAllBytes(other.toPath()), StandardCharsets.UTF_8); + if (!result1.equals(result2)) { + if (!expected.contains(file.getName())) { + System.err.println(file.getName()); + failures.add(file.getName()); + } else { + expected.remove(file.getName()); + } + } else { + successes++; + } + } + expected.remove("QGeneric16Test_HidaBez.java"); // unstable + expected.remove("QGeneric4Test_HidaBez.java"); // unstable + expected.remove("QGeneric16Test_HidaBezGruppe.java"); // unstable + expected.remove("QGeneric4Test_HidaBezGruppe.java"); // unstable + if (!expected.isEmpty()) { + fail("Following expected failures succeeded: " + expected); + } + + if (!failures.isEmpty()) { + for (String failure : failures) { + System.err.println(failure); + } + fail("Failed with " + failures.size() + " failures, " + successes + " succeeded, " + failures); + } + } + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/GenericTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/GenericTest.java new file mode 100644 index 0000000000..e9f93dc70f --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/GenericTest.java @@ -0,0 +1,25 @@ +package com.querydsl.apt; + +import java.io.IOException; +import java.util.Collections; +import java.util.List; + +import org.junit.Test; + +import com.querydsl.apt.jpa.JPAAnnotationProcessor; + +public class GenericTest extends AbstractProcessorTest { + + @Test + public void test() throws IOException { + List classes = Collections.singletonList("src/test/java/com/querydsl/apt/domain/Generic7Test.java"); + process(QuerydslAnnotationProcessor.class, classes,"GenericTest"); + } + + @Test + public void test2() throws IOException { + List classes = Collections.singletonList("src/test/java/com/querydsl/apt/domain/Generic9Test.java"); + process(JPAAnnotationProcessor.class, classes,"GenericTest2"); + } + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/IncludedClassesTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/IncludedClassesTest.java new file mode 100644 index 0000000000..86551d1497 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/IncludedClassesTest.java @@ -0,0 +1,45 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.io.IOException; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import org.junit.Test; + +public class IncludedClassesTest extends AbstractProcessorTest { + + private static final String packagePath = "src/test/java/com/querydsl/"; + + @Test + public void process() throws IOException { + List classes = getFiles(packagePath); + process(QuerydslAnnotationProcessor.class, classes, "includedClasses"); + + assertTrue(new File("target/includedClasses/com/querydsl/apt/domain/QArrayTest_ArrayTestEntity.java").exists()); + assertFalse(new File("target/includedClasses/com/querydsl/apt/domain/QArray2Test_Example.java").exists()); + } + + @Override + protected Collection getAPTOptions() { + return Collections.singletonList("-Aquerydsl.includedClasses=com.querydsl.apt.domain.ArrayTest.ArrayTestEntity"); + } + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/IncludedPackagesTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/IncludedPackagesTest.java new file mode 100644 index 0000000000..ee9abf6d61 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/IncludedPackagesTest.java @@ -0,0 +1,45 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.io.IOException; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import org.junit.Test; + +public class IncludedPackagesTest extends AbstractProcessorTest { + + private static final String packagePath = "src/test/java/com/querydsl/"; + + @Test + public void process() throws IOException { + List classes = getFiles(packagePath); + process(QuerydslAnnotationProcessor.class, classes, "includedPackages"); + + assertFalse(new File("target/includedPackages/com/querydsl/apt/domain/p1").exists()); + assertTrue(new File("target/includedPackages/com/querydsl/apt/domain/p2").exists()); + } + + @Override + protected Collection getAPTOptions() { + return Collections.singletonList("-Aquerydsl.includedPackages=com.querydsl.apt.domain.p2"); + } + +} diff --git a/querydsl-apt/src/test/java/com/mysema/query/apt/IncrementalCompilationTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/IncrementalCompilationTest.java similarity index 80% rename from querydsl-apt/src/test/java/com/mysema/query/apt/IncrementalCompilationTest.java rename to querydsl-apt/src/test/java/com/querydsl/apt/IncrementalCompilationTest.java index 8220935b3e..f1a1d60743 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/apt/IncrementalCompilationTest.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/IncrementalCompilationTest.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,50 +11,49 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.apt; +package com.querydsl.apt; -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertTrue; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import java.io.File; import java.io.IOException; +import java.nio.file.Files; import java.util.Collections; import org.junit.Ignore; import org.junit.Test; -import com.google.common.io.Files; - @Ignore -public class IncrementalCompilationTest extends AbstractProcessorTest{ - - private static final String packagePath = "src/test/java/com/mysema/query/domain/"; +public class IncrementalCompilationTest extends AbstractProcessorTest { + + private static final String packagePath = "src/test/java/com/querydsl/apt/domain/"; @Test - public void Does_Not_Overwrite_Unchanged_Files() throws IOException, InterruptedException { + public void does_not_overwrite_unchanged_files() throws IOException, InterruptedException { File source = new File(packagePath, "ExampleEntity.java"); String path = source.getPath(); - File qType = new File("target/overwrite/com/mysema/query/domain/QExampleEntity.java"); - + File qType = new File("target/overwrite/com/querydsl/apt/domain/QExampleEntity.java"); + // QTestEntity is generated process(QuerydslAnnotationProcessor.class, Collections.singletonList(path), "overwrite"); assertTrue(qType.exists()); long modified = qType.lastModified(); Thread.sleep(1000); - + // TestEntity has not changed, QTestEntity is not overwritten compile(QuerydslAnnotationProcessor.class, Collections.singletonList(path), "overwrite"); assertEquals(modified, qType.lastModified()); // TestEntity is updated, QTestEntity is overwritten - Files.touch(source); + Files.createFile(source.toPath()); compile(QuerydslAnnotationProcessor.class, Collections.singletonList(path), "overwrite"); assertTrue("" + modified + " >= " + qType.lastModified(), modified < qType.lastModified()); - - // QTestEntity is deleted and regenerated + + // QTestEntity is deleted and regenerated assertTrue(qType.delete()); compile(QuerydslAnnotationProcessor.class, Collections.singletonList(path), "overwrite"); assertTrue(qType.exists()); } - + } diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/IntegerExtensionsTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/IntegerExtensionsTest.java new file mode 100644 index 0000000000..c37343f272 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/IntegerExtensionsTest.java @@ -0,0 +1,30 @@ +package com.querydsl.apt; + +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.Arrays; +import java.util.List; + +import org.junit.Test; + +public class IntegerExtensionsTest extends AbstractProcessorTest { + + private static final String packagePath = "src/test/apt/com/querydsl/"; + + @Test + public void process() throws IOException { + List sources = Arrays.asList( + new File(packagePath, "IntegerExtensions.java").getPath(), + new File(packagePath, "ExampleEntity2.java").getPath()); + process(QuerydslAnnotationProcessor.class, sources, "integerExtensions"); + String qtypeContent = new String(Files.readAllBytes(Paths.get("target", "integerExtensions", "com", "querydsl", "QExampleEntity2.java")), StandardCharsets.UTF_8); + //The superclass' id property is inherited, but can't be assigned to the custom QInteger + assertTrue(qtypeContent.contains("public final ext.java.lang.QInteger id = new ext.java.lang.QInteger(_super.id);")); + } + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/NamePrefixTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/NamePrefixTest.java new file mode 100644 index 0000000000..bb662f0f1b --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/NamePrefixTest.java @@ -0,0 +1,46 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt; + +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.io.IOException; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + +import org.junit.Test; + +public class NamePrefixTest extends AbstractProcessorTest { + + private static final String packagePath = "src/test/java/com/querydsl/apt/domain/"; + + @Test + public void process_all() throws IOException { + // works only in Eclipse for the moment + List classes = getFiles(packagePath); + + // default Processor + process(QuerydslAnnotationProcessor.class, classes,"prefix"); + + assertTrue(new File("target/prefix/com/querydsl/apt/domain/query3/QTAnimalTest_Animal.java").exists()); + } + + @Override + protected Collection getAPTOptions() { + return Arrays.asList("-Aquerydsl.packageSuffix=.query3", "-Aquerydsl.prefix=QT"); + } + +} diff --git a/querydsl-apt/src/test/java/com/mysema/query/apt/NameSuffixTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/NameSuffixTest.java similarity index 75% rename from querydsl-apt/src/test/java/com/mysema/query/apt/NameSuffixTest.java rename to querydsl-apt/src/test/java/com/querydsl/apt/NameSuffixTest.java index 7d57353b9f..c6e6ccc55c 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/apt/NameSuffixTest.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/NameSuffixTest.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.apt; +package com.querydsl.apt; import static org.junit.Assert.assertTrue; @@ -24,23 +24,23 @@ import org.junit.Test; public class NameSuffixTest extends AbstractProcessorTest { - - private static final String packagePath = "src/test/java/com/mysema/query/domain/"; + + private static final String packagePath = "src/test/java/com/querydsl/apt/domain/"; @Test - public void ProcessAll() throws IOException { + public void process_all() throws IOException { // works only in Eclipse for the moment List classes = getFiles(packagePath); // default Processor process(QuerydslAnnotationProcessor.class, classes,"suffix"); - - assertTrue(new File("target/suffix/com/mysema/query/domain/QAnimalTest_AnimalType.java").exists()); + + assertTrue(new File("target/suffix/com/querydsl/apt/domain/query2/QAnimalTest_AnimalType.java").exists()); } - + @Override protected Collection getAPTOptions() { - return Arrays.asList("-Aquerydsl.suffix=Type"); + return Arrays.asList("-Aquerydsl.packageSuffix=.query2", "-Aquerydsl.suffix=Type"); } - + } diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/NoteTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/NoteTest.java new file mode 100644 index 0000000000..13b38cde22 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/NoteTest.java @@ -0,0 +1,62 @@ +package com.querydsl.apt; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import org.junit.Test; + +public class NoteTest extends AbstractProcessorTest { + + private Collection aptOptions; + + private ByteArrayOutputStream err = new ByteArrayOutputStream(); + + private static final String packagePath = "src/test/java/com/querydsl/apt/"; + + public void process() throws IOException { + List classes = getFiles(packagePath); + process(QuerydslAnnotationProcessor.class, classes, "includedClasses"); + } + + @Override + protected Collection getAPTOptions() { + return aptOptions; + } + + @Override + protected ByteArrayOutputStream getStdErr() { + return err; + } + + protected boolean isStdErrEmpty() { + return getStdErr().toByteArray().length == 0; + } + + @Test + public void processDefault() throws IOException { + aptOptions = Collections.emptyList(); + process(); + assertTrue(isStdErrEmpty()); + } + + @Test + public void processEnabled() throws IOException { + aptOptions = Collections.singletonList("-Aquerydsl.logInfo=true"); + process(); + assertFalse(isStdErrEmpty()); + } + + @Test + public void processDisabled() throws IOException { + aptOptions = Collections.singletonList("-Aquerydsl.logInfo=false"); + process(); + assertTrue(isStdErrEmpty()); + } + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/PackageSuffixTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/PackageSuffixTest.java new file mode 100644 index 0000000000..b521b2987b --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/PackageSuffixTest.java @@ -0,0 +1,46 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt; + +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.io.IOException; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import org.junit.Test; + +public class PackageSuffixTest extends AbstractProcessorTest { + + private static final String packagePath = "src/test/java/com/querydsl/apt/domain/"; + + @Test + public void process_all() throws IOException { + // works only in Eclipse for the moment + List classes = getFiles(packagePath); + + // default Processor + process(QuerydslAnnotationProcessor.class, classes,"packageSuffix"); + + assertTrue(new File("target/packageSuffix/com/querydsl/apt/domain/query/QAnimalTest_Animal.java").exists()); + } + + @Override + protected Collection getAPTOptions() { + return Collections.singletonList("-Aquerydsl.packageSuffix=.query"); + } + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/QuerydslAnnotationProcessorTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/QuerydslAnnotationProcessorTest.java new file mode 100644 index 0000000000..c841c4ba2b --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/QuerydslAnnotationProcessorTest.java @@ -0,0 +1,159 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt; + +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.io.IOException; +import java.util.Collections; +import java.util.List; + +import org.junit.Test; + +import com.querydsl.apt.hibernate.HibernateAnnotationProcessor; +import com.querydsl.apt.jdo.JDOAnnotationProcessor; +import com.querydsl.apt.jpa.JPAAnnotationProcessor; +import com.querydsl.apt.roo.RooAnnotationProcessor; + +public class QuerydslAnnotationProcessorTest extends AbstractProcessorTest { + + private static final String PACKAGE_PATH = "src/test/java/com/querydsl/apt/domain/"; + + private static final List CLASSES = getFiles(PACKAGE_PATH); + + @Test + public void process() throws IOException { + File file = new File(PACKAGE_PATH, "AbstractEntityTest.java"); + process(QuerydslAnnotationProcessor.class, Collections.singletonList(file.getPath()),"qdsl"); + } + + @Test + public void process_monitoredCompany() throws IOException { + String path = new File(PACKAGE_PATH, "MonitoredCompany.java").getPath(); + process(QuerydslAnnotationProcessor.class, Collections.singletonList(path),"MonitoredCompany"); + } + + @Test + public void process_inheritance3() throws IOException { + String path = new File("src/test/java/com/querydsl/apt/inheritance/Inheritance3Test.java").getPath(); + process(QuerydslAnnotationProcessor.class, Collections.singletonList(path),"Inheritance3Test"); + } + + @Test + public void process_inheritance8() throws IOException { + String path = new File("src/test/java/com/querydsl/apt/inheritance/Inheritance8Test.java").getPath(); + process(QuerydslAnnotationProcessor.class, Collections.singletonList(path),"Inheritance8Test"); + } + + @Test + public void process_queryEmbedded3() throws IOException { + String path = new File("src/test/java/com/querydsl/apt/domain/QueryEmbedded3Test.java").getPath(); + process(QuerydslAnnotationProcessor.class, Collections.singletonList(path),"QueryEmbedded3Test"); + } + + @Test + public void process_queryEmbedded4() throws IOException { + String path = new File("src/test/java/com/querydsl/apt/domain/QueryEmbedded4Test.java").getPath(); + process(QuerydslAnnotationProcessor.class, Collections.singletonList(path),"QueryEmbedded4Test"); + } + + @Test + public void process_delegate() throws IOException { + String path = new File("src/test/java/com/querydsl/apt/domain/DelegateTest.java").getPath(); + process(QuerydslAnnotationProcessor.class, Collections.singletonList(path),"DelegateTest"); + } + + @Test + public void process_abstractClasses() throws IOException { + String path = new File("src/test/java/com/querydsl/apt/domain/AbstractClassesTest.java").getPath(); + process(JPAAnnotationProcessor.class, Collections.singletonList(path),"AbstractClassesTest"); + } + + @Test + public void process_abstractClasses2() throws IOException { + String path = new File("src/test/java/com/querydsl/apt/domain/AbstractClasses2Test.java").getPath(); + process(JPAAnnotationProcessor.class, Collections.singletonList(path),"abstractClasses2"); + } + + @Test + public void process_genericSignature() throws IOException { + String path = new File("src/test/java/com/querydsl/apt/domain/GenericSignatureTest.java").getPath(); + process(QuerydslAnnotationProcessor.class, Collections.singletonList(path),"GenericSignatureTest"); + } + + @Test + public void process_abstractProperties2Test() throws IOException { + String path = new File("src/test/java/com/querydsl/apt/domain/AbstractProperties2Test.java").getPath(); + process(QuerydslAnnotationProcessor.class, Collections.singletonList(path),"AbstractProperties2Test"); + } + + @Test + public void process_inheritance2Test() throws IOException { + String path = new File("src/test/java/com/querydsl/apt/inheritance/Inheritance2Test.java").getPath(); + process(QuerydslAnnotationProcessor.class, Collections.singletonList(path),"InheritanceTest2"); + } + + @Test + public void process_entityInheritanceTest() throws IOException { + String path = new File("src/test/java/com/querydsl/apt/domain/EntityInheritanceTest.java").getPath(); + process(JPAAnnotationProcessor.class, Collections.singletonList(path),"EntityInheritanceTest"); + } + + @Test + public void process_enum2Test() throws IOException { + String path = new File("src/test/java/com/querydsl/apt/domain/Enum2Test.java").getPath(); + process(QuerydslAnnotationProcessor.class, Collections.singletonList(path),"Enum2Test"); + } + + @Test + public void process_externalEntityTest() throws IOException { + String path = new File("src/test/java/com/querydsl/apt/domain/ExternalEntityTest.java").getPath(); + process(QuerydslAnnotationProcessor.class, Collections.singletonList(path),"ExternalEntityTest"); + } + + @Test + public void process_generic13Test() throws IOException { + String path = new File("src/test/java/com/querydsl/apt/domain/Generic13Test.java").getPath(); + process(QuerydslAnnotationProcessor.class, Collections.singletonList(path),"Generic13Test"); + } + + @Test + public void querydslAnnotationProcessor() throws IOException { + process(QuerydslAnnotationProcessor.class, CLASSES, "querydsl"); + } + + @Test + public void jpaAnnotationProcessor() throws IOException { + process(JPAAnnotationProcessor.class, CLASSES, "jpa"); + } + + @Test + public void hibernateAnnotationProcessor() throws IOException { + process(HibernateAnnotationProcessor.class, CLASSES, "hibernate"); + } + + @Test + public void jdoAnnotationProcessor() throws IOException { + process(JDOAnnotationProcessor.class, CLASSES, "jdo"); + } + + @Test + public void rooAnnotationProcessor() throws IOException { + process(RooAnnotationProcessor.class, CLASSES, "roo"); + + assertTrue(new File("target/roo/com/querydsl/apt/domain/QRooEntities_MyEntity.java").exists()); + } + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/UnknownAsEmbeddableTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/UnknownAsEmbeddableTest.java new file mode 100644 index 0000000000..ea3e6f9f43 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/UnknownAsEmbeddableTest.java @@ -0,0 +1,46 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt; + +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.io.IOException; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import org.junit.Test; + +public class UnknownAsEmbeddableTest extends AbstractProcessorTest { + + private static final String packagePath = "src/test/java/com/querydsl/apt/domain"; + + @Test + public void process() throws IOException { + List classes = getFiles(packagePath); + process(QuerydslAnnotationProcessor.class, classes,"unknownAsEmbeddable"); + + assertTrue(new File("target/unknownAsEmbeddable/com/querydsl/apt/domain/custom/QEntity.java").exists()); + assertTrue(new File("target/unknownAsEmbeddable/com/querydsl/apt/domain/custom/QEmbeddedType.java").exists()); + assertTrue(new File("target/unknownAsEmbeddable/com/querydsl/apt/domain/custom/QEmbeddedType2.java").exists()); + assertTrue(new File("target/unknownAsEmbeddable/com/querydsl/apt/domain/custom/QEmbeddedType3.java").exists()); + } + + @Override + protected Collection getAPTOptions() { + return Collections.singletonList("-Aquerydsl.unknownAsEmbeddable=true"); + } + +} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/AbstractClasses2Test.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/AbstractClasses2Test.java similarity index 76% rename from querydsl-apt/src/test/java/com/mysema/query/domain/AbstractClasses2Test.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/AbstractClasses2Test.java index c3dd89ba99..fd16e74f62 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/AbstractClasses2Test.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/AbstractClasses2Test.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.domain; +package com.querydsl.apt.domain; import static org.junit.Assert.assertEquals; @@ -19,26 +19,22 @@ import java.util.HashSet; import java.util.Set; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import javax.persistence.ManyToOne; -import javax.persistence.MappedSuperclass; -import javax.persistence.OneToMany; +import javax.persistence.*; +import org.junit.Assert; import org.junit.Test; -import com.mysema.query.types.path.NumberPath; +import com.querydsl.core.types.dsl.NumberPath; -@SuppressWarnings("serial") +@SuppressWarnings({"rawtypes", "serial", "unchecked"}) public class AbstractClasses2Test { - + public interface Archetype extends Serializable, Comparable { } - + @MappedSuperclass - public static abstract class BaseArchetype implements Archetype { + public abstract static class BaseArchetype implements Archetype { @Id @GeneratedValue @@ -46,29 +42,29 @@ public static abstract class BaseArchetype extends BaseArchetype { public int compareTo(S o) { return 0; } - + public boolean equals(Object o) { return o == this; } } - + @Entity public static class Party extends BaseArchetype { @OneToMany() @@ -80,36 +76,36 @@ public Party() { public int compareTo(Party o) { return 0; } - + public boolean equals(Object o) { return o == this; } } - + @Entity public static class PartyRole

extends BaseArchetype> { @ManyToOne() P party; - public PartyRole() {} + public PartyRole() { } public int compareTo(PartyRole o) { return 0; } - + public boolean equals(Object o) { return o == this; } } - + @Test - public void Grant_id_Type_And_Class() { - assertEquals(QAbstractClasses2Test_Party.class, QAbstractClasses2Test_Grant.grant.id.getClass()); + public void grant_id_type_and_class() { + Assert.assertEquals(QAbstractClasses2Test_Party.class, QAbstractClasses2Test_Grant.grant.id.getClass()); assertEquals(Party.class, QAbstractClasses2Test_Grant.grant.id.getType()); } @Test - public void Party_id_Type_And_Class() { + public void party_id_type_and_class() { assertEquals(NumberPath.class, QAbstractClasses2Test_Party.party.id.getClass()); assertEquals(Long.class, QAbstractClasses2Test_Party.party.id.getType()); } diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/AbstractClassesTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/AbstractClassesTest.java similarity index 80% rename from querydsl-apt/src/test/java/com/mysema/query/domain/AbstractClassesTest.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/AbstractClassesTest.java index 216a860074..ab33d3eda1 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/AbstractClassesTest.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/AbstractClassesTest.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.domain; +package com.querydsl.apt.domain; import static org.junit.Assert.assertEquals; @@ -22,11 +22,12 @@ import javax.persistence.Id; import javax.persistence.MappedSuperclass; +import org.junit.Assert; import org.junit.Test; -import com.mysema.query.types.path.NumberPath; +import com.querydsl.core.types.dsl.NumberPath; -@SuppressWarnings("serial") +@SuppressWarnings({"rawtypes", "serial", "unchecked"}) public class AbstractClassesTest { public interface Archetype extends Serializable, Comparable { @@ -35,7 +36,7 @@ public interface Archetype ext @MappedSuperclass - public static abstract class BaseArchetype implements Archetype { + public abstract static class BaseArchetype implements Archetype { @Id @GeneratedValue @@ -43,12 +44,12 @@ public static abstract class BaseArchetype extends BaseArchetyp public int compareTo(S o) { return 0; } - + public boolean equals(Object o) { return o == this; } @@ -76,7 +77,7 @@ public Party() { public int compareTo(Party o) { return 0; } - + public boolean equals(Object o) { return o == this; } @@ -84,13 +85,13 @@ public boolean equals(Object o) { } @Test - public void Grant_id_Type() { - assertEquals(QAbstractClassesTest_Party.class, QAbstractClassesTest_Grant.grant.id.getClass()); + public void grant_id_type() { + Assert.assertEquals(QAbstractClassesTest_Party.class, QAbstractClassesTest_Grant.grant.id.getClass()); assertEquals(Party.class, QAbstractClassesTest_Grant.grant.id.getType()); } @Test - public void Party_id_Type() { + public void party_id_type() { assertEquals(NumberPath.class, QAbstractClassesTest_Party.party.id.getClass()); assertEquals(Long.class, QAbstractClassesTest_Party.party.id.getType()); } diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/AbstractEntityTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/AbstractEntityTest.java new file mode 100644 index 0000000000..b8e8b839f0 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/AbstractEntityTest.java @@ -0,0 +1,46 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt.domain; + +import static org.junit.Assert.assertNotNull; + +import org.junit.Test; + +import com.querydsl.core.annotations.QueryEntity; +import com.querydsl.core.annotations.QueryInit; + +public class AbstractEntityTest { + + @QueryEntity + public abstract static class Category> { + + public Category defaultChild; + + } + + @QueryEntity + public static class CategoryReference { + + @QueryInit("defaultChild") + public Category category; + + } + + @Test + public void path_is_available() { + QAbstractEntityTest_CategoryReference categoryReference = QAbstractEntityTest_CategoryReference.categoryReference; + assertNotNull(categoryReference.category.defaultChild); + } + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/AbstractProperties2Test.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/AbstractProperties2Test.java new file mode 100644 index 0000000000..ab876c165d --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/AbstractProperties2Test.java @@ -0,0 +1,81 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt.domain; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.io.Serializable; + +import org.junit.Test; + +import com.querydsl.core.annotations.QueryEntity; + +public class AbstractProperties2Test { + + public abstract static class GenericEntity, E extends GenericEntity> { + + public abstract K getId(); + + public abstract void setId(K id); + + } + + public abstract static class AbstractEntity

> extends GenericEntity { + + private Integer id; + + @Override + public Integer getId() { + return id; + } + + @Override + public void setId(Integer id) { + this.id = id; + } + + } + + @QueryEntity + public static class User extends AbstractEntity { + + } + + @Test + public void genericEntity_id_is_available() { + assertNotNull(QAbstractProperties2Test_GenericEntity.genericEntity.id); + } + + @Test + public void abstractEntity_is_available() { + assertNotNull(QAbstractProperties2Test_AbstractEntity.abstractEntity.id); + } + + @Test + public void abstractEntity_super_is_available() { + assertEquals(QAbstractProperties2Test_GenericEntity.class, QAbstractProperties2Test_AbstractEntity.abstractEntity._super.getClass()); + } + + @Test + public void user_is_available() { + assertNotNull(QAbstractProperties2Test_User.user.id); + } + + @Test + public void user_super_is_available() { + assertEquals(QAbstractProperties2Test_AbstractEntity.class, QAbstractProperties2Test_User.user._super.getClass()); + } + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/AbstractProperties3Test.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/AbstractProperties3Test.java new file mode 100644 index 0000000000..137a528e5f --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/AbstractProperties3Test.java @@ -0,0 +1,67 @@ +package com.querydsl.apt.domain; + +import java.io.Serializable; + +import javax.persistence.*; + +import org.hibernate.annotations.Cache; +import org.hibernate.annotations.CacheConcurrencyStrategy; +import org.junit.Ignore; +import org.junit.Test; + +import com.querydsl.core.annotations.PropertyType; +import com.querydsl.core.annotations.QueryType; + +@Ignore +public class AbstractProperties3Test { + + @MappedSuperclass + public static class BaseEntity { + + } + + @Entity + public static class Compound extends BaseEntity { + + String name; + + } + + @Entity + @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) + public abstract static class Containable extends BaseEntity implements Serializable { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO, generator = "containable_seq_gen") + @SequenceGenerator(name = "containable_seq_gen", sequenceName = "seq_containable") + @Column(name = "id") + Long id; + + @QueryType(PropertyType.ENTITY) + public abstract Compound getCompound(); + + } + + @MappedSuperclass + @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) + @Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL) + public abstract static class CompoundContainer extends BaseEntity implements Serializable { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO, generator = "compound_container_seq_gen") + @SequenceGenerator(name = "compound_container_seq_gen", sequenceName = "seq_compound_container", allocationSize = 1000) + @Column(name = "compound_container_id") + Long id; + + @JoinColumn(name = "containable_id") + @OneToOne(fetch = FetchType.EAGER) + Containable containable; + + } + + @Test + public void test() { + QAbstractProperties3Test_CompoundContainer.compoundContainer.containable.compound.name.isNotNull(); + } + +} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/AbstractPropertiesTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/AbstractPropertiesTest.java similarity index 88% rename from querydsl-apt/src/test/java/com/mysema/query/domain/AbstractPropertiesTest.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/AbstractPropertiesTest.java index 5597fcbd26..a3464d3f10 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/AbstractPropertiesTest.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/AbstractPropertiesTest.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.domain; +package com.querydsl.apt.domain; import java.io.Serializable; @@ -22,7 +22,7 @@ @Ignore public class AbstractPropertiesTest { - public static abstract class GenericEntity> { + public abstract static class GenericEntity> { private static final long serialVersionUID = -3988499137919577054L; diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/AbstractSecurable.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/AbstractSecurable.java similarity index 91% rename from querydsl-apt/src/test/java/com/mysema/query/domain/AbstractSecurable.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/AbstractSecurable.java index 045ca7a859..09fa2eb9f0 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/AbstractSecurable.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/AbstractSecurable.java @@ -1,22 +1,22 @@ -package com.mysema.query.domain; - -import java.io.Serializable; -import java.util.List; - -import javax.persistence.CascadeType; -import javax.persistence.JoinColumn; -import javax.persistence.MappedSuperclass; -import javax.persistence.OneToMany; - -@MappedSuperclass - -public abstract class AbstractSecurable { - - private static final long serialVersionUID = -6151927948714098845L; - - // ~ Meta-data - @OneToMany(cascade = { CascadeType.PERSIST, CascadeType.REMOVE }) - @JoinColumn(name = "SOURCE") - private List securityEntries; - +package com.querydsl.apt.domain; + +import java.io.Serializable; +import java.util.List; + +import javax.persistence.CascadeType; +import javax.persistence.JoinColumn; +import javax.persistence.MappedSuperclass; +import javax.persistence.OneToMany; + +@MappedSuperclass + +public abstract class AbstractSecurable { + + private static final long serialVersionUID = -6151927948714098845L; + + // ~ Meta-data + @OneToMany(cascade = { CascadeType.PERSIST, CascadeType.REMOVE }) + @JoinColumn(name = "SOURCE") + private List securityEntries; + } \ No newline at end of file diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/AbstractTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/AbstractTest.java new file mode 100644 index 0000000000..ed82d215d2 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/AbstractTest.java @@ -0,0 +1,57 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt.domain; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +public abstract class AbstractTest { + + private Class cl; + + private com.querydsl.core.types.Expression standardVariable; + + protected > void start(Class cl, T standardVariable) { + this.cl = cl; + this.standardVariable = standardVariable; + + } + + protected void match(Class expectedType, String name) throws SecurityException, NoSuchFieldException { + assertTrue(cl.getSimpleName() + "." + name + " failed", expectedType.isAssignableFrom(cl.getField(name).getType())); + } + + protected void matchType(Class expectedType, String name) throws NoSuchFieldException, IllegalAccessException { + Class type = ((com.querydsl.core.types.Expression) cl.getField(name).get(standardVariable)).getType(); + assertTrue(cl.getSimpleName() + "." + name + " failed", expectedType.isAssignableFrom(type)); + } + + protected void assertPresent(String name) { + try { + cl.getField(name); + } catch (NoSuchFieldException e) { + fail("Expected present field : " + cl.getSimpleName() + "." + name); + } + } + + protected void assertMissing(String name) { + try { + cl.getField(name); + fail("Expected missing field : " + cl.getSimpleName() + "." + name); + } catch (NoSuchFieldException e) { + // expected + } + } + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/Address.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Address.java new file mode 100644 index 0000000000..9871fa3c16 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Address.java @@ -0,0 +1,24 @@ +package com.querydsl.apt.domain; + +import com.querydsl.core.annotations.QueryEmbeddable; +import com.querydsl.core.annotations.QueryEmbedded; + +@QueryEmbeddable +public final class Address { + + public Address() { + + } + + public Address(String street, String postCode, City city) { + this.street = street; this.postCode = postCode; this.city = city; + } + + public String street; + + public String postCode; + + @QueryEmbedded + public City city; + +} \ No newline at end of file diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/AnimalTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/AnimalTest.java new file mode 100644 index 0000000000..f0c7c4a137 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/AnimalTest.java @@ -0,0 +1,46 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt.domain; + +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +import com.querydsl.core.annotations.QueryEntity; +import com.querydsl.core.annotations.QueryInit; + +public class AnimalTest { + + @QueryEntity + public static class Animal { + + public String name; + + } + + @QueryEntity + public static class Cat extends Animal { + + @QueryInit("name") + public Cat mate; + + } + + @Test + public void properties_are_copied_from_super() { + assertTrue("direct copy of StringPath field failed", QAnimalTest_Cat.cat.name == QAnimalTest_Cat.cat._super.name); + + } + +} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/AnnotatedGettersTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/AnnotatedGettersTest.java similarity index 80% rename from querydsl-apt/src/test/java/com/mysema/query/domain/AnnotatedGettersTest.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/AnnotatedGettersTest.java index 722d55b603..373f8edc23 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/AnnotatedGettersTest.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/AnnotatedGettersTest.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,13 +11,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.domain; +package com.querydsl.apt.domain; import static org.junit.Assert.assertNotNull; import org.junit.Test; -import com.mysema.query.annotations.QueryEntity; +import com.querydsl.core.annotations.QueryEntity; public class AnnotatedGettersTest { @@ -27,7 +27,7 @@ public interface Entity { } @Test - public void Annotated_Getter_Is_Supported() { + public void annotated_getter_is_supported() { assertNotNull(QAnnotatedGettersTest_Entity.entity.name); } diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/AnnotationTypeTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/AnnotationTypeTest.java new file mode 100644 index 0000000000..77030b4450 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/AnnotationTypeTest.java @@ -0,0 +1,29 @@ +package com.querydsl.apt.domain; + +import java.lang.annotation.Annotation; + +import javax.persistence.*; + +import org.junit.Ignore; + +@Ignore +public class AnnotationTypeTest { + + @MappedSuperclass + public abstract static class BaseObject { + + } + + @Entity + public static class Person extends BaseObject { + @Id + private Long id; + } + + @Embeddable + public static class Address extends BaseObject { + @EmbeddedId + private String street; + } + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/AnyPathTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/AnyPathTest.java new file mode 100644 index 0000000000..65f0c60470 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/AnyPathTest.java @@ -0,0 +1,60 @@ +package com.querydsl.apt.domain; + +import static org.junit.Assert.assertNotNull; + +import java.util.HashSet; +import java.util.Set; + +import javax.persistence.*; + +import org.junit.Test; + +import com.querydsl.core.annotations.QueryInit; +import com.querydsl.core.types.dsl.BooleanExpression; + +public class AnyPathTest { + @Entity + public static class Foo { + + @OneToMany(mappedBy = "key.foo") + @QueryInit("key.student") + private Set bars = new HashSet(); + + } + + @Entity + public static class Bar { + + @EmbeddedId + @QueryInit("student") + private BarId key = new BarId(); + + } + + @Embeddable + public static class BarId { + + @ManyToOne + private Student student; + + @ManyToOne + private Foo foo; + + } + + @Entity + public static class Student { + + } + + private BooleanExpression authorFilter(Student student) { + //return QFoo.foo.bars.any().key.student.eq(Student student); + return QAnyPathTest_Foo.foo.bars.any().key.student.eq(student); + } + + @Test + public void anyPath() { + assertNotNull(authorFilter(new Student())); + } + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/AnyUsageTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/AnyUsageTest.java new file mode 100644 index 0000000000..ad1c4c6580 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/AnyUsageTest.java @@ -0,0 +1,95 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt.domain; + +import static org.junit.Assert.assertNotNull; + +import java.io.Serializable; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; + +import javax.persistence.*; + +import org.junit.Test; + +import com.querydsl.core.types.dsl.BooleanExpression; + +public class AnyUsageTest { + + @Entity + public static class DealerGroup implements Serializable { + private static final long serialVersionUID = 8001287260658920066L; + + @Id + @GeneratedValue + public Long id; + + @OneToMany(mappedBy = "dealerGroup") + public Set dealers; + + } + + @Entity + public static class Dealer implements Serializable { + private static final long serialVersionUID = -6832045219902674887L; + + @Id + @GeneratedValue + public Long id; + + @ManyToOne + public DealerGroup dealerGroup; + + @ManyToOne + public Company company; + + } + + @Entity + public static class Company implements Serializable { + private static final long serialVersionUID = -5369301332567282659L; + + @Id + @GeneratedValue + public Long id; + + } + + @Test + public void test() { + QAnyUsageTest_Dealer dealer = QAnyUsageTest_DealerGroup.dealerGroup.dealers.any(); + assertNotNull(dealer); + assertNotNull(dealer.company); + } + + @Test + public void withQDealer() { + List companies = new LinkedList(); + companies.add(new Company()); + QAnyUsageTest_Dealer qDealer = QAnyUsageTest_Dealer.dealer; + BooleanExpression expression = qDealer.company.in(companies); + assertNotNull(expression); + } + + @Test + public void withQDealerGroup() { + List companies = new LinkedList(); + companies.add(new Company()); + QAnyUsageTest_Dealer qDealer = QAnyUsageTest_DealerGroup.dealerGroup.dealers.any(); + BooleanExpression expression = qDealer.company.in(companies); + assertNotNull(expression); + } + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/Array2Test.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Array2Test.java new file mode 100644 index 0000000000..512ce3c659 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Array2Test.java @@ -0,0 +1,25 @@ +package com.querydsl.apt.domain; + +import org.junit.Test; + +import com.querydsl.core.annotations.QueryProjection; +import com.querydsl.core.types.dsl.Expressions; + +public class Array2Test { + + public static class Example { + + byte[] imageData; + + @QueryProjection + public Example(byte[] param0) { + this.imageData = param0; + } + } + + @Test + public void test() { + new QArray2Test_Example(Expressions.path(byte[].class, "bytes")).newInstance(new byte[0]); + } + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/Array3Test.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Array3Test.java new file mode 100644 index 0000000000..2c04a0a7d9 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Array3Test.java @@ -0,0 +1,48 @@ +package com.querydsl.apt.domain; + +import static org.junit.Assert.assertEquals; + +import org.junit.Assert; +import org.junit.Test; + +import com.querydsl.core.annotations.QueryEntity; + +public class Array3Test { + + @QueryEntity + public static class Domain { + + byte[] bytes; + + Byte[] bytes2; + } + + @QueryEntity + public static class Domain2 { + + byte[] bytes; + } + + @QueryEntity + public static class Domain3 { + + Byte[] bytes; + } + + @Test + public void domain() { + Assert.assertEquals(byte[].class, QArray3Test_Domain.domain.bytes.getType()); + assertEquals(Byte[].class, QArray3Test_Domain.domain.bytes2.getType()); + } + + @Test + public void domain2() { + Assert.assertEquals(byte[].class, QArray3Test_Domain2.domain2.bytes.getType()); + } + + @Test + public void domain3() { + Assert.assertEquals(Byte[].class, QArray3Test_Domain3.domain3.bytes.getType()); + } + +} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/ArrayExtTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/ArrayExtTest.java similarity index 78% rename from querydsl-apt/src/test/java/com/mysema/query/domain/ArrayExtTest.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/ArrayExtTest.java index 7d4d53bf3b..43ef387849 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/ArrayExtTest.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/ArrayExtTest.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.domain; +package com.querydsl.apt.domain; import static org.junit.Assert.assertEquals; @@ -20,65 +20,61 @@ import org.junit.Test; -import com.mysema.query.annotations.QueryEntity; -import com.mysema.query.types.path.ArrayPath; -import com.mysema.query.types.path.ListPath; -import com.mysema.query.types.path.MapPath; -import com.mysema.query.types.path.SimplePath; -import com.mysema.query.types.path.StringPath; +import com.querydsl.core.annotations.QueryEntity; +import com.querydsl.core.types.dsl.*; public class ArrayExtTest { private static final QArrayExtTest_BinaryFile binaryFile = QArrayExtTest_BinaryFile.binaryFile; - + @QueryEntity public static class BinaryFile { byte[] contentPart; - + List list; - + Map map1; - + Map map2; } @Test - public void BinaryFile_contentPart() { + public void binaryFile_contentPart() { assertEquals(ArrayPath.class, binaryFile.contentPart.getClass()); assertEquals(byte[].class, binaryFile.contentPart.getType()); } - + @Test - public void BinaryFile_list() { + public void binaryFile_list() { assertEquals(ListPath.class, binaryFile.list.getClass()); - assertEquals(List.class, binaryFile.list.getType()); + assertEquals(List.class, binaryFile.list.getType()); assertEquals(byte[].class, binaryFile.list.getParameter(0)); - + assertEquals(SimplePath.class, binaryFile.list.get(0).getClass()); assertEquals(byte[].class, binaryFile.list.get(0).getType()); } - + @Test - public void BinaryFile_map1() { + public void binaryFile_map1() { assertEquals(MapPath.class, binaryFile.map1.getClass()); assertEquals(Map.class, binaryFile.map1.getType()); assertEquals(String.class, binaryFile.map1.getParameter(0)); assertEquals(byte[].class, binaryFile.map1.getParameter(1)); - + assertEquals(SimplePath.class, binaryFile.map1.get("").getClass()); assertEquals(byte[].class, binaryFile.map1.get("").getType()); } - + @Test - public void BinaryFile_map2() { + public void binaryFile_map2() { assertEquals(MapPath.class, binaryFile.map2.getClass()); assertEquals(Map.class, binaryFile.map2.getType()); assertEquals(byte[].class, binaryFile.map2.getParameter(0)); assertEquals(String.class, binaryFile.map2.getParameter(1)); - + assertEquals(StringPath.class, binaryFile.map2.get(new byte[0]).getClass()); assertEquals(String.class, binaryFile.map2.get(new byte[0]).getType()); } - + } diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/ArrayTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/ArrayTest.java similarity index 87% rename from querydsl-apt/src/test/java/com/mysema/query/domain/ArrayTest.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/ArrayTest.java index 5f97e9ff1d..eb80d0494f 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/ArrayTest.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/ArrayTest.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,23 +11,23 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.domain; +package com.querydsl.apt.domain; import static org.junit.Assert.assertEquals; import org.junit.Test; -import com.mysema.query.annotations.QueryEntity; +import com.querydsl.core.annotations.QueryEntity; public class ArrayTest { @QueryEntity public static class ArrayTestEntity { - + ArrayTestEntity[] entityArray; - + int[] primitiveArray; - + String[] stringArray; } diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/B.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/B.java new file mode 100644 index 0000000000..c9498b9ca2 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/B.java @@ -0,0 +1,9 @@ +package com.querydsl.apt.domain; + +import com.querydsl.core.annotations.QueryEntity; +import com.querydsl.core.domain.A; + +@QueryEntity +public class B extends A { + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/BlockingTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/BlockingTest.java new file mode 100644 index 0000000000..958f925b45 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/BlockingTest.java @@ -0,0 +1,56 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt.domain; + +import org.junit.Test; + +import com.querydsl.core.annotations.PropertyType; +import com.querydsl.core.annotations.QueryEntity; +import com.querydsl.core.annotations.QueryTransient; +import com.querydsl.core.annotations.QueryType; + +public class BlockingTest extends AbstractTest { + + @QueryEntity + public static class Entity { + + Entity field1; + + @QueryTransient + @QueryType(PropertyType.ENTITY) + Entity field2; + + @QueryTransient + Entity blockedField; + } + + @QueryEntity + public abstract static class Entity2 { + + @QueryTransient + @QueryType(PropertyType.ENTITY) + public abstract Entity getField2(); + + @QueryTransient + public abstract Entity getBlockedField(); + } + + @Test + public void entity_fields_are_available() { + start(QBlockingTest_Entity.class, QBlockingTest_Entity.entity); + assertPresent("field1"); + assertMissing("blockedField"); + } + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/City.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/City.java new file mode 100644 index 0000000000..ac3a926885 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/City.java @@ -0,0 +1,33 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt.domain; + + +public final class City { + + public City() { } + + public City(String name, Double latitude, Double longitude) { + this.name = name; + this.latitude = latitude; + this.longitude = longitude; + } + + public String name; + + public Double latitude; + + public Double longitude; + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/CollectionTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/CollectionTest.java new file mode 100644 index 0000000000..e9325cd67a --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/CollectionTest.java @@ -0,0 +1,100 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt.domain; + +import static org.junit.Assert.assertEquals; + +import java.util.*; + +import org.junit.Assert; +import org.junit.Test; + +import com.querydsl.core.annotations.QueryEntity; +import com.querydsl.core.types.dsl.ListPath; +import com.querydsl.core.types.dsl.MapPath; +import com.querydsl.core.types.dsl.SetPath; + +public class CollectionTest { + + @QueryEntity + public static class Person { + + Map map1; + + Map map2; + + Map map3; + + Map map4; + + List list1; + + List list2; + + Collection collection1; + + Collection collection2; + + Collection> collectionOfCollection; + + Collection> collectionOfSet; + + Set set1; + + Set set2; + } + + @QueryEntity + public static class Classes { + + HashMap map1; + + HashMap map2; + + HashMap map3; + + ArrayList list1; + + ArrayList list2; + + ArrayList list3; + + HashSet set1; + + HashSet set2; + + HashSet set3; + + } + + @Test + public void test() { +// assertEquals(String.class, QMapWithUndefinedValueTest_Person.person.appData.getParameter(1)); +// assertEquals(Object.class, QMapWithUndefinedValueTest_Person.person.appData.getParameter(1)); + + Assert.assertEquals(MapPath.class, QCollectionTest_Classes.classes.map1.getClass()); + assertEquals(MapPath.class, QCollectionTest_Classes.classes.map2.getClass()); + assertEquals(MapPath.class, QCollectionTest_Classes.classes.map3.getClass()); + + assertEquals(ListPath.class, QCollectionTest_Classes.classes.list1.getClass()); + assertEquals(ListPath.class, QCollectionTest_Classes.classes.list2.getClass()); + assertEquals(ListPath.class, QCollectionTest_Classes.classes.list3.getClass()); + + assertEquals(SetPath.class, QCollectionTest_Classes.classes.set1.getClass()); + assertEquals(SetPath.class, QCollectionTest_Classes.classes.set2.getClass()); + assertEquals(SetPath.class, QCollectionTest_Classes.classes.set3.getClass()); + + } + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/ComparableTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/ComparableTest.java new file mode 100644 index 0000000000..5e2e7f57c6 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/ComparableTest.java @@ -0,0 +1,73 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt.domain; + +import static org.junit.Assert.assertNotNull; + +import org.junit.Test; + +import com.querydsl.core.annotations.QueryEmbeddable; +import com.querydsl.core.annotations.QueryEntity; + +public class ComparableTest { + + @QueryEntity + public static class CustomComparableHolder { + + private CustomComparable customComparable; + + public CustomComparable getCustomComparable() { + return customComparable; + } + + public void setCustomComparable(CustomComparable customComparable) { + this.customComparable = customComparable; + } + } + + @QueryEmbeddable + public static class CustomComparable2 { + + + private CustomComparable customComparable; + + public CustomComparable getCustomComparable() { + return customComparable; + } + + public void setCustomComparable(CustomComparable customComparable) { + this.customComparable = customComparable; + } + + } + + public static class CustomComparable implements Comparable { + + @Override + public int compareTo(CustomComparable o) { + return 0; + } + + public boolean equals(Object o) { + return o == this; + } + + } + + @Test + public void customComparable_is_properly_handled() { + assertNotNull(QComparableTest_CustomComparableHolder.customComparableHolder.customComparable.asc()); + } + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/ConstructorTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/ConstructorTest.java new file mode 100644 index 0000000000..7314b56ec2 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/ConstructorTest.java @@ -0,0 +1,58 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt.domain; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import org.junit.Test; + +import com.querydsl.core.annotations.QueryEntity; +import com.querydsl.core.annotations.QuerySupertype; + +public class ConstructorTest { + + @QuerySupertype + public static class CategorySuperclass { + + } + + @QueryEntity + public static class Category> extends CategorySuperclass { + + public Category(int i) { } + + } + + @QueryEntity + public static class ClassWithConstructor { + + public ClassWithConstructor() { } + + } + + @Test + public void classes_are_available() { + assertNotNull(QConstructorTest_CategorySuperclass.class); + assertNotNull(QConstructorTest_Category.class); + assertNotNull(QConstructorTest_ClassWithConstructor.class); + } + + @Test + public void category_super_reference_is_correct() { + assertEquals(QConstructorTest_CategorySuperclass.class, QConstructorTest_Category.category._super.getClass()); + assertEquals(Category.class, QConstructorTest_Category.category._super.getType()); + } + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/CustomCollection.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/CustomCollection.java new file mode 100644 index 0000000000..67fa2ccb70 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/CustomCollection.java @@ -0,0 +1,48 @@ +package com.querydsl.apt.domain; + +import java.util.AbstractSet; +import java.util.Iterator; + +import javax.persistence.Entity; + +public class CustomCollection { + + @Entity + public static class MyCustomCollection extends AbstractSet { + + @Override + public Iterator iterator() { + return null; + } + + @Override + public int size() { + return 0; + } + + } + + @Entity + public static class MyCustomCollection2 extends AbstractSet { + + @Override + public Iterator iterator() { + return null; + } + + @Override + public int size() { + return 0; + } + + } + + @Entity + public static class MyEntity { + + MyCustomCollection strings; + + MyCustomCollection2 strings2; + } + +} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/CustomMethods.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/CustomMethods.java similarity index 85% rename from querydsl-apt/src/test/java/com/mysema/query/domain/CustomMethods.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/CustomMethods.java index ed925e57b6..bb736bec5c 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/CustomMethods.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/CustomMethods.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.domain; +package com.querydsl.apt.domain; public class CustomMethods { diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/DeepInitializationTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/DeepInitializationTest.java new file mode 100644 index 0000000000..ac21b956ce --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/DeepInitializationTest.java @@ -0,0 +1,111 @@ +package com.querydsl.apt.domain; + +import java.util.Collection; + +import javax.persistence.*; + +import org.junit.Test; + +import com.querydsl.core.annotations.QueryInit; + +public class DeepInitializationTest { + + @MappedSuperclass + public abstract static class AbstractEntity implements Cloneable { + + @Id + @Column(name = "ID") + @GeneratedValue(generator = "SEQUENCE") + private long id; + + public long getId() { + return id; + } + + @Override + protected Object clone() throws CloneNotSupportedException { + return super.clone(); + } + } + + @Entity + @SequenceGenerator(name = "SEQUENCE", sequenceName = "PARENT_SEQUENCE") + public static class Parent extends AbstractEntity { + @JoinColumn(name = "FK_PARENT_ID", nullable = false) + @OneToMany(cascade = CascadeType.PERSIST) + @QueryInit("subChild.*") + private Collection children; + + public Parent() { + } + + public Collection getChildren() { + return children; + } + + public void setChildren(Collection children) { + this.children = children; + } + } + + @Entity + @SequenceGenerator(name = "SEQUENCE", sequenceName = "CHILD_SEQUENCE") + public static class Child extends AbstractEntity { + @OneToOne + @JoinColumn(name = "FK_SUBCHILD_ID", referencedColumnName = "ID") + private SubChild subChild; + + public Child() { + } + + public SubChild getSubChild() { + return subChild; + } + + public void setSubChild(SubChild subChild) { + this.subChild = subChild; + } + } + + @Entity + @SequenceGenerator(name = "SEQUENCE", sequenceName = "SUBCHILD_SEQUENCE") + public static class SubChild extends AbstractEntity { + @Embedded + private MyEmbeddable myEmbeddable; + + public SubChild() { + } + + public MyEmbeddable getMyEmbeddable() { + return myEmbeddable; + } + + public void setMyEmbeddable(MyEmbeddable myEmbeddable) { + this.myEmbeddable = myEmbeddable; + } + } + + @Embeddable + public static class MyEmbeddable { + + private String number; + + public MyEmbeddable() { + } + + public String getNumber() { + return number; + } + + public void setNumber(String number) { + this.number = number; + } + } + + @Test + public void init_via_parent() { + QDeepInitializationTest_Parent parent = QDeepInitializationTest_Parent.parent; + parent.children.any().subChild.myEmbeddable.number.eq("Test"); + } + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/Delegate2Test.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Delegate2Test.java new file mode 100644 index 0000000000..860955164b --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Delegate2Test.java @@ -0,0 +1,50 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt.domain; + +import static org.junit.Assert.assertNotNull; + +import org.junit.Test; + +import com.querydsl.core.annotations.QueryDelegate; +import com.querydsl.core.annotations.QueryEntity; +import com.querydsl.core.types.ConstantImpl; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberExpression; + +public class Delegate2Test { + + @QueryEntity + public static class Entity { + + Point point; + } + + public static class Point { + + } + + @QueryDelegate(Point.class) + public static NumberExpression geoDistance(Path point, Point other) { + return Expressions.numberTemplate(Integer.class, "geo_distance({0},{1})", point, ConstantImpl.create(other)); + } + + @Test + public void test() { + QDelegate2Test_Entity entity = QDelegate2Test_Entity.entity; + assertNotNull(entity.point.geoDistance(new Point())); + } + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/Delegate3Test.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Delegate3Test.java new file mode 100644 index 0000000000..874b763c5f --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Delegate3Test.java @@ -0,0 +1,40 @@ +package com.querydsl.apt.domain; + +import org.junit.Test; + +import com.querydsl.core.annotations.QueryDelegate; +import com.querydsl.core.types.dsl.BooleanExpression; +import com.querydsl.core.types.dsl.ComparablePath; +import com.querydsl.core.types.dsl.Expressions; + +public class Delegate3Test { + + public static class Geometry implements Comparable { + + @Override + public int compareTo(Geometry o) { + return 0; + } + + } + + public static class Point extends Geometry { + + } + + public static class Polygon extends Geometry { + + } + + @QueryDelegate(Geometry.class) + public static BooleanExpression isWithin(ComparablePath geo1, ComparablePath geo2) { + return Expressions.TRUE; + } + + @Test + public void test() { + QDelegate3Test_Geometry.geometry.isWithin(null); + QDelegate3Test_Point.point.isWithin(null); + QDelegate3Test_Polygon.polygon.isWithin(null); + } +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/DelegateTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/DelegateTest.java new file mode 100644 index 0000000000..9708e00026 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/DelegateTest.java @@ -0,0 +1,101 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt.domain; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import org.junit.Test; + +import com.querydsl.core.annotations.QueryDelegate; +import com.querydsl.core.annotations.QueryEntity; +import com.querydsl.core.annotations.QuerySupertype; +import com.querydsl.core.types.ConstantImpl; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.dsl.StringPath; + +public class DelegateTest { + + @QuerySupertype + public static class Identifiable { + + long id; + + } + + @QueryEntity + public static class User extends Identifiable { + + String name; + + User managedBy; + + } + + @QueryEntity + public static class SimpleUser extends User { + + } + + @QueryEntity + public static class SimpleUser2 extends SimpleUser { + + } + + @QueryDelegate(User.class) + public static Expression isManagedBy(QDelegateTest_User user, User other) { + return ConstantImpl.create(true); + } + + @QueryDelegate(User.class) + public static Expression isManagedBy(QDelegateTest_User user, QDelegateTest_User other) { + return ConstantImpl.create(true); + } + + @QueryDelegate(User.class) + public static Expression simpleMethod(QDelegateTest_User user) { + return ConstantImpl.create(true); + } + + @QueryDelegate(DelegateTest.User.class) + public static StringPath getName(QDelegateTest_User user) { + return user.name; + } + + @Test + public void user() { + QDelegateTest_User user = QDelegateTest_User.user; + assertNotNull(user.isManagedBy(new User())); + assertNotNull(user.isManagedBy(user)); + assertNotNull(user.simpleMethod()); + assertEquals(user.name, user.getName()); + } + + @Test + public void simpleUser() { + QDelegateTest_SimpleUser user = QDelegateTest_SimpleUser.simpleUser; + assertNotNull(user.isManagedBy(new User())); + assertNotNull(user.isManagedBy(user._super)); + assertEquals(user.name, user.getName()); + } + + @Test + public void simpleUser2() { + QDelegateTest_SimpleUser2 user = QDelegateTest_SimpleUser2.simpleUser2; + assertNotNull(user.isManagedBy(new User())); + assertNotNull(user.isManagedBy(user._super._super)); + assertEquals(user.name, user.getName()); + } + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/Embeddable2Test.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Embeddable2Test.java new file mode 100644 index 0000000000..d25608357e --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Embeddable2Test.java @@ -0,0 +1,64 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt.domain; + +import static org.junit.Assert.assertNotNull; + +import org.junit.Ignore; +import org.junit.Test; + +import com.querydsl.core.annotations.QueryEmbedded; +import com.querydsl.core.annotations.QueryEntity; +import com.querydsl.core.annotations.QuerySupertype; +import com.querydsl.core.domain.MyEmbeddable; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.PathInits; + +public class Embeddable2Test { + + @QuerySupertype + public abstract static class SomeMappedSuperClassHavingMyEmbeddable { + + @QueryEmbedded + MyEmbeddable embeddable; + } + + @QueryEntity + public abstract static class SomeEntityClassHavingMyEmbeddable { + + @QueryEmbedded + MyEmbeddable embeddable; + + } + + @QueryEntity + public static class SomeEntity extends SomeMappedSuperClassHavingMyEmbeddable { + + } + + @Test + @Ignore + public void mapped_superClass_constructors() throws SecurityException, NoSuchMethodException { + assertNotNull(QEmbeddable2Test_SomeMappedSuperClassHavingMyEmbeddable.class.getConstructor( + Class.class, PathMetadata.class, PathInits.class)); + } + + @Test + @Ignore + public void entity_constructors() throws SecurityException, NoSuchMethodException { + assertNotNull(QEmbeddable2Test_SomeEntityClassHavingMyEmbeddable.class.getConstructor( + Class.class, PathMetadata.class, PathInits.class)); + } + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/Embeddable3Test.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Embeddable3Test.java new file mode 100644 index 0000000000..317b1f2a81 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Embeddable3Test.java @@ -0,0 +1,38 @@ +package com.querydsl.apt.domain; + +import org.junit.Test; + +import com.querydsl.core.annotations.QueryEmbeddable; +import com.querydsl.core.annotations.QueryProjection; +import com.querydsl.core.types.dsl.Expressions; + +public class Embeddable3Test { + + @QueryEmbeddable + public static class EmbeddableClass { + private Integer embeddedProperty; + + public EmbeddableClass() { } + + @QueryProjection + public EmbeddableClass(Integer embeddedProperty) { + super(); + this.embeddedProperty = embeddedProperty; + } + + public Integer getEmbeddedProperty() { + return embeddedProperty; + } + + public void setEmbeddedProperty(Integer embeddedProperty) { + this.embeddedProperty = embeddedProperty; + } + + } + + @Test + public void test() { + QEmbeddable3Test_EmbeddableClass.create(Expressions.path(Integer.class, "num")); + } + +} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/EmbeddableDeepTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/EmbeddableDeepTest.java similarity index 87% rename from querydsl-apt/src/test/java/com/mysema/query/domain/EmbeddableDeepTest.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/EmbeddableDeepTest.java index 4535472247..4ea8d591f0 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/EmbeddableDeepTest.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/EmbeddableDeepTest.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.domain; +package com.querydsl.apt.domain; import java.io.Serializable; @@ -31,12 +31,12 @@ public enum SomeType { } @MappedSuperclass - public static abstract class AValueObject implements Cloneable, Serializable { + public abstract static class AValueObject implements Cloneable, Serializable { } @MappedSuperclass - public static abstract class AEntity extends AValueObject { + public abstract static class AEntity extends AValueObject { } diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/EmbeddableInterfaceTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/EmbeddableInterfaceTest.java new file mode 100644 index 0000000000..4b5e2249b6 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/EmbeddableInterfaceTest.java @@ -0,0 +1,66 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt.domain; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.util.Collection; + +import javax.persistence.ElementCollection; +import javax.persistence.Embeddable; +import javax.persistence.Entity; + +import org.junit.Test; + +public class EmbeddableInterfaceTest { + + @Entity + public static class EntityClass { + + @ElementCollection(targetClass = EmbeddableClass.class) + Collection children; + + } + + @Embeddable + public interface EmbeddableInterface { + + String getName(); + } + + @Embeddable + public static class EmbeddableClass implements EmbeddableInterface { + + @Override + public String getName() { + return null; + } + + } + + @Test + public void type() { + assertEquals( + QEmbeddableInterfaceTest_EmbeddableInterface.class, + QEmbeddableInterfaceTest_EntityClass.entityClass.children.any().getClass()); + } + + @Test + public void properties() { + assertNotNull(QEmbeddableInterfaceTest_EmbeddableInterface.embeddableInterface.name); + assertNotNull(QEmbeddableInterfaceTest_EmbeddableClass.embeddableClass.name); + } + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/EmbeddableTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/EmbeddableTest.java new file mode 100644 index 0000000000..83a7cf1c26 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/EmbeddableTest.java @@ -0,0 +1,80 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt.domain; + +import java.util.List; + +import org.junit.Ignore; + +import com.querydsl.core.annotations.QueryEmbeddable; +import com.querydsl.core.annotations.QueryEntity; +import com.querydsl.core.annotations.QuerySupertype; + +@Ignore +public class EmbeddableTest { + + @QueryEntity + public static class EntityWithEmbedded { + + public WithEntityRef e1; + + public WithStringProp e2; + + public WithEntityAndString e3; + + public WithList e4; + } + + @QueryEmbeddable + public static class WithEntityRef { + + public AnimalTest.Cat cat; + + } + + @QueryEmbeddable + public static class WithStringProp { + + public String str; + } + + @QueryEmbeddable + public static class WithEntityAndString extends WithEntityRef { + + public String str2; + + } + + @QueryEmbeddable + public static class WithList extends WithStringProp { + + public List cats; + + public String str3; + + } + + @QueryEntity + @QueryEmbeddable + public static class EntityAndEmbeddable { + + } + + @QuerySupertype + @QueryEmbeddable + public static class SuperclassAndEmbeddable { + + } + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/Embedded2Test.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Embedded2Test.java new file mode 100644 index 0000000000..c8881699f1 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Embedded2Test.java @@ -0,0 +1,85 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt.domain; + +import java.io.Serializable; + +import javax.persistence.*; + +import org.junit.Test; + +public class Embedded2Test { + + @MappedSuperclass + public static class EntityCode { + + @Column(name = "code", unique = true) + String code; + + } + + @MappedSuperclass + public abstract static class AbstractEntity { + + @Embedded + @Column(name = "code", nullable = false, unique = true) + C code; + + } + + @MappedSuperclass + public static class AbstractMultilingualEntity extends AbstractEntity { + + } + + @MappedSuperclass + public abstract static class AbstractNamedEntity extends AbstractMultilingualEntity { + + @Column(name = "name_en", nullable = false) + String nameEn; + + @Column(name = "name_nl") + String nameNl; + + } + + @javax.persistence.Entity + public static class Brand extends AbstractNamedEntity { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + @Column(name = "brand_id") + Long id; + + } + + public interface Entity extends Serializable { + + boolean sameIdentityAs(T other); + + } + + @Embeddable + public static class BrandCode extends EntityCode { + + } + + @Test + public void test() { + // TODO + } + + + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/EmbeddedTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/EmbeddedTest.java new file mode 100644 index 0000000000..b38f1dfd7d --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/EmbeddedTest.java @@ -0,0 +1,60 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt.domain; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import javax.persistence.*; + +import org.junit.Test; + +public class EmbeddedTest { + + @Entity + public static class EntityClass extends AbstractEntity { + + } + + @MappedSuperclass + public abstract static class AbstractEntity { + + @Embedded + @Column(name = "code", nullable = false, unique = true) + C code; + } + + @MappedSuperclass + public static class EntityCode { + + @Column(name = "code", unique = true) + String code; + + } + + @Embeddable + public static class SubEntityCode extends EntityCode { + + String property; + + } + + @Test + public void entityClass() { + assertNotNull(QEmbeddedTest_EntityClass.entityClass.code.property); + assertEquals(SubEntityCode.class, QEmbeddedTest_EntityClass.entityClass.code.getType()); + } + + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/EntityInheritanceTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/EntityInheritanceTest.java new file mode 100644 index 0000000000..4dd4a86311 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/EntityInheritanceTest.java @@ -0,0 +1,47 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt.domain; + +import javax.persistence.Entity; +import javax.persistence.MappedSuperclass; + +import org.junit.Assert; +import org.junit.Test; + +public class EntityInheritanceTest { + + @MappedSuperclass + public static class TreeEntity> { + + Integer id; + + T parent; + + } + + @Entity + public static class TestEntity extends TreeEntity { + + String name; + + } + + @Test + public void test() { + Assert.assertEquals( + QEntityInheritanceTest_TestEntity.class, + QEntityInheritanceTest_TestEntity.testEntity.parent.getClass()); + } + +} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/EntityTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/EntityTest.java similarity index 76% rename from querydsl-apt/src/test/java/com/mysema/query/domain/EntityTest.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/EntityTest.java index c563df6b35..69fd3c7e28 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/EntityTest.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/EntityTest.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,17 +11,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.domain; +package com.querydsl.apt.domain; import static org.junit.Assert.assertNotNull; import org.junit.Test; -import com.mysema.query.annotations.QueryEntity; -import com.mysema.query.annotations.QueryInit; -import com.mysema.query.annotations.QuerySupertype; -import com.mysema.query.types.PathMetadata; -import com.mysema.query.types.path.PathInits; +import com.querydsl.core.annotations.QueryEntity; +import com.querydsl.core.annotations.QueryInit; +import com.querydsl.core.annotations.QuerySupertype; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.PathInits; public class EntityTest extends AbstractTest { @@ -71,14 +71,14 @@ public static class Supertype { public static class Supertype2 extends Supertype { } - + @Test - public void Initialization_Depth() { + public void initialization_depth() { assertNotNull(QEntityTest_Entity1.entity1.entity1Ref.entity1Ref.entity1Field); } @Test - public void Inheritance() { + public void inheritance() { assertNotNull(entity3.entity3Ref.entity2Ref); assertNotNull(entity3.entity3Ref.entity3Ref); @@ -87,7 +87,7 @@ public void Inheritance() { } @Test - public void SupertypePaths() { + public void supertype_paths() { assertNotNull(entity3.superTypeEntityRef.entity2Ref); assertNotNull(entity3._super.superTypeEntityRef.entity2Ref); assertNotNull(entity3._super._super.superTypeEntityRef.entity2Ref); @@ -96,8 +96,8 @@ public void SupertypePaths() { } @Test - public void Constructors() throws SecurityException, NoSuchMethodException { - Class[] types = new Class[]{Class.class, PathMetadata.class, PathInits.class}; + public void constructors() throws SecurityException, NoSuchMethodException { + Class[] types = new Class[]{Class.class, PathMetadata.class, PathInits.class}; QEntityTest_Entity1.class.getConstructor(types); QEntityTest_Entity2.class.getConstructor(types); QEntityTest_Entity3.class.getConstructor(types); @@ -106,9 +106,9 @@ public void Constructors() throws SecurityException, NoSuchMethodException { QEntityTest_Supertype2.class.getConstructor(types); } - @Test(expected=NoSuchMethodException.class) - public void Constructors2() throws SecurityException, NoSuchMethodException { - Class[] types = new Class[]{Class.class, PathMetadata.class, PathInits.class}; + @Test(expected = NoSuchMethodException.class) + public void constructors2() throws SecurityException, NoSuchMethodException { + Class[] types = new Class[]{Class.class, PathMetadata.class, PathInits.class}; QEntityTest_EntityNoReferences.class.getConstructor(types); } diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/Enum2Test.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Enum2Test.java new file mode 100644 index 0000000000..1cf8060470 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Enum2Test.java @@ -0,0 +1,41 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt.domain; + +import org.junit.Ignore; + +import com.querydsl.core.annotations.QueryEntity; + +@Ignore +public class Enum2Test { + + @QueryEntity + public abstract static class EnumPermissions

& Permission> extends EntityImpl implements Permissions

{ + + } + + @QueryEntity + public abstract static class EntityImpl { + + } + + public interface Permission { + + } + + public interface Permissions

extends GenericBase { + P p; + } + + @QueryEntity + public static class Subclass extends GenericBaseSubclass { + } + + public static class AnotherClass { + } + + @Test + public void test() throws IllegalAccessException, NoSuchFieldException { + start(QGeneric13Test_GenericBase.class, QGeneric13Test_GenericBase.genericBase); + matchType(AnotherClass.class, "t"); + + start(QGeneric13Test_GenericBaseSubclass.class, QGeneric13Test_GenericBaseSubclass.genericBaseSubclass); + matchType(Object.class, "p"); + + start(QGeneric13Test_Subclass.class, QGeneric13Test_Subclass.subclass); + matchType(Number.class, "p"); + } +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/Generic14Test.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Generic14Test.java new file mode 100644 index 0000000000..4b2d3a6b69 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Generic14Test.java @@ -0,0 +1,75 @@ +package com.querydsl.apt.domain; + +import static org.junit.Assert.assertNotNull; + +import java.io.Serializable; + +import javax.persistence.Entity; +import javax.persistence.MappedSuperclass; + +import org.junit.Test; + +public class Generic14Test extends AbstractTest { + + @Entity + public static class UserAccount extends BaseReferencablePersistable { + + public UserAccount() { + super(UserAccount.class); + } + + } + + @MappedSuperclass + public abstract static class BaseReferencablePersistable extends BasePersistable { + + private Class entityClass; + + public BaseReferencablePersistable(Class entityClass) { + this.entityClass = entityClass; + } + + } + + @MappedSuperclass + public static class BasePersistable extends AbstractPersistable implements UpdateInfo { + + private T id; + + @Override + public T getId() { + return id; + } + + } + + @MappedSuperclass + public abstract static class AbstractPersistable implements Persistable { + + } + + public interface Persistable { + + T getId(); + + } + + public interface UpdateInfo { + + } + + @Test + public void test() throws IllegalAccessException, NoSuchFieldException { + assertNotNull(QGeneric14Test_AbstractPersistable.abstractPersistable); + + start(QGeneric14Test_BasePersistable.class, QGeneric14Test_BasePersistable.basePersistable); + matchType(Serializable.class, "id"); + + start(QGeneric14Test_BaseReferencablePersistable.class, QGeneric14Test_BaseReferencablePersistable.baseReferencablePersistable); + matchType(Class.class, "entityClass"); + matchType(Serializable.class, "id"); + + start(QGeneric14Test_UserAccount.class, QGeneric14Test_UserAccount.userAccount); + matchType(Long.class, "id"); + } +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/Generic15Test.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Generic15Test.java new file mode 100644 index 0000000000..83924cc6b1 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Generic15Test.java @@ -0,0 +1,41 @@ +package com.querydsl.apt.domain; + +import java.util.HashSet; +import java.util.Set; + +import javax.persistence.Entity; +import javax.persistence.MappedSuperclass; + +import org.junit.Test; + +public class Generic15Test extends AbstractTest { + + @MappedSuperclass + public abstract static class Compound { + + private Set containables = new HashSet(); + } + + @MappedSuperclass + public abstract static class Containable { + + private T compound; + } + + @Entity + public static class MyCompound extends Compound { + } + + @Entity + public static class MyContainable extends Containable { + + private String additionalField; + } + + @Test + public void test() throws IllegalAccessException, NoSuchFieldException { + start(QGeneric15Test_MyContainable.class, QGeneric15Test_MyContainable.myContainable); + match(QGeneric15Test_MyCompound.class, "compound"); + matchType(MyCompound.class, "compound"); + } +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/Generic16Test.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Generic16Test.java new file mode 100644 index 0000000000..f64d2eb8e6 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Generic16Test.java @@ -0,0 +1,50 @@ +package com.querydsl.apt.domain; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.util.SortedSet; +import java.util.TreeSet; + +import javax.persistence.Entity; +import javax.persistence.MappedSuperclass; + +import org.junit.Test; + +public class Generic16Test extends AbstractTest { + + @Entity + public abstract static class HidaBez, G extends HidaBezGruppe> extends CapiBCKeyedByGrundstueck { + + } + + @Entity + public abstract static class HidaBezGruppe, B extends HidaBez> extends CapiBCKeyedByGrundstueck { + + SortedSet bez = new TreeSet(); + + } + + @MappedSuperclass + public abstract static class CapiBCKeyedByGrundstueck extends CapiBusinessClass { + + } + + @MappedSuperclass + public abstract static class CapiBusinessClass implements ICapiBusinessClass { + + } + + public interface ICapiBusinessClass extends Comparable { + + + } + + @Test + public void test() { + assertNotNull(QGeneric16Test_HidaBez.hidaBez); + assertNotNull(QGeneric4Test_HidaBezGruppe.hidaBezGruppe); + assertTrue(QGeneric16Test_HidaBezGruppe.hidaBezGruppe.bez.getElementType().equals(HidaBez.class)); + } + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/Generic2Test.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Generic2Test.java new file mode 100644 index 0000000000..447c9bf25d --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Generic2Test.java @@ -0,0 +1,61 @@ +package com.querydsl.apt.domain; + +import java.io.Serializable; + +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.MappedSuperclass; + +import org.junit.Test; + +public class Generic2Test extends AbstractTest { + + public static class Range> { + private T min; + private T max; + + public T getMin() { + return min; + } + + public void setMin(T min) { + this.min = min; + } + + public T getMax() { + return max; + } + + public void setMax(T max) { + this.max = max; + } + } + + @MappedSuperclass + public abstract static class BaseEntity> implements + Serializable { + @Embedded + private Range range; + + public Range getRange() { + return range; + } + + public void setRange(Range range) { + this.range = range; + } + } + + @Entity + public static class Foo extends BaseEntity { + + } + + @Test + public void test() throws NoSuchFieldException { + start(QGeneric2Test_Foo.class, QGeneric2Test_Foo.foo); + assertPresent("range"); + match(QGeneric2Test_Range.class, "range"); + } + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/Generic3Test.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Generic3Test.java new file mode 100644 index 0000000000..c621110a6b --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Generic3Test.java @@ -0,0 +1,36 @@ +package com.querydsl.apt.domain; + +import javax.persistence.Entity; +import javax.persistence.MappedSuperclass; + +import org.junit.Test; + +import com.querydsl.core.types.dsl.StringPath; + +public class Generic3Test extends AbstractTest { + + @MappedSuperclass + public abstract static class BaseEntity> { + + } + + @MappedSuperclass + public abstract static class Order> extends BaseEntity implements Cloneable { + + String property1; + } + + @Entity + public static class MyOrder> extends Order { + + String property2; + } + + @Test + public void test() throws NoSuchFieldException { + start(QGeneric3Test_MyOrder.class, QGeneric3Test_MyOrder.myOrder); + match(StringPath.class, "property1"); + match(StringPath.class, "property2"); + } + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/Generic4Test.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Generic4Test.java new file mode 100644 index 0000000000..be6cc75021 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Generic4Test.java @@ -0,0 +1,30 @@ +package com.querydsl.apt.domain; + +import javax.persistence.MappedSuperclass; + +import org.junit.Test; + +public class Generic4Test { + + @MappedSuperclass + public abstract static class CapiBCKeyedByGrundstueck { + + } + + @MappedSuperclass + public abstract static class HidaBez, G extends HidaBezGruppe> extends CapiBCKeyedByGrundstueck { + + } + + @MappedSuperclass + public abstract static class HidaBezGruppe, B extends HidaBez> extends + CapiBCKeyedByGrundstueck { + + } + + @Test + public void test() { + + } + +} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/Generic5Test.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Generic5Test.java similarity index 82% rename from querydsl-apt/src/test/java/com/mysema/query/domain/Generic5Test.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/Generic5Test.java index 45f40be89b..8d5bf66b95 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/Generic5Test.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Generic5Test.java @@ -1,4 +1,4 @@ -package com.mysema.query.domain; +package com.querydsl.apt.domain; import javax.persistence.Entity; import javax.persistence.MappedSuperclass; @@ -6,35 +6,35 @@ import org.junit.Test; public class Generic5Test { - + @MappedSuperclass public static class Base> { - + } - + @Entity public static class Entity1> { - + } - + @Entity public static class Entity2 extends Entity1 { - + } - + @Entity public static class Entity3> extends Base { - + } - + @Entity public static class Entity4 extends Entity3 { - + } - + @Test public void test() { - + } } diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/Generic6Test.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Generic6Test.java similarity index 85% rename from querydsl-apt/src/test/java/com/mysema/query/domain/Generic6Test.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/Generic6Test.java index 01d278770b..d1bd4497c6 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/Generic6Test.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Generic6Test.java @@ -1,4 +1,4 @@ -package com.mysema.query.domain; +package com.querydsl.apt.domain; import javax.persistence.Entity; @@ -8,9 +8,9 @@ public class Generic6Test { @Entity public static class Cycle2> { - + } - + @Entity public static class Cycle1, T extends Cycle2> implements Comparable> { @@ -18,12 +18,12 @@ public static class Cycle1, T extends Cycle2> impleme public int compareTo(Cycle1 o) { return 0; } - + } - + @Test public void test() { - + } - + } diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/Generic7Test.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Generic7Test.java similarity index 84% rename from querydsl-apt/src/test/java/com/mysema/query/domain/Generic7Test.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/Generic7Test.java index 9429f05faf..9f055af4cf 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/Generic7Test.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Generic7Test.java @@ -1,11 +1,11 @@ -package com.mysema.query.domain; +package com.querydsl.apt.domain; import java.util.Collection; import java.util.List; import org.junit.Test; -import com.mysema.query.annotations.QueryEntity; +import com.querydsl.core.annotations.QueryEntity; public class Generic7Test { @@ -30,10 +30,10 @@ public static class Product { ListAttribute stringAttributes; } - + @Test public void test() { - + } - + } diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/Generic8Test.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Generic8Test.java new file mode 100644 index 0000000000..2aba2456f5 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Generic8Test.java @@ -0,0 +1,52 @@ +package com.querydsl.apt.domain; + +import java.util.List; + +import org.junit.Assert; +import org.junit.Test; + +import com.querydsl.core.annotations.QueryEntity; +import com.querydsl.core.annotations.QuerySupertype; + +public class Generic8Test { + + @QuerySupertype + public static class Superclass { + + Long id; + + List values; + + List values2; + + } + + @QueryEntity + public static class IntermediateEntity extends Superclass { + + } + + @QueryEntity + public static class Entity extends Superclass { + + } + + + @QueryEntity + public static class Entity2 extends Superclass { + + } + + @QueryEntity + public static class Entity3 extends IntermediateEntity { + + } + + @Test + public void test() { + Assert.assertEquals(String.class, QGeneric8Test_Entity.entity.values.getElementType()); + Assert.assertEquals(Integer.class, QGeneric8Test_Entity2.entity2.values.getElementType()); + Assert.assertEquals(String.class, QGeneric8Test_Entity3.entity3.values.getElementType()); + } + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/Generic9Test.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Generic9Test.java new file mode 100644 index 0000000000..a24c47945f --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Generic9Test.java @@ -0,0 +1,66 @@ +package com.querydsl.apt.domain; + +import java.io.Serializable; + +import javax.persistence.*; + +import org.junit.Test; + +public class Generic9Test { + + @MappedSuperclass + public abstract static class CommonOrganizationalUnit> extends + LocalizableEntity implements Serializable, Comparable> { + + P parent; + +// CommonOrganizationalUnit parent2; +// +// CommonOrganizationalUnit parent3; + + } + + @MappedSuperclass + public abstract static class ProductionSurface> extends + CommonOrganizationalUnit implements Serializable { + + } + +// @Entity +// public class Building extends ProductionSurface { +// +// } + + @MappedSuperclass + public abstract static class EntityLocalized extends CommonEntity { + + } + + @Entity + public static class Preference { + + } + + @Entity + @Table(name = "preference") + @DiscriminatorColumn(name = "discriminator", discriminatorType = DiscriminatorType.STRING) + public abstract static class TenantPreference extends Preference { + + } + + @MappedSuperclass + public abstract static class CommonEntity { + + } + + @MappedSuperclass + public abstract static class LocalizableEntity extends CommonEntity { + + } + + @Test + public void test() { + new QGeneric9Test_CommonOrganizationalUnit("test"); + } + +} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/GenericSignatureTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/GenericSignatureTest.java similarity index 75% rename from querydsl-apt/src/test/java/com/mysema/query/domain/GenericSignatureTest.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/GenericSignatureTest.java index 27845dc69a..4c675fdfa1 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/GenericSignatureTest.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/GenericSignatureTest.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,9 +11,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.domain; +package com.querydsl.apt.domain; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; import java.util.Collection; import java.util.List; @@ -22,43 +22,43 @@ import org.junit.Test; -import com.mysema.query.annotations.QueryEntity; +import com.querydsl.core.annotations.QueryEntity; public class GenericSignatureTest { - + @QueryEntity @SuppressWarnings("unchecked") public static class Entity> { - - // collection - Collection rawCollection; - - Collection> genericCollection; - + + // collection + Collection rawCollection; + + Collection> genericCollection; + Collection genericCollection2; - + // list - List rawList; - - List> genericList; - + List rawList; + + List> genericList; + List genericList2; - + // set - Set rawSet; - - Set> genericSet; - + Set rawSet; + + Set> genericSet; + Set genericSet2; - + // map - Map rawMap; - - Map> genericMap; - + Map rawMap; + + Map> genericMap; + Map genericMap2; } - + @Test public void test() { QGenericSignatureTest_Entity entity = QGenericSignatureTest_Entity.entity; @@ -66,17 +66,17 @@ public void test() { assertEquals(Entity.class, entity.rawCollection.getParameter(0)); assertEquals(Entity.class, entity.genericCollection.getParameter(0)); assertEquals(Entity.class, entity.genericCollection2.getParameter(0)); - + // list assertEquals(Entity.class, entity.rawList.getParameter(0)); assertEquals(Entity.class, entity.genericList.getParameter(0)); assertEquals(Entity.class, entity.genericList2.getParameter(0)); - + // set assertEquals(Entity.class, entity.rawSet.getParameter(0)); assertEquals(Entity.class, entity.genericSet.getParameter(0)); assertEquals(Entity.class, entity.genericSet2.getParameter(0)); - + // map assertEquals(Entity.class, entity.rawMap.getParameter(1)); assertEquals(Entity.class, entity.genericMap.getParameter(1)); diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/GenericStackOverflowTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/GenericStackOverflowTest.java new file mode 100644 index 0000000000..8b435d8168 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/GenericStackOverflowTest.java @@ -0,0 +1,29 @@ +package com.querydsl.apt.domain; + +import static org.junit.Assert.assertNotNull; + +import java.io.Serializable; + +import org.junit.Test; + +import com.querydsl.core.annotations.QueryEntity; +import com.querydsl.core.annotations.QuerySupertype; + +public class GenericStackOverflowTest extends AbstractTest { + + public interface Identifiable & Serializable> { + } + + @QuerySupertype + public abstract static class AbstractEntity & Serializable> implements Identifiable { + } + + @QueryEntity + public static class TestEntity extends AbstractEntity { + } + + @Test + public void test() { + assertNotNull(QGenericStackOverflowTest_AbstractEntity.abstractEntity); + } +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/GenericTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/GenericTest.java new file mode 100644 index 0000000000..02c706276f --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/GenericTest.java @@ -0,0 +1,143 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt.domain; + +import static org.junit.Assert.assertNotNull; + +import java.util.Date; + +import org.junit.Test; + +import com.querydsl.apt.domain.rel.SimpleType; +import com.querydsl.apt.domain.rel.SimpleType2; +import com.querydsl.core.annotations.QueryEntity; +import com.querydsl.core.annotations.QueryTransient; + +public class GenericTest extends AbstractTest { + + @QueryEntity + public static class GenericType { + T itemType; + } + + @QueryEntity + @SuppressWarnings("unchecked") + public static class GenericType2 { + T itemType; + + // simple + GenericSimpleType prop1; + GenericSimpleType prop2; + GenericSimpleType> prop3; + + // comparable + GenericComparableType comp1; + GenericComparableType comp2; + GenericComparableType comp3; + + // number + + @QueryTransient + GenericNumberType num1; // NOTE : doesn't work! + + GenericNumberType num2; + GenericNumberType num3; + } + + public static class GenericSimpleType> { + + } + + @SuppressWarnings("unchecked") + public static class GenericComparableType implements Comparable> { + @Override + public int compareTo(GenericComparableType o) { + return 0; + } + + @Override + public boolean equals(Object o) { + return o instanceof GenericComparableType; + } + } + + @SuppressWarnings({ "unchecked", "serial" }) + public static class GenericNumberType extends Number implements Comparable> { + @Override + public double doubleValue() { + return 0; + } + @Override + public float floatValue() { + return 0; + } + @Override + public int intValue() { + return 0; + } + @Override + public long longValue() { + return 0; + } + @Override + public int compareTo(GenericNumberType o) { + return 0; + } + + @Override + public int hashCode() { + return super.hashCode(); + } + + @Override + public boolean equals(Object o) { + return o instanceof GenericNumberType; + } + } + + @QueryEntity + @SuppressWarnings("unchecked") + public static class ItemType { + Amount prop; + SimpleType2> prop2; + SimpleType2 prop3; + SimpleType2 prop4; + } + + public static class Amount { + + } + + @Test + public void test() throws NoSuchFieldException, IllegalAccessException { + assertNotNull(QGenericTest_ItemType.itemType); + assertNotNull(QGenericTest_GenericType.genericType); + assertNotNull(QGenericTest_GenericType2.genericType2); + + start(QGenericTest_GenericType.class, QGenericTest_GenericType.genericType); + matchType(ItemType.class, "itemType"); + + start(QGenericTest_GenericType2.class, QGenericTest_GenericType2.genericType2); + matchType(ItemType.class, "itemType"); + matchType(GenericSimpleType.class, "prop1"); + matchType(GenericSimpleType.class, "prop2"); + matchType(GenericSimpleType.class, "prop3"); + matchType(GenericComparableType.class, "comp1"); + matchType(GenericComparableType.class, "comp2"); + matchType(GenericComparableType.class, "comp3"); + assertMissing("num1"); + matchType(GenericNumberType.class, "num2"); + matchType(GenericNumberType.class, "num3"); + } +} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/Hierarchy2Test.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Hierarchy2Test.java similarity index 78% rename from querydsl-apt/src/test/java/com/mysema/query/domain/Hierarchy2Test.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/Hierarchy2Test.java index 3ed97bf269..3d0442e24e 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/Hierarchy2Test.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Hierarchy2Test.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,14 +11,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.domain; +package com.querydsl.apt.domain; -import javax.persistence.Basic; -import javax.persistence.Embeddable; -import javax.persistence.Embedded; -import javax.persistence.Entity; -import javax.persistence.MappedSuperclass; -import javax.persistence.OneToOne; +import javax.persistence.*; import org.junit.Ignore; @@ -26,7 +21,7 @@ public class Hierarchy2Test { @MappedSuperclass - public static abstract class SomeMappedSuperClassHavingMyEmbeddable { + public abstract static class SomeMappedSuperClassHavingMyEmbeddable { @Embedded MyEmbeddable embeddable; @@ -55,7 +50,7 @@ public static class MyEmbeddable implements Comparable { public int compareTo(MyEmbeddable individualToCompare) { return -1; } - + public boolean equals(Object o) { return o == this; } diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/HierarchyTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/HierarchyTest.java similarity index 88% rename from querydsl-apt/src/test/java/com/mysema/query/domain/HierarchyTest.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/HierarchyTest.java index bb394c9d67..80f6d49b06 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/HierarchyTest.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/HierarchyTest.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,16 +11,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.domain; +package com.querydsl.apt.domain; + +import static org.junit.Assert.assertNotNull; import javax.persistence.Column; import javax.persistence.Entity; -import com.mysema.query.annotations.PropertyType; -import com.mysema.query.annotations.QueryType; import org.junit.Test; -import static org.junit.Assert.assertNotNull; +import com.querydsl.core.annotations.PropertyType; +import com.querydsl.core.annotations.QueryType; public class HierarchyTest { diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/InitTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/InitTest.java new file mode 100644 index 0000000000..b88430b343 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/InitTest.java @@ -0,0 +1,49 @@ +package com.querydsl.apt.domain; + +import org.junit.Test; + +import javax.persistence.*; + +import static org.junit.Assert.assertNotNull; + +public class InitTest { + + @Entity + public static class User { + + @ManyToOne(fetch = FetchType.EAGER) + private Address address; + + } + + @Entity + public static class Address extends AddressBase { + + } + + @MappedSuperclass + public abstract static class AddressBase { + + @Id + private long idAddress; + + @Id + private int numVersion; + + @ManyToOne + private City city; + + } + + @Entity + public static class City { + + } + + @Test + public void test() { + assertNotNull(QInitTest_User.user.address.city); + } + + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/InnerExtensionsTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/InnerExtensionsTest.java new file mode 100644 index 0000000000..fff4c181cc --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/InnerExtensionsTest.java @@ -0,0 +1,31 @@ +package com.querydsl.apt.domain; + +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.Arrays; +import java.util.List; + +import org.junit.Test; + +import com.querydsl.apt.AbstractProcessorTest; +import com.querydsl.apt.QuerydslAnnotationProcessor; + +public class InnerExtensionsTest extends AbstractProcessorTest { + + private static final String packagePath = "src/test/apt/com/querydsl/"; + + @Test + public void process() throws IOException { + List sources = Arrays.asList( + new File(packagePath, "InnerExtensions.java").getPath(), + new File(packagePath, "ExampleEntity2.java").getPath()); + process(QuerydslAnnotationProcessor.class, sources, "innerextensions"); + String qtypeContent = new String(Files.readAllBytes(Paths.get("target", "innerextensions", "com", "querydsl", "QExampleEntity2.java")), StandardCharsets.UTF_8); + assertTrue(qtypeContent.contains("return InnerExtensions.ExampleEntity2Extensions.isZero(this);")); + } +} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/InterfaceType2Test.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/InterfaceType2Test.java similarity index 81% rename from querydsl-apt/src/test/java/com/mysema/query/domain/InterfaceType2Test.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/InterfaceType2Test.java index 9643c3d176..f57822609e 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/InterfaceType2Test.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/InterfaceType2Test.java @@ -1,18 +1,9 @@ -package com.mysema.query.domain; +package com.querydsl.apt.domain; -import static org.junit.Assert.assertEquals; - -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.MappedSuperclass; -import javax.persistence.Table; +import javax.persistence.*; import org.hibernate.annotations.NaturalId; +import org.junit.Assert; import org.junit.Test; public class InterfaceType2Test { @@ -90,7 +81,7 @@ public void setParty(Party party) { @Table(name = "PARTY") @org.hibernate.annotations.AccessType("field") @org.hibernate.annotations.Proxy(proxyClass = Party.class) - public static abstract class PartyImpl extends EntityImpl implements Party { + public abstract static class PartyImpl extends EntityImpl implements Party { @Column(name = "NAME", nullable = false) private String name; @@ -108,7 +99,7 @@ public void setName(String name) { @Test public void test() { - assertEquals( + Assert.assertEquals( QInterfaceType2Test_PartyImpl.class, QInterfaceType2Test_UserImpl.userImpl.party.getClass()); } diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/InterfaceType3Test.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/InterfaceType3Test.java similarity index 85% rename from querydsl-apt/src/test/java/com/mysema/query/domain/InterfaceType3Test.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/InterfaceType3Test.java index e0c7e2ffa8..00b8bed962 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/InterfaceType3Test.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/InterfaceType3Test.java @@ -1,11 +1,13 @@ -package com.mysema.query.domain; +package com.querydsl.apt.domain; -import com.mysema.query.annotations.QueryEntity; -import org.junit.Test; import static org.junit.Assert.assertNotNull; +import org.junit.Test; + +import com.querydsl.core.annotations.QueryEntity; + public class InterfaceType3Test { - + @QueryEntity public interface A { String getA(); @@ -20,7 +22,7 @@ public interface B { public interface C extends A, B { String getC(); } - + @Test public void test() { assertNotNull(QInterfaceType3Test_C.c1.a); diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/InterfaceTypeTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/InterfaceTypeTest.java new file mode 100644 index 0000000000..012eccce47 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/InterfaceTypeTest.java @@ -0,0 +1,109 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt.domain; + +import java.util.List; + +import org.junit.Test; + +import com.querydsl.core.annotations.QueryEntity; +import com.querydsl.core.types.dsl.ListPath; +import com.querydsl.core.types.dsl.NumberPath; + +public class InterfaceTypeTest extends AbstractTest { + + @QueryEntity + public interface InterfaceType { + InterfaceType getRelation(); + + List getRelation2(); + + List getRelation3(); + + int getRelation4(); + + String getProp(); + } + + @QueryEntity + public interface InterfaceType2 { + + String getProp2(); + + } + + @QueryEntity + public interface InterfaceType3 extends InterfaceType, InterfaceType2 { + + String getProp3(); + + } + + @QueryEntity + public interface InterfaceType4 { + + String getProp4(); + + } + + @QueryEntity + public interface InterfaceType5 extends InterfaceType3, InterfaceType4 { + + String getProp5(); + + } + + @Test + public void qInterfaceType_relation() throws SecurityException, NoSuchFieldException { + start(QInterfaceTypeTest_InterfaceType.class, QInterfaceTypeTest_InterfaceType.interfaceType); + match(QInterfaceTypeTest_InterfaceType.class, "relation"); + } + + @Test + public void qInterfaceType_relation2() throws SecurityException, NoSuchFieldException { + start(QInterfaceTypeTest_InterfaceType.class, QInterfaceTypeTest_InterfaceType.interfaceType); + match(ListPath.class, "relation2"); + } + + @Test + public void qInterfaceType_relation3() throws SecurityException, NoSuchFieldException { + start(QInterfaceTypeTest_InterfaceType.class, QInterfaceTypeTest_InterfaceType.interfaceType); + match(ListPath.class, "relation3"); + } + + @Test + public void qInterfaceType_relation4() throws SecurityException, NoSuchFieldException { + start(QInterfaceTypeTest_InterfaceType.class, QInterfaceTypeTest_InterfaceType.interfaceType); + match(NumberPath.class, "relation4"); + } + + @Test + public void qInterfaceType3() throws SecurityException, NoSuchFieldException { + Class cl = QInterfaceTypeTest_InterfaceType3.class; + cl.getField("prop"); + cl.getField("prop2"); + cl.getField("prop3"); + } + + @Test + public void qInterfaceType5() throws SecurityException, NoSuchFieldException { + Class cl = QInterfaceTypeTest_InterfaceType5.class; + cl.getField("prop"); + cl.getField("prop2"); + cl.getField("prop3"); + cl.getField("prop4"); + cl.getField("prop5"); + } + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/JDOTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/JDOTest.java new file mode 100644 index 0000000000..ffc6e01bab --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/JDOTest.java @@ -0,0 +1,92 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt.domain; + +import javax.jdo.annotations.NotPersistent; +import javax.jdo.annotations.PersistenceCapable; +import javax.jdo.annotations.Persistent; +import javax.jdo.annotations.PrimaryKey; + +import org.junit.Test; + +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.StringPath; + +public class JDOTest extends AbstractTest { + + @PersistenceCapable + public static class JDOEntity { + + String prop; + + @NotPersistent + String skipped; + + @NotPersistent + JDOEntity skippedEntity; + } + + @PersistenceCapable + public static class JDOEntity2 { + + private String stringField1; + + private String stringField2; + + public String getStringfield1() { + return stringField1; + } + + public String getStringField2() { + return stringField2; + } + } + + @PersistenceCapable + public static class JDOEntity3 { + + private Integer integerField; + + private String stringField; + + @PrimaryKey + public Integer getId() { + return integerField; + } + + @Persistent + public String getName() { + return stringField; + } + } + + @Test + public void test() throws IllegalAccessException, NoSuchFieldException { + start(QJDOTest_JDOEntity.class, QJDOTest_JDOEntity.jDOEntity); + match(StringPath.class, "prop"); + assertMissing("skipped"); + assertMissing("skippedEntity"); + + start(QJDOTest_JDOEntity2.class, QJDOTest_JDOEntity2.jDOEntity2); + match(StringPath.class, "stringField1"); + assertMissing("stringfield1"); + match(StringPath.class, "stringField2"); + + start(QJDOTest_JDOEntity3.class, QJDOTest_JDOEntity3.jDOEntity3); + match(NumberPath.class, "id"); + matchType(Integer.class, "id"); + match(StringPath.class, "name"); + } + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/JPATest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/JPATest.java new file mode 100644 index 0000000000..e49463d609 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/JPATest.java @@ -0,0 +1,44 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt.domain; + +import javax.persistence.Entity; +import javax.persistence.Transient; + +import org.junit.Test; + +import com.querydsl.core.types.dsl.StringPath; + +public class JPATest extends AbstractTest { + + @Entity + public static class JPAEntity { + + String prop; + + @Transient + String skipped; + + @Transient + JDOTest.JDOEntity skippedEntity; + } + + @Test + public void test() throws SecurityException, NoSuchFieldException { + start(QJPATest_JPAEntity.class, QJPATest_JPAEntity.jPAEntity); + match(StringPath.class, "prop"); + assertMissing("skipped"); + assertMissing("skippedEntity"); + } +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/JodaMoneyHelpers.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/JodaMoneyHelpers.java new file mode 100644 index 0000000000..9425c39e1e --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/JodaMoneyHelpers.java @@ -0,0 +1,22 @@ +package com.querydsl.apt.domain; + +import java.math.BigDecimal; + +import org.joda.money.Money; +import org.joda.money.QMoney; + +import com.querydsl.core.annotations.QueryDelegate; +import com.querydsl.core.types.Ops; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberExpression; + +public final class JodaMoneyHelpers { + + private JodaMoneyHelpers() { } + + @QueryDelegate(Money.class) + public static NumberExpression sum(QMoney money) { + return Expressions.numberOperation(BigDecimal.class, Ops.AggOps.SUM_AGG, money); + } + +} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/JodaMoneyTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/JodaMoneyTest.java similarity index 77% rename from querydsl-apt/src/test/java/com/mysema/query/domain/JodaMoneyTest.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/JodaMoneyTest.java index 9b7a15d6a3..0863132af0 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/JodaMoneyTest.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/JodaMoneyTest.java @@ -1,4 +1,4 @@ -package com.mysema.query.domain; +package com.querydsl.apt.domain; import static org.junit.Assert.assertNotNull; @@ -7,7 +7,7 @@ import org.joda.money.QMoney; import org.junit.Test; -import com.mysema.query.types.expr.NumberExpression; +import com.querydsl.core.types.dsl.NumberExpression; public class JodaMoneyTest { diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/JodaTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/JodaTest.java new file mode 100644 index 0000000000..7e2313fe2f --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/JodaTest.java @@ -0,0 +1,40 @@ +package com.querydsl.apt.domain; + +import static org.junit.Assert.assertEquals; + +import java.util.Date; + +import javax.persistence.*; + +import org.joda.time.DateTime; +import org.junit.Test; + +public class JodaTest { + + @MappedSuperclass + @Access(AccessType.FIELD) + public abstract static class BaseEntity { + + public abstract Long getId(); + + @Temporal(TemporalType.TIMESTAMP) + private Date createdDate; + + public boolean isNew() { + return null == getId(); + } + + public DateTime getCreatedDate() { + return null == createdDate ? null : new DateTime(createdDate); + } + + public void setCreatedDate(DateTime creationDate) { + this.createdDate = null == creationDate ? null : creationDate.toDate(); + } + } + + @Test + public void test() { + assertEquals(Date.class, QJodaTest_BaseEntity.baseEntity.createdDate.getType()); + } +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/JodaTimeSupportTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/JodaTimeSupportTest.java new file mode 100644 index 0000000000..8d4f0cfcfe --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/JodaTimeSupportTest.java @@ -0,0 +1,64 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt.domain; + +import org.joda.time.*; +import org.junit.Test; + +import com.querydsl.core.annotations.QueryEntity; +import com.querydsl.core.types.dsl.ComparablePath; +import com.querydsl.core.types.dsl.DatePath; +import com.querydsl.core.types.dsl.DateTimePath; +import com.querydsl.core.types.dsl.TimePath; + +public class JodaTimeSupportTest extends AbstractTest { + + @QueryEntity + public static class JodaTimeSupport { + + DateMidnight dateMidnight; + + DateTime dateTime; + + Instant instant; + + LocalDate localDate; + + LocalDateTime localDateTime; + + LocalTime localTime; + + Partial partial; + + } + + @Test + public void test() throws IllegalAccessException, NoSuchFieldException { + start(QJodaTimeSupportTest_JodaTimeSupport.class, QJodaTimeSupportTest_JodaTimeSupport.jodaTimeSupport); + match(DateTimePath.class, "dateMidnight"); + matchType(DateMidnight.class, "dateMidnight"); + match(DateTimePath.class, "dateTime"); + matchType(DateTime.class, "dateTime"); + match(DateTimePath.class, "instant"); + matchType(Instant.class, "instant"); + match(DatePath.class, "localDate"); + matchType(LocalDate.class, "localDate"); + match(DateTimePath.class, "localDateTime"); + matchType(LocalDateTime.class, "localDateTime"); + match(TimePath.class, "localTime"); + matchType(LocalTime.class, "localTime"); + match(ComparablePath.class, "partial"); + matchType(Partial.class, "partial"); + } +} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/KeywordsTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/KeywordsTest.java similarity index 76% rename from querydsl-apt/src/test/java/com/mysema/query/domain/KeywordsTest.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/KeywordsTest.java index 53abcc5f02..34fbc262c9 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/KeywordsTest.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/KeywordsTest.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.domain; +package com.querydsl.apt.domain; import static org.junit.Assert.assertEquals; @@ -47,10 +47,10 @@ public static class Distinct { @Test public void test() { - assertEquals("order1",QKeywordsTest_Order.order.toString()); + assertEquals("order1", QKeywordsTest_Order.order.toString()); assertEquals("from1", QKeywordsTest_From.from.toString()); - assertEquals("nonKeyword",QKeywordsTest_NonKeyword.nonKeyword.toString()); - assertEquals("distinct1",QKeywordsTest_Distinct.distinct1.toString()); + assertEquals("nonKeyword", QKeywordsTest_NonKeyword.nonKeyword.toString()); + assertEquals("distinct1", QKeywordsTest_Distinct.distinct1.toString()); } } diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/LiteralEntityTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/LiteralEntityTest.java similarity index 82% rename from querydsl-apt/src/test/java/com/mysema/query/domain/LiteralEntityTest.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/LiteralEntityTest.java index f28a3ff6e9..029e47559e 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/LiteralEntityTest.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/LiteralEntityTest.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,14 +11,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.domain; +package com.querydsl.apt.domain; -import com.mysema.query.annotations.QueryEntity; -import com.mysema.query.types.path.EnumPath; -import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import org.junit.Test; + +import com.querydsl.core.annotations.QueryEntity; +import com.querydsl.core.types.dsl.EnumPath; + public class LiteralEntityTest { @QueryEntity diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/Location.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Location.java new file mode 100644 index 0000000000..3a6d27813a --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Location.java @@ -0,0 +1,11 @@ +package com.querydsl.apt.domain; + +import java.util.Set; + +import javax.persistence.Entity; + +@Entity +public class Location { + + public Set paths; +} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/ManagedEmailTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/ManagedEmailTest.java similarity index 81% rename from querydsl-apt/src/test/java/com/mysema/query/domain/ManagedEmailTest.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/ManagedEmailTest.java index 09541eaefe..8da49c6a2d 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/ManagedEmailTest.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/ManagedEmailTest.java @@ -1,4 +1,4 @@ -package com.mysema.query.domain; +package com.querydsl.apt.domain; import static org.junit.Assert.assertEquals; @@ -8,6 +8,7 @@ import javax.persistence.MapKey; import javax.persistence.OneToMany; +import org.junit.Assert; import org.junit.Test; public class ManagedEmailTest { @@ -34,7 +35,7 @@ public static class ManagedEmails { @Test public void test() { - assertEquals(EmailType.class, QManagedEmailTest_ManagedEmails.managedEmails.emails.getKeyType()); + Assert.assertEquals(EmailType.class, QManagedEmailTest_ManagedEmails.managedEmails.emails.getKeyType()); assertEquals(ManagedEmailImpl.class, QManagedEmailTest_ManagedEmails.managedEmails.emails.getValueType()); } diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/ManyToManyTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/ManyToManyTest.java new file mode 100644 index 0000000000..c0547f9ae3 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/ManyToManyTest.java @@ -0,0 +1,34 @@ +package com.querydsl.apt.domain; + +import java.util.Set; + +import javax.persistence.Entity; +import javax.persistence.ManyToMany; + +import org.junit.Assert; +import org.junit.Test; + +public class ManyToManyTest { + + public interface PhoneNumber { + + } + + @Entity + public static class PhoneNumberImpl { + + } + + @Entity + public static class Person { + + @ManyToMany(targetEntity = PhoneNumberImpl.class) + Set phones; + } + + @Test + public void test() { + Assert.assertEquals(PhoneNumberImpl.class, QManyToManyTest_Person.person.phones.getElementType()); + } + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/MonitoredCompany.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/MonitoredCompany.java new file mode 100644 index 0000000000..5ddbf321f3 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/MonitoredCompany.java @@ -0,0 +1,31 @@ +package com.querydsl.apt.domain; + +import com.querydsl.core.annotations.QueryEntity; +import com.querydsl.core.annotations.QueryInit; +import com.querydsl.core.domain.CompanyGroup; + +@QueryEntity +public class MonitoredCompany { + + private Long key; + + @QueryInit("mainCompany") + private CompanyGroup companyGroup; + + public Long getKey() { + return key; + } + + public void setKey(final Long aKey) { + this.key = aKey; + } + + public CompanyGroup getCompanyGroup() { + return companyGroup; + } + + public void setCompanyGroup(CompanyGroup aCompanyGroup) { + this.companyGroup = aCompanyGroup; + } + +} \ No newline at end of file diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/MonitoredCompanyTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/MonitoredCompanyTest.java new file mode 100644 index 0000000000..37c87a78a4 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/MonitoredCompanyTest.java @@ -0,0 +1,16 @@ +package com.querydsl.apt.domain; + +import static org.junit.Assert.assertNotNull; + +import org.junit.Test; + +public class MonitoredCompanyTest { + + @Test + public void test() { + QMonitoredCompany monitoredCompany = QMonitoredCompany.monitoredCompany; + assertNotNull(monitoredCompany.companyGroup); + assertNotNull(monitoredCompany.companyGroup.mainCompany); + } + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/NumberTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/NumberTest.java new file mode 100644 index 0000000000..769d39e9f1 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/NumberTest.java @@ -0,0 +1,17 @@ +package com.querydsl.apt.domain; + +import org.junit.Ignore; + +import com.querydsl.apt.domain.custom.CustomNumber; +import com.querydsl.core.annotations.QueryEntity; + +@Ignore +public class NumberTest { + + @QueryEntity + public static class Entity { + + CustomNumber customNumber; + + } +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/OneToOneTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/OneToOneTest.java new file mode 100644 index 0000000000..3821444b1b --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/OneToOneTest.java @@ -0,0 +1,31 @@ +package com.querydsl.apt.domain; + +import javax.persistence.Entity; +import javax.persistence.OneToOne; + +import org.junit.Assert; +import org.junit.Test; + +public class OneToOneTest { + + public interface PhoneNumber { + + } + + @Entity + public static class PhoneNumberImpl { + + } + + @Entity + public static class Person { + + @OneToOne(targetEntity = PhoneNumberImpl.class) + PhoneNumber phone; + } + + @Test + public void test() { + Assert.assertEquals(PhoneNumberImpl.class, QOneToOneTest_Person.person.phone.getType()); + } +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/OrderTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/OrderTest.java new file mode 100644 index 0000000000..06b65f3d28 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/OrderTest.java @@ -0,0 +1,32 @@ +package com.querydsl.apt.domain; + +import static org.junit.Assert.assertEquals; + +import java.util.List; + +import javax.persistence.Entity; +import javax.persistence.OneToMany; + +import org.junit.Test; + +public class OrderTest { + + @Entity + public static class Order { + @OneToMany(targetEntity = OrderItemImpl.class) + List orderItems; + } + + @Entity + public interface OrderItem { } + + @Entity + public static class OrderItemImpl implements OrderItem { } + + @Test + public void test() { + assertEquals(QOrderTest_OrderItemImpl.class, + QOrderTest_Order.order.orderItems.any().getClass()); + } + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/Path.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Path.java new file mode 100644 index 0000000000..cb7e3516f4 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Path.java @@ -0,0 +1,8 @@ +package com.querydsl.apt.domain; + +import javax.persistence.Entity; + +@Entity +public class Path { + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/PathInits.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/PathInits.java new file mode 100644 index 0000000000..43ff18930b --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/PathInits.java @@ -0,0 +1,5 @@ +package com.querydsl.apt.domain; + +public class PathInits { + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/PathMetadata.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/PathMetadata.java new file mode 100644 index 0000000000..33a735e53a --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/PathMetadata.java @@ -0,0 +1,5 @@ +package com.querydsl.apt.domain; + +public class PathMetadata { + +} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/PathMetadataTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/PathMetadataTest.java similarity index 89% rename from querydsl-apt/src/test/java/com/mysema/query/domain/PathMetadataTest.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/PathMetadataTest.java index 4f8005ab22..0b0e33d028 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/PathMetadataTest.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/PathMetadataTest.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.domain; +package com.querydsl.apt.domain; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; @@ -23,8 +23,8 @@ import org.junit.Ignore; import org.junit.Test; -import com.mysema.query.types.ConstantImpl; -import com.mysema.query.types.expr.StringExpression; +import com.querydsl.core.types.ConstantImpl; +import com.querydsl.core.types.dsl.StringExpression; @Ignore public class PathMetadataTest { @@ -38,7 +38,7 @@ public void setUp() { } @SuppressWarnings("unchecked") - @Test + @Test public void test() throws Exception { Field field = ConstantImpl.class.getDeclaredField("STRINGS"); field.setAccessible(true); diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/PathTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/PathTest.java new file mode 100644 index 0000000000..c56971e01f --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/PathTest.java @@ -0,0 +1,14 @@ +package com.querydsl.apt.domain; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +public class PathTest { + + @Test + public void test() { + assertEquals(Path.class, QPath.path.getType()); + } + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/Person.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Person.java new file mode 100644 index 0000000000..7f4e3f4a62 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Person.java @@ -0,0 +1,140 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt.domain; + +import java.io.Serializable; + +import javax.persistence.*; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * + * @author Arash + */ +@Entity +@Table(name = "Person", catalog = "TestDB", schema = "dbo") +@XmlRootElement +@NamedQueries({ + @NamedQuery(name = "Person.findAll", query = "SELECT p FROM Person p"), + @NamedQuery(name = "Person.findByPersonId", query = "SELECT p FROM Person p WHERE p.personId = :personId"), + @NamedQuery(name = "Person.findByPersonName", query = "SELECT p FROM Person p WHERE p.personName = :personName"), + @NamedQuery(name = "Person.findByPersonFamily", query = "SELECT p FROM Person p WHERE p.personFamily = :personFamily"), + @NamedQuery(name = "Person.findByPersonReference", query = "SELECT p FROM Person p WHERE p.personReference = :personReference")}) +public class Person implements Serializable { + private static final long serialVersionUID = 1L; + @Id + @Basic(optional = false) + @Column(name = "person_id", nullable = false) + private Integer personId; + + @Column(name = "person_name", length = 50) + private String personName; + + @Column(name = "person_family", length = 50) + private String personFamily; + + @Column(name = "person_reference") + + private Integer personReference; + @OneToOne(cascade = CascadeType.ALL, mappedBy = "person1", fetch = FetchType.LAZY) + + private Person person; + @JoinColumn(name = "person_id", referencedColumnName = "person_id", nullable = false, insertable = false, updatable = false) + @OneToOne(optional = false, fetch = FetchType.LAZY) + + private Person person1; + + public Person() { + } + + public Person(Integer personId) { + this.personId = personId; + } + + public Integer getPersonId() { + return personId; + } + + public void setPersonId(Integer personId) { + this.personId = personId; + } + + public String getPersonName() { + return personName; + } + + public void setPersonName(String personName) { + this.personName = personName; + } + + public String getPersonFamily() { + return personFamily; + } + + public void setPersonFamily(String personFamily) { + this.personFamily = personFamily; + } + + public Integer getPersonReference() { + return personReference; + } + + public void setPersonReference(Integer personReference) { + this.personReference = personReference; + } + + public Person getPerson() { + return person; + } + + public void setPerson(Person person) { + this.person = person; + } + + public Person getPerson1() { + return person1; + } + + public void setPerson1(Person person1) { + this.person1 = person1; + } + + @Override + public int hashCode() { + int hash = 0; + hash += (personId != null ? personId.hashCode() : 0); + return hash; + } + + @Override + public boolean equals(Object object) { + // TODO: Warning - this method won't work in the case the id fields are not set + if (!(object instanceof Person)) { + return false; + } + Person other = (Person) object; + if ((this.personId == null && other.personId != null) || (this.personId != null && !this.personId.equals(other.personId))) { + return false; + } + return true; + } + + @Override + public String toString() { + return "newpackage.Person[ personId=" + personId + " ]"; + } + + + +} \ No newline at end of file diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/PersonTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/PersonTest.java similarity index 87% rename from querydsl-apt/src/test/java/com/mysema/query/domain/PersonTest.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/PersonTest.java index 846db2bc5a..cc46cea16c 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/PersonTest.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/PersonTest.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.domain; +package com.querydsl.apt.domain; import static org.junit.Assert.assertNotNull; @@ -23,5 +23,5 @@ public class PersonTest { public void test() { assertNotNull(QPerson.person2.person); } - + } diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/Private.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Private.java similarity index 79% rename from querydsl-apt/src/test/java/com/mysema/query/domain/Private.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/Private.java index 2d2c9f11d8..4c3f86214c 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/Private.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Private.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,9 +11,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.domain; +package com.querydsl.apt.domain; -import com.mysema.query.annotations.QueryEntity; +import com.querydsl.core.annotations.QueryEntity; @QueryEntity public class Private { diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/Properties2Test.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Properties2Test.java new file mode 100644 index 0000000000..15f0f85986 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Properties2Test.java @@ -0,0 +1,38 @@ +package com.querydsl.apt.domain; + +import java.io.Serializable; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +import org.junit.Test; + +public class Properties2Test { + + public abstract static class BaseX implements Serializable { + + public abstract T getId(); + } + + @SuppressWarnings("serial") + @Entity + @Table(name = "X") + public static class ConcreteX extends BaseX { + + @Id + @Column(name = "name", nullable = false) + private String name; + + @Override + public String getId() { + return name; + } + } + + @Test(expected = NoSuchFieldException.class) + public void test() throws NoSuchFieldException { + QProperties2Test_ConcreteX.class.getDeclaredField("id"); + } +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/Properties3Test.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Properties3Test.java new file mode 100644 index 0000000000..41ab3cb6e5 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Properties3Test.java @@ -0,0 +1,34 @@ +package com.querydsl.apt.domain; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; + +import org.joda.time.LocalDateTime; +import org.junit.Test; + +import com.querydsl.core.types.dsl.DateTimePath; + +public class Properties3Test extends AbstractTest { + + @Entity + public static class Order { + + @Column(name = "order_date") + @Temporal(TemporalType.TIMESTAMP) + private java.util.Date orderDate; + + public LocalDateTime getOrderDate() { + return orderDate != null ? new LocalDateTime(orderDate) : null; + } + } + + @Test + public void propertyType() throws IllegalAccessException, NoSuchFieldException { + start(QProperties3Test_Order.class, QProperties3Test_Order.order); + match(DateTimePath.class, "orderDate"); + matchType(java.util.Date.class, "orderDate"); + } + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/Properties4Test.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Properties4Test.java new file mode 100644 index 0000000000..c0ebcc9c3c --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Properties4Test.java @@ -0,0 +1,22 @@ +package com.querydsl.apt.domain; + +import static org.junit.Assert.assertEquals; + +import javax.persistence.MappedSuperclass; + +import org.junit.Test; + +public class Properties4Test extends AbstractTest { + + @MappedSuperclass + public abstract static class Naming { + + public abstract boolean is8FRecord(); + + } + + @Test + public void test() { + assertEquals("8FRecord", QProperties4Test_Naming.naming._8FRecord.getMetadata().getName()); + } +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/PropertiesTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/PropertiesTest.java new file mode 100644 index 0000000000..6571533b5d --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/PropertiesTest.java @@ -0,0 +1,114 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt.domain; + +import static org.junit.Assert.assertNotNull; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import javax.persistence.*; + +import org.junit.Test; + +public class PropertiesTest { + + @Entity + public abstract static class AbstractEntity { + + } + + @Entity + @Table(name = "Customer") + public static class Customer extends AbstractEntity { + + private String name; + private List pizzas = new ArrayList(0); + + @Column + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @OneToMany(mappedBy = "customer") + public List getPizzas() { + return pizzas; + } + + public void setPizzas(List pizzas) { + this.pizzas = pizzas; + } + } + + @Entity + @Table(name = "Pizza") + public static class Pizza extends AbstractEntity { + + private Date orderTime; + private Customer customer; + private List toppings = new ArrayList(0); + + @Column @Temporal(TemporalType.TIMESTAMP) + public Date getOrderTime() { + return new Date(orderTime.getTime()); + } + + public void setOrderTime(Date orderTime) { + this.orderTime = new Date(orderTime.getTime()); + } + + @ManyToOne + @JoinColumn(name = "customerId") + public Customer getCustomer() { + return customer; + } + + public void setCustomer(Customer customer) { + this.customer = customer; + } + + @OneToMany(mappedBy = "pizza") + public List getToppings() { + return toppings; + } + + public void setToppings(List toppings) { + this.toppings = toppings; + } + } + + @Entity + public static class Topping { + + } + + @Test + public void customer() { + assertNotNull(QPropertiesTest_Customer.customer.name); + assertNotNull(QPropertiesTest_Customer.customer.pizzas); + } + + @Test + public void pizza() { + assertNotNull(QPropertiesTest_Pizza.pizza.orderTime); + assertNotNull(QPropertiesTest_Pizza.pizza.customer); + assertNotNull(QPropertiesTest_Pizza.pizza.toppings); + } + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/PropertyTypeTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/PropertyTypeTest.java new file mode 100644 index 0000000000..25a030c5ce --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/PropertyTypeTest.java @@ -0,0 +1,38 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt.domain; + +import org.junit.Ignore; +import org.junit.Test; + +import com.querydsl.core.annotations.PropertyType; +import com.querydsl.core.annotations.QueryEntity; +import com.querydsl.core.annotations.QueryType; + +@Ignore +public class PropertyTypeTest { + + @QueryEntity + public static class Entity { + + @QueryType(PropertyType.STRING) + Integer numberAsString; + + } + + @Test + public void numberAsString_like() { + QPropertyTypeTest_Entity.entity.numberAsString.like("a"); + } +} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/Public.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Public.java similarity index 79% rename from querydsl-apt/src/test/java/com/mysema/query/domain/Public.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/Public.java index 3a312a350d..02e6395c1d 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/Public.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Public.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,9 +11,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.domain; +package com.querydsl.apt.domain; -import com.mysema.query.annotations.QueryEntity; +import com.querydsl.core.annotations.QueryEntity; @QueryEntity public class Public { diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/QueryByExampleTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/QueryByExampleTest.java new file mode 100644 index 0000000000..30f864f96c --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/QueryByExampleTest.java @@ -0,0 +1,33 @@ +package com.querydsl.apt.domain; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import org.junit.Test; + +import com.querydsl.core.annotations.QueryDelegate; +import com.querydsl.core.types.Predicate; + +public class QueryByExampleTest { + + @QueryDelegate(ExampleEntity.class) + public static Predicate like(QExampleEntity qtype, ExampleEntity example) { + return example.name != null ? qtype.name.eq(example.name) : null; + } + + @Test + public void name_not_set() { + ExampleEntity entity = new ExampleEntity(); + Predicate qbe = QExampleEntity.exampleEntity.like(entity); + assertNull(qbe); + } + + @Test + public void name_set() { + ExampleEntity entity = new ExampleEntity(); + entity.name = "XXX"; + Predicate qbe = QExampleEntity.exampleEntity.like(entity); + assertEquals("exampleEntity.name = XXX", qbe.toString()); + } + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/QueryEmbeddable2Test.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/QueryEmbeddable2Test.java new file mode 100644 index 0000000000..b71f58ddbb --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/QueryEmbeddable2Test.java @@ -0,0 +1,52 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt.domain; + +import static org.junit.Assert.assertNotNull; + +import org.junit.Test; + +import com.querydsl.core.annotations.QueryEmbeddable; +import com.querydsl.core.annotations.QueryEntity; + +public class QueryEmbeddable2Test { + + @QueryEntity + public static class User { + + Complex complex; + } + + @QueryEmbeddable + public static class Complex> implements Comparable> { + + T a; + + @Override + public int compareTo(Complex arg0) { + return 0; + } + + public boolean equals(Object o) { + return o == this; + } + + } + + @Test + public void user_complex_a() { + assertNotNull(QQueryEmbeddable2Test_User.user.complex.a); + } + +} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/QueryEmbeddable3Test.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/QueryEmbeddable3Test.java similarity index 77% rename from querydsl-apt/src/test/java/com/mysema/query/domain/QueryEmbeddable3Test.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/QueryEmbeddable3Test.java index 142d3f4c73..4832234c05 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/QueryEmbeddable3Test.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/QueryEmbeddable3Test.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.domain; +package com.querydsl.apt.domain; import static org.junit.Assert.assertEquals; @@ -20,83 +20,84 @@ import java.util.Map; import java.util.Set; +import org.junit.Assert; import org.junit.Test; -import com.mysema.query.annotations.QueryEmbeddable; -import com.mysema.query.annotations.QueryEntity; +import com.querydsl.core.annotations.QueryEmbeddable; +import com.querydsl.core.annotations.QueryEntity; public class QueryEmbeddable3Test { @QueryEntity public static class User { - + List> rawList; - + List> list; - + Set> set; - + Collection> collection; - + Map> map; - + Map> rawMap1; - + Map> rawMap2; - + Map> rawMap3; - + } - + @QueryEmbeddable public static class Complex> implements Comparable> { T a; - + @Override public int compareTo(Complex arg0) { return 0; } - + public boolean equals(Object o) { return o == this; } - + } - + @Test - public void User_rawList() { - assertEquals(QQueryEmbeddable3Test_Complex.class, QQueryEmbeddable3Test_User.user.rawList.any().getClass()); + public void user_rawList() { + Assert.assertEquals(QQueryEmbeddable3Test_Complex.class, QQueryEmbeddable3Test_User.user.rawList.any().getClass()); } - + @Test - public void User_list() { + public void user_list() { assertEquals(QQueryEmbeddable3Test_Complex.class, QQueryEmbeddable3Test_User.user.list.any().getClass()); } - + @Test - public void User_set() { + public void user_set() { assertEquals(QQueryEmbeddable3Test_Complex.class, QQueryEmbeddable3Test_User.user.set.any().getClass()); } - + @Test - public void User_collection() { + public void user_collection() { assertEquals(QQueryEmbeddable3Test_Complex.class, QQueryEmbeddable3Test_User.user.collection.any().getClass()); } - + @Test - public void User_map() { + public void user_map() { assertEquals(QQueryEmbeddable3Test_Complex.class, QQueryEmbeddable3Test_User.user.map.get("XXX").getClass()); } - + @Test - public void User_rawMap1() { + public void user_rawMap1() { assertEquals(QQueryEmbeddable3Test_Complex.class, QQueryEmbeddable3Test_User.user.rawMap1.get("XXX").getClass()); } - + @Test - public void User_rawMap2() { + public void user_rawMap2() { assertEquals(QQueryEmbeddable3Test_Complex.class, QQueryEmbeddable3Test_User.user.rawMap2.get("XXX").getClass()); } - + } diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/QueryEmbeddableTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/QueryEmbeddableTest.java similarity index 78% rename from querydsl-apt/src/test/java/com/mysema/query/domain/QueryEmbeddableTest.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/QueryEmbeddableTest.java index f724c8c3ca..a644c9fea0 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/QueryEmbeddableTest.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/QueryEmbeddableTest.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,36 +11,36 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.domain; +package com.querydsl.apt.domain; -import static org.junit.Assert.*; +import static org.junit.Assert.assertNotNull; import org.junit.Test; -import com.mysema.query.annotations.QueryEmbeddable; -import com.mysema.query.annotations.QueryEntity; +import com.querydsl.core.annotations.QueryEmbeddable; +import com.querydsl.core.annotations.QueryEntity; public class QueryEmbeddableTest { @QueryEntity public static class Parent { - + String parentProperty; - + Child child; - + } - + @QueryEmbeddable public static class Child { - + String childProperty; - + } - + @Test public void test() { assertNotNull(QQueryEmbeddableTest_Parent.parent.child.childProperty); } - + } diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/QueryEmbedded2Test.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/QueryEmbedded2Test.java similarity index 78% rename from querydsl-apt/src/test/java/com/mysema/query/domain/QueryEmbedded2Test.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/QueryEmbedded2Test.java index b962915fa3..1701b41fc2 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/QueryEmbedded2Test.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/QueryEmbedded2Test.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,38 +11,38 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.domain; +package com.querydsl.apt.domain; import static org.junit.Assert.assertNotNull; import org.junit.Test; -import com.mysema.query.annotations.QueryEmbeddable; -import com.mysema.query.annotations.QueryEmbedded; -import com.mysema.query.annotations.QueryEntity; +import com.querydsl.core.annotations.QueryEmbeddable; +import com.querydsl.core.annotations.QueryEmbedded; +import com.querydsl.core.annotations.QueryEntity; public class QueryEmbedded2Test { @QueryEntity public static class Parent { - + String parentProperty; - + @QueryEmbedded Child child; - + } - + @QueryEmbeddable public static class Child { - + String childProperty; - + } - + @Test public void test() { assertNotNull(QQueryEmbedded2Test_Parent.parent.child.childProperty); } - + } diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/QueryEmbedded3Test.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/QueryEmbedded3Test.java similarity index 83% rename from querydsl-apt/src/test/java/com/mysema/query/domain/QueryEmbedded3Test.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/QueryEmbedded3Test.java index baf6640ce2..fc3cfd43bc 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/QueryEmbedded3Test.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/QueryEmbedded3Test.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.domain; +package com.querydsl.apt.domain; import static org.junit.Assert.assertNotNull; @@ -19,34 +19,34 @@ import org.junit.Test; -import com.mysema.query.annotations.QueryEmbedded; -import com.mysema.query.annotations.QueryEntity; +import com.querydsl.core.annotations.QueryEmbedded; +import com.querydsl.core.annotations.QueryEntity; public class QueryEmbedded3Test { @QueryEntity public static class Parent { - + String parentProperty; @QueryEmbedded List children; - + @QueryEmbedded Child child; - + } - + public static class Child { - + String childProperty; - + } - + @Test public void test() { assertNotNull(QQueryEmbedded3Test_Parent.parent.child.childProperty); assertNotNull(QQueryEmbedded3Test_Parent.parent.children.any().childProperty); } - + } diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/QueryEmbedded4Test.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/QueryEmbedded4Test.java similarity index 77% rename from querydsl-apt/src/test/java/com/mysema/query/domain/QueryEmbedded4Test.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/QueryEmbedded4Test.java index 27d99e760f..36b6713373 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/QueryEmbedded4Test.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/QueryEmbedded4Test.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,76 +11,76 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.domain; +package com.querydsl.apt.domain; import static org.junit.Assert.assertNotNull; import org.junit.Test; -import com.mysema.query.annotations.QueryEmbedded; -import com.mysema.query.annotations.QueryEntity; -import com.mysema.query.annotations.QueryInit; +import com.querydsl.core.annotations.QueryEmbedded; +import com.querydsl.core.annotations.QueryEntity; +import com.querydsl.core.annotations.QueryInit; public class QueryEmbedded4Test { @QueryEntity public static class User { - + @QueryEmbedded @QueryInit("city.name") Address address; - + @QueryEmbedded Complex complex; } - + public static class Address { - + @QueryEmbedded City city; - + String name; } - + public static class City { - + String name; - + } - + public static class Complex> implements Comparable> { T a; - + @Override public int compareTo(Complex arg0) { return 0; } - + public boolean equals(Object o) { return o == this; } - + } - + @Test - public void User_Address_City() { + public void user_address_city() { assertNotNull(QQueryEmbedded4Test_User.user.address.city); } - + @Test - public void User_Address_Name() { + public void user_address_name() { assertNotNull(QQueryEmbedded4Test_User.user.address.name); } - + @Test - public void User_Address_City_Name() { + public void user_address_city_name() { assertNotNull(QQueryEmbedded4Test_User.user.address.city.name); } - + @Test - public void User_Complex_a() { + public void user_complex_a() { assertNotNull(QQueryEmbedded4Test_User.user.complex.a); } - + } diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/QueryEmbedded5Test.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/QueryEmbedded5Test.java similarity index 80% rename from querydsl-apt/src/test/java/com/mysema/query/domain/QueryEmbedded5Test.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/QueryEmbedded5Test.java index 970cef3958..fbf6b2f897 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/QueryEmbedded5Test.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/QueryEmbedded5Test.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,9 +11,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.domain; +package com.querydsl.apt.domain; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; import java.util.Collection; import java.util.List; @@ -22,93 +22,93 @@ import org.junit.Test; -import com.mysema.query.annotations.QueryEmbedded; -import com.mysema.query.annotations.QueryEntity; +import com.querydsl.core.annotations.QueryEmbedded; +import com.querydsl.core.annotations.QueryEntity; public class QueryEmbedded5Test { @QueryEntity public static class User { - + @QueryEmbedded List> rawList; - + @QueryEmbedded List> list; - + @QueryEmbedded Set> set; - + @QueryEmbedded Collection> collection; - + @QueryEmbedded Map> map; - + @QueryEmbedded Map> rawMap1; - + @QueryEmbedded Map> rawMap2; - + @QueryEmbedded Map> rawMap3; - + } - - + + public static class Complex> implements Comparable> { T a; - + @Override public int compareTo(Complex arg0) { return 0; } - + public boolean equals(Object o) { return o == this; } - + } - + @Test - public void User_rawList() { + public void user_rawList() { assertEquals(QQueryEmbedded5Test_Complex.class, QQueryEmbedded5Test_User.user.rawList.any().getClass()); } - + @Test - public void User_list() { + public void user_list() { assertEquals(QQueryEmbedded5Test_Complex.class, QQueryEmbedded5Test_User.user.list.any().getClass()); } - + @Test - public void User_set() { + public void user_set() { assertEquals(QQueryEmbedded5Test_Complex.class, QQueryEmbedded5Test_User.user.set.any().getClass()); } - + @Test - public void User_collection() { + public void user_collection() { assertEquals(QQueryEmbedded5Test_Complex.class, QQueryEmbedded5Test_User.user.collection.any().getClass()); } - + @Test - public void User_map() { + public void user_map() { assertEquals(QQueryEmbedded5Test_Complex.class, QQueryEmbedded5Test_User.user.map.get("XXX").getClass()); } - + @Test - public void User_rawMap1() { + public void user_rawMap1() { assertEquals(QQueryEmbedded5Test_Complex.class, QQueryEmbedded5Test_User.user.rawMap1.get("XXX").getClass()); } - + @Test - public void User_rawMap2() { + public void user_rawMap2() { assertEquals(QQueryEmbedded5Test_Complex.class, QQueryEmbedded5Test_User.user.rawMap2.get("XXX").getClass()); } - + @Test - public void User_rawMap3() { + public void user_rawMap3() { assertEquals(QQueryEmbedded5Test_Complex.class, QQueryEmbedded5Test_User.user.rawMap3.get("XXX").getClass()); } } diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/QueryEmbedded6Test.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/QueryEmbedded6Test.java new file mode 100644 index 0000000000..b509686a7b --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/QueryEmbedded6Test.java @@ -0,0 +1,46 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt.domain; + +import static org.junit.Assert.assertEquals; + +import java.util.List; + +import org.junit.Test; + +import com.querydsl.core.annotations.QueryEmbedded; +import com.querydsl.core.annotations.QueryEntity; +import com.querydsl.core.types.dsl.EntityPathBase; + +public class QueryEmbedded6Test { + + @QueryEntity + public static class User { + + @QueryEmbedded + List list; + + } + + @Test + public void entityPathBase_is_superClass() { + assertEquals(EntityPathBase.class, QQueryEmbedded6Test_User.class.getSuperclass()); + } + + @Test + public void user_list_any() { + assertEquals(QQueryEmbedded6Test_User.class, QQueryEmbedded6Test_User.user.list.any().getClass()); + } + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/QueryEmbedded7Test.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/QueryEmbedded7Test.java new file mode 100644 index 0000000000..c62995c296 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/QueryEmbedded7Test.java @@ -0,0 +1,43 @@ +package com.querydsl.apt.domain; + +import static org.junit.Assert.assertEquals; + +import java.util.Collection; +import java.util.Locale; +import java.util.Set; + +import org.junit.Assert; +import org.junit.Test; + +import com.querydsl.core.annotations.QueryEmbedded; +import com.querydsl.core.annotations.QueryEntity; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.StringPath; + +public class QueryEmbedded7Test { + + @QueryEntity + public static class Entity { + + @QueryEmbedded + Collection users; + + @QueryEmbedded + Set productRoles; + + // misuse, but shouldn't cause problems + @QueryEmbedded + Locale locale; + + // misuse, but shouldn't cause problems + @QueryEmbedded + String string; + + } + + @Test + public void test() { + Assert.assertEquals(StringPath.class, QQueryEmbedded7Test_Entity.entity.users.any().getClass()); + assertEquals(NumberPath.class, QQueryEmbedded7Test_Entity.entity.productRoles.any().getClass()); + } +} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/QueryEmbeddedTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/QueryEmbeddedTest.java similarity index 78% rename from querydsl-apt/src/test/java/com/mysema/query/domain/QueryEmbeddedTest.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/QueryEmbeddedTest.java index adc45b479e..d970b893d4 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/QueryEmbeddedTest.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/QueryEmbeddedTest.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.domain; +package com.querydsl.apt.domain; import static org.junit.Assert.assertNotNull; @@ -20,52 +20,52 @@ import org.junit.Test; -import com.mysema.query.annotations.QueryEmbedded; -import com.mysema.query.annotations.QueryEntity; +import com.querydsl.core.annotations.QueryEmbedded; +import com.querydsl.core.annotations.QueryEntity; public class QueryEmbeddedTest { @QueryEntity public static class Parent { - + String parentProperty; - + @QueryEmbedded Child child; - + } @QueryEntity public static class Parent2 { - + String parentProperty; - + @QueryEmbedded List children; - + @QueryEmbedded Map children2; - + } - + public static class Child { - + String childProperty; - + } - + @Test - public void Parent_Child_ChildProperty() { + public void parent_child_childProperty() { assertNotNull(QQueryEmbeddedTest_Parent.parent.child.childProperty); } - + @Test - public void Parent_Children_Any_ChildrenProperty() { + public void parent_children_any_childProperty() { assertNotNull(QQueryEmbeddedTest_Parent2.parent2.children.any().childProperty); } - + @Test - public void Parent_Children2_MapAccess() { + public void parent_children2_mapAccess() { assertNotNull(QQueryEmbeddedTest_Parent2.parent2.children2.containsKey("XXX")); assertNotNull(QQueryEmbeddedTest_Parent2.parent2.children2.get("XXX").childProperty); } diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/QueryExcludeTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/QueryExcludeTest.java new file mode 100644 index 0000000000..55a6701e2f --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/QueryExcludeTest.java @@ -0,0 +1,43 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt.domain; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import com.querydsl.core.annotations.QueryEntity; +import com.querydsl.core.annotations.QueryExclude; +import com.querydsl.core.types.dsl.EntityPathBase; + +public class QueryExcludeTest { + + @QueryExclude + @QueryEntity + public static class Entity { + + } + + @QueryEntity + public static class SubEntity extends Entity { + + } + + @Test + public void subEntity() { + assertEquals(EntityPathBase.class, QQueryExcludeTest_SubEntity.class.getSuperclass()); + } + + +} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/QueryInit2Test.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/QueryInit2Test.java similarity index 77% rename from querydsl-apt/src/test/java/com/mysema/query/domain/QueryInit2Test.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/QueryInit2Test.java index 00e8e2e55c..94b8ec7279 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/QueryInit2Test.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/QueryInit2Test.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,14 +11,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.domain; +package com.querydsl.apt.domain; import static org.junit.Assert.assertNotNull; import org.junit.Test; -import com.mysema.query.annotations.QueryEntity; -import com.mysema.query.annotations.QueryInit; +import com.querydsl.core.annotations.QueryEntity; +import com.querydsl.core.annotations.QueryInit; public class QueryInit2Test { @@ -36,23 +36,23 @@ public static class Event { } @QueryEntity - public static class Activation extends Event { + public static class Activation extends Event { } @QueryEntity - public static class Account{ + public static class Account { Owner owner; } @QueryEntity - public static class Owner{ + public static class Owner { } @Test - public void Long_Path() { + public void long_path() { assertNotNull(QQueryInit2Test_Categorization.categorization.event.account.owner); assertNotNull(QQueryInit2Test_Categorization.categorization.event.as(QQueryInit2Test_Activation.class).account.owner); } diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/QueryInit3Test.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/QueryInit3Test.java similarity index 80% rename from querydsl-apt/src/test/java/com/mysema/query/domain/QueryInit3Test.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/QueryInit3Test.java index 97ac26ad5b..ce8a5152ba 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/QueryInit3Test.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/QueryInit3Test.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,17 +11,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.domain; +package com.querydsl.apt.domain; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; import java.util.List; import java.util.Map; import org.junit.Test; -import com.mysema.query.annotations.QueryEntity; -import com.mysema.query.annotations.QueryInit; +import com.querydsl.core.annotations.QueryEntity; +import com.querydsl.core.annotations.QueryInit; public class QueryInit3Test { @@ -38,10 +38,10 @@ public static class Entity { Map entityMap; } - + @Test public void test() { assertEquals("entity.prop1.prop2.prop1", QQueryInit3Test_Entity.entity.prop1.prop2.prop1.toString()); } - + } diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/QueryInit4Test.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/QueryInit4Test.java similarity index 85% rename from querydsl-apt/src/test/java/com/mysema/query/domain/QueryInit4Test.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/QueryInit4Test.java index 3bf6b6ab91..64a9cca811 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/QueryInit4Test.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/QueryInit4Test.java @@ -1,25 +1,25 @@ -package com.mysema.query.domain; +package com.querydsl.apt.domain; -import static org.junit.Assert.*; +import static org.junit.Assert.assertNotNull; import java.sql.Date; import java.util.Set; import org.junit.Test; -import com.mysema.query.annotations.QueryEntity; -import com.mysema.query.annotations.QueryInit; +import com.querydsl.core.annotations.QueryEntity; +import com.querydsl.core.annotations.QueryInit; public class QueryInit4Test { - + @QueryEntity public static class Organization { - + } - + @QueryEntity public static class Application { - + } @QueryEntity @@ -34,7 +34,7 @@ public static class Tenant { @QueryInit({"user.primaryTenant", "tenant"}) Set userTenantApplications; - + Set organizations; Date lastModifiedDate; @@ -46,11 +46,11 @@ public static class Tenant { public static class UserTenantApplication { User user; - + Tenant tenant; Application application; - + Date lastModifiedDate; Long lastModifiedUserId; @@ -65,10 +65,10 @@ public static class User { Set userTenantApplications; } - + @Test public void test() { - QQueryInit4Test_Tenant tenant = QQueryInit4Test_Tenant.tenant; + QQueryInit4Test_Tenant tenant = QQueryInit4Test_Tenant.tenant; assertNotNull(tenant.userTenantApplications.any().user.id); assertNotNull(tenant.userTenantApplications.any().tenant.id); assertNotNull(tenant.userTenantApplications.any().user.primaryTenant.id); diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/QueryInit5Test.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/QueryInit5Test.java similarity index 79% rename from querydsl-apt/src/test/java/com/mysema/query/domain/QueryInit5Test.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/QueryInit5Test.java index 156c843672..65ea069971 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/QueryInit5Test.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/QueryInit5Test.java @@ -1,45 +1,47 @@ -package com.mysema.query.domain; +package com.querydsl.apt.domain; -import com.mysema.query.annotations.QueryEntity; -import com.mysema.query.annotations.QueryInit; -import org.junit.Test; import static org.junit.Assert.assertNotNull; +import org.junit.Test; + +import com.querydsl.core.annotations.QueryEntity; +import com.querydsl.core.annotations.QueryInit; + public class QueryInit5Test { - + @QueryEntity public static class OtherClass { OtherClass entity; } - + @QueryEntity public static class OtherClassTwo { - OtherClassTwo entity; + OtherClassTwo entity; } - + @QueryEntity public static class Parent { int x; - + @QueryInit("*") OtherClass z; } - + @QueryEntity public static class Child extends Parent { @QueryInit("*") OtherClassTwo y; } - + @Test public void test() { //QChild c = QParent.parent.as(QChild.class) assertNotNull(QQueryInit5Test_Parent.parent.z.entity); - + QQueryInit5Test_Child child = QQueryInit5Test_Parent.parent.as(QQueryInit5Test_Child.class); assertNotNull(child.z.entity); assertNotNull(child.y.entity); - + } } diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/QueryInit6Test.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/QueryInit6Test.java new file mode 100644 index 0000000000..c0d8bababc --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/QueryInit6Test.java @@ -0,0 +1,195 @@ +package com.querydsl.apt.domain; + +import static org.junit.Assert.assertNotNull; + +import java.io.Serializable; +import java.util.HashSet; +import java.util.Set; + +import javax.persistence.*; + +import org.hibernate.proxy.HibernateProxy; +import org.junit.Test; + +import com.querydsl.core.annotations.PropertyType; +import com.querydsl.core.annotations.QueryInit; +import com.querydsl.core.annotations.QueryType; + +public class QueryInit6Test { + + @Entity(name = Component.NAME) + @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) + public abstract static class Component implements Serializable { + public static final String NAME = "Component"; + + @Id + protected String id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "parent_id") + private Component parent; + + @QueryType(PropertyType.ENTITY) + @QueryInit("*") + @Transient + public Container getContainer() { + Component temp = this.parent; + if (this.parent instanceof HibernateProxy) { + temp = (Component) ((HibernateProxy) this.parent) + .getHibernateLazyInitializer().getImplementation(); + } + + if (temp instanceof Container) { + return (Container) temp; + } else { + if (!temp.isRoot()) { + return temp.getParent().getContainer(); + } else { + return null; + } + } + } + + @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, fetch = FetchType.LAZY) + private Set children; + + protected Component() { + + } + + protected Component(String id, Component parent) { + this.id = id; + this.parent = parent; + this.children = new HashSet(); + } + + @Transient + public boolean isRoot() { + return (parent == null); + } + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public Set getChildren() { + return children; + } + + public void setChildren(Set children) { + this.children = children; + } + + public Component getParent() { + return parent; + } + + public void setParent(Component parent) { + this.parent = parent; + } + } + + @Entity(name = Content.NAME) + public static class Content extends Component { + + public static final String NAME = "Content"; + + @Column(name = "quantity") + private long quantity; + + public Content() { + super(null, null); + } + + public Content(String id, Component parent) { + super(id, parent); + this.quantity = 0; + } + + @Override + public String toString() { + return "Content [id=" + id + " qty=" + quantity + "]"; + } + + public long getQuantity() { + return quantity; + } + + public void setQuantity(long quantity) { + this.quantity = quantity; + } + } + + @Entity(name = Container.NAME) + public static class Container extends Component { + + public static final String NAME = "Container"; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "packaging_id") + private Packaging packaging; + + public Container() { + super(null, null); + } + + public Container(String id, Component parent) { + super(id, parent); + this.packaging = null; + } + + public Packaging getPackaging() { + return packaging; + } + + public void setPackaging(Packaging packaging) { + this.packaging = packaging; + } + } + + @Entity(name = Packaging.NAME) + public static class Packaging implements Serializable { + + public static final String NAME = "Packaging"; + + @Id + private String id; + + @Column(name = "description") + private String description; + + public Packaging() { + + } + + public Packaging(String id, String description) { + this.id = id; + this.description = description; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + } + + @Test + public void test() { + assertNotNull(QQueryInit6Test_Content.content.container.packaging); + assertNotNull(QQueryInit6Test_Content.content.container.packaging.id); + } +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/QueryInit7Test.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/QueryInit7Test.java new file mode 100644 index 0000000000..b88020967e --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/QueryInit7Test.java @@ -0,0 +1,141 @@ +/* + * Copyright 2016, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt.domain; + +import static org.junit.Assert.assertNotNull; + +import java.io.Serializable; + +import javax.persistence.*; + +import org.junit.Test; + +import com.querydsl.core.annotations.QueryEmbedded; +import com.querydsl.core.annotations.QueryInit; + +public class QueryInit7Test { + + @MappedSuperclass + public abstract static class Access, S extends Serializable, T extends Serializable> implements Serializable { + + private static final long serialVersionUID = 1L; + + @EmbeddedId + @QueryEmbedded + private I id; + + public I getId() { + return id; + } + + public void setId(I id) { + this.id = id; + } + + } + + + @MappedSuperclass + public static class AccessId implements Serializable { + + private static final long serialVersionUID = 1L; + + @ManyToOne + private S source; + + @ManyToOne + private T target; + + } + + @Entity + public static class Source implements Serializable { + + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + + } + + @Entity + public static class SourceToTarget1 extends Access { + + private static final long serialVersionUID = 1L; + + } + + @Entity + public static class SourceToTarget2 extends Access { + + private static final long serialVersionUID = 1L; + + @QueryInit({"source", "target"}) + @Override + public SourceToTargetId getId() { + return super.getId(); + } + + } + + @Entity + public static class SourceToTarget3 extends Access { + + private static final long serialVersionUID = 1L; + + @Column + private String imNotEmpty; + + @QueryInit({"source", "target"}) + @Override + public SourceToTargetId getId() { + return super.getId(); + } + + } + + @Embeddable + public static class SourceToTargetId extends AccessId { + + private static final long serialVersionUID = 1L; + + } + + @Entity + public static class Target implements Serializable { + + private static final long serialVersionUID = 1L; + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + + } + + @Test + public void test1DefaultCase() { + assertNotNull(QQueryInit7Test_SourceToTarget1.sourceToTarget1.id.source); + } + + @Test + public void test2AtQueryInitAndEmptyClass() { + assertNotNull(QQueryInit7Test_SourceToTarget2.sourceToTarget2.id.source); + } + + @Test + public void test3AtQueryInitAndNonEmptyClass() { + assertNotNull(QQueryInit7Test_SourceToTarget3.sourceToTarget3.id.source); + } +} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/QueryInitTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/QueryInitTest.java similarity index 80% rename from querydsl-apt/src/test/java/com/mysema/query/domain/QueryInitTest.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/QueryInitTest.java index c797c801bd..f66db190e3 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/QueryInitTest.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/QueryInitTest.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,15 +11,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.domain; +package com.querydsl.apt.domain; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import org.junit.Test; -import com.mysema.query.annotations.QueryEntity; -import com.mysema.query.annotations.QueryInit; +import com.querydsl.core.annotations.QueryEntity; +import com.querydsl.core.annotations.QueryInit; public class QueryInitTest { @@ -45,7 +45,7 @@ public static class PEntity { } @QueryEntity - public static class PEntity2Super{ + public static class PEntity2Super { public PEntity3 e333; @@ -54,7 +54,7 @@ public static class PEntity2Super{ } @QueryEntity - public static class PEntity2 extends PEntity2Super{ + public static class PEntity2 extends PEntity2Super { public PEntity3 e3; @@ -62,7 +62,7 @@ public static class PEntity2 extends PEntity2Super{ } @QueryEntity - public static class PEntity3{ + public static class PEntity3 { public PEntity4 e4; @@ -70,7 +70,7 @@ public static class PEntity3{ } @QueryEntity - public static class PEntity4{ + public static class PEntity4 { public PEntity e1; @@ -78,7 +78,7 @@ public static class PEntity4{ } @Test - public void Basic_Inits() { + public void basic_inits() { // e2 assertNotNull(e1.e2); assertNotNull(e1.e2.e3.e4); @@ -92,12 +92,12 @@ public void Basic_Inits() { } @Test - public void Deep_Super_Inits() { + public void deep_super_inits() { assertNotNull(e1.e22._super.e333); } @Test - public void Root_Super_Inits() { + public void root_super_inits() { assertNotNull(e2.e3333.e4); assertNotNull(e2._super.e3333.e4); } diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/QueryProjectionTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/QueryProjectionTest.java similarity index 75% rename from querydsl-apt/src/test/java/com/mysema/query/domain/QueryProjectionTest.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/QueryProjectionTest.java index 78af88af3c..fcd2e98c8b 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/QueryProjectionTest.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/QueryProjectionTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2011, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.domain; +package com.querydsl.apt.domain; import java.util.Map; @@ -20,14 +20,13 @@ import org.junit.Test; -import com.mysema.query.annotations.PropertyType; -import com.mysema.query.annotations.QueryEntity; -import com.mysema.query.annotations.QueryProjection; -import com.mysema.query.annotations.QueryType; -import com.mysema.query.types.expr.NumberExpression; -import com.mysema.query.types.expr.StringExpression; -import com.mysema.query.types.path.NumberPath; -import com.mysema.query.types.path.StringPath; +import com.querydsl.core.annotations.PropertyType; +import com.querydsl.core.annotations.QueryEntity; +import com.querydsl.core.annotations.QueryProjection; +import com.querydsl.core.annotations.QueryType; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberExpression; +import com.querydsl.core.types.dsl.StringExpression; public class QueryProjectionTest { @@ -64,13 +63,13 @@ public EntityWithProjection(String param0, CharSequence param1) { } @Test - public void Entity_Case() { - NumberExpression longExpr = new NumberPath(Long.class, "x"); - StringExpression stringExpr = new StringPath("x"); + public void entity_case() { + NumberExpression longExpr = Expressions.numberPath(Long.class, "x"); + StringExpression stringExpr = Expressions.stringPath("x"); - QQueryProjectionTest_EntityWithProjection.create(longExpr).newInstance(0l); + QQueryProjectionTest_EntityWithProjection.create(longExpr).newInstance(0L); QQueryProjectionTest_EntityWithProjection.create(stringExpr).newInstance(""); - QQueryProjectionTest_EntityWithProjection.create(longExpr, stringExpr).newInstance(0l,""); + QQueryProjectionTest_EntityWithProjection.create(longExpr, stringExpr).newInstance(0L,""); QQueryProjectionTest_EntityWithProjection.create(stringExpr,stringExpr).newInstance("",""); } @@ -117,13 +116,13 @@ public DTOWithProjection(String param0, CharSequence param1, Map pa } @Test - public void Dto_Case() throws SecurityException, NoSuchMethodException{ - NumberExpression longExpr = new NumberPath(Long.class, "x"); - StringExpression stringExpr = new StringPath("x"); + public void dto_case() throws SecurityException, NoSuchMethodException { + NumberExpression longExpr = Expressions.numberPath(Long.class, "x"); + StringExpression stringExpr = Expressions.stringPath("x"); - new QQueryProjectionTest_DTOWithProjection(longExpr).newInstance(0l); + new QQueryProjectionTest_DTOWithProjection(longExpr).newInstance(0L); new QQueryProjectionTest_DTOWithProjection(stringExpr).newInstance(""); - new QQueryProjectionTest_DTOWithProjection(longExpr, stringExpr).newInstance(0l,""); + new QQueryProjectionTest_DTOWithProjection(longExpr, stringExpr).newInstance(0L,""); new QQueryProjectionTest_DTOWithProjection(stringExpr, stringExpr).newInstance("",""); } diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/QuerySuperTypeTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/QuerySuperTypeTest.java similarity index 81% rename from querydsl-apt/src/test/java/com/mysema/query/domain/QuerySuperTypeTest.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/QuerySuperTypeTest.java index fa670125af..931266f830 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/QuerySuperTypeTest.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/QuerySuperTypeTest.java @@ -1,4 +1,4 @@ -package com.mysema.query.domain; +package com.querydsl.apt.domain; import static org.junit.Assert.assertEquals; @@ -8,7 +8,7 @@ import org.junit.Test; -import com.mysema.query.annotations.QuerySupertype; +import com.querydsl.core.annotations.QuerySupertype; public class QuerySuperTypeTest { @@ -23,7 +23,7 @@ public static class JdoEntity { } @Test - public void JdoEntity() { + public void jdoEntity() { assertEquals(QQuerySuperTypeTest_Supertype.class, QQuerySuperTypeTest_JdoEntity.jdoEntity.references.any().getClass()); } diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/QueryTypeOverTransientTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/QueryTypeOverTransientTest.java new file mode 100644 index 0000000000..8ae5bf63e0 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/QueryTypeOverTransientTest.java @@ -0,0 +1,55 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt.domain; + +import static org.junit.Assert.assertNotNull; + +import org.junit.Test; + +import com.querydsl.core.annotations.PropertyType; +import com.querydsl.core.annotations.QueryEntity; +import com.querydsl.core.annotations.QueryTransient; +import com.querydsl.core.annotations.QueryType; + +public class QueryTypeOverTransientTest { + + @QueryEntity + public static class Entity { + + @QueryType(PropertyType.ENTITY) + @QueryTransient + Entity reference; + + } + + @QueryEntity + public abstract static class Entity2 { + + @QueryType(PropertyType.ENTITY) + @QueryTransient + public abstract Entity getReference(); + + } + + @Test + public void entity_reference_is_available() { + assertNotNull(QQueryTypeOverTransientTest_Entity.entity.reference); + } + + @Test + public void entity2_reference_is_available() { + assertNotNull(QQueryTypeOverTransientTest_Entity2.entity2.reference); + } + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/QueryTypeTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/QueryTypeTest.java new file mode 100644 index 0000000000..9a92e345f3 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/QueryTypeTest.java @@ -0,0 +1,57 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt.domain; + +import org.junit.Test; + +import com.querydsl.core.annotations.PropertyType; +import com.querydsl.core.annotations.QueryEntity; +import com.querydsl.core.annotations.QueryType; +import com.querydsl.core.types.dsl.*; + +public class QueryTypeTest extends AbstractTest { + + @QueryEntity + public static class QueryTypeEntity { + @QueryType(PropertyType.SIMPLE) + public String stringAsSimple; + + @QueryType(PropertyType.COMPARABLE) + public String stringAsComparable; + + @QueryType(PropertyType.DATE) + public String stringAsDate; + + @QueryType(PropertyType.DATETIME) + public String stringAsDateTime; + + @QueryType(PropertyType.TIME) + public String stringAsTime; + + @QueryType(PropertyType.NONE) + public String stringNotInQuerydsl; + + } + + @Test + public void test() throws SecurityException, NoSuchFieldException { + start(QQueryTypeTest_QueryTypeEntity.class, QQueryTypeTest_QueryTypeEntity.queryTypeEntity); + match(SimplePath.class, "stringAsSimple"); + match(ComparablePath.class, "stringAsComparable"); + match(DatePath.class, "stringAsDate"); + match(DateTimePath.class, "stringAsDateTime"); + match(TimePath.class, "stringAsTime"); + assertMissing("stringNotInQuerydsl"); + } +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/QuerydslConfig2Test.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/QuerydslConfig2Test.java new file mode 100644 index 0000000000..4f2f454376 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/QuerydslConfig2Test.java @@ -0,0 +1,64 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt.domain; + +import static org.junit.Assert.assertNotNull; + +import org.junit.Test; + +import com.querydsl.core.annotations.Config; +import com.querydsl.core.annotations.QueryEntity; + +public class QuerydslConfig2Test { + + @Config(entityAccessors = true) + @QueryEntity + public static class Entity extends Superclass { + + Entity prop1; + + } + + @Config(createDefaultVariable = false) + @QueryEntity + public static class Entity2 extends Superclass2 { + + Entity prop1; + + } + + @QueryEntity + public static class Superclass { + + Entity prop2; + } + + @Config(entityAccessors = true) + @QueryEntity + public static class Superclass2 { + + Entity prop2; + } + + @Test + public void test() { + assertNotNull(QQuerydslConfig2Test_Entity.entity); + } + + @Test(expected = NoSuchFieldException.class) + public void create_default_variable() throws SecurityException, NoSuchFieldException { + QQuerydslConfig2Test_Entity2.class.getField("entity2"); + } +} + diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/QuerydslConfigTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/QuerydslConfigTest.java similarity index 76% rename from querydsl-apt/src/test/java/com/mysema/query/domain/QuerydslConfigTest.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/QuerydslConfigTest.java index 14dfdaf85c..b1e9255b69 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/QuerydslConfigTest.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/QuerydslConfigTest.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.domain; +package com.querydsl.apt.domain; import static org.junit.Assert.assertEquals; @@ -20,19 +20,19 @@ import org.junit.Test; -import com.mysema.query.annotations.QueryEntity; -import com.mysema.query.annotations.Config; +import com.querydsl.core.annotations.Config; +import com.querydsl.core.annotations.QueryEntity; public class QuerydslConfigTest { - @Config(entityAccessors=true) + @Config(entityAccessors = true) @QueryEntity public static class Superclass { Entity prop3; } - @Config(entityAccessors=true, listAccessors = true, mapAccessors= true) + @Config(entityAccessors = true, listAccessors = true, mapAccessors = true) @QueryEntity public static class Entity extends Superclass { @@ -46,7 +46,7 @@ public static class Entity extends Superclass { } @Test - public void Long_Path() { + public void long_path() { assertEquals("entity.prop1.prop2.prop1", QQuerydslConfigTest_Entity.entity.prop1().prop2().prop1().toString()); } diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/RawTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/RawTest.java new file mode 100644 index 0000000000..2c67a486de --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/RawTest.java @@ -0,0 +1,29 @@ +package com.querydsl.apt.domain; + +import org.junit.Test; + +import com.querydsl.core.annotations.QueryEntity; +import com.querydsl.core.annotations.QuerySupertype; + +public class RawTest { + + @QuerySupertype + public static class SuperClass> { + + public String property; + + } + + @SuppressWarnings("rawtypes") + @QueryEntity + public static class Entity extends SuperClass { + + public String property2; + } + + @Test + public void test() { + + } + +} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/RelationTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/RelationTest.java similarity index 86% rename from querydsl-apt/src/test/java/com/mysema/query/domain/RelationTest.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/RelationTest.java index 2b620a8ae0..d51bbcf486 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/RelationTest.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/RelationTest.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,26 +11,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.domain; +package com.querydsl.apt.domain; import static org.junit.Assert.assertEquals; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.SortedSet; +import java.util.*; import org.junit.Test; -import com.mysema.query.annotations.QueryEntity; -import com.mysema.query.annotations.Config; -import com.mysema.query.domain.rel.RelationType2; -import com.mysema.query.types.path.CollectionPath; -import com.mysema.query.types.path.EnumPath; -import com.mysema.query.types.path.ListPath; -import com.mysema.query.types.path.MapPath; -import com.mysema.query.types.path.SetPath; +import com.querydsl.apt.domain.rel.RelationType2; +import com.querydsl.core.annotations.Config; +import com.querydsl.core.annotations.QueryEntity; +import com.querydsl.core.types.dsl.*; public class RelationTest extends AbstractTest { @@ -62,7 +54,7 @@ public static class GenericRelations { } @QueryEntity - @Config(listAccessors=true, mapAccessors=true) + @Config(listAccessors = true, mapAccessors = true) public static class RelationType { MyEnum enumProperty; @@ -115,7 +107,7 @@ public static class RelationType { @Test public void test() throws SecurityException, NoSuchFieldException { - cl = QRelationTest_RelationType.class; + start(QRelationTest_RelationType.class, QRelationTest_RelationType.relationType); match(EnumPath.class, "enumProperty"); match(ListPath.class, "enumList"); match(MapPath.class, "enumMap1"); @@ -154,7 +146,7 @@ public void test() throws SecurityException, NoSuchFieldException { } @Test - public void List_Usage() { + public void list_usage() { String expected = "relationType.list.get(0).set"; assertEquals(expected, QRelationTest_RelationType.relationType.list.get(0).set.toString()); // assertEquals(expected, QRelationTest_RelationType.relationType.getList(0).set.toString()); diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/ReservedNamesInTypesTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/ReservedNamesInTypesTest.java similarity index 84% rename from querydsl-apt/src/test/java/com/mysema/query/domain/ReservedNamesInTypesTest.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/ReservedNamesInTypesTest.java index eb2c24d9ee..d5f90b57d2 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/ReservedNamesInTypesTest.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/ReservedNamesInTypesTest.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,16 +11,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.domain; +package com.querydsl.apt.domain; import static org.junit.Assert.assertNotNull; import org.junit.Test; public class ReservedNamesInTypesTest { - + @Test - public void Correctly_Escaped() { + public void correctly_escaped() { assertNotNull(QPublic.public$); assertNotNull(QPrivate.private$); } diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/ReservedNamesTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/ReservedNamesTest.java similarity index 92% rename from querydsl-apt/src/test/java/com/mysema/query/domain/ReservedNamesTest.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/ReservedNamesTest.java index b6fa510462..4fcdc3cb77 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/ReservedNamesTest.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/ReservedNamesTest.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.domain; +package com.querydsl.apt.domain; import java.util.List; import java.util.Map; @@ -19,7 +19,7 @@ import org.junit.Test; -import com.mysema.query.annotations.QueryEntity; +import com.querydsl.core.annotations.QueryEntity; public class ReservedNamesTest { diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/Revision.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Revision.java similarity index 89% rename from querydsl-apt/src/test/java/com/mysema/query/domain/Revision.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/Revision.java index cb2e22fb47..d8506639b2 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/Revision.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Revision.java @@ -1,4 +1,4 @@ -package com.mysema.query.domain; +package com.querydsl.apt.domain; import javax.persistence.Entity; import org.hibernate.envers.DefaultRevisionEntity; diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/RooEntities.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/RooEntities.java similarity index 94% rename from querydsl-apt/src/test/java/com/mysema/query/domain/RooEntities.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/RooEntities.java index 088f2edefb..127bb13880 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/RooEntities.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/RooEntities.java @@ -1,4 +1,4 @@ -package com.mysema.query.domain; +package com.querydsl.apt.domain; import javax.persistence.Id; import javax.persistence.ManyToOne; diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/RooEntitiesTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/RooEntitiesTest.java new file mode 100644 index 0000000000..e4f4463037 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/RooEntitiesTest.java @@ -0,0 +1,19 @@ +package com.querydsl.apt.domain; + +import static org.junit.Assert.assertNotNull; + +import org.junit.Test; + +public class RooEntitiesTest { + + @Test + public void rooJpaEntity() { + assertNotNull(QRooEntities_MyEntity.myEntity); + } + + @Test + public void rooJpaActiveRecord() { + assertNotNull(QRooEntities_MyEntity2.myEntity2); + } + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/SecurableEntity.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/SecurableEntity.java new file mode 100644 index 0000000000..159d98e050 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/SecurableEntity.java @@ -0,0 +1,26 @@ +package com.querydsl.apt.domain; + +import javax.persistence.*; + +/** + * This is an example of using system ACL function. Note, field id is required, + * abstract function getId must also be implemented. + */ +@Entity +public class SecurableEntity extends AbstractSecurable { + + private static final long serialVersionUID = 3197097608363811501L; + + @Id + @TableGenerator(name = "SECUREENTITY_SEQ", allocationSize = 1) + @GeneratedValue(strategy = GenerationType.TABLE, generator = "SECUREENTITY_SEQ") + private Long securableEntityId; + + @Column(length = 50) + private String name; + + // public Long getId() { + // return getSecurableEntityId(); + // } + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/SignatureTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/SignatureTest.java new file mode 100644 index 0000000000..d92a14c3f6 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/SignatureTest.java @@ -0,0 +1,47 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt.domain; + +import static org.junit.Assert.assertEquals; + +import java.io.Serializable; + +import com.querydsl.core.types.dsl.EntityPathBase; +import org.junit.Test; + +import com.querydsl.core.annotations.QuerySupertype; + +public class SignatureTest { + + @QuerySupertype + public abstract static class APropertyChangeSupported implements Comparable, Cloneable, Serializable { + + } + + @QuerySupertype + public abstract static class AValueObject extends APropertyChangeSupported implements Comparable, Cloneable, Serializable { + + } + + @Test + public void aPropertyChangeSupported() { + assertEquals(EntityPathBase.class, QSignatureTest_APropertyChangeSupported.class.getSuperclass()); + } + + @Test + public void aValueObject() { + assertEquals(EntityPathBase.class, QSignatureTest_AValueObject.class.getSuperclass()); + } + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/SimpleTypesTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/SimpleTypesTest.java new file mode 100644 index 0000000000..82f5d7c6fe --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/SimpleTypesTest.java @@ -0,0 +1,361 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt.domain; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.sql.Blob; +import java.sql.Clob; +import java.sql.Time; +import java.util.Calendar; +import java.util.Date; +import java.util.List; +import java.util.Locale; + +import org.junit.Test; + +import com.querydsl.core.annotations.*; +import com.querydsl.core.types.dsl.*; + +public class SimpleTypesTest extends AbstractTest { + + public enum MyEnum { + VAL1, + VAL2 + } + + public static class CustomLiteral { + + } + + @SuppressWarnings("serial") + public static class CustomNumber extends Number { + + @Override + public double doubleValue() { + return 0; + } + + @Override + public float floatValue() { + return 0; + } + + @Override + public int intValue() { + return 0; + } + + @Override + public long longValue() { + return 0; + } + + } + + public static class CustomComparableNumber extends CustomNumber implements Comparable { + + private static final long serialVersionUID = 4398583038967396133L; + + @Override + public int compareTo(CustomComparableNumber o) { + return 0; + } + + @Override + public int hashCode() { + return super.hashCode(); + } + + @Override + public boolean equals(Object o) { + return o instanceof CustomComparableNumber; + } + } + + public static class CustomComparableLiteral implements Comparable { + + @Override + public int compareTo(CustomComparableLiteral o) { + return 0; + } + + @Override + public int hashCode() { + return super.hashCode(); + } + + @Override + public boolean equals(Object o) { + return o instanceof CustomComparableLiteral; + } + } + + public static class CustomGenericComparableLiteral implements Comparable { + + @Override + public int compareTo(CustomComparableLiteral o) { + return 0; + } + + @Override + public int hashCode() { + return super.hashCode(); + } + + @Override + public boolean equals(Object o) { + return o instanceof CustomGenericComparableLiteral; + } + } + + @QueryEntity + @Config(listAccessors = true) + public static class SimpleTypes { + transient int test; + List testList; + + Calendar calendar; + List calendarList; + + long id; + List idList; + + BigDecimal bigDecimal; + List bigDecimalList; + + Byte bbyte; + List bbyteList; + byte bbyte2; + + Short sshort; + List sshortList; + short sshort2; + + Character cchar; + List ccharList; + char cchar2; + + Double ddouble; + List ddoubleList; + double ddouble2; + + Float ffloat; + List ffloatList; + float ffloat2; + + Integer iint; + List iintList; + int iint2; + + Locale llocale; + List llocaleList; + + Long llong; + List llongList; + long llong2; + + BigInteger bigInteger; + + String sstring; + List sstringList; + + Date date; + List dateList; + + java.sql.Time time; + List timeList; + + java.sql.Timestamp timestamp; + List timestampList; + + Serializable serializable; + List serializableList; + + Object object; + List objectList; + + Class clazz; + List classList2; + List> classList3; + List> classList4; + List> classList5; + + Package packageAsLiteral; + List packageAsLiteralList; + + CustomLiteral customLiteral; + List customLiteralList; + + CustomComparableLiteral customComparableLiteral; + List customComparableLiteralList; + + CustomNumber customNumber; + List customNumberList; + + CustomComparableNumber customComparableNumber; + List customComparableNumber2; + + CustomGenericComparableLiteral customComparableLiteral2; + List customComparableLiteral2List; + + CustomGenericComparableLiteral customComparableLiteral3; + List> customComparableLiteral3List; + + java.sql.Clob clob; + List clobList; + + java.sql.Blob blob; + List blobList; + + @QueryTransient + String skipMe; + + MyEnum myEnum; + + int[] intArray; + byte[] byteArray; + long[] longArray; + float[] floatArray; + double[] doubleArray; + short[] shortArray; + + @QueryType(PropertyType.SIMPLE) + byte[] byteArrayAsSimple; + } + + @Test + public void list_access() { + // date / time + QSimpleTypesTest_SimpleTypes.simpleTypes.dateList.get(0).after(new Date()); + QSimpleTypesTest_SimpleTypes.simpleTypes.timeList.get(0).after(new Time(0L)); + QSimpleTypesTest_SimpleTypes.simpleTypes.calendarList.get(0).before(Calendar.getInstance()); + + // numeric + QSimpleTypesTest_SimpleTypes.simpleTypes.bbyteList.get(0).abs(); + + // string + QSimpleTypesTest_SimpleTypes.simpleTypes.sstringList.get(0).toLowerCase(); + + // boolean +// QSimpleTypes.simpleTypes.b + + } + + @Test + public void simple_types() throws IllegalAccessException, NoSuchFieldException { + start(QSimpleTypesTest_SimpleTypes.class, QSimpleTypesTest_SimpleTypes.simpleTypes); + match(NumberPath.class, "id"); + matchType(Long.class, "id"); + match(NumberPath.class, "bigDecimal"); + matchType(BigDecimal.class, "bigDecimal"); + match(NumberPath.class, "bigInteger"); + matchType(BigInteger.class, "bigInteger"); +// match(PNumber.class, "bbyte"); + match(NumberPath.class, "bbyte2"); + matchType(Byte.class, "bbyte"); + match(NumberPath.class, "ddouble"); + matchType(Double.class, "ddouble"); + match(NumberPath.class, "ddouble2"); + matchType(Double.class, "ddouble2"); + match(NumberPath.class, "ffloat"); + matchType(Float.class, "ffloat"); + match(NumberPath.class, "ffloat2"); + matchType(Float.class, "ffloat2"); +// match(PNumber.class, "iint"); + match(NumberPath.class, "iint2"); + matchType(Integer.class, "iint2"); + match(NumberPath.class, "llong"); + matchType(Long.class, "llong"); + match(NumberPath.class, "llong2"); + matchType(Long.class, "llong2"); + + match(ComparablePath.class, "cchar"); + matchType(Character.class, "cchar"); + match(ComparablePath.class, "cchar2"); + matchType(Character.class, "cchar2"); + + match(StringPath.class, "sstring"); + + match(DateTimePath.class, "date"); + matchType(Date.class, "date"); + match(DateTimePath.class, "calendar"); + matchType(Calendar.class, "calendar"); +// match(PDateTime.class, "timestamp"); + + match(TimePath.class, "time"); + matchType(Time.class, "time"); + + match(SimplePath.class, "llocale"); + matchType(Locale.class, "llocale"); + match(SimplePath.class, "serializable"); + matchType(Serializable.class, "serializable"); + match(SimplePath.class, "object"); + matchType(Object.class, "object"); + match(SimplePath.class, "clazz"); + matchType(Class.class, "clazz"); + match(SimplePath.class, "packageAsLiteral"); + matchType(Package.class, "packageAsLiteral"); + + match(SimplePath.class, "clob"); + matchType(Clob.class, "clob"); + match(SimplePath.class, "blob"); + matchType(Blob.class, "blob"); + + match(EnumPath.class, "myEnum"); + matchType(MyEnum.class, "myEnum"); + } + + @Test + public void custom_literal() throws IllegalAccessException, NoSuchFieldException { + start(QSimpleTypesTest_SimpleTypes.class, QSimpleTypesTest_SimpleTypes.simpleTypes); + match(SimplePath.class, "customLiteral"); + matchType(CustomLiteral.class, "customLiteral"); + } + + @Test + public void custom_comparableLiteral() throws IllegalAccessException, NoSuchFieldException { + start(QSimpleTypesTest_SimpleTypes.class, QSimpleTypesTest_SimpleTypes.simpleTypes); + match(ComparablePath.class, "customComparableLiteral"); + matchType(CustomComparableLiteral.class, "customComparableLiteral"); + } + + @Test + public void custom_number() throws IllegalAccessException, NoSuchFieldException { + start(QSimpleTypesTest_SimpleTypes.class, QSimpleTypesTest_SimpleTypes.simpleTypes); + match(SimplePath.class, "customNumber"); + matchType(CustomNumber.class, "customNumber"); + } + + @Test + public void custom_comparableNumber() throws IllegalAccessException, NoSuchFieldException { + start(QSimpleTypesTest_SimpleTypes.class, QSimpleTypesTest_SimpleTypes.simpleTypes); + match(NumberPath.class, "customComparableNumber"); + matchType(CustomComparableNumber.class, "customComparableNumber"); + } + + @Test + public void skipped_field1() { + start(QSimpleTypesTest_SimpleTypes.class, QSimpleTypesTest_SimpleTypes.simpleTypes); + assertMissing("skipMe"); + } + + @Test + public void skipped_field2() { + start(QSimpleTypesTest_SimpleTypes.class, QSimpleTypesTest_SimpleTypes.simpleTypes); + assertMissing("test"); + } + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/SubCat.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/SubCat.java new file mode 100644 index 0000000000..b5d3832aea --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/SubCat.java @@ -0,0 +1,5 @@ +package com.querydsl.apt.domain; + +public class SubCat { + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/Subclass.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Subclass.java new file mode 100644 index 0000000000..41c10acfdc --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Subclass.java @@ -0,0 +1,19 @@ +package com.querydsl.apt.domain; + +import com.querydsl.core.annotations.QueryEntity; + +@QueryEntity +public class Subclass extends com.querydsl.core.domain.Superclass { + + private int number; + + public int getNumber() { + return number; + } + + public void setNumber(int number) { + this.number = number; + } + + +} \ No newline at end of file diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/Superclass2Test.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Superclass2Test.java similarity index 91% rename from querydsl-apt/src/test/java/com/mysema/query/domain/Superclass2Test.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/Superclass2Test.java index a69d437431..d80be80d84 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/Superclass2Test.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Superclass2Test.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.domain; +package com.querydsl.apt.domain; import static org.junit.Assert.assertNotNull; @@ -49,15 +49,15 @@ public static class Subtype extends CommonPersistence { } @Test - public void DefaultInstance() { + public void defaultInstance() { assertNotNull(QSuperclass2Test_CommonPersistence.commonPersistence); } - + @Test public void test() { assertNotNull(QSuperclass2Test_Subtype.subtype.createdOn); } - - + + } diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/Superclass3Test.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Superclass3Test.java similarity index 81% rename from querydsl-apt/src/test/java/com/mysema/query/domain/Superclass3Test.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/Superclass3Test.java index 60adeb7484..fd74120f2b 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/Superclass3Test.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Superclass3Test.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,13 +11,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.domain; +package com.querydsl.apt.domain; import org.junit.Assert; import org.junit.Test; -import com.mysema.query.DefaultQueryMetadata; -import com.mysema.query.annotations.QueryEntity; +import com.querydsl.core.DefaultQueryMetadata; +import com.querydsl.core.annotations.QueryEntity; public class Superclass3Test { diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/Superclass4Test.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Superclass4Test.java similarity index 81% rename from querydsl-apt/src/test/java/com/mysema/query/domain/Superclass4Test.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/Superclass4Test.java index 67219782c4..317ce31ffd 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/Superclass4Test.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Superclass4Test.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,38 +11,38 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.domain; +package com.querydsl.apt.domain; import static org.junit.Assert.assertNotNull; import org.junit.Test; -import com.mysema.query.annotations.QueryEntity; +import com.querydsl.core.annotations.QueryEntity; public class Superclass4Test { - + public static class SuperClass { - + String superClassProperty; - + } - + @QueryEntity public static class Entity extends SuperClass { - + String entityProperty; - + } @Test - public void SuperClass_Properties() { + public void superClass_properties() { assertNotNull(QSuperclass4Test_SuperClass.superClass.superClassProperty); } - + @Test - public void Entity_Properties() { + public void entity_properties() { assertNotNull(QSuperclass4Test_Entity.entity.entityProperty); assertNotNull(QSuperclass4Test_Entity.entity.superClassProperty); } - + } diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/Superclass5Test.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Superclass5Test.java similarity index 80% rename from querydsl-apt/src/test/java/com/mysema/query/domain/Superclass5Test.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/Superclass5Test.java index 97f18b6ab5..8d0ba7d3ee 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/Superclass5Test.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Superclass5Test.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,38 +11,38 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.domain; +package com.querydsl.apt.domain; import static org.junit.Assert.assertNotNull; import org.junit.Test; -import com.mysema.query.annotations.QueryEmbeddable; -import com.mysema.query.types.PathMetadataFactory; +import com.querydsl.core.annotations.QueryEmbeddable; +import com.querydsl.core.types.PathMetadataFactory; public class Superclass5Test { - + public static class SuperClass { - + String superClassProperty; - + } - + @QueryEmbeddable public static class Embeddable extends SuperClass { - + String embeddableProperty; - + } @Test - public void SuperClass_Properties() { + public void superClass_properties() { QSuperclass5Test_SuperClass qtype = new QSuperclass5Test_SuperClass(PathMetadataFactory.forVariable("var")); assertNotNull(qtype.superClassProperty); } - + @Test - public void Entity_Properties() { + public void entity_properties() { QSuperclass5Test_Embeddable qtype = new QSuperclass5Test_Embeddable(PathMetadataFactory.forVariable("var")); assertNotNull(qtype.superClassProperty); assertNotNull(qtype.embeddableProperty); diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/SuperclassTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/SuperclassTest.java similarity index 82% rename from querydsl-apt/src/test/java/com/mysema/query/domain/SuperclassTest.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/SuperclassTest.java index d2048c23e6..92591c206e 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/SuperclassTest.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/SuperclassTest.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,12 +11,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.domain; +package com.querydsl.apt.domain; import org.junit.Ignore; -import com.mysema.query.annotations.QueryEntity; -import com.mysema.query.annotations.QuerySupertype; +import com.querydsl.core.annotations.QueryEntity; +import com.querydsl.core.annotations.QuerySupertype; @Ignore public class SuperclassTest { diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/Temporal2Test.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Temporal2Test.java new file mode 100644 index 0000000000..64499fa1fc --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Temporal2Test.java @@ -0,0 +1,43 @@ +package com.querydsl.apt.domain; + +import java.math.BigDecimal; +import java.util.Date; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; + +import org.junit.Test; + +import com.querydsl.core.annotations.QueryProjection; +import com.querydsl.core.types.dsl.DatePath; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberPath; + +public class Temporal2Test { + + @Entity + public static class Cheque { + @Temporal(TemporalType.DATE) + private Date dataVencimento; + + @Column(precision = 15, scale = 2) + private BigDecimal valor; + + @QueryProjection + public Cheque(Date param0, BigDecimal param1) { + this.dataVencimento = param0; + this.valor = param1; + } + + } + + @Test + public void test() { + DatePath datePath = Expressions.datePath(Date.class, "date"); + NumberPath numberPath = Expressions.numberPath(BigDecimal.class, "num"); + new QTemporal2Test_Cheque(datePath, numberPath); + } + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/TemporalTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/TemporalTest.java new file mode 100644 index 0000000000..dc4388e20d --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/TemporalTest.java @@ -0,0 +1,34 @@ +package com.querydsl.apt.domain; + +import static org.junit.Assert.assertEquals; + +import java.util.Date; + +import javax.persistence.Entity; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; + +import org.junit.Test; + +import com.querydsl.core.types.dsl.DatePath; +import com.querydsl.core.types.dsl.TimePath; + +public class TemporalTest { + + @Entity + public static class MyEntity { + + @Temporal(value = TemporalType.DATE) + private Date date; + + @Temporal(value = TemporalType.TIME) + private Date time; + } + + @Test + public void test() { + assertEquals(DatePath.class, QTemporalTest_MyEntity.myEntity.date.getClass()); + assertEquals(TimePath.class, QTemporalTest_MyEntity.myEntity.time.getClass()); + } + +} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/TransientTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/TransientTest.java similarity index 85% rename from querydsl-apt/src/test/java/com/mysema/query/domain/TransientTest.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/TransientTest.java index bf8b1236e8..926e24d540 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/TransientTest.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/TransientTest.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,34 +11,36 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.domain; +package com.querydsl.apt.domain; + +import static org.junit.Assert.assertNotNull; import javax.persistence.Entity; import javax.persistence.Transient; -import com.mysema.query.annotations.PropertyType; -import com.mysema.query.annotations.QueryType; import org.junit.Test; -import static org.junit.Assert.assertNotNull; + +import com.querydsl.core.annotations.PropertyType; +import com.querydsl.core.annotations.QueryType; public class TransientTest { - + @Entity public static class ExampleEntity { - + @QueryType(PropertyType.SIMPLE) @Transient String property1; - + @Transient String property2; - + @QueryType(PropertyType.SIMPLE) transient String property3; - + transient String property4; } - + @Test public void test() { assertNotNull(QTransientTest_ExampleEntity.exampleEntity.property1); diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/UserUtils.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/UserUtils.java similarity index 75% rename from querydsl-apt/src/test/java/com/mysema/query/domain/UserUtils.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/UserUtils.java index dec4cfcfcc..c71c46635f 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/UserUtils.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/UserUtils.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,15 +11,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.domain; +package com.querydsl.apt.domain; -import com.mysema.query.annotations.QueryDelegate; -import com.mysema.query.domain.QDelegateTest_User; -import com.mysema.query.types.path.StringPath; +import com.querydsl.core.annotations.QueryDelegate; +import com.querydsl.core.types.dsl.StringPath; public final class UserUtils { - private UserUtils() {} + private UserUtils() { } @QueryDelegate(DelegateTest.User.class) public static StringPath getName(QDelegateTest_User user) { diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/custom/CustomNumber.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/custom/CustomNumber.java similarity index 94% rename from querydsl-apt/src/test/java/com/mysema/query/domain/custom/CustomNumber.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/custom/CustomNumber.java index ee6cb2c906..f777a9e97d 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/custom/CustomNumber.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/custom/CustomNumber.java @@ -1,4 +1,4 @@ -package com.mysema.query.domain.custom; +package com.querydsl.apt.domain.custom; public class CustomNumber extends Number implements Comparable { diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/custom/EmbeddedType.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/custom/EmbeddedType.java new file mode 100644 index 0000000000..97913e6e41 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/custom/EmbeddedType.java @@ -0,0 +1,18 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt.domain.custom; + +public class EmbeddedType { + +} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/custom/EmbeddedType2.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/custom/EmbeddedType2.java similarity index 84% rename from querydsl-apt/src/test/java/com/mysema/query/domain/custom/EmbeddedType2.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/custom/EmbeddedType2.java index a2d4d97c95..2ea10a5d05 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/custom/EmbeddedType2.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/custom/EmbeddedType2.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.domain.custom; +package com.querydsl.apt.domain.custom; public class EmbeddedType2 { diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/custom/EmbeddedType3.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/custom/EmbeddedType3.java similarity index 84% rename from querydsl-apt/src/test/java/com/mysema/query/domain/custom/EmbeddedType3.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/custom/EmbeddedType3.java index 1eb092f9ab..8dacf630f8 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/custom/EmbeddedType3.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/custom/EmbeddedType3.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.domain.custom; +package com.querydsl.apt.domain.custom; public class EmbeddedType3 { diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/custom/Entity.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/custom/Entity.java new file mode 100644 index 0000000000..097d67f33e --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/custom/Entity.java @@ -0,0 +1,32 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt.domain.custom; + +import java.util.List; +import java.util.Map; + +import com.querydsl.core.annotations.QueryEntity; + +@QueryEntity +public class Entity { + + List list; + + EmbeddedType2 embedded; + + Map map; + + String stringProperty; + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/p1/SEntity1.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/p1/SEntity1.java new file mode 100644 index 0000000000..fb918a5e82 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/p1/SEntity1.java @@ -0,0 +1,22 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt.domain.p1; + +import com.querydsl.core.annotations.QueryEntity; + +@QueryEntity +public class SEntity1 { + + String entity1Field; +} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/p10/AbstractPersistable.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/p10/AbstractPersistable.java similarity index 83% rename from querydsl-apt/src/test/java/com/mysema/query/domain/p10/AbstractPersistable.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/p10/AbstractPersistable.java index 65cb68082f..c2aed8b97e 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/p10/AbstractPersistable.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/p10/AbstractPersistable.java @@ -1,8 +1,9 @@ -package com.mysema.query.domain.p10; +package com.querydsl.apt.domain.p10; -import javax.persistence.MappedSuperclass; import java.io.Serializable; +import javax.persistence.MappedSuperclass; + @MappedSuperclass public abstract class AbstractPersistable implements Persistable { diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/p10/BasePersistable.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/p10/BasePersistable.java similarity index 84% rename from querydsl-apt/src/test/java/com/mysema/query/domain/p10/BasePersistable.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/p10/BasePersistable.java index 05b7c468cb..ff380ce735 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/p10/BasePersistable.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/p10/BasePersistable.java @@ -1,8 +1,9 @@ -package com.mysema.query.domain.p10; +package com.querydsl.apt.domain.p10; -import javax.persistence.MappedSuperclass; import java.io.Serializable; +import javax.persistence.MappedSuperclass; + @MappedSuperclass public class BasePersistable extends AbstractPersistable implements UpdateInfo { diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/p10/BaseReferencablePersistable.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/p10/BaseReferencablePersistable.java similarity index 83% rename from querydsl-apt/src/test/java/com/mysema/query/domain/p10/BaseReferencablePersistable.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/p10/BaseReferencablePersistable.java index 88ea4580a1..fdb1228b74 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/p10/BaseReferencablePersistable.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/p10/BaseReferencablePersistable.java @@ -1,8 +1,9 @@ -package com.mysema.query.domain.p10; +package com.querydsl.apt.domain.p10; -import javax.persistence.MappedSuperclass; import java.io.Serializable; +import javax.persistence.MappedSuperclass; + @MappedSuperclass public abstract class BaseReferencablePersistable extends BasePersistable { diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/p10/Persistable.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/p10/Persistable.java new file mode 100644 index 0000000000..4e43cd3e66 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/p10/Persistable.java @@ -0,0 +1,5 @@ +package com.querydsl.apt.domain.p10; + +public interface Persistable { + +} \ No newline at end of file diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/p10/UpdateInfo.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/p10/UpdateInfo.java new file mode 100644 index 0000000000..29efe72257 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/p10/UpdateInfo.java @@ -0,0 +1,5 @@ +package com.querydsl.apt.domain.p10; + +public interface UpdateInfo { + +} \ No newline at end of file diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/p10/UserAccount.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/p10/UserAccount.java similarity index 75% rename from querydsl-apt/src/test/java/com/mysema/query/domain/p10/UserAccount.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/p10/UserAccount.java index 8f515431a6..823ceb477f 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/p10/UserAccount.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/p10/UserAccount.java @@ -1,4 +1,4 @@ -package com.mysema.query.domain.p10; +package com.querydsl.apt.domain.p10; import javax.persistence.Entity; diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/p2/SEntity2.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/p2/SEntity2.java similarity index 75% rename from querydsl-apt/src/test/java/com/mysema/query/domain/p2/SEntity2.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/p2/SEntity2.java index 1b49dcc162..9c3865f343 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/p2/SEntity2.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/p2/SEntity2.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,10 +11,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.domain.p2; +package com.querydsl.apt.domain.p2; -import com.mysema.query.annotations.QueryEntity; -import com.mysema.query.domain.p4.SSupertype; +import com.querydsl.apt.domain.p4.SSupertype; +import com.querydsl.core.annotations.QueryEntity; @QueryEntity public class SEntity2 extends SSupertype { diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/p3/SEntity3.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/p3/SEntity3.java similarity index 75% rename from querydsl-apt/src/test/java/com/mysema/query/domain/p3/SEntity3.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/p3/SEntity3.java index 772053900b..0e14c8c5b9 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/p3/SEntity3.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/p3/SEntity3.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,10 +11,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.domain.p3; +package com.querydsl.apt.domain.p3; -import com.mysema.query.annotations.QueryEntity; -import com.mysema.query.domain.p2.SEntity2; +import com.querydsl.apt.domain.p2.SEntity2; +import com.querydsl.core.annotations.QueryEntity; @QueryEntity public class SEntity3 extends SEntity2 { diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/p4/SSupertype.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/p4/SSupertype.java similarity index 79% rename from querydsl-apt/src/test/java/com/mysema/query/domain/p4/SSupertype.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/p4/SSupertype.java index b507851ad8..f7512cb5b2 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/p4/SSupertype.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/p4/SSupertype.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,9 +11,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.domain.p4; +package com.querydsl.apt.domain.p4; -import com.mysema.query.annotations.QuerySupertype; +import com.querydsl.core.annotations.QuerySupertype; @QuerySupertype public class SSupertype { diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/p6/Type1.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/p6/Type1.java similarity index 87% rename from querydsl-apt/src/test/java/com/mysema/query/domain/p6/Type1.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/p6/Type1.java index 799cd6f223..9db4bc2106 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/p6/Type1.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/p6/Type1.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,10 +11,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.domain.p6; +package com.querydsl.apt.domain.p6; public class Type1 { - + private Type2 property; public Type2 getProperty() { @@ -24,5 +24,5 @@ public Type2 getProperty() { public void setProperty(Type2 property) { this.property = property; } - + } diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/p6/Type2.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/p6/Type2.java similarity index 87% rename from querydsl-apt/src/test/java/com/mysema/query/domain/p6/Type2.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/p6/Type2.java index 549554eebc..b44f80ae42 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/p6/Type2.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/p6/Type2.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,10 +11,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.domain.p6; +package com.querydsl.apt.domain.p6; public class Type2 { - + private String property; public String getProperty() { @@ -24,5 +24,5 @@ public String getProperty() { public void setProperty(String property) { this.property = property; } - + } diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/p6/TypeTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/p6/TypeTest.java new file mode 100644 index 0000000000..879c1c7f14 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/p6/TypeTest.java @@ -0,0 +1,29 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt.domain.p6; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +public class TypeTest { + + @Test + public void test() { + QType1 type1 = QType1.type1; + QType2 type2 = QType2.type2; + assertEquals(type2.getType(), type1.property.getType()); + assertEquals(type2.getClass(), type1.property.getClass()); + } +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/p6/package-info.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/p6/package-info.java new file mode 100644 index 0000000000..481fa709ba --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/p6/package-info.java @@ -0,0 +1,5 @@ +@QueryEntities({Type1.class, Type2.class}) +package com.querydsl.apt.domain.p6; + + +import com.querydsl.core.annotations.QueryEntities; \ No newline at end of file diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/p7/MyEntity.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/p7/MyEntity.java new file mode 100644 index 0000000000..76aaa2ad78 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/p7/MyEntity.java @@ -0,0 +1,8 @@ +package com.querydsl.apt.domain.p7; + +import javax.persistence.Entity; + +@Entity +public class MyEntity { + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/p8/Custom.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/p8/Custom.java new file mode 100644 index 0000000000..8699dbf85b --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/p8/Custom.java @@ -0,0 +1,5 @@ +package com.querydsl.apt.domain.p8; + +public class Custom { + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/p8/Entity.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/p8/Entity.java new file mode 100644 index 0000000000..c01dcea19e --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/p8/Entity.java @@ -0,0 +1,28 @@ +package com.querydsl.apt.domain.p8; + +import com.querydsl.core.annotations.QueryEntity; + +@QueryEntity +public class Entity { + + private Long id; + + private Custom custom; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Custom getCustom() { + return custom; + } + + public void setCustom(Custom custom) { + this.custom = custom; + } + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/p9/Article.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/p9/Article.java new file mode 100644 index 0000000000..149cbd9407 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/p9/Article.java @@ -0,0 +1,14 @@ +package com.querydsl.apt.domain.p9; + +import javax.persistence.Entity; + +@Entity +public class Article { + + String name; + + Content content; + + Person author; + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/p9/Content.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/p9/Content.java new file mode 100644 index 0000000000..bcc0ac62a5 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/p9/Content.java @@ -0,0 +1,10 @@ +package com.querydsl.apt.domain.p9; + +import javax.persistence.Embeddable; + +@Embeddable +public class Content { + + Article article; + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/p9/Person.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/p9/Person.java new file mode 100644 index 0000000000..f973529758 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/p9/Person.java @@ -0,0 +1,9 @@ +package com.querydsl.apt.domain.p9; + +import javax.persistence.Entity; + +@Entity +public class Person { + + String firstName, lastName; +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/package-info.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/package-info.java new file mode 100644 index 0000000000..1ef37ed62b --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/package-info.java @@ -0,0 +1,8 @@ +@QueryEntities({A.class, Tenant.class, DefaultRevisionEntity.class, Delegate3Test.Point.class, Delegate3Test.Polygon.class}) +package com.querydsl.apt.domain; + +import org.hibernate.envers.DefaultRevisionEntity; + +import com.querydsl.core.annotations.QueryEntities; +import com.querydsl.core.domain.A; +import com.querydsl.core.domain.Tenant; diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/rel/RelationType2.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/rel/RelationType2.java similarity index 80% rename from querydsl-apt/src/test/java/com/mysema/query/domain/rel/RelationType2.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/rel/RelationType2.java index 31a30055d6..3cd9a1931d 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/rel/RelationType2.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/rel/RelationType2.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,11 +11,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.domain.rel; +package com.querydsl.apt.domain.rel; import java.util.List; -import com.mysema.query.annotations.QueryEntity; +import com.querydsl.core.annotations.QueryEntity; @QueryEntity public class RelationType2> { diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/rel/SimpleType.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/rel/SimpleType.java new file mode 100644 index 0000000000..14d725a53c --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/rel/SimpleType.java @@ -0,0 +1,18 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt.domain.rel; + +public class SimpleType { + +} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/rel/SimpleType2.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/rel/SimpleType2.java similarity index 84% rename from querydsl-apt/src/test/java/com/mysema/query/domain/rel/SimpleType2.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/rel/SimpleType2.java index 1daf7e8f43..eb8a3ca11d 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/rel/SimpleType2.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/rel/SimpleType2.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.domain.rel; +package com.querydsl.apt.domain.rel; public class SimpleType2 { diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain2/BImpl.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain2/BImpl.java new file mode 100644 index 0000000000..23af2149b7 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain2/BImpl.java @@ -0,0 +1,9 @@ +package com.querydsl.apt.domain2; + +import com.querydsl.core.annotations.QueryEntity; +import com.querydsl.core.domain2.AImpl; + +@QueryEntity +public class BImpl extends AImpl { + +} \ No newline at end of file diff --git a/querydsl-apt/src/test/java/com/mysema/query/inheritance/Inheritance11Test.java b/querydsl-apt/src/test/java/com/querydsl/apt/inheritance/Inheritance11Test.java similarity index 84% rename from querydsl-apt/src/test/java/com/mysema/query/inheritance/Inheritance11Test.java rename to querydsl-apt/src/test/java/com/querydsl/apt/inheritance/Inheritance11Test.java index 4d08329599..412b72f790 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/inheritance/Inheritance11Test.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/inheritance/Inheritance11Test.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,36 +11,36 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.inheritance; +package com.querydsl.apt.inheritance; -import static org.junit.Assert.*; +import static org.junit.Assert.assertNotNull; import org.junit.Test; -import com.mysema.query.annotations.QueryEntity; +import com.querydsl.core.annotations.QueryEntity; public class Inheritance11Test { - + @QueryEntity public class Foo extends FooBase { - + } @QueryEntity public class FooBase { - + } @QueryEntity public class BarBase { - + } - + @QueryEntity public class Bar extends BarBase { - + } - + @Test public void test() { assertNotNull(QInheritance11Test_Foo.foo); diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/inheritance/Inheritance2Test.java b/querydsl-apt/src/test/java/com/querydsl/apt/inheritance/Inheritance2Test.java new file mode 100644 index 0000000000..c410718972 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/inheritance/Inheritance2Test.java @@ -0,0 +1,54 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt.inheritance; + +import org.junit.Ignore; + +import com.querydsl.core.annotations.QueryEntity; + +@Ignore +public class Inheritance2Test { + + @QueryEntity + public abstract class Base> { + @SuppressWarnings("unchecked") + Base2 base; + Base2 base2; + } + + @QueryEntity + public abstract class Base2,U extends IFace> { + + } + + @QueryEntity + public abstract class BaseSub extends Base { + + } + + @QueryEntity + public abstract class BaseSub2> extends Base { + + } + + @QueryEntity + public abstract class Base2Sub extends Base2,T> { + + } + + public interface IFace { + + } + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/inheritance/Inheritance3Test.java b/querydsl-apt/src/test/java/com/querydsl/apt/inheritance/Inheritance3Test.java new file mode 100644 index 0000000000..ba6d070d3f --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/inheritance/Inheritance3Test.java @@ -0,0 +1,87 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt.inheritance; + +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.junit.Test; + +import com.querydsl.apt.domain.AbstractTest; +import com.querydsl.core.annotations.QueryEntity; +import com.querydsl.core.types.dsl.SimplePath; +import com.querydsl.core.types.dsl.StringPath; + +public class Inheritance3Test extends AbstractTest { + + /* + * TODO : map type variables to BeanModels + */ + + @QueryEntity + public class GenericSupertype { + A field; + Collection fieldCol; + Set fieldSet; + List fieldList; + Map fieldMap1; + Map fieldMap2; + + String stringField; + } + + @QueryEntity + public class GenericSupertypeC> extends GenericSupertype { + + } + + @QueryEntity + public class GenericSupertypeS extends GenericSupertypeC { + + } + + @QueryEntity + public class GenericSupertypeS2 extends GenericSupertype { + + } + + @Test + public void genericSupertype() throws IllegalAccessException, NoSuchFieldException { + start(QInheritance3Test_GenericSupertype.class, QInheritance3Test_GenericSupertype.genericSupertype); + match(SimplePath.class, "field"); + matchType(Object.class, "field"); + } + + @Test + public void genericSupertypeC() throws IllegalAccessException, NoSuchFieldException { + start(QInheritance3Test_GenericSupertypeC.class, QInheritance3Test_GenericSupertypeC.genericSupertypeC); + match(SimplePath.class, "field"); + matchType(Comparable.class, "field"); + } + + @Test + public void genericSupertypeS() throws IllegalAccessException, NoSuchFieldException { + start(QInheritance3Test_GenericSupertypeS.class, QInheritance3Test_GenericSupertypeS.genericSupertypeS); + match(StringPath.class, "field"); + } + + @Test + public void genericSupertypeS2() throws IllegalAccessException, NoSuchFieldException { + start(QInheritance3Test_GenericSupertypeS2.class, QInheritance3Test_GenericSupertypeS2.genericSupertypeS2); + match(StringPath.class, "field"); + } + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/inheritance/Inheritance4Test.java b/querydsl-apt/src/test/java/com/querydsl/apt/inheritance/Inheritance4Test.java new file mode 100644 index 0000000000..21dcd68f10 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/inheritance/Inheritance4Test.java @@ -0,0 +1,71 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt.inheritance; + +import org.junit.Test; + +import com.querydsl.apt.domain.AbstractTest; +import com.querydsl.core.annotations.QueryEntity; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.SimplePath; +import com.querydsl.core.types.dsl.StringPath; + +public class Inheritance4Test extends AbstractTest { + + @QueryEntity + public class EntityWithComparable { + private Comparable field; + + public Comparable getField() { + return field; + } + + } + + @QueryEntity + public class EntityWithNumber extends EntityWithComparable { + private Long field; + + public Long getField() { + return field; + } + + } + + @QueryEntity + public class EntityWithString extends EntityWithComparable { + private String field; + + public String getField() { + return field; + } + + } + + @Test + public void test() throws IllegalAccessException, NoSuchFieldException { + start(QInheritance4Test_EntityWithComparable.class, QInheritance4Test_EntityWithComparable.entityWithComparable); + match(SimplePath.class, "field"); + matchType(Comparable.class, "field"); + + start(QInheritance4Test_EntityWithNumber.class, QInheritance4Test_EntityWithNumber.entityWithNumber); + match(NumberPath.class, "field"); + matchType(Long.class, "field"); + + start(QInheritance4Test_EntityWithString.class, QInheritance4Test_EntityWithString.entityWithString); + match(StringPath.class, "field"); + matchType(String.class, "field"); + + } +} diff --git a/querydsl-apt/src/test/java/com/mysema/query/inheritance/Inheritance5Test.java b/querydsl-apt/src/test/java/com/querydsl/apt/inheritance/Inheritance5Test.java similarity index 85% rename from querydsl-apt/src/test/java/com/mysema/query/inheritance/Inheritance5Test.java rename to querydsl-apt/src/test/java/com/querydsl/apt/inheritance/Inheritance5Test.java index e8a917561b..c4f7ed3426 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/inheritance/Inheritance5Test.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/inheritance/Inheritance5Test.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.inheritance; +package com.querydsl.apt.inheritance; import static org.junit.Assert.assertEquals; @@ -20,9 +20,9 @@ import org.junit.Test; -import com.mysema.query.annotations.QueryEntity; -import com.mysema.query.annotations.QuerySupertype; -import com.mysema.query.types.path.NumberPath; +import com.querydsl.core.annotations.QueryEntity; +import com.querydsl.core.annotations.QuerySupertype; +import com.querydsl.core.types.dsl.NumberPath; public class Inheritance5Test { diff --git a/querydsl-apt/src/test/java/com/mysema/query/inheritance/Inheritance6Test.java b/querydsl-apt/src/test/java/com/querydsl/apt/inheritance/Inheritance6Test.java similarity index 80% rename from querydsl-apt/src/test/java/com/mysema/query/inheritance/Inheritance6Test.java rename to querydsl-apt/src/test/java/com/querydsl/apt/inheritance/Inheritance6Test.java index b8f63a051e..91e66bf066 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/inheritance/Inheritance6Test.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/inheritance/Inheritance6Test.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.inheritance; +package com.querydsl.apt.inheritance; import static org.junit.Assert.assertEquals; @@ -20,10 +20,10 @@ import org.junit.Test; -import com.mysema.query.annotations.QueryEntity; -import com.mysema.query.annotations.QuerySupertype; -import com.mysema.query.types.path.DateTimePath; -import com.mysema.query.types.path.NumberPath; +import com.querydsl.core.annotations.QueryEntity; +import com.querydsl.core.annotations.QuerySupertype; +import com.querydsl.core.types.dsl.DateTimePath; +import com.querydsl.core.types.dsl.NumberPath; /** * Test multiple level superclasses with generics. @@ -69,23 +69,23 @@ public static class GlossKey extends TranslationKey { } @Test - public void Gloss_subtype_should_contain_fields_from_superclass() { + public void gloss_subtype_should_contain_fields_from_superclass() { assertEquals(String.class, QInheritance6Test_Gloss.gloss.value.getType()); } @Test - public void Intermediate_superclass_should_contain_fields_from_top_superclass() { + public void intermediate_superclass_should_contain_fields_from_top_superclass() { QInheritance6Test_Translation translation = QInheritance6Test_Gloss.gloss._super; assertEquals(DateTimePath.class, translation.createdOn.getClass()); } @Test - public void Gloss_subtype_should_contain_fields_from_top_superclass() { + public void gloss_subtype_should_contain_fields_from_top_superclass() { assertEquals(DateTimePath.class, QInheritance6Test_Gloss.gloss.createdOn.getClass()); } @Test - public void Gloss_subtype_should_contain_id_from_top_superclass() { + public void gloss_subtype_should_contain_id_from_top_superclass() { assertEquals(NumberPath.class, QInheritance6Test_Gloss.gloss.id.getClass()); } diff --git a/querydsl-apt/src/test/java/com/mysema/query/inheritance/Inheritance7Test.java b/querydsl-apt/src/test/java/com/querydsl/apt/inheritance/Inheritance7Test.java similarity index 90% rename from querydsl-apt/src/test/java/com/mysema/query/inheritance/Inheritance7Test.java rename to querydsl-apt/src/test/java/com/querydsl/apt/inheritance/Inheritance7Test.java index 79fb83b977..49ac4a3741 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/inheritance/Inheritance7Test.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/inheritance/Inheritance7Test.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.inheritance; +package com.querydsl.apt.inheritance; import static org.junit.Assert.assertEquals; @@ -20,7 +20,7 @@ import org.junit.Ignore; import org.junit.Test; -import com.mysema.query.annotations.QueryEntity; +import com.querydsl.core.annotations.QueryEntity; public class Inheritance7Test { @@ -35,7 +35,7 @@ public static class SubCategory extends Category { } @QueryEntity - public static class Category> implements Comparable{ + public static class Category> implements Comparable { private User owner; @@ -51,11 +51,11 @@ public User getOwner() { public int compareTo(T o) { return 0; } - + public boolean equals(Object o) { return o == this; } - + public T getParent() { return parent; } @@ -73,7 +73,7 @@ public static class SubCategory2 extends Category { @Test @Ignore - public void Parent() { + public void parent() { // FIXME assertEquals(Category.class, QInheritance7Test_Category.category.parent.getType()); assertEquals(SubCategory.class, QInheritance7Test_SubCategory.subCategory.parent.getType()); @@ -82,7 +82,7 @@ public void Parent() { @Test @Ignore - public void Children() { + public void children() { // FIXME assertEquals(Category.class, QInheritance7Test_Category.category.children.getElementType()); assertEquals(SubCategory.class, QInheritance7Test_SubCategory.subCategory.children.getElementType()); diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/inheritance/Inheritance8Test.java b/querydsl-apt/src/test/java/com/querydsl/apt/inheritance/Inheritance8Test.java new file mode 100644 index 0000000000..dc012774db --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/inheritance/Inheritance8Test.java @@ -0,0 +1,45 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt.inheritance; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import com.querydsl.core.annotations.QueryEntity; +import com.querydsl.core.domain.CommonIdentifiable; +import com.querydsl.core.domain.CommonPersistence; +import com.querydsl.core.types.dsl.NumberPath; + +public class Inheritance8Test { + + @QueryEntity + public static class SimpleSubclass extends CommonPersistence { + } + + @QueryEntity + public static class GenericSubclass extends CommonIdentifiable { + } + + @Test + public void simple_subclass_should_contain_fields_from_external_superclass() { + assertEquals(NumberPath.class, QInheritance8Test_SimpleSubclass.simpleSubclass.version.getClass()); + } + + @Test + public void generic_subclass_should_contain_fields_from_external_superclass() { + assertEquals(NumberPath.class, QInheritance8Test_GenericSubclass.genericSubclass.version.getClass()); + } + +} diff --git a/querydsl-apt/src/test/java/com/mysema/query/inheritance/Inheritance9Test.java b/querydsl-apt/src/test/java/com/querydsl/apt/inheritance/Inheritance9Test.java similarity index 86% rename from querydsl-apt/src/test/java/com/mysema/query/inheritance/Inheritance9Test.java rename to querydsl-apt/src/test/java/com/querydsl/apt/inheritance/Inheritance9Test.java index a1c962e884..ca6ac9ad15 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/inheritance/Inheritance9Test.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/inheritance/Inheritance9Test.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,14 +11,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.inheritance; +package com.querydsl.apt.inheritance; import static org.junit.Assert.assertNotNull; import org.junit.Test; -import com.mysema.query.annotations.QueryEntity; -import com.mysema.query.domain.SuperSupertype; +import com.querydsl.core.annotations.QueryEntity; +import com.querydsl.core.domain.SuperSupertype; /** * related to https://bugs.launchpad.net/querydsl/+bug/538148 diff --git a/querydsl-apt/src/test/java/com/mysema/query/inheritance/InheritanceTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/inheritance/InheritanceTest.java similarity index 91% rename from querydsl-apt/src/test/java/com/mysema/query/inheritance/InheritanceTest.java rename to querydsl-apt/src/test/java/com/querydsl/apt/inheritance/InheritanceTest.java index b5132fcd70..d04252d377 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/inheritance/InheritanceTest.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/inheritance/InheritanceTest.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,18 +11,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.inheritance; +package com.querydsl.apt.inheritance; import static org.junit.Assert.assertNotNull; import org.junit.Test; -import com.mysema.query.annotations.QueryEntity; +import com.querydsl.core.annotations.QueryEntity; public class InheritanceTest { @QueryEntity - public abstract class BobbinGenOperation extends Operation{ + public abstract class BobbinGenOperation extends Operation { } @@ -37,7 +37,7 @@ public abstract class FlexPlastic extends Storable { } @QueryEntity - public abstract class FlexPlasticFilm extends FlexPlastic implements Rimmable { + public abstract class FlexPlasticFilm extends FlexPlastic implements Rimmable { } diff --git a/querydsl-apt/template.mf b/querydsl-apt/template.mf deleted file mode 100644 index 38f0a7c8ae..0000000000 --- a/querydsl-apt/template.mf +++ /dev/null @@ -1,20 +0,0 @@ -Bundle-SymbolicName: com.mysema.querydsl.apt -Bundle-Name: Querydsl APT -Bundle-Vendor: Mysema -Bundle-ManifestVersion: 2 -Import-Template: - com.mysema.codegen.*;version="${codegen.version}", - com.mysema.commons.lang.*;version="${mysema.lang.version}", - com.mysema.query.*;version="${project.version}", - com.mysema.util.*;version="${project.version}", - javax.annotation.*;version="0", - javax.inject.*;version="0", - javax.lang.model.*;version="0", - javax.tools.*;version="0", - net.sf.cglib.proxy.*;version="${cglib.version}", - com.google.common.*;version="${guava.version}" -Excluded-Imports: - javax.persistence.*;version="[2.0.0,2.1.0)", - javax.jdo.*;version="[2.0.0,3.0.0)", - org.springframework.roo.*;version="1.2.3", - org.mongodb.morphia.annotations.*;version="0.99" \ No newline at end of file diff --git a/querydsl-bom/pom.xml b/querydsl-bom/pom.xml new file mode 100644 index 0000000000..7aa0f87bac --- /dev/null +++ b/querydsl-bom/pom.xml @@ -0,0 +1,172 @@ + + + 4.0.0 + + + com.querydsl + querydsl-root + 5.1.0 + + + querydsl-bom + Querydsl - Bill of materials + Bill of materials + ${project.homepage} + pom + + + 1.2.7 + + + + + + ${project.groupId} + querydsl-core + ${project.version} + + + ${project.groupId} + querydsl-codegen + ${project.version} + + + ${project.groupId} + codegen-utils + ${project.version} + + + ${project.groupId} + querydsl-spatial + ${project.version} + + + ${project.groupId} + querydsl-apt + ${project.version} + + + ${project.groupId} + querydsl-collections + ${project.version} + + + ${project.groupId} + querydsl-guava + ${project.version} + + + ${project.groupId} + querydsl-sql + ${project.version} + + + ${project.groupId} + querydsl-sql-spatial + ${project.version} + + + ${project.groupId} + querydsl-sql-codegen + ${project.version} + + + ${project.groupId} + querydsl-sql-spring + ${project.version} + + + ${project.groupId} + querydsl-jpa + ${project.version} + + + ${project.groupId} + querydsl-jpa-codegen + ${project.version} + + + ${project.groupId} + querydsl-jdo + ${project.version} + + + ${project.groupId} + querydsl-kotlin-codegen + ${project.version} + + + ${project.groupId} + querydsl-lucene3 + ${project.version} + + + ${project.groupId} + querydsl-lucene4 + ${project.version} + + + ${project.groupId} + querydsl-lucene5 + ${project.version} + + + ${project.groupId} + querydsl-hibernate-search + ${project.version} + + + ${project.groupId} + querydsl-mongodb + ${project.version} + + + ${project.groupId} + querydsl-scala + ${project.version} + + + ${project.groupId} + querydsl-kotlin + ${project.version} + + + + + + + + org.codehaus.mojo + flatten-maven-plugin + ${flatten-maven-plugin.version} + + + flatten + process-resources + + flatten + + + true + bom + + remove + remove + remove + + + + + flatten-clean + clean + + clean + + + + + + + diff --git a/querydsl-codegen-utils/pom.xml b/querydsl-codegen-utils/pom.xml new file mode 100644 index 0000000000..8e825d818a --- /dev/null +++ b/querydsl-codegen-utils/pom.xml @@ -0,0 +1,126 @@ + + + + 4.0.0 + codegen-utils + 5.1.0 + Querydsl - Codegen utils + Code generation and compilation for Java + + + com.querydsl + querydsl-root + 5.1.0 + ../pom.xml + + + jar + + 2010 + + + + Apache License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + + + + + scm:git:git@github.com:querydsl/codegen.git + git@github.com:querydsl/codegen.git + + + + 4.01 + 3.0.1 + 3.26.0 + javax.annotation.*;version="0",javax.tools.*;version="0",org.eclipse.jdt.*;version="3.7.2"${osgi.import.package.root} + + + + + org.eclipse.jdt + ecj + ${ecj.version} + + + io.github.classgraph + classgraph + compile + + + + + junit + junit + 4.13.2 + test + + + javax.validation + validation-api + provided + + + + + + + org.apache.maven.plugins + maven-jar-plugin + 3.2.2 + + + + com.querydsl.codegen.utils + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + + + + org.apache.maven.plugins + maven-surefire-plugin + + true + + + + + + + + com.springsource.repository.bundles.release + http://repository.springsource.com/maven/bundles/release + + + + + + + tiwe + Timo Westkämper + timo.westkamper@mysema.com + Mysema Ltd + + Architect + + + + laim + Lassi Immonen + lassi.immonen@mysema.com + Mysema Ltd + + Consultant + + + + diff --git a/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/AbstractCodeWriter.java b/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/AbstractCodeWriter.java new file mode 100644 index 0000000000..8941de6078 --- /dev/null +++ b/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/AbstractCodeWriter.java @@ -0,0 +1,99 @@ +/* + * Copyright 2010, Mysema Ltd + * + * 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. + */ +package com.querydsl.codegen.utils; + +import java.io.IOException; + +/** + * @author tiwe + * + * @param + */ +public abstract class AbstractCodeWriter> implements Appendable, + CodeWriter { + + private final Appendable appendable; + + private final int spaces; + + private final String spacesString; + + private String indent = ""; + + @SuppressWarnings("unchecked") + private final T self = (T) this; + + public AbstractCodeWriter(Appendable appendable, int spaces) { + if (appendable == null) { + throw new IllegalArgumentException("appendable is null"); + } + this.appendable = appendable; + this.spaces = spaces; + this.spacesString = StringUtils.repeat(' ', spaces); + } + + @Override + public T append(char c) throws IOException { + appendable.append(c); + return self; + } + + @Override + public T append(CharSequence csq) throws IOException { + appendable.append(csq); + return self; + } + + @Override + public T append(CharSequence csq, int start, int end) throws IOException { + appendable.append(csq, start, end); + return self; + } + + @Override + public T beginLine(String... segments) throws IOException { + append(indent); + for (String segment : segments) { + append(segment); + } + return self; + } + + protected T goIn() { + indent += spacesString; + return self; + } + + protected T goOut() { + if (indent.length() >= spaces) { + indent = indent.substring(0, indent.length() - spaces); + } + return self; + } + + @Override + public T line(String... segments) throws IOException { + append(indent); + for (String segment : segments) { + append(segment); + } + return nl(); + } + + @Override + public T nl() throws IOException { + return append(System.lineSeparator()); + } + +} diff --git a/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/AbstractEvaluatorFactory.java b/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/AbstractEvaluatorFactory.java new file mode 100644 index 0000000000..f54357ad62 --- /dev/null +++ b/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/AbstractEvaluatorFactory.java @@ -0,0 +1,180 @@ +/* + * Copyright 2012, Mysema Ltd + * + * 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. + */ +package com.querydsl.codegen.utils; + +import java.io.IOException; +import java.io.StringWriter; +import java.lang.reflect.Method; +import java.util.Collection; +import java.util.Map; +import java.util.WeakHashMap; + +import com.querydsl.codegen.utils.model.ClassType; +import com.querydsl.codegen.utils.model.Parameter; +import com.querydsl.codegen.utils.model.SimpleType; +import com.querydsl.codegen.utils.model.Type; +import com.querydsl.codegen.utils.model.TypeCategory; +import com.querydsl.codegen.utils.support.ClassUtils; + +/** + * @author tiwe + * + */ +public abstract class AbstractEvaluatorFactory implements EvaluatorFactory { + + private final Map cache = new WeakHashMap(); + + protected ClassLoader loader; + + /** + * @param source + * @param projection + * @param names + * @param types + * @param id + * @param constants + * @throws IOException + */ + protected abstract void compile(String source, ClassType projection, String[] names, Type[] types, + String id, Map constants) throws IOException; + + /** + * @param source + * @param projectionType + * @param names + * @param types + * @param id + * @param constants + * @return + * @throws IOException + */ + protected String createSource(String source, ClassType projectionType, String[] names, + Type[] types, String id, Map constants) throws IOException { + // create source + StringWriter writer = new StringWriter(); + JavaWriter javaw = new JavaWriter(writer); + SimpleType idType = new SimpleType(id, "", id); + javaw.beginClass(idType, null); + Parameter[] params = new Parameter[names.length + constants.size()]; + for (int i = 0; i < names.length; i++) { + params[i] = new Parameter(names[i], types[i]); + } + int i = names.length; + for (Map.Entry entry : constants.entrySet()) { + Type type = new ClassType(TypeCategory.SIMPLE, ClassUtils.normalize(entry.getValue().getClass())); + params[i++] = new Parameter(entry.getKey(), type); + } + + javaw.beginStaticMethod(projectionType, "eval", params); + javaw.append(source); + javaw.end(); + javaw.end(); + return writer.toString(); + } + + + @Override + public Evaluator createEvaluator(String source, Class projectionType, + String[] names, Class[] classes, Map constants) { + Type[] types = new Type[classes.length]; + for (int i = 0; i < types.length; i++) { + types[i] = new ClassType(TypeCategory.SIMPLE, classes[i]); + } + return createEvaluator(source, new ClassType(TypeCategory.SIMPLE, projectionType), names, + types, classes, constants); + } + + + /** + * Create a new Evaluator instance + * + * @param + * projection type + * @param source + * expression in Java source code form + * @param projection + * type of the source expression + * @param names + * names of the arguments + * @param types + * types of the arguments + * @param constants + * @return + */ + @SuppressWarnings("unchecked") + @Override + public synchronized Evaluator createEvaluator(String source, ClassType projection, String[] names, + Type[] types, Class[] classes, Map constants) { + try { + final String id = toId(source, projection.getJavaClass(), types, constants.values()); + Method method = cache.get(id); + + if (method == null) { + Class clazz; + try { + clazz = loader.loadClass(id); + } catch (ClassNotFoundException e) { + compile(source, projection, names, types, id, constants); + // reload + clazz = loader.loadClass(id); + } + method = findEvalMethod(clazz); + cache.put(id, method); + } + + return new MethodEvaluator(method, constants, (Class) projection.getJavaClass()); + } catch (ClassNotFoundException e) { + throw new CodegenException(e); + } catch (SecurityException e) { + throw new CodegenException(e); + } catch (IOException e) { + throw new CodegenException(e); + } + } + + protected Method findEvalMethod(Class clazz) { + /* + * Note 1: + * Some Java instrumentation tools (e.g. JaCoCo) insert code into + * classes at runtime. This means that the static eval() method *could* + * not be the first method of our runtime generated classes anymore. + * + * Note 2: + * We can't use clazz.getDeclaredMethod(name, classes), as the argument + * types of the eval() method could be normalized (see createSource()). + */ + for (Method method : clazz.getDeclaredMethods()) { + if ("eval".equals(method.getName())) { + return method; + } + } + + throw new IllegalArgumentException("Couldn't find eval method!"); + } + + protected String toId(String source, Class returnType, Type[] types, Collection constants) { + StringBuilder b = new StringBuilder(128); + b.append("Q"); + b.append("_").append(source.hashCode()); + b.append("_").append(returnType.getName().hashCode()); + for (Type type : types) { + b.append("_").append(type.getFullName().hashCode()); + } + for (Object constant : constants) { + b.append("_").append(constant.getClass().getName().hashCode()); + } + return b.toString().replace('-', '0'); + } + +} diff --git a/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/CodeWriter.java b/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/CodeWriter.java new file mode 100644 index 0000000000..555c2f502d --- /dev/null +++ b/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/CodeWriter.java @@ -0,0 +1,114 @@ +/* + * Copyright 2010, Mysema Ltd + * + * 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. + */ +package com.querydsl.codegen.utils; + +import java.io.IOException; +import java.lang.annotation.Annotation; +import java.util.Collection; +import java.util.function.Function; + +import com.querydsl.codegen.utils.model.Parameter; +import com.querydsl.codegen.utils.model.Type; + +/** + * CodeWriter defines an interface for serializing Java source code + * + * @author tiwe + * + */ +public interface CodeWriter extends Appendable { + + String getRawName(Type type); + + String getGenericName(boolean asArgType, Type type); + + String getClassConstant(String className); + + CodeWriter annotation(Annotation annotation) throws IOException; + + CodeWriter annotation(Class annotation) throws IOException; + + CodeWriter beginClass(Type type) throws IOException; + + CodeWriter beginClass(Type type, Type superClass, Type... interfaces) throws IOException; + + CodeWriter beginConstructor(Collection params, Function transformer) throws IOException; + + CodeWriter beginConstructor(Parameter... params) throws IOException; + + CodeWriter beginInterface(Type type, Type... interfaces) throws IOException; + + CodeWriter beginLine(String... segments) throws IOException; + + CodeWriter beginPublicMethod(Type returnType, String methodName, Collection parameters, + Function transformer) throws IOException; + + CodeWriter beginPublicMethod(Type returnType, String methodName, Parameter... args) throws IOException; + + CodeWriter beginStaticMethod(Type type, String name, Collection params, + Function transformer) throws IOException; + + CodeWriter beginStaticMethod(Type returnType, String methodName, Parameter... args) throws IOException; + + CodeWriter end() throws IOException; + + CodeWriter field(Type type, String name) throws IOException; + + CodeWriter imports(Class... imports) throws IOException; + + CodeWriter imports(Package... imports) throws IOException; + + CodeWriter importClasses(String... classes) throws IOException; + + CodeWriter importPackages(String... packages) throws IOException; + + CodeWriter javadoc(String... lines) throws IOException; + + CodeWriter line(String... segments) throws IOException; + + CodeWriter nl() throws IOException; + + CodeWriter packageDecl(String packageName) throws IOException; + + CodeWriter privateField(Type type, String name) throws IOException; + + CodeWriter privateFinal(Type type, String name) throws IOException; + + CodeWriter privateFinal(Type type, String name, String value) throws IOException; + + CodeWriter privateStaticFinal(Type type, String name, String value) throws IOException; + + CodeWriter protectedField(Type type, String name) throws IOException; + + CodeWriter protectedFinal(Type type, String name) throws IOException; + + CodeWriter protectedFinal(Type type, String name, String value) throws IOException; + + CodeWriter publicField(Type type, String name) throws IOException; + + CodeWriter publicField(Type type, String name, String value) throws IOException; + + CodeWriter publicFinal(Type type, String name) throws IOException; + + CodeWriter publicFinal(Type type, String name, String value) throws IOException; + + CodeWriter publicStaticFinal(Type type, String name, String value) throws IOException; + + CodeWriter staticimports(Class... imports) throws IOException; + + CodeWriter suppressWarnings(String type) throws IOException; + + CodeWriter suppressWarnings(String... types) throws IOException; + +} \ No newline at end of file diff --git a/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/CodegenException.java b/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/CodegenException.java new file mode 100644 index 0000000000..52d34c9022 --- /dev/null +++ b/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/CodegenException.java @@ -0,0 +1,35 @@ +/* + * Copyright 2010, Mysema Ltd + * + * 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. + */ +package com.querydsl.codegen.utils; + +/** + * @author tiwe + * + */ +public class CodegenException extends RuntimeException { + + private static final long serialVersionUID = -8704782349669898467L; + + public CodegenException(String msg) { + super(msg); + } + + public CodegenException(String msg, Throwable t) { + super(msg, t); + } + + public CodegenException(Throwable t) { + super(t); + } +} diff --git a/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/ECJEvaluatorFactory.java b/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/ECJEvaluatorFactory.java new file mode 100644 index 0000000000..77ec0e39c0 --- /dev/null +++ b/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/ECJEvaluatorFactory.java @@ -0,0 +1,306 @@ +/* + * Copyright 2010, Mysema Ltd + * + * 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. + */ +package com.querydsl.codegen.utils; + +import javax.tools.JavaFileObject; +import javax.tools.StandardLocation; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.StringTokenizer; +import java.util.stream.Collectors; + +import com.querydsl.codegen.utils.model.ClassType; +import com.querydsl.codegen.utils.model.Type; +import org.eclipse.jdt.core.compiler.CategorizedProblem; +import org.eclipse.jdt.core.compiler.CharOperation; +import org.eclipse.jdt.internal.compiler.*; +import org.eclipse.jdt.internal.compiler.Compiler; +import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader; +import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException; +import org.eclipse.jdt.internal.compiler.env.ICompilationUnit; +import org.eclipse.jdt.internal.compiler.env.INameEnvironment; +import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer; +import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; +import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory; +import org.eclipse.jdt.internal.compiler.tool.EclipseFileManager; + +/** + * EvaluatorFactory is a factory implementation for creating Evaluator instances + * + * @author tiwe + * + */ +public class ECJEvaluatorFactory extends AbstractEvaluatorFactory { + + private final MemFileManager fileManager; + + private final ClassLoader parentClassLoader; + + private final List problemList = new ArrayList<>(); + + private final CompilerOptions compilerOptions; + + public static CompilerOptions getDefaultCompilerOptions() { + String javaSpecVersion = System.getProperty("java.specification.version"); + Map settings = new HashMap<>(); + settings.put(CompilerOptions.OPTION_Source, javaSpecVersion); + settings.put(CompilerOptions.OPTION_TargetPlatform, javaSpecVersion); + settings.put(CompilerOptions.OPTION_ReportDeprecation, CompilerOptions.IGNORE); + return new CompilerOptions(settings); + } + + public ECJEvaluatorFactory(ClassLoader parent) { + this(parent, getDefaultCompilerOptions()); + } + + public ECJEvaluatorFactory(ClassLoader parent, CompilerOptions compilerOptions) { + this.parentClassLoader = parent; + this.fileManager = new MemFileManager(parent, new EclipseFileManager(Locale.getDefault(), Charset.defaultCharset())); + this.loader = fileManager.getClassLoader(StandardLocation.CLASS_OUTPUT); + this.compilerOptions = compilerOptions; + } + + protected void compile(String source, ClassType projectionType, String[] names, Type[] types, + String id, Map constants) throws IOException { + // create source + source = createSource(source, projectionType, names, types, id, constants); + + // compile + final char[] targetContents = source.toCharArray(); + final String targetName = id; + final ICompilationUnit[] targetCompilationUnits = new ICompilationUnit[] { new ICompilationUnit() { + @Override + public char[] getContents() { + return targetContents; + } + + @Override + public char[] getMainTypeName() { + int dot = targetName.lastIndexOf('.'); + if (dot > 0) { + return targetName.substring(dot + 1).toCharArray(); + } else { + return targetName.toCharArray(); + } + } + + @Override + public char[][] getPackageName() { + StringTokenizer tok = new StringTokenizer(targetName, "."); + char[][] result = new char[tok.countTokens() - 1][]; + for (int j = 0; j < result.length; j++) { + result[j] = tok.nextToken().toCharArray(); + } + return result; + } + + @Override + public char[] getFileName() { + return CharOperation.concat(targetName.toCharArray(), ".java".toCharArray()); + } + + @Override + public boolean ignoreOptionalProblems() { + return true; + } + } }; + + INameEnvironment env = new INameEnvironment() { + + private String join(char[][] compoundName, char separator) { + if (compoundName == null) { + return ""; + } else { + List parts = new ArrayList<>(compoundName.length); + for (char[] part: compoundName) { + parts.add(new String(part)); + } + return parts.stream().collect(Collectors.joining(new String(new char[] { separator }))); + } + } + + @Override + public NameEnvironmentAnswer findType(char[][] compoundTypeName) { + return findType(join(compoundTypeName, '.')); + } + + @Override + public NameEnvironmentAnswer findType(char[] typeName, char[][] packageName) { + return findType(CharOperation.arrayConcat(packageName, typeName)); + } + + private boolean isClass(String result) { + if (result == null || result.isEmpty()) { + return false; + } + + // if it's the class we're compiling, then of course it's a class + if (result.equals(targetName)) { + return true; + } + InputStream is = null; + try { + // if this is a class we've already compiled, it's a class + is = loader.getResourceAsStream(result); + if (is == null) { + // use our normal class loader now... + String resourceName = result.replace('.', '/') + ".class"; + is = parentClassLoader.getResourceAsStream(resourceName); + if (is == null && !result.contains(".")) { + // we couldn't find the class, and it has no package; is it a core class? + is = parentClassLoader.getResourceAsStream("java/lang/" + resourceName); + } + } + return is != null; + } finally { + if (is != null) { + try { + is.close(); + } catch (IOException ex) { } + } + } + } + + @Override + public boolean isPackage(char[][] parentPackageName, char[] packageName) { + // if the parent is a class, the child can't be a package + String parent = join(parentPackageName, '.'); + if (isClass(parent)) { + return false; + } + + // if the child is a class, it's not a package + String qualifiedName = (parent.isEmpty() ? "" : parent + ".") + new String(packageName); + return !isClass(qualifiedName); + } + + @Override + public void cleanup() { + } + + private NameEnvironmentAnswer findType(String className) { + String resourceName = className.replace('.', '/') + ".class"; + InputStream is = null; + try { + // we're only asking ECJ to compile a single class; we shouldn't need this + if (className.equals(targetName)) { + return new NameEnvironmentAnswer(targetCompilationUnits[0], null); + } + + is = loader.getResourceAsStream(resourceName); + if (is == null) { + is = parentClassLoader.getResourceAsStream(resourceName); + } + + if (is != null) { + + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + int nRead; + byte[] data = new byte[1024]; + while ((nRead = is.read(data, 0, data.length)) != -1) { + buffer.write(data, 0, nRead); + } + buffer.flush(); + + ClassFileReader cfr = new ClassFileReader(buffer.toByteArray(), className.toCharArray(), true); + return new NameEnvironmentAnswer(cfr, null); + } else { + return null; + } + } catch (ClassFormatException | IOException ex) { + throw new RuntimeException(ex); + } finally { + if (is != null) { + try { + is.close(); + } catch (IOException e) { } + } + } + + } + }; + + ICompilerRequestor requestor = new ICompilerRequestor() { + + @Override + public void acceptResult(CompilationResult result) { + if (result.hasErrors()) { + for (CategorizedProblem problem: result.getProblems()) { + if (problem.isError()) { + problemList.add(problem.getMessage()); + } + } + } else { + for (ClassFile clazz: result.getClassFiles()) { + try { + MemJavaFileObject jfo = (MemJavaFileObject) fileManager + .getJavaFileForOutput(StandardLocation.CLASS_OUTPUT, + new String(clazz.fileName()), JavaFileObject.Kind.CLASS, null); + OutputStream os = jfo.openOutputStream(); + os.write(clazz.getBytes()); + } catch (IOException ex) { + throw new RuntimeException(ex); + } + } + } + } + }; + + problemList.clear(); + + IErrorHandlingPolicy policy = DefaultErrorHandlingPolicies.exitAfterAllProblems(); + IProblemFactory problemFactory = new DefaultProblemFactory(Locale.getDefault()); + + try { + //Compiler compiler = new Compiler(env, policy, getCompilerOptions(), requestor, problemFactory, true); + Compiler compiler = new Compiler(env, policy, compilerOptions, requestor, problemFactory); + compiler.compile(targetCompilationUnits); + if (!problemList.isEmpty()) { + StringBuilder sb = new StringBuilder(); + for (String problem: problemList) { + sb.append("\t").append(problem).append("\n"); + } + throw new CodegenException("Compilation of " + id + " failed:\n" + source + "\n" + sb.toString()); + } + } catch (RuntimeException ex) { + // if we encountered an IOException, unbox and throw it; + // if we encountered a ClassFormatException, box it as an IOException and throw it + // otherwise, it's a legit RuntimeException, + // not one of our checked exceptions boxed as unchecked; just rethrow + Throwable cause = ex.getCause(); + if (cause != null) { + if (cause instanceof IOException) { + throw (IOException) cause; + } else if (cause instanceof ClassFormatException) { + throw new IOException(cause); + } + } + throw ex; + } + } + + public CompilerOptions getCompilerOptions() { + return compilerOptions; + } + + +} diff --git a/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/Evaluator.java b/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/Evaluator.java new file mode 100644 index 0000000000..d49d5dd175 --- /dev/null +++ b/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/Evaluator.java @@ -0,0 +1,36 @@ +/* + * Copyright 2010, Mysema Ltd + * + * 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. + */ +package com.querydsl.codegen.utils; + +/** + * Evaluator defines an interface for returning a value as a result of + * evaluating an expression using the given argument array + * + * @author tiwe + * + */ +public interface Evaluator { + + /** + * @param args + * @return + */ + T evaluate(Object... args); + + /** + * @return + */ + Class getType(); + +} diff --git a/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/EvaluatorFactory.java b/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/EvaluatorFactory.java new file mode 100644 index 0000000000..12a7d43ca4 --- /dev/null +++ b/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/EvaluatorFactory.java @@ -0,0 +1,57 @@ +/* + * Copyright 2010, Mysema Ltd + * + * 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. + */ +package com.querydsl.codegen.utils; + +import com.querydsl.codegen.utils.model.ClassType; +import com.querydsl.codegen.utils.model.Type; + +import java.util.Map; + +/** + * + * @author pgrant + */ +public interface EvaluatorFactory { + + /** + * @param source + * @param projectionType + * @param names + * @param classes + * @param constants + * @return + */ + Evaluator createEvaluator(String source, Class projectionType, + String[] names, Class[] classes, Map constants); + + /** + * Create a new Evaluator instance + * + * @param + * projection type + * @param source + * expression in Java source code form + * @param projection + * type of the source expression + * @param names + * names of the arguments + * @param types + * types of the arguments + * @param constants + * @return + */ + Evaluator createEvaluator(String source, ClassType projection, String[] names, + Type[] types, Class[] classes, Map constants); + +} diff --git a/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/JDKEvaluatorFactory.java b/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/JDKEvaluatorFactory.java new file mode 100644 index 0000000000..2c5b731cd7 --- /dev/null +++ b/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/JDKEvaluatorFactory.java @@ -0,0 +1,78 @@ +/* + * Copyright 2010, Mysema Ltd + * + * 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. + */ +package com.querydsl.codegen.utils; + +import java.io.IOException; +import java.io.StringWriter; +import java.io.Writer; +import java.net.URLClassLoader; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import javax.tools.JavaCompiler; +import javax.tools.JavaCompiler.CompilationTask; +import javax.tools.SimpleJavaFileObject; +import javax.tools.StandardLocation; +import javax.tools.ToolProvider; + +import com.querydsl.codegen.utils.model.ClassType; +import com.querydsl.codegen.utils.model.Type; + +/** + * JDKEvaluatorFactory is a factory implementation for creating Evaluator instances + * + * @author tiwe + * + */ +public class JDKEvaluatorFactory extends AbstractEvaluatorFactory { + + private final MemFileManager fileManager; + + private final String classpath; + + private final List compilationOptions; + + private final JavaCompiler compiler; + + public JDKEvaluatorFactory(URLClassLoader parent) { + this(parent, ToolProvider.getSystemJavaCompiler()); + } + + public JDKEvaluatorFactory(URLClassLoader parent, JavaCompiler compiler) { + this.fileManager = new MemFileManager(parent, compiler.getStandardFileManager(null, null, null)); + this.compiler = compiler; + this.classpath = SimpleCompiler.getClassPath(parent); + this.loader = fileManager.getClassLoader(StandardLocation.CLASS_OUTPUT); + this.compilationOptions = Arrays.asList("-classpath", classpath, "-g:none"); + } + + protected void compile(String source, ClassType projectionType, String[] names, Type[] types, + String id, Map constants) throws IOException { + // create source + source = createSource(source, projectionType, names, types, id, constants); + + // compile + SimpleJavaFileObject javaFileObject = new MemSourceFileObject(id, source); + Writer out = new StringWriter(); + + CompilationTask task = compiler.getTask(out, fileManager, null, compilationOptions, null, + Collections.singletonList(javaFileObject)); + if (!task.call().booleanValue()) { + throw new CodegenException("Compilation of " + source + " failed.\n" + out.toString()); + } + } + +} diff --git a/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/JavaWriter.java b/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/JavaWriter.java new file mode 100644 index 0000000000..762a2d5c87 --- /dev/null +++ b/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/JavaWriter.java @@ -0,0 +1,492 @@ +/* + * Copyright 2010, Mysema Ltd + * + * 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. + */ +package com.querydsl.codegen.utils; + +import java.io.IOException; +import java.lang.annotation.Annotation; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; +import java.util.Stack; +import java.util.function.Function; + +import com.querydsl.codegen.utils.model.Parameter; +import com.querydsl.codegen.utils.model.Type; + +/** + * JavaWriter is the default implementation of the CodeWriter interface + * + * @author tiwe + * + */ +public final class JavaWriter extends AbstractCodeWriter { + + private static final String EXTENDS = " extends "; + + private static final String IMPLEMENTS = " implements "; + + private static final String IMPORT = "import "; + + private static final String IMPORT_STATIC = "import static "; + + private static final String PACKAGE = "package "; + + private static final String PRIVATE = "private "; + + private static final String PRIVATE_FINAL = "private final "; + + private static final String PRIVATE_STATIC_FINAL = "private static final "; + + private static final String PROTECTED = "protected "; + + private static final String PROTECTED_FINAL = "protected final "; + + private static final String PUBLIC = "public "; + + private static final String PUBLIC_CLASS = "public class "; + + private static final String PUBLIC_FINAL = "public final "; + + private static final String PUBLIC_INTERFACE = "public interface "; + + private static final String PUBLIC_STATIC = "public static "; + + private static final String PUBLIC_STATIC_FINAL = "public static final "; + + private final Set classes = new HashSet(); + + private final Set packages = new HashSet(); + + private final Stack types = new Stack(); + + public JavaWriter(Appendable appendable) { + super(appendable, 4); + this.packages.add("java.lang"); + } + + @Override + public JavaWriter annotation(Annotation annotation) throws IOException { + beginLine().append("@").appendType(annotation.annotationType()); + Method[] methods = annotation.annotationType().getDeclaredMethods(); + if (methods.length == 1 && methods[0].getName().equals("value")) { + try { + Object value = methods[0].invoke(annotation); + append("("); + annotationConstant(value); + append(")"); + } catch (IllegalArgumentException e) { + throw new CodegenException(e); + } catch (IllegalAccessException e) { + throw new CodegenException(e); + } catch (InvocationTargetException e) { + throw new CodegenException(e); + } + } else { + boolean first = true; + for (Method method : methods) { + try { + Object value = method.invoke(annotation); + if (value == null || value.equals(method.getDefaultValue())) { + continue; + } else if (value.getClass().isArray() + && Arrays.equals((Object[]) value, (Object[]) method.getDefaultValue())) { + continue; + } else if (!first) { + append(Symbols.COMMA); + } else { + append("("); + } + append(method.getName()).append("="); + annotationConstant(value); + } catch (IllegalArgumentException e) { + throw new CodegenException(e); + } catch (IllegalAccessException e) { + throw new CodegenException(e); + } catch (InvocationTargetException e) { + throw new CodegenException(e); + } + first = false; + } + if (!first) { + append(")"); + } + } + return nl(); + } + + @Override + public JavaWriter annotation(Class annotation) throws IOException { + return beginLine().append("@").appendType(annotation).nl(); + } + + @SuppressWarnings("unchecked") + private void annotationConstant(Object value) throws IOException { + if (value.getClass().isArray()) { + append("{"); + boolean first = true; + for (Object o : (Object[]) value) { + if (!first) { + append(", "); + } + annotationConstant(o); + first = false; + } + append("}"); + } else if (value instanceof Class) { + appendType((Class) value).append(".class"); + } else if (value instanceof Number || value instanceof Boolean) { + append(value.toString()); + } else if (value instanceof Enum) { + Enum enumValue = (Enum) value; + if (classes.contains(enumValue.getClass().getName()) + || packages.contains(enumValue.getClass().getPackage().getName())) { + append(enumValue.name()); + } else { + append(enumValue.getDeclaringClass().getName()).append(Symbols.DOT).append(enumValue.name()); + } + } else if (value instanceof String) { + String escaped = StringUtils.escapeJava(value.toString()); + append(Symbols.QUOTE).append(escaped.replace("\\/", "/")).append(Symbols.QUOTE); + } else { + throw new IllegalArgumentException("Unsupported annotation value : " + value); + } + } + + private JavaWriter appendType(Class type) throws IOException { + if (classes.contains(type.getName()) || packages.contains(type.getPackage().getName())) { + append(type.getSimpleName()); + } else { + append(type.getName()); + } + return this; + } + + @Override + public JavaWriter beginClass(Type type) throws IOException { + return beginClass(type, null); + } + + @Override + public JavaWriter beginClass(Type type, Type superClass, Type... interfaces) throws IOException { + packages.add(type.getPackageName()); + beginLine(PUBLIC_CLASS, type.getGenericName(false, packages, classes)); + if (superClass != null) { + append(EXTENDS).append(superClass.getGenericName(false, packages, classes)); + } + if (interfaces.length > 0) { + append(IMPLEMENTS); + for (int i = 0; i < interfaces.length; i++) { + if (i > 0) { + append(Symbols.COMMA); + } + append(interfaces[i].getGenericName(false, packages, classes)); + } + } + append(" {").nl().nl(); + goIn(); + types.push(type); + return this; + } + + @Override + public JavaWriter beginConstructor(Collection parameters, + Function transformer) throws IOException { + types.push(types.peek()); + beginLine(PUBLIC, types.peek().getSimpleName()).params(parameters, transformer) + .append(" {").nl(); + return goIn(); + } + + @Override + public JavaWriter beginConstructor(Parameter... parameters) throws IOException { + types.push(types.peek()); + beginLine(PUBLIC, types.peek().getSimpleName()).params(parameters).append(" {").nl(); + return goIn(); + } + + @Override + public JavaWriter beginInterface(Type type, Type... interfaces) throws IOException { + packages.add(type.getPackageName()); + beginLine(PUBLIC_INTERFACE, type.getGenericName(false, packages, classes)); + if (interfaces.length > 0) { + append(EXTENDS); + for (int i = 0; i < interfaces.length; i++) { + if (i > 0) { + append(Symbols.COMMA); + } + append(interfaces[i].getGenericName(false, packages, classes)); + } + } + append(" {").nl().nl(); + goIn(); + types.push(type); + return this; + } + + private JavaWriter beginMethod(String modifiers, Type returnType, String methodName, + Parameter... args) throws IOException { + types.push(types.peek()); + beginLine( + modifiers, returnType.getGenericName(true, packages, classes), Symbols.SPACE, methodName) + .params(args).append(" {").nl(); + return goIn(); + } + + @Override + public JavaWriter beginPublicMethod(Type returnType, String methodName, + Collection parameters, Function transformer) throws IOException { + return beginMethod(PUBLIC, returnType, methodName, transform(parameters, transformer)); + } + + @Override + public JavaWriter beginPublicMethod(Type returnType, String methodName, Parameter... args) + throws IOException { + return beginMethod(PUBLIC, returnType, methodName, args); + } + + @Override + public JavaWriter beginStaticMethod(Type returnType, String methodName, + Collection parameters, Function transformer) throws IOException { + return beginMethod(PUBLIC_STATIC, returnType, methodName, + transform(parameters, transformer)); + } + + @Override + public JavaWriter beginStaticMethod(Type returnType, String methodName, Parameter... args) + throws IOException { + return beginMethod(PUBLIC_STATIC, returnType, methodName, args); + } + + @Override + public JavaWriter end() throws IOException { + types.pop(); + goOut(); + return line("}").nl(); + } + + @Override + public JavaWriter field(Type type, String name) throws IOException { + return line(type.getGenericName(true, packages, classes), Symbols.SPACE, name, Symbols.SEMICOLON).nl(); + } + + private JavaWriter field(String modifier, Type type, String name) throws IOException { + return line( + modifier, type.getGenericName(true, packages, classes), Symbols.SPACE, name, Symbols.SEMICOLON) + .nl(); + } + + private JavaWriter field(String modifier, Type type, String name, String value) + throws IOException { + return line( + modifier, type.getGenericName(true, packages, classes), Symbols.SPACE, name, + Symbols.ASSIGN, value, Symbols.SEMICOLON).nl(); + } + + + @Override + public String getClassConstant(String className) { + return className + ".class"; + } + + @Override + public String getGenericName(boolean asArgType, Type type) { + return type.getGenericName(asArgType, packages, classes); + } + + @Override + public String getRawName(Type type) { + return type.getRawName(packages, classes); + } + + @Override + public JavaWriter imports(Class... imports) throws IOException { + for (Class cl : imports) { + classes.add(cl.getName()); + line(IMPORT, cl.getName(), Symbols.SEMICOLON); + } + nl(); + return this; + } + + @Override + public JavaWriter imports(Package... imports) throws IOException { + for (Package p : imports) { + packages.add(p.getName()); + line(IMPORT, p.getName(), ".*;"); + } + nl(); + return this; + } + + @Override + public JavaWriter importClasses(String... imports) throws IOException { + for (String cl : imports) { + classes.add(cl); + line(IMPORT, cl, Symbols.SEMICOLON); + } + nl(); + return this; + } + + @Override + public JavaWriter importPackages(String... imports) throws IOException { + for (String p : imports) { + packages.add(p); + line(IMPORT, p, ".*;"); + } + nl(); + return this; + } + + @Override + public JavaWriter javadoc(String... lines) throws IOException { + line("/**"); + for (String line : lines) { + line(" * ", line); + } + return line(" */"); + } + + @Override + public JavaWriter packageDecl(String packageName) throws IOException { + packages.add(packageName); + return line(PACKAGE, packageName, Symbols.SEMICOLON).nl(); + } + + private JavaWriter params(Collection parameters, Function transformer) + throws IOException { + append("("); + boolean first = true; + for (T param : parameters) { + if (!first) { + append(Symbols.COMMA); + } + param(transformer.apply(param)); + first = false; + } + append(")"); + return this; + } + + private JavaWriter params(Parameter... params) throws IOException { + append("("); + for (int i = 0; i < params.length; i++) { + if (i > 0) { + append(Symbols.COMMA); + } + param(params[i]); + } + append(")"); + return this; + } + + private JavaWriter param(Parameter parameter) throws IOException { + append(parameter.getType().getGenericName(true, packages, classes)); + append(" "); + append(parameter.getName()); + return this; + } + + @Override + public JavaWriter privateField(Type type, String name) throws IOException { + return field(PRIVATE, type, name); + } + + @Override + public JavaWriter privateFinal(Type type, String name) throws IOException { + return field(PRIVATE_FINAL, type, name); + } + + @Override + public JavaWriter privateFinal(Type type, String name, String value) throws IOException { + return field(PRIVATE_FINAL, type, name, value); + } + + @Override + public JavaWriter privateStaticFinal(Type type, String name, String value) throws IOException { + return field(PRIVATE_STATIC_FINAL, type, name, value); + } + + @Override + public JavaWriter protectedField(Type type, String name) throws IOException { + return field(PROTECTED, type, name); + } + + @Override + public JavaWriter protectedFinal(Type type, String name) throws IOException { + return field(PROTECTED_FINAL, type, name); + } + + @Override + public JavaWriter protectedFinal(Type type, String name, String value) throws IOException { + return field(PROTECTED_FINAL, type, name, value); + } + + @Override + public JavaWriter publicField(Type type, String name) throws IOException { + return field(PUBLIC, type, name); + } + + @Override + public JavaWriter publicField(Type type, String name, String value) throws IOException { + return field(PUBLIC, type, name, value); + } + + @Override + public JavaWriter publicFinal(Type type, String name) throws IOException { + return field(PUBLIC_FINAL, type, name); + } + + @Override + public JavaWriter publicFinal(Type type, String name, String value) throws IOException { + return field(PUBLIC_FINAL, type, name, value); + } + + @Override + public JavaWriter publicStaticFinal(Type type, String name, String value) throws IOException { + return field(PUBLIC_STATIC_FINAL, type, name, value); + } + + @Override + public JavaWriter staticimports(Class... imports) throws IOException { + for (Class cl : imports) { + line(IMPORT_STATIC, cl.getName(), ".*;"); + } + return this; + } + + @Override + public JavaWriter suppressWarnings(String type) throws IOException { + return line("@SuppressWarnings(\"", type, "\")"); + } + + @Override + public CodeWriter suppressWarnings(String... types) throws IOException { + return annotation(new MultiSuppressWarnings(types)); + } + + private Parameter[] transform(Collection parameters, + Function transformer) { + Parameter[] rv = new Parameter[parameters.size()]; + int i = 0; + for (T value : parameters) { + rv[i++] = transformer.apply(value); + } + return rv; + } + +} diff --git a/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/LocationAndKind.java b/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/LocationAndKind.java new file mode 100644 index 0000000000..1aef4714c1 --- /dev/null +++ b/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/LocationAndKind.java @@ -0,0 +1,58 @@ +/* + * Copyright 2010, Mysema Ltd + * + * 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. + */ +package com.querydsl.codegen.utils; + +import javax.tools.JavaFileManager.Location; +import javax.tools.JavaFileObject.Kind; + +/** + * LocationAndKind defines a pair of Location and Kind + * + * @author tiwe + * + */ +public class LocationAndKind { + + private final Kind kind; + + private final Location location; + + public LocationAndKind(Location location, Kind kind) { + this.location = location; + this.kind = kind; + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } else if (obj instanceof LocationAndKind) { + LocationAndKind other = (LocationAndKind) obj; + return location.equals(other.location) && kind.equals(other.kind); + } else { + return false; + } + } + + @Override + public int hashCode() { + return kind.hashCode() * 31 + location.hashCode(); + } + + @Override + public String toString() { + return kind.toString() + "@" + location.toString(); + } + +} diff --git a/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/MemClassLoader.java b/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/MemClassLoader.java new file mode 100644 index 0000000000..90bcd12410 --- /dev/null +++ b/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/MemClassLoader.java @@ -0,0 +1,126 @@ +/* + * Copyright 2010, Mysema Ltd + * + * 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. + */ +package com.querydsl.codegen.utils; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Collections; +import java.util.Enumeration; +import java.util.List; +import java.util.Map; + +import javax.tools.JavaFileObject; +import javax.tools.JavaFileObject.Kind; +import javax.tools.StandardLocation; + +/** + * MemClassLoader is a mmemory based implementation of the ClassLoader interface + * + * @author tiwe + * + */ +public final class MemClassLoader extends ClassLoader { + + private static final LocationAndKind CLASS_KEY = new LocationAndKind( + StandardLocation.CLASS_OUTPUT, Kind.CLASS); + + private static final LocationAndKind OTHER_KEY = new LocationAndKind( + StandardLocation.CLASS_OUTPUT, Kind.OTHER); + + private static final LocationAndKind SOURCE_KEY = new LocationAndKind( + StandardLocation.CLASS_OUTPUT, Kind.SOURCE); + + private final Map> memFileSystem; + + public MemClassLoader(ClassLoader parent, + Map> ramFileSystem) { + super(parent); + this.memFileSystem = ramFileSystem; + } + + @Override + protected Class findClass(String name) throws ClassNotFoundException { + JavaFileObject jfo = memFileSystem.get(CLASS_KEY).get(name); + if (jfo != null) { + byte[] bytes = ((MemJavaFileObject) jfo).getByteArray(); + return defineClass(name, bytes, 0, bytes.length); + } else { + return super.findClass(name); + } + } + + @Override + protected URL findResource(String name) { + URL retValue = super.findResource(name); + if (retValue != null) { + return retValue; + } else { + JavaFileObject jfo = getFileObject(name); + if (jfo != null) { + try { + return jfo.toUri().toURL(); + } catch (MalformedURLException ex) { + return null; + } + } else { + return null; + } + } + } + + private JavaFileObject getFileObject(String n) { + LocationAndKind key; + String name; + if (n.endsWith(Kind.CLASS.extension)) { + name = n.replace('.', '/') + Kind.CLASS.extension; + key = CLASS_KEY; + } else if (n.endsWith(Kind.SOURCE.extension)) { + name = n.replace('.', '/') + Kind.SOURCE.extension; + key = SOURCE_KEY; + } else { + name = n; + key = OTHER_KEY; + } + if (memFileSystem.containsKey(key)) { + return memFileSystem.get(key).get(name); + } else { + return null; + } + } + + @Override + public InputStream getResourceAsStream(String name) { + JavaFileObject jfo = getFileObject(name); + if (jfo != null) { + byte[] bytes = ((MemJavaFileObject) jfo).getByteArray(); + return new ByteArrayInputStream(bytes); + } else { + return null; + } + } + + @Override + public Enumeration getResources(String name) throws IOException { + List retValue; + retValue = Collections.list(super.getResources(name)); + JavaFileObject jfo = getFileObject(name); + if (jfo != null) { + retValue.add(jfo.toUri().toURL()); + } + return Collections.enumeration(retValue); + } +} diff --git a/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/MemFileManager.java b/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/MemFileManager.java new file mode 100644 index 0000000000..ab34d13768 --- /dev/null +++ b/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/MemFileManager.java @@ -0,0 +1,166 @@ +/* + * Copyright 2010, Mysema Ltd + * + * 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. + */ +package com.querydsl.codegen.utils; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.tools.FileObject; +import javax.tools.ForwardingJavaFileManager; +import javax.tools.JavaFileManager; +import javax.tools.JavaFileObject; +import javax.tools.StandardJavaFileManager; +import javax.tools.StandardLocation; +import javax.tools.JavaFileObject.Kind; + +/** + * MemFileManager is a memory based implementation of the JavaFileManager + * interface + * + * @author tiwe + * + */ +public class MemFileManager extends ForwardingJavaFileManager { + + private final ClassLoader classLoader; + + private final Map> ramFileSystem; + + private final String urlPrefix; + + public MemFileManager(ClassLoader parent, StandardJavaFileManager sjfm) { + super(sjfm); + ramFileSystem = new HashMap>(); + Map classLoaderContent = new HashMap(); + ramFileSystem.put(new LocationAndKind(StandardLocation.CLASS_OUTPUT, Kind.CLASS), + classLoaderContent); + classLoader = new MemClassLoader(parent, ramFileSystem); + urlPrefix = MemFileSystemRegistry.DEFAULT.getUrlPrefix(this); + } + + @Override + public ClassLoader getClassLoader(JavaFileManager.Location location) { + return classLoader; + } + + @Override + public FileObject getFileForInput(JavaFileManager.Location location, String packageName, + String relativeName) throws IOException { + throw new UnsupportedOperationException(); + } + + @Override + public FileObject getFileForOutput(JavaFileManager.Location location, String packageName, + String relativeName, FileObject sibling) throws IOException { + String name = null; + if ("".equals(packageName)) { + name = relativeName; + } else { + name = packageName.replace('.', '/') + "/" + relativeName; + } + LocationAndKind key = new LocationAndKind(location, Kind.OTHER); + if (ramFileSystem.containsKey(key)) { + JavaFileObject jfo = ramFileSystem.get(key).get(name); + if (jfo != null) { + return jfo; + } + } + JavaFileObject jfo = new MemJavaFileObject(urlPrefix, name, Kind.OTHER); + register(key, jfo); + return jfo; + } + + @Override + public JavaFileObject getJavaFileForOutput(Location location, String name, Kind kind, + FileObject sibling) throws IOException { + JavaFileObject javaFileObject = null; + LocationAndKind key = new LocationAndKind(location, kind); + + if (ramFileSystem.containsKey(key)) { + javaFileObject = ramFileSystem.get(key).get(name); + if (javaFileObject != null) { + return javaFileObject; + } + } + if (kind == Kind.SOURCE) { + javaFileObject = new MemSourceFileObject(name); + } else { + javaFileObject = new MemJavaFileObject(urlPrefix, name, kind); + } + register(key, javaFileObject); + return javaFileObject; + } + + @Override + public String inferBinaryName(Location loc, JavaFileObject javaFileObject) { + String result; + if (loc == StandardLocation.CLASS_PATH && javaFileObject instanceof MemJavaFileObject) { + result = javaFileObject.getName(); + } else { + result = super.inferBinaryName(loc, javaFileObject); + } + return result; + } + + @Override + public boolean isSameFile(FileObject a, FileObject b) { + return a.equals(b); + } + + @Override + public Iterable list(Location location, String pkg, Set kinds, + boolean recurse) throws IOException { + + List result = new ArrayList(); + for (JavaFileObject f : super.list(location, pkg, kinds, recurse)) { + result.add(f); + } + if (location == StandardLocation.CLASS_PATH) { + location = StandardLocation.CLASS_OUTPUT; + } + + for (Kind kind : kinds) { + LocationAndKind key = new LocationAndKind(location, kind); + if (ramFileSystem.containsKey(key)) { + Map locatedFiles = ramFileSystem.get(key); + for (Map.Entry entry : locatedFiles.entrySet()) { + String name = entry.getKey(); + String packageName = ""; + if (name.indexOf('.') > -1) { + packageName = name.substring(0, name.lastIndexOf('.')); + } + if (recurse ? packageName.startsWith(pkg) : packageName.equals(pkg)) { + JavaFileObject candidate = entry.getValue(); + if (kinds.contains(candidate.getKind())) { + result.add(candidate); + } + } + } + } + } + return result; + } + + private void register(LocationAndKind key, JavaFileObject javaFileObject) { + if (!ramFileSystem.containsKey(key)) { + ramFileSystem.put(key, new HashMap()); + } + ramFileSystem.get(key).put(javaFileObject.getName(), javaFileObject); + } + +} diff --git a/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/MemFileSystemRegistry.java b/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/MemFileSystemRegistry.java new file mode 100644 index 0000000000..85e4f1dc1b --- /dev/null +++ b/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/MemFileSystemRegistry.java @@ -0,0 +1,68 @@ +/* + * Copyright 2010, Mysema Ltd + * + * 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. + */ +package com.querydsl.codegen.utils; + +import java.lang.ref.WeakReference; +import java.net.URL; +import java.util.Map; +import java.util.WeakHashMap; + +import javax.tools.JavaFileManager; + +/** + * @author tiwe + * + */ +public final class MemFileSystemRegistry { + + public static final MemFileSystemRegistry DEFAULT = new MemFileSystemRegistry(); + + private final Map jfm2prefix = new WeakHashMap(); + + private Map> prefix2jfm = new WeakHashMap>(); + + private final String protocolName; + + private int sequence = 0; + + private MemFileSystemRegistry() { + String pkgName = MemFileSystemRegistry.class.getPackage().getName(); + protocolName = pkgName.substring(pkgName.lastIndexOf('.') + 1); + String pkgs = System.getProperty("java.protocol.handler.pkgs"); + String parentPackage = pkgName.substring(0, pkgName.lastIndexOf('.')); + pkgs = pkgs == null ? parentPackage : pkgs + "|" + parentPackage; + System.setProperty("java.protocol.handler.pkgs", pkgs); + } + + public JavaFileManager getFileSystem(URL url) { + String prefix = url.getProtocol() + "://" + url.getHost() + "/"; + if (prefix2jfm.containsKey(prefix)) { + return prefix2jfm.get(prefix).get(); + } else { + return null; + } + } + + public String getUrlPrefix(JavaFileManager jfm) { + if (jfm2prefix.containsKey(jfm)) { + return jfm2prefix.get(jfm); + } else { + String result = protocolName + "://jfm" + (sequence++) + "/"; + jfm2prefix.put(jfm, result); + prefix2jfm.put(result, new WeakReference(jfm)); + return result; + } + } + +} diff --git a/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/MemJavaFileObject.java b/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/MemJavaFileObject.java new file mode 100644 index 0000000000..f762e4c99f --- /dev/null +++ b/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/MemJavaFileObject.java @@ -0,0 +1,77 @@ +/* + * Copyright 2010, Mysema Ltd + * + * 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. + */ +package com.querydsl.codegen.utils; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.URI; +import java.nio.charset.StandardCharsets; + +import javax.tools.SimpleJavaFileObject; + +/** + * MemJavaFileObject defines an in memory compiled Java file + * + * @author tiwe + * + */ +public class MemJavaFileObject extends SimpleJavaFileObject { + + private ByteArrayOutputStream baos; + + private final String name; + + public MemJavaFileObject(String urlPrefix, String name, Kind kind) { + super(URI.create(urlPrefix + name + kind.extension), kind); + this.name = name; + } + + @Override + public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException { + if (baos == null) { + throw new FileNotFoundException(name); + } + return new String(baos.toByteArray(), StandardCharsets.UTF_8); + } + + @Override + public String getName() { + return name; + } + + public byte[] getByteArray() { + return baos.toByteArray(); + } + + @Override + public InputStream openInputStream() throws IOException { + if (baos == null) { + throw new FileNotFoundException(name); + } + return new ByteArrayInputStream(baos.toByteArray()); + } + + @Override + public OutputStream openOutputStream() throws IOException { + if (baos == null) { + baos = new ByteArrayOutputStream(); + } + return baos; + } + +} diff --git a/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/MemSourceFileObject.java b/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/MemSourceFileObject.java new file mode 100644 index 0000000000..931b3e341e --- /dev/null +++ b/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/MemSourceFileObject.java @@ -0,0 +1,75 @@ +/* + * Copyright 2010, Mysema Ltd + * + * 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. + */ +package com.querydsl.codegen.utils; + +import java.io.IOException; +import java.io.Writer; +import java.net.URI; + +import javax.tools.JavaFileObject; +import javax.tools.SimpleJavaFileObject; + +/** + * MemSourceFileObject defines a in-memory Java source file object + * + * @author tiwe + * + */ +public class MemSourceFileObject extends SimpleJavaFileObject { + + private static URI toUri(String fqname) { + return URI.create("file:///" + fqname.replace(".", "/") + ".java"); + } + + private final StringBuilder contents; + + public MemSourceFileObject(String fullName) { + super(toUri(fullName), JavaFileObject.Kind.SOURCE); + contents = new StringBuilder(1000); + } + + public MemSourceFileObject(String fullName, String content) { + this(fullName); + contents.append(content); + } + + @Override + public CharSequence getCharContent(boolean ignoreEncodingErrors) { + return contents; + } + + @Override + public Writer openWriter() { + return new Writer() { + @Override + public Writer append(CharSequence csq) throws IOException { + contents.append(csq); + return this; + } + + @Override + public void close() { + } + + @Override + public void flush() { + } + + @Override + public void write(char[] cbuf, int off, int len) throws IOException { + contents.append(cbuf, off, len); + } + }; + } +} diff --git a/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/MethodEvaluator.java b/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/MethodEvaluator.java new file mode 100644 index 0000000000..6109b67668 --- /dev/null +++ b/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/MethodEvaluator.java @@ -0,0 +1,60 @@ +/* + * Copyright 2010, Mysema Ltd + * + * 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. + */ +package com.querydsl.codegen.utils; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Map; + +/** + * @author tiwe + * + * @param + */ +public final class MethodEvaluator implements Evaluator { + + private final Method method; + + private final Class projectionType; + + private final Object[] args; + + MethodEvaluator(Method method, Map constants, Class projectionType) { + this.method = method; + this.projectionType = projectionType; + this.args = new Object[method.getParameterTypes().length]; + int i = args.length - constants.size(); + for (Object value : constants.values()) { + args[i++] = value; + } + } + + @SuppressWarnings("unchecked") + @Override + public T evaluate(Object... args) { + try { + System.arraycopy(args, 0, this.args, 0, args.length); + return (T) method.invoke(null, this.args); + } catch (IllegalAccessException e) { + throw new IllegalArgumentException(e); + } catch (InvocationTargetException e) { + throw new IllegalArgumentException(e); + } + } + + @Override + public Class getType() { + return projectionType; + } +} \ No newline at end of file diff --git a/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/MultiSuppressWarnings.java b/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/MultiSuppressWarnings.java new file mode 100644 index 0000000000..6014cd4803 --- /dev/null +++ b/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/MultiSuppressWarnings.java @@ -0,0 +1,40 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.codegen.utils; + +import java.lang.annotation.Annotation; +import java.util.Arrays; + +@SuppressWarnings("AnnotationAsSuperInterface") // Internal helper class +class MultiSuppressWarnings implements SuppressWarnings { + + private final String[] values; + + MultiSuppressWarnings(String... values) { + this.values = Arrays.copyOf(values, values.length); + } + + @Override + @SuppressWarnings("ReturnOfCollectionOrArrayField") + public String[] value() { + return values; + } + + @Override + public Class annotationType() { + return SuppressWarnings.class; + } +} diff --git a/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/ScalaWriter.java b/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/ScalaWriter.java new file mode 100644 index 0000000000..75509a599d --- /dev/null +++ b/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/ScalaWriter.java @@ -0,0 +1,617 @@ +/* + * Copyright 2011, Mysema Ltd + * + * 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. + */ +package com.querydsl.codegen.utils; + +import static com.querydsl.codegen.utils.Symbols.ASSIGN; +import static com.querydsl.codegen.utils.Symbols.COMMA; +import static com.querydsl.codegen.utils.Symbols.DOT; +import static com.querydsl.codegen.utils.Symbols.QUOTE; + +import java.io.IOException; +import java.lang.annotation.Annotation; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; +import java.util.function.Function; + +import com.querydsl.codegen.utils.model.Parameter; +import com.querydsl.codegen.utils.model.Type; +import com.querydsl.codegen.utils.model.Types; +import com.querydsl.codegen.utils.support.ScalaSyntaxUtils; + +/** + * @author tiwe + * + */ +public class ScalaWriter extends AbstractCodeWriter { + + private static final Set PRIMITIVE_TYPES = new HashSet(Arrays.asList("boolean", + "byte", "char", "int", "long", "short", "double", "float")); + + private static final String DEF = "def "; + + private static final String OVERRIDE_DEF = "override " + DEF; + + private static final String EXTENDS = " extends "; + + private static final String WITH = " with "; + + private static final String IMPORT = "import "; + + private static final String IMPORT_STATIC = "import "; + + private static final String PACKAGE = "package "; + + private static final String PRIVATE = "private "; + + private static final String PRIVATE_VAL = "private val "; + + private static final String PROTECTED = "protected "; + + private static final String PROTECTED_VAL = "protected val "; + + private static final String PUBLIC = "public "; + + private static final String PUBLIC_CLASS = "class "; + + private static final String PUBLIC_OBJECT = "object "; + + private static final String CASE_CLASS = "case class "; + + private static final String VAR = "var "; + + private static final String VAL = "val "; + + private static final String THIS = "this"; + + private static final String TRAIT = "trait "; + + private final Set classes = new HashSet(); + + private final Set packages = new HashSet(); + + private Type type; + + private final boolean compact; + + public ScalaWriter(Appendable appendable) { + this(appendable, false); + } + + public ScalaWriter(Appendable appendable, boolean compact) { + super(appendable, 2); + this.classes.add("java.lang.String"); + this.classes.add("java.lang.Object"); + this.classes.add("java.lang.Integer"); + this.classes.add("java.lang.Comparable"); + this.compact = compact; + } + + @Override + public ScalaWriter annotation(Annotation annotation) throws IOException { + beginLine().append("@").appendType(annotation.annotationType()); + Method[] methods = annotation.annotationType().getDeclaredMethods(); + if (methods.length == 1 && methods[0].getName().equals("value")) { + try { + Object value = methods[0].invoke(annotation); + append("("); + annotationConstant(value); + append(")"); + } catch (IllegalArgumentException e) { + throw new CodegenException(e); + } catch (IllegalAccessException e) { + throw new CodegenException(e); + } catch (InvocationTargetException e) { + throw new CodegenException(e); + } + } else { + boolean first = true; + for (Method method : methods) { + try { + Object value = method.invoke(annotation); + if (value == null + || value.equals(method.getDefaultValue()) + || (value.getClass().isArray() && Arrays.equals((Object[]) value, + (Object[]) method.getDefaultValue()))) { + continue; + } else if (!first) { + append(COMMA); + } else { + append("("); + } + append(escape(method.getName())).append("="); + annotationConstant(value); + } catch (IllegalArgumentException e) { + throw new CodegenException(e); + } catch (IllegalAccessException e) { + throw new CodegenException(e); + } catch (InvocationTargetException e) { + throw new CodegenException(e); + } + first = false; + } + if (!first) { + append(")"); + } + } + return nl(); + } + + @Override + public ScalaWriter annotation(Class annotation) throws IOException { + return beginLine().append("@").appendType(annotation).nl(); + } + + @SuppressWarnings("unchecked") + private void annotationConstant(Object value) throws IOException { + if (value.getClass().isArray()) { + append("Array("); + boolean first = true; + for (Object o : (Object[]) value) { + if (!first) { + append(", "); + } + annotationConstant(o); + first = false; + } + append(")"); + } else if (value instanceof Class) { + append("classOf["); + appendType((Class) value); + append("]"); + } else if (value instanceof Number || value instanceof Boolean) { + append(value.toString()); + } else if (value instanceof Enum) { + Enum enumValue = (Enum) value; + if (classes.contains(enumValue.getClass().getName()) + || packages.contains(enumValue.getClass().getPackage().getName())) { + append(enumValue.name()); + } else { + append(enumValue.getDeclaringClass().getName()).append(DOT).append(enumValue.name()); + } + } else if (value instanceof String) { + append(QUOTE).append(StringUtils.escapeJava(value.toString())).append(QUOTE); + } else { + throw new IllegalArgumentException("Unsupported annotation value : " + value); + } + } + + private ScalaWriter appendType(Class type) throws IOException { + if (type.isPrimitive()) { + append(StringUtils.capitalize(type.getName())); + } else if (type.getPackage() == null || classes.contains(type.getName()) + || packages.contains(type.getPackage().getName())) { + append(type.getSimpleName()); + } else { + append(type.getName()); + } + return this; + } + + public ScalaWriter beginObject(String header) throws IOException { + line(PUBLIC_OBJECT, header, " {"); + goIn(); + return this; + } + + public ScalaWriter beginClass(String header) throws IOException { + line(PUBLIC_CLASS, header, " {"); + goIn(); + return this; + } + + @Override + public ScalaWriter beginClass(Type type) throws IOException { + return beginClass(type, null); + } + + @Override + public ScalaWriter beginClass(Type type, Type superClass, Type... interfaces) + throws IOException { + packages.add(type.getPackageName()); + beginLine(PUBLIC_CLASS, getGenericName(false, type)); + if (superClass != null) { + append(EXTENDS).append(getGenericName(false, superClass)); + } + if (interfaces.length > 0) { + if (superClass == null) { + append(EXTENDS); + append(getGenericName(false, interfaces[0])); + append(WITH); + for (int i = 1; i < interfaces.length; i++) { + if (i > 1) { + append(COMMA); + } + append(getGenericName(false, interfaces[i])); + } + } else { + append(WITH); + for (int i = 0; i < interfaces.length; i++) { + if (i > 0) { + append(COMMA); + } + append(getGenericName(false, interfaces[i])); + } + } + } + append(" {").nl().nl(); + goIn(); + this.type = type; + return this; + } + + @Override + public ScalaWriter beginConstructor(Collection parameters, + Function transformer) throws IOException { + beginLine(DEF, THIS).params(parameters, transformer).append(" {").nl(); + return goIn(); + } + + @Override + public ScalaWriter beginConstructor(Parameter... params) throws IOException { + beginLine(DEF, THIS).params(params).append(" {").nl(); + return goIn(); + } + + @Override + public ScalaWriter beginInterface(Type type, Type... interfaces) throws IOException { + packages.add(type.getPackageName()); + beginLine(TRAIT, getGenericName(false, type)); + if (interfaces.length > 0) { + append(EXTENDS); + append(getGenericName(false, interfaces[0])); + if (interfaces.length > 1) { + append(WITH); + for (int i = 1; i < interfaces.length; i++) { + if (i > 1) { + append(COMMA); + } + append(getGenericName(false, interfaces[i])); + } + } + + } + append(" {").nl().nl(); + goIn(); + this.type = type; + return this; + } + + private ScalaWriter beginMethod(String modifiers, Type returnType, String methodName, + Parameter... args) throws IOException { + if (returnType.equals(Types.VOID)) { + beginLine(modifiers, escape(methodName)).params(args).append(" {").nl(); + } else { + beginLine(modifiers, escape(methodName)).params(args) + .append(": ").append(getGenericName(true, returnType)).append(" = {").nl(); + } + + return goIn(); + } + + @Override + public ScalaWriter beginPublicMethod(Type returnType, String methodName, + Collection parameters, Function transformer) throws IOException { + return beginMethod(DEF, returnType, methodName, transform(parameters, transformer)); + } + + @Override + public ScalaWriter beginPublicMethod(Type returnType, String methodName, Parameter... args) + throws IOException { + return beginMethod(DEF, returnType, methodName, args); + } + + public ScalaWriter beginOverridePublicMethod(Type returnType, String methodName, + Collection parameters, Function transformer) + throws IOException { + return beginMethod(OVERRIDE_DEF, returnType, methodName, transform(parameters, transformer)); + } + + public ScalaWriter beginOverridePublicMethod(Type returnType, String methodName, Parameter... args) + throws IOException { + return beginMethod(OVERRIDE_DEF, returnType, methodName, args); + } + + @Override + public ScalaWriter beginStaticMethod(Type returnType, String methodName, + Collection parameters, Function transformer) throws IOException { + return beginMethod(DEF, returnType, methodName, transform(parameters, transformer)); + } + + @Override + public ScalaWriter beginStaticMethod(Type returnType, String methodName, Parameter... args) + throws IOException { + return beginMethod(DEF, returnType, methodName, args); + } + + public ScalaWriter caseClass(String header, Parameter... parameters) throws IOException { + beginLine(CASE_CLASS, header).params(parameters).nl(); + return this; + } + + @Override + public ScalaWriter end() throws IOException { + goOut(); + return line("}").nl(); + } + + public ScalaWriter field(Type type, String name) throws IOException { + line(VAR, escape(name), ": ", getGenericName(true, type)); + return compact ? this : nl(); + } + + private ScalaWriter field(String modifier, Type type, String name) throws IOException { + line(modifier, escape(name), ": ", getGenericName(true, type)); + return compact ? this : nl(); + } + + private ScalaWriter field(String modifier, Type type, String name, String value) + throws IOException { + line(modifier, escape(name), ": ", getGenericName(true, type), ASSIGN, value); + return compact ? this : nl(); + } + + @Override + public String getClassConstant(String className) { + return "classOf[" + className + "]"; + } + + @Override + public String getGenericName(boolean asArgType, Type type) { + if (type.getParameters().isEmpty()) { + return getRawName(type); + } else { + StringBuilder builder = new StringBuilder(); + builder.append(getRawName(type)); + builder.append("["); + boolean first = true; + String fullName = type.getFullName(); + for (Type parameter : type.getParameters()) { + if (!first) { + builder.append(", "); + } + if (parameter == null || parameter.getFullName().equals(fullName)) { + builder.append("_"); + } else { + builder.append(getGenericName(false, parameter)); + } + first = false; + } + builder.append("]"); + return builder.toString(); + } + } + + @Override + public String getRawName(Type type) { + String fullName = type.getFullName(); + if (PRIMITIVE_TYPES.contains(fullName)) { + fullName = StringUtils.capitalize(fullName); + } + String packageName = type.getPackageName(); + if (packageName != null && packageName.length() > 0) { + fullName = packageName + "." + fullName.substring(packageName.length() + 1).replace('.', '$'); + } else { + fullName = fullName.replace('.', '$'); + } + String rv = fullName; + if (type.isPrimitive() && packageName.isEmpty()) { + rv = Character.toUpperCase(rv.charAt(0)) + rv.substring(1); + } + if (packages.contains(packageName) || classes.contains(fullName)) { + if (packageName.length() > 0) { + rv = fullName.substring(packageName.length() + 1); + } + } + if (rv.endsWith("[]")) { + rv = rv.substring(0, rv.length() - 2); + if (PRIMITIVE_TYPES.contains(rv)) { + rv = StringUtils.capitalize(rv); + } else if (classes.contains(rv)) { + rv = rv.substring(packageName.length() + 1); + } + return "Array[" + rv + "]"; + } else { + return rv; + } + } + + @Override + public ScalaWriter imports(Class... imports) throws IOException { + for (Class cl : imports) { + classes.add(cl.getName()); + line(IMPORT, cl.getName()); + } + nl(); + return this; + } + + @Override + public ScalaWriter imports(Package... imports) throws IOException { + for (Package p : imports) { + packages.add(p.getName()); + line(IMPORT, p.getName(), "._"); + } + nl(); + return this; + } + + @Override + public ScalaWriter importClasses(String... imports) throws IOException { + for (String cl : imports) { + classes.add(cl); + line(IMPORT, cl); + } + nl(); + return this; + } + + @Override + public ScalaWriter importPackages(String... imports) throws IOException { + for (String p : imports) { + packages.add(p); + line(IMPORT, p, "._"); + } + nl(); + return this; + } + + @Override + public ScalaWriter javadoc(String... lines) throws IOException { + line("/**"); + for (String line : lines) { + line(" * ", line); + } + return line(" */"); + } + + @Override + public ScalaWriter packageDecl(String packageName) throws IOException { + packages.add(packageName); + return line(PACKAGE, packageName).nl(); + } + + private ScalaWriter params(Collection parameters, Function transformer) + throws IOException { + append("("); + boolean first = true; + for (T param : parameters) { + if (!first) { + append(COMMA); + } + param(transformer.apply(param)); + first = false; + } + append(")"); + return this; + } + + private ScalaWriter params(Parameter... params) throws IOException { + append("("); + for (int i = 0; i < params.length; i++) { + if (i > 0) { + append(COMMA); + } + param(params[i]); + } + append(")"); + return this; + } + + private ScalaWriter param(Parameter parameter) throws IOException { + append(escape(parameter.getName())); + append(": "); + append(getGenericName(true, parameter.getType())); + return this; + } + + @Override + public ScalaWriter privateField(Type type, String name) throws IOException { + return field(PRIVATE, type, name); + } + + @Override + public ScalaWriter privateFinal(Type type, String name) throws IOException { + return field(PRIVATE_VAL, type, name); + } + + @Override + public ScalaWriter privateFinal(Type type, String name, String value) throws IOException { + return field(PRIVATE_VAL, type, name, value); + } + + @Override + public ScalaWriter privateStaticFinal(Type type, String name, String value) throws IOException { + return field(PRIVATE_VAL, type, name, value); + } + + @Override + public ScalaWriter protectedField(Type type, String name) throws IOException { + return field(PROTECTED, type, name); + } + + @Override + public ScalaWriter protectedFinal(Type type, String name) throws IOException { + return field(PROTECTED_VAL, type, name); + } + + @Override + public ScalaWriter protectedFinal(Type type, String name, String value) throws IOException { + return field(PROTECTED_VAL, type, name, value); + } + + @Override + public ScalaWriter publicField(Type type, String name) throws IOException { + return field(VAR, type, name); + } + + @Override + public ScalaWriter publicField(Type type, String name, String value) throws IOException { + return field(VAR, type, name, value); + } + + @Override + public ScalaWriter publicFinal(Type type, String name) throws IOException { + return field(VAL, type, name); + } + + @Override + public ScalaWriter publicFinal(Type type, String name, String value) throws IOException { + return field(VAL, type, name, value); + } + + @Override + public ScalaWriter publicStaticFinal(Type type, String name, String value) throws IOException { + return field(VAL, type, name, value); + } + + @Override + public ScalaWriter staticimports(Class... imports) throws IOException { + for (Class cl : imports) { + line(IMPORT_STATIC, cl.getName(), "._;"); + } + return this; + } + + @Override + public ScalaWriter suppressWarnings(String type) throws IOException { + return line("@SuppressWarnings(\"", type, "\")"); + } + + @Override + public CodeWriter suppressWarnings(String... types) throws IOException { + return annotation(new MultiSuppressWarnings(types)); + } + + private Parameter[] transform(Collection parameters, + Function transformer) { + Parameter[] rv = new Parameter[parameters.size()]; + int i = 0; + for (T value : parameters) { + rv[i++] = transformer.apply(value); + } + return rv; + } + + private String escape(String token) { + if (ScalaSyntaxUtils.isReserved(token)) { + return "`" + token + "`"; + } else { + return token; + } + } +} diff --git a/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/SimpleCompiler.java b/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/SimpleCompiler.java new file mode 100644 index 0000000000..3f4725a364 --- /dev/null +++ b/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/SimpleCompiler.java @@ -0,0 +1,120 @@ +/* + * Copyright 2010, Mysema Ltd + * + * 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. + */ +package com.querydsl.codegen.utils; + +import io.github.classgraph.ClassGraph; + +import javax.lang.model.SourceVersion; +import javax.tools.*; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.Writer; +import java.net.URL; +import java.net.URLClassLoader; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; +import java.util.Set; + +/** + * SimpleCompiler provides a convenience wrapper of the JavaCompiler interface + * with automatic classpath generation + * + * @author tiwe + * + */ +public class SimpleCompiler implements JavaCompiler { + + protected static boolean isSureFireBooter(URLClassLoader cl) { + for (URL url : cl.getURLs()) { + if (url.getPath().contains("surefirebooter")) { + return true; + } + } + + return false; + } + + public static String getClassPath(ClassLoader cl) { + return new ClassGraph().overrideClassLoaders(cl).getClasspath(); + } + + private final ClassLoader classLoader; + + private String classPath; + + private final JavaCompiler compiler; + + public SimpleCompiler() { + this(ToolProvider.getSystemJavaCompiler(), Thread.currentThread().getContextClassLoader()); + } + + public SimpleCompiler(JavaCompiler compiler, ClassLoader classLoader) { + this.compiler = compiler; + this.classLoader = classLoader; + } + + private String getClasspath() { + if (classPath == null) { + classPath = getClassPath(classLoader); + } + return classPath; + } + + @Override + public Set getSourceVersions() { + return compiler.getSourceVersions(); + } + + @Override + public StandardJavaFileManager getStandardFileManager( + DiagnosticListener diagnosticListener, Locale locale, + Charset charset) { + return compiler.getStandardFileManager(diagnosticListener, locale, charset); + } + + @Override + public CompilationTask getTask(Writer out, JavaFileManager fileManager, + DiagnosticListener diagnosticListener, + Iterable options, Iterable classes, + Iterable compilationUnits) { + return compiler.getTask(out, fileManager, diagnosticListener, options, classes, + compilationUnits); + } + + @Override + public int isSupportedOption(String option) { + return compiler.isSupportedOption(option); + } + + @Override + public int run(InputStream in, OutputStream out, OutputStream err, String... arguments) { + for (String a : arguments) { + if (a.equals("-classpath")) { + return compiler.run(in, out, err, arguments); + } + } + + // no classpath given + List args = new ArrayList(arguments.length + 2); + args.add("-classpath"); + args.add(getClasspath()); + for (String arg : arguments) { + args.add(arg); + } + return compiler.run(in, out, err, args.toArray(new String[args.size()])); + } + +} diff --git a/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/StringUtils.java b/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/StringUtils.java new file mode 100644 index 0000000000..8a1c476369 --- /dev/null +++ b/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/StringUtils.java @@ -0,0 +1,45 @@ +/* + * Copyright 2010, Mysema Ltd + * + * 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. + */ +package com.querydsl.codegen.utils; + +import java.util.Arrays; + +public final class StringUtils { + + public static String capitalize(String str) { + return str.substring(0, 1).toUpperCase() + str.substring(1); + } + + public static String uncapitalize(String str) { + return str.substring(0, 1).toLowerCase() + str.substring(1); + } + + public static String escapeJava(String str) { + str = str.replace("\\", "\\\\"); + str = str.replace("\"", "\\\""); + str = str.replace("\r", "\\\r"); + str = str.replace("\t", "\\\t"); + str = str.replace("\n", "\\\n"); + return str; + } + + public static String repeat(char value, int times) { + char[] chars = new char[times]; + Arrays.fill(chars, value); + return new String(chars); + } + + private StringUtils() { } + +} diff --git a/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/Symbols.java b/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/Symbols.java new file mode 100644 index 0000000000..61b08bc363 --- /dev/null +++ b/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/Symbols.java @@ -0,0 +1,58 @@ +/* + * Copyright 2010, Mysema Ltd + * + * 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. + */ +package com.querydsl.codegen.utils; + +/** + * Defines general String constants + * + * @author tiwe + * + */ +public final class Symbols { + + public static final String ASSIGN = " = "; + + public static final String COMMA = ", "; + + public static final String DOT = "."; + + public static final String DOT_CLASS = ".class"; + + public static final String EMPTY = ""; + + public static final String NEW = "new "; + + public static final String NEWLINE = "\n"; + + public static final String QUOTE = "\""; + + public static final String RETURN = "return "; + + public static final String SEMICOLON = ";"; + + public static final String SERIAL = "serial"; + + public static final String SPACE = " "; + + public static final String STAR = "*"; + + public static final String SUPER = "super"; + + public static final String THIS = "this"; + + public static final String UNCHECKED = "unchecked"; + + private Symbols() { + } +} diff --git a/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/model/ClassType.java b/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/model/ClassType.java new file mode 100644 index 0000000000..d582ceef16 --- /dev/null +++ b/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/model/ClassType.java @@ -0,0 +1,197 @@ +/* + * Copyright 2010, Mysema Ltd + * + * 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. + */ +package com.querydsl.codegen.utils.model; + +import java.lang.reflect.Modifier; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Set; + +import com.querydsl.codegen.utils.support.ClassUtils; + +/** + * @author tiwe + * + */ +public class ClassType implements Type { + + private final TypeCategory category; + + private final Class javaClass; + + private final String className; + + private final List parameters; + + private Type arrayType, componentType, enclosingType; + + public ClassType(Class javaClass, Type... parameters) { + this(TypeCategory.SIMPLE, javaClass, Arrays.asList(parameters)); + } + + public ClassType(TypeCategory category, Class clazz, Type... parameters) { + this(category, clazz, Arrays.asList(parameters)); + } + + public ClassType(TypeCategory category, Class clazz, List parameters) { + this.category = category; + this.javaClass = clazz; + this.parameters = parameters; + this.className = ClassUtils.getFullName(javaClass); + } + + + @Override + public Type as(TypeCategory c) { + if (category == c) { + return this; + } else { + return new ClassType(c, javaClass); + } + } + + @Override + public Type asArrayType() { + if (arrayType == null) { + String fullName = ClassUtils.getFullName(javaClass) + "[]"; + String simpleName = javaClass.getSimpleName() + "[]"; + arrayType = new SimpleType(TypeCategory.ARRAY, fullName, getPackageName(), simpleName, + false, false); + } + return arrayType; + } + + @Override + public boolean equals(Object o) { + if (o == this) { + return true; + } else if (o instanceof Type) { + Type t = (Type) o; + return t.getFullName().equals(className) && t.getParameters().equals(parameters); + } else { + return false; + } + } + + public TypeCategory getCategory() { + return category; + } + + @Override + public Type getComponentType() { + Class clazz = javaClass.getComponentType(); + if (clazz != null && componentType == null) { + componentType = new ClassType(TypeCategory.SIMPLE, clazz); + } + return componentType; + } + + @Override + public Type getEnclosingType() { + if (enclosingType == null) { + Class enclosingClass = javaClass.getEnclosingClass(); + if (enclosingClass != null) { + enclosingType = new ClassType(enclosingClass); + } + } + return enclosingType; + } + + @Override + public String getFullName() { + return className; + } + + @Override + public String getGenericName(boolean asArgType) { + return getGenericName(asArgType, Collections.singleton("java.lang"), + Collections. emptySet()); + } + + @Override + public String getGenericName(boolean asArgType, Set packages, Set classes) { + if (parameters.isEmpty()) { + return ClassUtils.getName(javaClass, packages, classes); + } else { + StringBuilder builder = new StringBuilder(); + builder.append(ClassUtils.getName(javaClass, packages, classes)); + builder.append("<"); + boolean first = true; + for (Type parameter : parameters) { + if (!first) { + builder.append(", "); + } + if (parameter == null || parameter.getFullName().equals(getFullName())) { + builder.append("?"); + } else { + builder.append(parameter.getGenericName(false, packages, classes)); + } + first = false; + } + builder.append(">"); + return builder.toString(); + } + } + + public Class getJavaClass() { + return javaClass; + } + + @Override + public String getPackageName() { + return ClassUtils.getPackageName(javaClass); + } + + @Override + public List getParameters() { + return parameters; + } + + @Override + public String getRawName(Set packages, Set classes) { + return ClassUtils.getName(javaClass, packages, classes); + } + + @Override + public String getSimpleName() { + return javaClass.getSimpleName(); + } + + @Override + public int hashCode() { + return className.hashCode(); + } + + @Override + public boolean isFinal() { + return Modifier.isFinal(javaClass.getModifiers()); + } + + @Override + public boolean isPrimitive() { + return javaClass.isPrimitive(); + } + + @Override + public boolean isMember() { + return javaClass.getEnclosingClass() != null; + } + + @Override + public String toString() { + return getGenericName(true); + } + +} diff --git a/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/model/Constructor.java b/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/model/Constructor.java new file mode 100644 index 0000000000..6afc52bad7 --- /dev/null +++ b/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/model/Constructor.java @@ -0,0 +1,50 @@ +/* + * Copyright 2010, Mysema Ltd + * + * 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. + */ +package com.querydsl.codegen.utils.model; + +import java.util.Collection; + +/** + * @author tiwe + * + */ +public final class Constructor { + + private final Collection parameters; + + public Constructor(Collection params) { + parameters = params; + } + + @Override + public boolean equals(Object o) { + if (o == this) { + return true; + } else if (o instanceof Constructor) { + return ((Constructor) o).parameters.equals(parameters); + } else { + return false; + } + } + + public Collection getParameters() { + return parameters; + } + + @Override + public int hashCode() { + return parameters.hashCode(); + } + +} diff --git a/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/model/Parameter.java b/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/model/Parameter.java new file mode 100644 index 0000000000..241ed73b3f --- /dev/null +++ b/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/model/Parameter.java @@ -0,0 +1,61 @@ +/* + * Copyright 2010, Mysema Ltd + * + * 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. + */ +package com.querydsl.codegen.utils.model; + +/** + * Parameter represents a parameter in a Constructor + * + * @author tiwe + */ +public final class Parameter { + + private final String name; + + private final Type type; + + public Parameter(String name, Type type) { + this.name = name; + this.type = type; + } + + @Override + public boolean equals(Object o) { + if (o == this) { + return true; + } else if (o instanceof Parameter) { + Parameter t = (Parameter) o; + return type.equals(t.type) && name.equals(t.name); + } else { + return false; + } + } + + public String getName() { + return name; + } + + public Type getType() { + return type; + } + + @Override + public int hashCode() { + return type.hashCode(); + } + + @Override + public String toString() { + return type + " " + name; + } +} diff --git a/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/model/SimpleType.java b/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/model/SimpleType.java new file mode 100644 index 0000000000..bec61531b5 --- /dev/null +++ b/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/model/SimpleType.java @@ -0,0 +1,272 @@ +/* + * Copyright 2010, Mysema Ltd + * + * 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. + */ +package com.querydsl.codegen.utils.model; + +import java.lang.reflect.Array; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * @author tiwe + */ +public class SimpleType implements Type { + + private static final Map> PRIMITIVES = new HashMap>(); + + static { + for (Class cl : Arrays.>asList(byte.class, int.class, long.class, short.class, + float.class, double.class, boolean.class, char.class)) { + PRIMITIVES.put(cl.getName(), cl); + } + } + + private final TypeCategory category; + + private final String fullName, outerClassName, packageName, simpleName, localName; + + private final List parameters; + + private final boolean primitiveClass, finalClass, memberClass; + + private Type arrayType, componentType, enclosingType; + + private transient Class javaClass; + + public SimpleType(String fullName, String packageName, String simpleName, Type... parameters) { + this(TypeCategory.SIMPLE, fullName, packageName, simpleName, false, false, Arrays + .asList(parameters)); + } + + public SimpleType(String simpleName) { + this(TypeCategory.SIMPLE, simpleName, "", simpleName, false, false); + } + + public SimpleType(Type type, List parameters) { + this(type.getCategory(), type.getFullName(), type.getPackageName(), type.getSimpleName(), + type.isPrimitive(), type.isFinal(), parameters); + } + + public SimpleType(Type type, Type... parameters) { + this(type.getCategory(), type.getFullName(), type.getPackageName(), type.getSimpleName(), + type.isPrimitive(), type.isFinal(), Arrays.asList(parameters)); + } + + public SimpleType(TypeCategory category, String fullName, String packageName, + String simpleName, boolean primitiveClass, boolean finalClass, List parameters) { + this.category = category; + this.fullName = fullName; + this.packageName = packageName; + this.simpleName = simpleName; + if (packageName.length() > 0) { + this.localName = fullName.substring(packageName.length() + 1); + } else { + this.localName = fullName; + } + if (localName.contains(".")) { + this.outerClassName = fullName.substring(0, fullName.lastIndexOf('.')); + } else { + this.outerClassName = fullName; + } + this.primitiveClass = primitiveClass; + this.finalClass = finalClass; + this.parameters = parameters; + this.memberClass = localName.contains("."); + } + + public SimpleType(TypeCategory typeCategory, String fullName, String packageName, + String simpleName, boolean p, boolean f, Type... parameters) { + this(typeCategory, fullName, packageName, simpleName, p, f, Arrays.asList(parameters)); + } + + @Override + public Type as(TypeCategory c) { + if (category != c) { + return new SimpleType(c, fullName, packageName, simpleName, primitiveClass, finalClass, + parameters); + } else { + return this; + } + } + + @Override + public Type asArrayType() { + if (arrayType == null) { + String newFullName = getFullName() + "[]"; + String newSimpleName = getSimpleName() + "[]"; + arrayType = new SimpleType(TypeCategory.ARRAY, newFullName, getPackageName(), + newSimpleName, false, false); + } + return arrayType; + } + + @Override + public boolean equals(Object o) { + if (o == this) { + return true; + } else if (o instanceof Type) { + Type t = (Type) o; + return t.getFullName().equals(fullName) && t.getParameters().equals(parameters); + } else { + return false; + } + } + + public TypeCategory getCategory() { + return category; + } + + @Override + public Type getComponentType() { + if (fullName.endsWith("[]")) { + if (componentType == null) { + String newFullName = fullName.substring(0, fullName.length() - 2); + String newSimpleName = simpleName.substring(0, simpleName.length() - 2); + componentType = new SimpleType(TypeCategory.SIMPLE, newFullName, getPackageName(), + newSimpleName, false, false); + } + return componentType; + } else { + return null; + } + } + + @Override + public Type getEnclosingType() { + if (enclosingType == null && memberClass) { + String newLocalName = localName.substring(0, localName.lastIndexOf('.')); + String newSimpleName = newLocalName.substring(newLocalName.lastIndexOf('.') + 1); + enclosingType = new SimpleType(outerClassName, packageName, newSimpleName); + } + return enclosingType; + } + + @Override + public String getFullName() { + return fullName; + } + + @Override + public String getGenericName(boolean asArgType) { + return getGenericName(asArgType, Collections.singleton("java.lang"), + Collections. emptySet()); + } + + @Override + public String getGenericName(boolean asArgType, Set packages, Set classes) { + if (parameters.isEmpty()) { + return getRawName(packages, classes); + } else { + StringBuilder builder = new StringBuilder(); + builder.append(getRawName(packages, classes)); + builder.append("<"); + boolean first = true; + for (Type parameter : parameters) { + if (!first) { + builder.append(", "); + } + if (parameter == null || parameter.getFullName().equals(fullName)) { + builder.append("?"); + } else { + builder.append(parameter.getGenericName(false, packages, classes)); + } + first = false; + } + builder.append(">"); + return builder.toString(); + } + } + + @Override + public Class getJavaClass() { + if (javaClass == null) { + String className; + if (packageName.length() > 0) { + className = packageName + "." + localName.replace('.', '$'); + } else { + className = localName.replace('.', '$'); + } + try { + if (className.endsWith("[]")) { + Class component = getComponentType().getJavaClass(); + javaClass = Array.newInstance(component, 0).getClass(); + } else if (PRIMITIVES.containsKey(className)) { + javaClass = PRIMITIVES.get(className); + } else { + javaClass = Class.forName(className); + } + } catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } + } + return javaClass; + } + + @Override + public String getPackageName() { + return packageName; + } + + @Override + public List getParameters() { + return parameters; + } + + @Override + public String getRawName(Set packages, Set classes) { + if (classes.contains(fullName)) { + return simpleName; + } else if (classes.contains(outerClassName)) { + return fullName.substring(outerClassName.lastIndexOf('.') + 1); + } else if (packages.contains(packageName)) { + return localName; + } else { + return fullName; + } + } + + @Override + public String getSimpleName() { + return simpleName; + } + + @Override + public int hashCode() { + return fullName.hashCode(); + } + + @Override + public boolean isFinal() { + return finalClass; + } + + @Override + public boolean isPrimitive() { + return primitiveClass; + } + + @Override + public boolean isMember() { + return memberClass; + } + + @Override + public String toString() { + return getGenericName(true); + } + +} diff --git a/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/model/Type.java b/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/model/Type.java new file mode 100644 index 0000000000..568d6b373f --- /dev/null +++ b/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/model/Type.java @@ -0,0 +1,56 @@ +/* + * Copyright 2010, Mysema Ltd + * + * 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. + */ +package com.querydsl.codegen.utils.model; + +import java.util.List; +import java.util.Set; + +/** + * @author tiwe + */ +public interface Type { + + Type as(TypeCategory category); + + Type asArrayType(); + + Type getComponentType(); + + Type getEnclosingType(); + + TypeCategory getCategory(); + + String getFullName(); + + String getGenericName(boolean asArgType); + + String getGenericName(boolean asArgType, Set packages, Set classes); + + Class getJavaClass(); + + String getPackageName(); + + List getParameters(); + + String getRawName(Set packages, Set classes); + + String getSimpleName(); + + boolean isFinal(); + + boolean isPrimitive(); + + boolean isMember(); + +} \ No newline at end of file diff --git a/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/model/TypeAdapter.java b/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/model/TypeAdapter.java new file mode 100644 index 0000000000..158359b5e6 --- /dev/null +++ b/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/model/TypeAdapter.java @@ -0,0 +1,132 @@ +/* + * Copyright 2010, Mysema Ltd + * + * 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. + */ +package com.querydsl.codegen.utils.model; + +import java.util.List; +import java.util.Set; + +/** + * TypeAdapter is a basic adapter implementation for the Type interface + * + * @author tiwe + * + */ +public class TypeAdapter implements Type { + + protected final Type type; + + public TypeAdapter(Type type) { + this.type = type; + } + + @Override + public Type as(TypeCategory category) { + return type.as(category); + } + + @Override + public Type asArrayType() { + return type.asArrayType(); + } + + @Override + public Type getComponentType() { + return type.getComponentType(); + } + + @Override + public Type getEnclosingType() { + return type.getEnclosingType(); + } + + @Override + public boolean equals(Object o) { + return type.equals(o); + } + + @Override + public TypeCategory getCategory() { + return type.getCategory(); + } + + @Override + public String getFullName() { + return type.getFullName(); + } + + @Override + public String getGenericName(boolean asArgType) { + return type.getGenericName(asArgType); + } + + @Override + public String getGenericName(boolean asArgType, Set packages, Set classes) { + return type.getGenericName(asArgType, packages, classes); + } + + @Override + public Class getJavaClass() { + return type.getJavaClass(); + } + + @Override + public String getPackageName() { + return type.getPackageName(); + } + + @Override + public List getParameters() { + return type.getParameters(); + } + + @Override + public String getRawName(Set packages, Set classes) { + return type.getRawName(packages, classes); + } + + @Override + public String getSimpleName() { + return type.getSimpleName(); + } + + protected Type getType() { + return type; + } + + @Override + public int hashCode() { + return type.hashCode(); + } + + @Override + public boolean isFinal() { + return type.isFinal(); + } + + @Override + public boolean isPrimitive() { + return type.isPrimitive(); + } + + @Override + public boolean isMember() { + return type.isMember(); + } + + @Override + public String toString() { + return type.toString(); + } + +} diff --git a/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/model/TypeCategory.java b/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/model/TypeCategory.java new file mode 100644 index 0000000000..80e31cf29c --- /dev/null +++ b/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/model/TypeCategory.java @@ -0,0 +1,147 @@ +/* + * Copyright 2010, Mysema Ltd + * + * 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. + */ +package com.querydsl.codegen.utils.model; + +import java.util.HashSet; +import java.util.Set; + +/** + * TypeCategory defines the expression type used for a Field + * + * @author tiwe + * + */ +public enum TypeCategory { + /** + * + */ + SIMPLE(null), + /** + * + */ + MAP(null), + /** + * + */ + COLLECTION(null), + /** + * + */ + LIST(COLLECTION), + /** + * + */ + SET(COLLECTION), + /** + * + */ + ARRAY(null), + /** + * + */ + COMPARABLE(SIMPLE), + /** + * + */ + BOOLEAN(COMPARABLE, Boolean.class.getName()), + /** + * + */ + DATE(COMPARABLE, java.sql.Date.class.getName(), "org.joda.time.LocalDate", + "java.time.LocalDate"), + /** + * + */ + DATETIME(COMPARABLE, java.util.Calendar.class.getName(), java.util.Date.class.getName(), + java.sql.Timestamp.class.getName(), "org.joda.time.LocalDateTime", + "org.joda.time.Instant", "org.joda.time.DateTime", "org.joda.time.DateMidnight", + "java.time.Instant", "java.time.LocalDateTime", "java.time.OffsetDateTime", "java.time.ZonedDateTime"), + /** + * + */ + ENUM(COMPARABLE), + /** + * + */ + CUSTOM(null), + + /** + * + */ + ENTITY(null), + + /** + * + */ + NUMERIC(COMPARABLE), + /** + * + */ + STRING(COMPARABLE, String.class.getName()), + /** + * + */ + TIME(COMPARABLE, java.sql.Time.class.getName(), "org.joda.time.LocalTime", + "java.time.LocalTime", "java.time.OffsetTime"); + + private final TypeCategory superType; + + private final Set types; + + TypeCategory(TypeCategory superType, String... types) { + this.superType = superType; + this.types = new HashSet(types.length); + for (String type : types) { + this.types.add(type); + } + } + + public TypeCategory getSuperType() { + return superType; + } + + public boolean supports(Class cl) { + return supports(cl.getName()); + } + + public boolean supports(String className) { + return types.contains(className); + } + + /** + * transitive and reflexive subCategoryOf check + * + * @param ancestor + * @return + */ + public boolean isSubCategoryOf(TypeCategory ancestor) { + if (this == ancestor) { + return true; + } else if (superType == null) { + return false; + } else { + return superType == ancestor || superType.isSubCategoryOf(ancestor); + } + } + + public static TypeCategory get(String className) { + for (TypeCategory category : values()) { + if (category.supports(className)) { + return category; + } + } + return SIMPLE; + } + +} diff --git a/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/model/TypeExtends.java b/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/model/TypeExtends.java new file mode 100644 index 0000000000..c0bd393255 --- /dev/null +++ b/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/model/TypeExtends.java @@ -0,0 +1,74 @@ +/* + * Copyright 2010, Mysema Ltd + * + * 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. + */ +package com.querydsl.codegen.utils.model; + +import java.util.Collections; +import java.util.Objects; +import java.util.Set; + +/** + * @author tiwe + * + */ +public class TypeExtends extends TypeAdapter { + + private final String varName; + + public TypeExtends(String varName, Type type) { + super(type); + this.varName = varName; + } + + public TypeExtends(Type type) { + super(type); + varName = null; + } + + @Override + public String getGenericName(boolean asArgType) { + return getGenericName(asArgType, Collections. emptySet(), + Collections. emptySet()); + } + + @Override + public String getGenericName(boolean asArgType, Set packages, Set classes) { + if (!asArgType) { + if (Types.OBJECT.equals(type)) { + return "?"; + } else { + String genericName = super.getGenericName(true, packages, classes); + return genericName == null || genericName.isEmpty() ? "?" : "? extends " + genericName; + } + } else { + return super.getGenericName(asArgType, packages, classes); + } + } + + public String getVarName() { + return varName; + } + + @Override + public boolean equals(Object o) { + if (o == this) { + return true; + } else if (o instanceof TypeExtends) { + return Objects.equals(((TypeExtends) o).varName, varName) + && ((TypeExtends) o).type.equals(type); + } else { + return false; + } + } + +} diff --git a/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/model/TypeSuper.java b/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/model/TypeSuper.java new file mode 100644 index 0000000000..71a1cd7587 --- /dev/null +++ b/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/model/TypeSuper.java @@ -0,0 +1,79 @@ +/* + * Copyright 2010, Mysema Ltd + * + * 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. + */ +package com.querydsl.codegen.utils.model; + +import java.util.Collections; +import java.util.Objects; +import java.util.Set; + +/** + * TypeSuper is a Type for type variables and wildcard types + * + * @author tiwe + * + */ +public class TypeSuper extends TypeAdapter { + + private final Type superType; + + private final String varName; + + public TypeSuper(String varName, Type type) { + super(Types.OBJECT); + this.superType = type; + this.varName = varName; + } + + public TypeSuper(Type type) { + super(Types.OBJECT); + this.superType = type; + this.varName = null; + } + + @Override + public String getGenericName(boolean asArgType) { + return getGenericName(asArgType, Collections. emptySet(), + Collections. emptySet()); + } + + @Override + public String getGenericName(boolean asArgType, Set packages, Set classes) { + if (!asArgType) { + if (superType instanceof TypeExtends) { + return "?"; + } else { + return "? super " + superType.getGenericName(true, packages, classes); + } + + } else { + return super.getGenericName(asArgType, packages, classes); + } + } + + public String getVarName() { + return varName; + } + + @Override + public boolean equals(Object o) { + if (o == this) { + return true; + } else if (o instanceof TypeSuper) { + return Objects.equals(((TypeSuper) o).varName, varName) + && ((TypeSuper) o).superType.equals(superType); + } else { + return false; + } + } +} diff --git a/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/model/Types.java b/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/model/Types.java new file mode 100644 index 0000000000..c0870ef9d4 --- /dev/null +++ b/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/model/Types.java @@ -0,0 +1,119 @@ +/* + * Copyright 2010, Mysema Ltd + * + * 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. + */ +package com.querydsl.codegen.utils.model; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.net.URI; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Set; + +/** + * @author tiwe + * + */ +public final class Types { + + public static final Map PRIMITIVES; + + public static final ClassType OBJECT = new ClassType(TypeCategory.SIMPLE, Object.class); + + public static final ClassType OBJECTS = new ClassType(TypeCategory.ARRAY, Object[].class); + + public static final ClassType BIG_DECIMAL = new ClassType(TypeCategory.NUMERIC, BigDecimal.class); + + public static final ClassType BIG_INTEGER = new ClassType(TypeCategory.NUMERIC, BigInteger.class); + + public static final ClassType BOOLEAN = new ClassType(TypeCategory.BOOLEAN, Boolean.class); + + public static final ClassType BOOLEAN_P = new ClassType(TypeCategory.BOOLEAN, boolean.class); + + public static final ClassType BYTE = new ClassType(TypeCategory.NUMERIC, Byte.class); + + public static final ClassType BYTE_P = new ClassType(TypeCategory.NUMERIC, byte.class); + + public static final ClassType CHARACTER = new ClassType(TypeCategory.COMPARABLE, Character.class); + + public static final ClassType CHAR = new ClassType(TypeCategory.COMPARABLE, char.class); + + public static final ClassType COLLECTION = new ClassType(TypeCategory.COLLECTION, Collection.class, OBJECT); + + public static final ClassType DOUBLE = new ClassType(TypeCategory.NUMERIC, Double.class); + + public static final ClassType DOUBLE_P = new ClassType(TypeCategory.NUMERIC, double.class); + + public static final ClassType FLOAT = new ClassType(TypeCategory.NUMERIC, Float.class); + + public static final ClassType FLOAT_P = new ClassType(TypeCategory.NUMERIC, float.class); + + public static final ClassType INTEGER = new ClassType(TypeCategory.NUMERIC, Integer.class); + + public static final ClassType INT = new ClassType(TypeCategory.NUMERIC, int.class); + + public static final ClassType ITERABLE = new ClassType(TypeCategory.SIMPLE, Iterable.class, OBJECT); + + public static final ClassType LIST = new ClassType(TypeCategory.LIST, List.class, OBJECT); + + public static final ClassType LOCALE = new ClassType(TypeCategory.SIMPLE, Locale.class); + + public static final ClassType LONG = new ClassType(TypeCategory.NUMERIC, Long.class); + + public static final ClassType LONG_P = new ClassType(TypeCategory.NUMERIC, long.class); + + public static final ClassType MAP = new ClassType(TypeCategory.MAP, Map.class, OBJECT, OBJECT); + + public static final ClassType SET = new ClassType(TypeCategory.SET, Set.class, OBJECT); + + public static final ClassType SHORT = new ClassType(TypeCategory.NUMERIC, Short.class); + + public static final ClassType SHORT_P = new ClassType(TypeCategory.NUMERIC, short.class); + + public static final ClassType STRING = new ClassType(TypeCategory.STRING, String.class); + + public static final ClassType URI = new ClassType(TypeCategory.COMPARABLE, URI.class); + + public static final ClassType VOID = new ClassType(TypeCategory.SIMPLE, void.class); + + public static final SimpleType DATE_TIME = new SimpleType(TypeCategory.DATETIME, + "org.joda.time.DateTime", "org.joda.time", "DateTime", false, false); + + public static final SimpleType LOCAL_DATE = new SimpleType(TypeCategory.DATE, + "org.joda.time.LocalDate", "org.joda.time", "LocalDate", false, false); + + public static final SimpleType LOCAL_TIME = new SimpleType(TypeCategory.TIME, + "org.joda.time.LocalTime", "org.joda.time", "LocalTime", false, false); + + static { + Map primitives = new HashMap(); + primitives.put(BOOLEAN, BOOLEAN_P); + primitives.put(BYTE, BYTE_P); + primitives.put(CHARACTER, CHAR); + primitives.put(DOUBLE, DOUBLE_P); + primitives.put(FLOAT, FLOAT_P); + primitives.put(INTEGER, INT); + primitives.put(LONG, LONG_P); + primitives.put(SHORT, SHORT_P); + PRIMITIVES = Collections.unmodifiableMap(primitives); + } + + + private Types() { + } + +} diff --git a/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/support/ClassUtils.java b/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/support/ClassUtils.java new file mode 100644 index 0000000000..ad2b8592bb --- /dev/null +++ b/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/support/ClassUtils.java @@ -0,0 +1,98 @@ +/* + * Copyright 2010, Mysema Ltd + * + * 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. + */ +package com.querydsl.codegen.utils.support; + +import java.lang.reflect.Modifier; +import java.util.*; + +/** + * @author tiwe + * + */ +public final class ClassUtils { + + private static final Set JAVA_LANG = Collections.singleton("java.lang"); + + public static String getName(Class cl) { + return getName(cl, JAVA_LANG, Collections. emptySet()); + } + + public static String getFullName(Class cl) { + if (cl.isArray()) { + return getFullName(cl.getComponentType()) + "[]"; + } + final String name = cl.getName(); + if (name.indexOf('$') > 0) { + return getFullName(cl.getDeclaringClass()) + "." + cl.getSimpleName(); + } + return name; + } + + public static String getPackageName(Class cl) { + while (cl.isArray()) { + cl = cl.getComponentType(); + } + final String name = cl.getName(); + final int i = name.lastIndexOf('.'); + if (i > 0) { + return name.substring(0, i); + } else { + return ""; + } + } + + public static String getName(Class cl, Set packages, Set classes) { + if (cl.isArray()) { + return getName(cl.getComponentType(), packages, classes) + "[]"; + } + final String canonicalName = cl.getName().replace('$', '.'); + final int i = cl.getName().lastIndexOf('.'); + if (classes.contains(canonicalName)) { + return cl.getSimpleName(); + } else if (cl.getEnclosingClass() != null) { + return getName(cl.getEnclosingClass(), packages, classes) + "." + cl.getSimpleName(); + } else if (i == -1) { + return canonicalName; + } else if (packages.contains(canonicalName.substring(0, i))) { + return canonicalName.substring(i + 1); + } else { + return canonicalName; + } + } + + public static Class normalize(Class clazz) { + if (List.class.isAssignableFrom(clazz)) { + return List.class; + } else if (Set.class.isAssignableFrom(clazz)) { + return Set.class; + } else if (Collection.class.isAssignableFrom(clazz)) { + return Collection.class; + } else if (Map.class.isAssignableFrom(clazz)) { + return Map.class; + // check for CGLIB generated classes + } else if (clazz.getName().contains("$$")) { + Class zuper = clazz.getSuperclass(); + if (zuper != null && !Object.class.equals(zuper)) { + return zuper; + } + } else if (!Modifier.isPublic(clazz.getModifiers())) { + return normalize(clazz.getSuperclass()); + } + return clazz; + } + + private ClassUtils() { + } + +} diff --git a/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/support/ScalaSyntaxUtils.java b/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/support/ScalaSyntaxUtils.java new file mode 100644 index 0000000000..1d7a6f058e --- /dev/null +++ b/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/support/ScalaSyntaxUtils.java @@ -0,0 +1,38 @@ +/* + * Copyright 2010, Mysema Ltd + * + * 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. + */ +package com.querydsl.codegen.utils.support; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +/** + * @author tiwe + * + */ +public final class ScalaSyntaxUtils { + + private ScalaSyntaxUtils() { } + + private static final Set reserved = new HashSet(Arrays.asList("abstract", "do", + "finally", "import", "object", "return", "trait", "var", "_", ":", "case", "else", + "for", "lazy", "override", "sealed", "try", "while", "=", "=>", "<-", "catch", + "extends", "forSome", "match", "package", "super", "true", "with", "<:", "class", + "false", "if", "new", "private", "this", "type", "yield", "<%", ">:", "def", "final", + "implicit", "null", "protected", "throw", "val", "#", "@")); + + public static boolean isReserved(String token) { + return reserved.contains(token); + } +} diff --git a/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/support/package-info.java b/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/support/package-info.java new file mode 100644 index 0000000000..3b18ad601e --- /dev/null +++ b/querydsl-codegen-utils/src/main/java/com/querydsl/codegen/utils/support/package-info.java @@ -0,0 +1,8 @@ +/* + * Copyright (c) 2010 Mysema Ltd. + * All rights reserved. + * + */ + +package com.querydsl.codegen.utils.support; + diff --git a/querydsl-codegen-utils/src/test/java/NestedTest.java b/querydsl-codegen-utils/src/test/java/NestedTest.java new file mode 100644 index 0000000000..75b7c36a6b --- /dev/null +++ b/querydsl-codegen-utils/src/test/java/NestedTest.java @@ -0,0 +1,25 @@ +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import com.querydsl.codegen.utils.model.ClassType; +import com.querydsl.codegen.utils.support.ClassUtils; + +public class NestedTest { + + public static class Inner { + + } + + @Test + public void ClassUtils_getName() { + String name = ClassUtils.getName(NestedTest.Inner.class); + assertEquals("NestedTest.Inner", name); + } + + @Test + public void ClassType_getName() { + assertEquals("NestedTest.Inner", new ClassType(NestedTest.Inner.class).getFullName()); + } + +} diff --git a/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/Annotation.java b/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/Annotation.java new file mode 100644 index 0000000000..7218a81313 --- /dev/null +++ b/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/Annotation.java @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2010 Mysema Ltd. + * All rights reserved. + * + */ +package com.querydsl.codegen.utils; + +import static java.lang.annotation.ElementType.TYPE; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ TYPE }) +@Retention(RetentionPolicy.RUNTIME) +public @interface Annotation { + + boolean prop1() default false; + + boolean prop2(); + + Class clazz(); + +} diff --git a/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/Annotation2.java b/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/Annotation2.java new file mode 100644 index 0000000000..49bb20c371 --- /dev/null +++ b/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/Annotation2.java @@ -0,0 +1,18 @@ +/** + * + */ +package com.querydsl.codegen.utils; + +import static java.lang.annotation.ElementType.TYPE; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ TYPE }) +@Retention(RetentionPolicy.RUNTIME) +public @interface Annotation2 { + + String value(); + +} \ No newline at end of file diff --git a/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/Annotation2Impl.java b/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/Annotation2Impl.java new file mode 100644 index 0000000000..52b9ac0396 --- /dev/null +++ b/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/Annotation2Impl.java @@ -0,0 +1,24 @@ +package com.querydsl.codegen.utils; + +import java.lang.annotation.Annotation; + +@SuppressWarnings("all") +public class Annotation2Impl implements Annotation2 { + + private final String value; + + public Annotation2Impl(String value) { + this.value = value; + } + + @Override + public String value() { + return value; + } + + @Override + public Class annotationType() { + return Annotation2.class; + } + +} diff --git a/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/Annotation3.java b/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/Annotation3.java new file mode 100644 index 0000000000..4981b1c1ce --- /dev/null +++ b/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/Annotation3.java @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2010 Mysema Ltd. + * All rights reserved. + * + */ +package com.querydsl.codegen.utils; + +import static java.lang.annotation.ElementType.TYPE; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ TYPE }) +@Retention(RetentionPolicy.RUNTIME) +public @interface Annotation3 { + + ElementType type(); + +} diff --git a/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/AnnotationTest.java b/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/AnnotationTest.java new file mode 100644 index 0000000000..8d29b0e25d --- /dev/null +++ b/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/AnnotationTest.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2010 Mysema Ltd. + * All rights reserved. + * + */ +package com.querydsl.codegen.utils; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.io.StringWriter; +import java.lang.annotation.ElementType; + +import org.junit.Test; + +@Annotation(prop2 = false, clazz = AnnotationTest.class) +@Annotation2("Hello") +@Annotation3(type = ElementType.ANNOTATION_TYPE) +public class AnnotationTest { + + private StringWriter w = new StringWriter(); + private CodeWriter writer = new JavaWriter(w); + + @Test + public void ClassAnnotation() throws IOException { + writer.annotation(getClass().getAnnotation(Annotation.class)); + String option1 = "@com.querydsl.codegen.utils.Annotation(clazz=com.querydsl.codegen.utils.AnnotationTest.class, prop2=false)"; + String option2 = "@com.querydsl.codegen.utils.Annotation(prop2=false, clazz=com.querydsl.codegen.utils.AnnotationTest.class)"; + String serialized = w.toString().trim(); + assertTrue(serialized.equals(option1) || serialized.equals(option2)); + } + + @Test + public void ClassAnnotation2() throws IOException { + writer.annotation(getClass().getAnnotation(Annotation2.class)); + assertEquals("@com.querydsl.codegen.utils.Annotation2(\"Hello\")", w.toString().trim()); + } + + @Test + public void ClassAnnotation3() throws IOException { + writer.annotation(getClass().getAnnotation(Annotation3.class)); + assertEquals( + "@com.querydsl.codegen.utils.Annotation3(type=java.lang.annotation.ElementType.ANNOTATION_TYPE)", + w.toString().trim()); + } + + @Test + public void MethodAnnotation() throws IOException, SecurityException, NoSuchMethodException { + writer.annotation(getClass().getMethod("MethodAnnotation").getAnnotation(Test.class)); + assertEquals("@org.junit.Test", w.toString().trim()); + } + + @Test + public void Min() throws IOException { + writer.annotation(new MinImpl(10)); + assertEquals("@javax.validation.constraints.Min(value=10)", w.toString().trim()); + } + + @Test + public void Max() throws IOException { + writer.annotation(new MaxImpl(10)); + assertEquals("@javax.validation.constraints.Max(value=10)", w.toString().trim()); + } + + @Test + public void NotNull() throws IOException { + writer.annotation(new NotNullImpl()); + assertEquals("@javax.validation.constraints.NotNull", w.toString().trim()); + } + + @Test + public void Uri_Value() throws IOException { + writer.annotation(new Annotation2Impl("http://www.example.com#")); + assertEquals("@com.querydsl.codegen.utils.Annotation2(\"http://www.example.com#\")", w.toString() + .trim()); + } + +} diff --git a/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/ComplexEvaluationTest.java b/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/ComplexEvaluationTest.java new file mode 100644 index 0000000000..6fadc442d9 --- /dev/null +++ b/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/ComplexEvaluationTest.java @@ -0,0 +1,213 @@ +/* + * Copyright (c) 2010 Mysema Ltd. + * All rights reserved. + * + */ +package com.querydsl.codegen.utils; + +import static org.junit.Assert.*; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import com.querydsl.codegen.utils.model.ClassType; +import com.querydsl.codegen.utils.model.Type; +import com.querydsl.codegen.utils.model.TypeCategory; +import com.querydsl.codegen.utils.model.Types; +import org.junit.Test; + +import com.querydsl.codegen.utils.support.Cat; + +public class ComplexEvaluationTest { + + private EvaluatorFactory factory = new ECJEvaluatorFactory(getClass().getClassLoader()); + + @Test + @SuppressWarnings("unchecked") + public void Complex() { + ClassType resultType = new ClassType(TypeCategory.LIST, List.class, Types.STRING); + StringBuilder source = new StringBuilder(); + source.append("java.util.List rv = new java.util.ArrayList();\n"); + source.append("for (String a : a_){\n"); + source.append(" for (String b : b_){\n"); + source.append(" if (a.equals(b)){\n"); + source.append(" rv.add(a);\n"); + source.append(" }\n"); + source.append(" }\n"); + source.append("}\n"); + source.append("return rv;"); + + @SuppressWarnings("rawtypes") // cannot specify further than List.class + Evaluator evaluator = factory.createEvaluator(source.toString(), resultType, + new String[] { "a_", "b_" }, new Type[] { resultType, resultType }, new Class[] { + List.class, List.class }, Collections. emptyMap()); + + List a = Arrays.asList("1", "2", "3", "4"); + List b = Arrays.asList("2", "4", "6", "8"); + + assertEquals(Arrays.asList("2", "4"), evaluator.evaluate(a, b)); + } + + @Test + @SuppressWarnings("unchecked") + public void ComplexClassLoading() { + ClassType resultType = new ClassType(TypeCategory.LIST, List.class, Types.OBJECTS); + StringBuilder source = new StringBuilder(); + source.append("java.util.List rv = new java.util.ArrayList();\n"); + source.append("for (com.querydsl.codegen.utils.support.Cat cat : (java.util.List)cat_){\n"); + source.append("for (com.querydsl.codegen.utils.support.Cat otherCat : (java.util.List)otherCat_){\n"); + source.append("rv.add(new Object[]{cat,otherCat});\n"); + source.append("}\n"); + source.append("}\n"); + source.append("return rv;\n"); + + Cat fuzzy = new Cat("fuzzy"); + Cat spot = new Cat("spot"); + Cat mittens = new Cat("mittens"); + Cat sparkles = new Cat("sparkles"); + + List a = Arrays.asList(fuzzy, spot); + List b = Arrays.asList(mittens, sparkles); + + ClassType argType = new ClassType(TypeCategory.LIST, List.class, new ClassType(Cat.class)); + @SuppressWarnings("rawtypes") // cannot specify further than List.class + Evaluator evaluator = factory.createEvaluator(source.toString(), resultType, + new String[] { "cat_", "otherCat_" }, new Type[] { argType, argType }, new Class[] { + List.class, List.class }, Collections. emptyMap()); + + Object[][] expResults = { {fuzzy, mittens}, {fuzzy, sparkles}, {spot, mittens}, {spot, sparkles} }; + List result = evaluator.evaluate(a, b); + assertEquals(expResults.length, result.size()); + + for (int i = 0; i < expResults.length; i++) { + assertEquals(expResults[i].length, result.get(i).length); + for (int j = 0; j < expResults[i].length; j++) { + assertEquals(expResults[i][j], result.get(i)[j]); + } + } + } + + @Test(expected = CodegenException.class) + @SuppressWarnings("unchecked") + public void ComplexClassLoadingFailure() { + ClassType resultType = new ClassType(TypeCategory.LIST, List.class, Types.STRING); + StringBuilder source = new StringBuilder(); + source.append("java.util.List rv = (java.util.List) new java.util.ArrayList();\n"); + source.append("for (String a : a_){\n"); + source.append(" for (String b : b_){\n"); + source.append(" if (a.equals(b)){\n"); + source.append(" rv.add(a);\n"); + source.append(" }\n"); + source.append(" }\n"); + source.append("}\n"); + source.append("return rv;"); + + @SuppressWarnings("rawtypes") // cannot specify further than List.class + Evaluator evaluator = factory.createEvaluator(source.toString(), resultType, + new String[] { "a_", "b_" }, new Type[] { resultType, resultType }, new Class[] { + List.class, List.class }, Collections. emptyMap()); + + List a = Arrays.asList("1", "2", "3", "4"); + List b = Arrays.asList("2", "4", "6", "8"); + + assertEquals(Arrays.asList("2", "4"), evaluator.evaluate(a, b)); + } + + @Test + @SuppressWarnings("unchecked") + public void ComplexPrimitiveType() { + ClassType resultType = new ClassType(TypeCategory.LIST, List.class, Types.BOOLEAN); + StringBuilder source = new StringBuilder(); + source.append("java.util.List rv = new java.util.ArrayList();\n"); + source.append("for (boolean a : a_){\n"); + source.append(" for (boolean b : b_){\n"); + source.append(" if (a == b){\n"); + source.append(" rv.add(a);\n"); + source.append(" }\n"); + source.append(" }\n"); + source.append("}\n"); + source.append("return rv;"); + + @SuppressWarnings("rawtypes") // cannot specify further than List.class + Evaluator evaluator = factory.createEvaluator(source.toString(), resultType, + new String[] { "a_", "b_" }, new Type[] { resultType, resultType }, new Class[] { + List.class, List.class }, Collections. emptyMap()); + + List a = Arrays.asList(true, true, true); + List b = Arrays.asList(false, false, true); + + assertEquals(Arrays.asList(true, true, true), evaluator.evaluate(a, b)); + } + + @Test + @SuppressWarnings("unchecked") + public void ComplexEmbeddedClass() { + ClassType resultType = new ClassType(TypeCategory.LIST, List.class, Types.BOOLEAN); + StringBuilder source = new StringBuilder(); + source.append("java.util.List rv = new java.util.ArrayList();\n"); + source.append("for (boolean a : a_){\n"); + source.append(" for (boolean b : b_){\n"); + source.append(" if (a == b && new TestEmbedded().DO_RETURN()){\n"); + source.append(" rv.add(a);\n"); + source.append(" }\n"); + source.append(" }\n"); + source.append("}\n"); + source.append("return rv;} private static class TestEmbedded { public TestEmbedded() {} public boolean DO_RETURN() { return true; } "); + + @SuppressWarnings("rawtypes") // cannot specify further than List.class + Evaluator evaluator = factory.createEvaluator(source.toString(), resultType, + new String[] { "a_", "b_" }, new Type[] { resultType, resultType }, new Class[] { + List.class, List.class }, Collections. emptyMap()); + + List a = Arrays.asList(true, true, true); + List b = Arrays.asList(false, false, true); + + assertEquals(Arrays.asList(true, true, true), evaluator.evaluate(a, b)); + } + + public static final class SuperCat extends Cat { + private SuperCat(String name) { + super(name); + } + } + + @Test + public void ComplexDifferentConstants() { + ClassType resultType = new ClassType(TypeCategory.LIST, List.class, new ClassType(Cat.class)); + String source = new StringBuilder() + .append("java.util.List rv = new java.util.ArrayList();\n") + .append("for (com.querydsl.codegen.utils.support.Cat cat : (java.util.List)cat_){\n") + .append("if (cat.equals(a1)) {\n") + .append("rv.add(cat);\n") + .append("}\n") + .append("}\n") + .append("return rv;\n") + .toString(); + + List cats = Arrays.asList(new Cat("fuzzy"), new Cat("spot")); + String[] names = new String[] { "cat_" }; + Type[] types = new Type[] { new ClassType(TypeCategory.LIST, List.class, new ClassType(Cat.class)) }; + Class[] classes = new Class[] { List.class }; + + // first pass + factory.createEvaluator( + source, + resultType, + names, + types, + classes, + Collections.singletonMap("a1", (Object) new SuperCat("superMittens")) + ).evaluate(cats); + + // second pass + factory.createEvaluator( + source, + resultType, + names, + types, + classes, + Collections.singletonMap("a1", (Object) new Cat("normalMittens")) + ).evaluate(cats); + } +} diff --git a/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/ECJEvaluatorFactoryTest.java b/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/ECJEvaluatorFactoryTest.java new file mode 100644 index 0000000000..9d9c3633ed --- /dev/null +++ b/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/ECJEvaluatorFactoryTest.java @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2010 Mysema Ltd. + * All rights reserved. + * + */ +package com.querydsl.codegen.utils; + +import static org.junit.Assert.assertEquals; + +import java.io.IOException; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +public class ECJEvaluatorFactoryTest { + + public static class TestEntity { + + private final String name; + + public TestEntity(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + } + + private EvaluatorFactory factory; + + private List names = Arrays.asList("a", "b"); + + private List> ints = Arrays.> asList(int.class, int.class); + + private List> strings = Arrays.> asList(String.class, String.class); + + private List> string_int = Arrays.> asList(String.class, int.class); + + @Before + public void setUp() throws IOException { + factory = new ECJEvaluatorFactory(getClass().getClassLoader()); + } + + @Test + public void Simple() { + for (String expr : Arrays.asList("a.equals(b)", "a.startsWith(b)", "a.equalsIgnoreCase(b)")) { + long start = System.currentTimeMillis(); + evaluate(expr, boolean.class, names, strings, Arrays.asList("a", "b"), + Collections. emptyMap()); + long duration = System.currentTimeMillis() - start; + System.err.println(expr + " took " + duration + "ms\n"); + } + + for (String expr : Arrays.asList("a != b", "a < b", "a > b", "a <= b", "a >= b")) { + long start = System.currentTimeMillis(); + evaluate(expr, boolean.class, names, ints, Arrays.asList(0, 1), + Collections. emptyMap()); + long duration = System.currentTimeMillis() - start; + System.err.println(expr + " took " + duration + "ms\n"); + } + } + + @Test + public void Results() { + // String + String + test("a + b", String.class, names, strings, Arrays.asList("Hello ", "World"), "Hello World"); + + // String + int + test("a.substring(b)", String.class, names, string_int, + Arrays. asList("Hello World", 6), "World"); + + // int + int + test("a + b", int.class, names, ints, Arrays.asList(1, 2), 3); + } + + @Test + public void WithConstants() { + Map constants = new HashMap(); + constants.put("x", "Hello World"); + List> types = Arrays.> asList(String.class); + List names = Arrays.asList("a"); + assertEquals( + Boolean.TRUE, + evaluate("a.equals(x)", boolean.class, names, types, Arrays.asList("Hello World"), + constants)); + assertEquals( + Boolean.FALSE, + evaluate("a.equals(x)", boolean.class, names, types, Arrays.asList("Hello"), + constants)); + } + + @Test + public void CustomType() { + test("a.getName()", String.class, Collections.singletonList("a"), + Collections.> singletonList(TestEntity.class), + Arrays.asList(new TestEntity("Hello World")), "Hello World"); + } + + private void test(String source, Class projectionType, List names, + List> types, List args, Object expectedResult) { + Assert.assertEquals( + expectedResult, + evaluate(source, projectionType, names, types, args, + Collections. emptyMap())); + } + + private Object evaluate(String source, Class projectionType, List names, + List> types, List args, Map constants) { + Evaluator evaluator = factory.createEvaluator("return " + source + ";", projectionType, + names.toArray(new String[names.size()]), types.toArray(new Class[types.size()]), + constants); + return evaluator.evaluate(args.toArray()); + } + +} diff --git a/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/Entity.java b/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/Entity.java new file mode 100644 index 0000000000..829a3f2ef2 --- /dev/null +++ b/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/Entity.java @@ -0,0 +1,10 @@ +/* + * Copyright (c) 2010 Mysema Ltd. + * All rights reserved. + * + */ +package com.querydsl.codegen.utils; + +public @interface Entity { + +} diff --git a/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/InnerClassesTest.java b/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/InnerClassesTest.java new file mode 100644 index 0000000000..c58d44d045 --- /dev/null +++ b/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/InnerClassesTest.java @@ -0,0 +1,52 @@ +package com.querydsl.codegen.utils; + +import static org.junit.Assert.*; + +import java.io.IOException; +import java.io.StringWriter; + +import com.querydsl.codegen.utils.model.ClassType; +import com.querydsl.codegen.utils.model.SimpleType; +import org.junit.Test; + +import com.querydsl.codegen.utils.model.Type; + +public class InnerClassesTest { + + public static class Entity { + + } + + @Test + public void DirectParameter() throws IOException { + Type entityType = new ClassType(Entity.class); + Type type = new SimpleType("com.querydsl.codegen.utils.gen.QEntity", "com.querydsl.codegen.utils.gen", + "QEntity", entityType); + + StringWriter str = new StringWriter(); + JavaWriter writer = new JavaWriter(str); + writer.beginClass(type); + writer.end(); + + System.err.println(str.toString()); + } + + @Test + public void Java() { + StringWriter str = new StringWriter(); + JavaWriter writer = new JavaWriter(str); + + assertEquals("com.querydsl.codegen.utils.InnerClassesTest.Entity", + writer.getRawName(new ClassType(Entity.class))); + } + + @Test + public void Scala() { + StringWriter str = new StringWriter(); + ScalaWriter writer = new ScalaWriter(str); + + assertEquals("com.querydsl.codegen.utils.InnerClassesTest$Entity", + writer.getRawName(new ClassType(Entity.class))); + } + +} diff --git a/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/JDKEvaluatorFactoryTest.java b/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/JDKEvaluatorFactoryTest.java new file mode 100644 index 0000000000..3ddc1f3cd1 --- /dev/null +++ b/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/JDKEvaluatorFactoryTest.java @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2010 Mysema Ltd. + * All rights reserved. + * + */ +package com.querydsl.codegen.utils; + +import static org.junit.Assert.assertEquals; + +import java.io.IOException; +import java.net.URLClassLoader; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +public class JDKEvaluatorFactoryTest { + + public static class TestEntity { + + private final String name; + + public TestEntity(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + } + + private EvaluatorFactory factory; + + private List names = Arrays.asList("a", "b"); + + private List> ints = Arrays.> asList(int.class, int.class); + + private List> strings = Arrays.> asList(String.class, String.class); + + private List> string_int = Arrays.> asList(String.class, int.class); + + @Before + public void setUp() throws IOException { + factory = new JDKEvaluatorFactory((URLClassLoader) getClass().getClassLoader()); + } + + @Test + public void Simple() { + for (String expr : Arrays.asList("a.equals(b)", "a.startsWith(b)", "a.equalsIgnoreCase(b)")) { + long start = System.currentTimeMillis(); + evaluate(expr, boolean.class, names, strings, Arrays.asList("a", "b"), + Collections. emptyMap()); + long duration = System.currentTimeMillis() - start; + System.err.println(expr + " took " + duration + "ms\n"); + } + + for (String expr : Arrays.asList("a != b", "a < b", "a > b", "a <= b", "a >= b")) { + long start = System.currentTimeMillis(); + evaluate(expr, boolean.class, names, ints, Arrays.asList(0, 1), + Collections. emptyMap()); + long duration = System.currentTimeMillis() - start; + System.err.println(expr + " took " + duration + "ms\n"); + } + } + + @Test + public void Results() { + // String + String + test("a + b", String.class, names, strings, Arrays.asList("Hello ", "World"), "Hello World"); + + // String + int + test("a.substring(b)", String.class, names, string_int, + Arrays. asList("Hello World", 6), "World"); + + // int + int + test("a + b", int.class, names, ints, Arrays.asList(1, 2), 3); + } + + @Test + public void WithConstants() { + Map constants = new HashMap(); + constants.put("x", "Hello World"); + List> types = Arrays.> asList(String.class); + List names = Arrays.asList("a"); + assertEquals( + Boolean.TRUE, + evaluate("a.equals(x)", boolean.class, names, types, Arrays.asList("Hello World"), + constants)); + assertEquals( + Boolean.FALSE, + evaluate("a.equals(x)", boolean.class, names, types, Arrays.asList("Hello"), + constants)); + } + + @Test + public void CustomType() { + test("a.getName()", String.class, Collections.singletonList("a"), + Collections.> singletonList(TestEntity.class), + Arrays.asList(new TestEntity("Hello World")), "Hello World"); + } + + private void test(String source, Class projectionType, List names, + List> types, List args, Object expectedResult) { + Assert.assertEquals( + expectedResult, + evaluate(source, projectionType, names, types, args, + Collections. emptyMap())); + } + + private Object evaluate(String source, Class projectionType, List names, + List> types, List args, Map constants) { + Evaluator evaluator = factory.createEvaluator("return " + source + ";", projectionType, + names.toArray(new String[names.size()]), types.toArray(new Class[types.size()]), + constants); + return evaluator.evaluate(args.toArray()); + } + +} diff --git a/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/JavaWriterTest.java b/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/JavaWriterTest.java new file mode 100644 index 0000000000..98f321e42f --- /dev/null +++ b/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/JavaWriterTest.java @@ -0,0 +1,355 @@ +/* + * Copyright (c) 2010 Mysema Ltd. + * All rights reserved. + * + */ +package com.querydsl.codegen.utils; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.io.StringWriter; +import java.lang.annotation.Annotation; +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.function.Function; + +import com.querydsl.codegen.utils.model.ClassType; +import com.querydsl.codegen.utils.model.Parameter; +import com.querydsl.codegen.utils.model.SimpleType; +import com.querydsl.codegen.utils.model.Type; +import com.querydsl.codegen.utils.model.TypeCategory; +import com.querydsl.codegen.utils.model.Types; +import org.junit.Before; +import org.junit.Test; + +public class JavaWriterTest { + + private static final Function transformer = new Function() { + @Override + public Parameter apply(Parameter input) { + return input; + } + }; + + private StringWriter w; + + private CodeWriter writer; + + private Type testType, testType2, testSuperType, testInterface1, testInterface2; + + private static void match(String resource, String text) throws IOException { + // TODO : try to compile ? + final InputStream resourceAsStream = JavaWriterTest.class.getResourceAsStream(resource); + StringBuilder textBuilder = new StringBuilder(); + try (Reader reader = new BufferedReader(new InputStreamReader(resourceAsStream, StandardCharsets.UTF_8))) { + int c = 0; + while ((c = reader.read()) != -1) { + textBuilder.append((char) c); + } + } + String expected = textBuilder.toString().replace("\r\n", System.lineSeparator()).trim(); + String actual = text.trim(); + assertEquals(expected, actual); + } + + @Before + public void setUp() { + w = new StringWriter(); + writer = new JavaWriter(w); + testType = new ClassType(JavaWriterTest.class); + testType2 = new SimpleType("com.querydsl.codegen.utils.Test", "com.querydsl.codegen.utils", "Test"); + testSuperType = new SimpleType("com.querydsl.codegen.utils.Superclass", "com.querydsl.codegen.utils", + "Superclass"); + testInterface1 = new SimpleType("com.querydsl.codegen.utils.TestInterface1", "com.querydsl.codegen.utils", + "TestInterface1"); + testInterface2 = new SimpleType("com.querydsl.codegen.utils.TestInterface2", "com.querydsl.codegen.utils", + "TestInterface2"); + } + + @Test + public void Arrays() throws IOException { + writer.beginClass(new SimpleType("Main")); + writer.field(Types.STRING.asArrayType(), "stringArray"); + writer.beginPublicMethod(Types.VOID, "main", + new Parameter("args", Types.STRING.asArrayType())); + writer.line("//"); + writer.end(); + writer.beginPublicMethod(Types.VOID, "main2", new Parameter("args", new ClassType( + TypeCategory.ARRAY, String[].class))); + writer.line("//"); + writer.end(); + writer.end(); + + System.out.println(w); + assertTrue(w.toString().contains("String[] stringArray;")); + assertTrue(w.toString().contains("public void main(String[] args) {")); + assertTrue(w.toString().contains("public void main2(String[] args) {")); + } + + @Test + public void Primitive_Arrays() { + ClassType byteArray = new ClassType(byte[].class); + assertEquals("byte[]", writer.getRawName(byteArray)); + } + + @Test + public void Basic() throws IOException { + writer.packageDecl("com.querydsl.codegen.utils"); + writer.imports(IOException.class, StringWriter.class, Test.class); + writer.beginClass(testType); + writer.annotation(Test.class); + writer.beginPublicMethod(Types.VOID, "test"); + writer.line("// TODO"); + writer.end(); + writer.end(); + + match("/testBasic", w.toString()); + } + + @Test + public void Extends() throws IOException { + writer.beginClass(testType2, testSuperType); + writer.end(); + + match("/testExtends", w.toString()); + } + + @Test + public void Implements() throws IOException { + writer.beginClass(testType2, null, testInterface1, testInterface2); + writer.end(); + + match("/testImplements", w.toString()); + } + + @Test + public void Interface() throws IOException { + writer.packageDecl("com.querydsl.codegen.utils"); + writer.imports(IOException.class, StringWriter.class, Test.class); + writer.beginInterface(testType); + writer.end(); + + match("/testInterface", w.toString()); + } + + @Test + public void Interface2() throws IOException { + writer.beginInterface(testType2, testInterface1); + writer.end(); + + match("/testInterface2", w.toString()); + } + + @Test + public void Interface3() throws IOException { + writer.beginInterface(testType, testType2, testInterface1, testInterface2); + writer.end(); + + assertTrue(w.toString().contains( + "public interface JavaWriterTest extends Test, TestInterface1, TestInterface2 {")); + } + + @Test + public void Javadoc() throws IOException { + writer.packageDecl("com.querydsl.codegen.utils"); + writer.imports(IOException.class, StringWriter.class, Test.class); + writer.javadoc("JavaWriterTest is a test class"); + writer.beginClass(testType); + writer.end(); + + match("/testJavadoc", w.toString()); + } + + @Test + public void Annotations() throws IOException { + writer.packageDecl("com.querydsl.codegen.utils"); + writer.imports(IOException.class, StringWriter.class); + writer.annotation(Entity.class); + writer.beginClass(testType); + writer.annotation(Test.class); + writer.beginPublicMethod(Types.VOID, "test"); + writer.end(); + writer.end(); + + match("/testAnnotations", w.toString()); + } + + @Test + public void Annotations2() throws IOException { + writer.packageDecl("com.querydsl.codegen.utils"); + writer.imports(IOException.class.getPackage(), StringWriter.class.getPackage()); + writer.annotation(Entity.class); + writer.beginClass(testType); + writer.annotation(new Test() { + @Override + public Class expected() { + // TODO Auto-generated method stub + return null; + } + + @Override + public long timeout() { + + return 0; + } + + @Override + public Class annotationType() { + return Test.class; + } + }); + writer.beginPublicMethod(Types.VOID, "test"); + writer.end(); + writer.end(); + + match("/testAnnotations2", w.toString()); + } + + @Test + public void Annotation_With_ArrayMethod() throws IOException { + Target annotation = new Target() { + @Override + public ElementType[] value() { + return new ElementType[] { ElementType.FIELD, ElementType.METHOD }; + } + + @Override + public Class annotationType() { + return Target.class; + } + }; + + writer.imports(Target.class.getPackage()); + writer.annotation(annotation); + assertTrue(w.toString().contains("@Target({FIELD, METHOD})")); + } + + @Test + public void ClassConstants() { + assertEquals("SomeClass.class", writer.getClassConstant("SomeClass")); + } + + @Test + public void Fields() throws IOException { + writer.beginClass(testType); + // private + writer.privateField(Types.STRING, "privateField"); + writer.privateStaticFinal(Types.STRING, "privateStaticFinal", "\"val\""); + // protected + writer.protectedField(Types.STRING, "protectedField"); + // field + writer.field(Types.STRING, "field"); + // public + writer.publicField(Types.STRING, "publicField"); + writer.publicStaticFinal(Types.STRING, "publicStaticFinal", "\"val\""); + writer.publicFinal(Types.STRING, "publicFinalField"); + writer.publicFinal(Types.STRING, "publicFinalField2", "\"val\""); + + writer.end(); + + match("/testFields", w.toString()); + } + + @Test + public void Methods() throws IOException { + writer.beginClass(testType); + // private + + // protected + + // method + + // public + writer.beginPublicMethod(Types.STRING, "publicMethod", + Arrays.asList(new Parameter("a", Types.STRING)), transformer); + writer.line("return null;"); + writer.end(); + + writer.beginStaticMethod(Types.STRING, "staticMethod", + Arrays.asList(new Parameter("a", Types.STRING)), transformer); + writer.line("return null;"); + writer.end(); + + writer.end(); + + match("/testMethods", w.toString()); + } + + @Test + public void Constructors() throws IOException { + writer.beginClass(testType); + + writer.beginConstructor( + Arrays.asList(new Parameter("a", Types.STRING), new Parameter("b", Types.STRING)), + transformer); + writer.end(); + + writer.beginConstructor(new Parameter("a", Types.STRING)); + writer.end(); + + writer.end(); + + match("/testConstructors", w.toString()); + + } + + @Test + public void Inner_Classes() throws IOException { + writer.beginClass(testType); + + writer.beginClass(testType2); + writer.end(); + + writer.beginConstructor(new Parameter("a", Types.STRING)); + writer.end(); + + writer.end(); + + match("/testInnerClasses", w.toString()); + } + + @Test + public void Imports() throws IOException { + writer.staticimports(Arrays.class); + + match("/testImports", w.toString()); + } + + @Test + public void Imports2() throws IOException { + writer.importPackages("java.lang.reflect", "java.util"); + + match("/testImports2", w.toString()); + } + + @Test + public void Imports3() throws IOException { + writer.importClasses("java.util.Locale"); + + assertTrue(w.toString().contains("import java.util.Locale;")); + } + + @Test + public void SuppressWarnings() throws IOException { + writer.suppressWarnings("unused"); + writer.privateField(Types.STRING, "test"); + + match("/testSuppressWarnings", w.toString()); + } + + @Test + public void SuppressWarnings2() throws IOException { + writer.suppressWarnings("all", "unused"); + writer.privateField(Types.STRING, "test"); + + match("/testSuppressWarnings2", w.toString()); + } +} diff --git a/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/MaxImpl.java b/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/MaxImpl.java new file mode 100644 index 0000000000..fbfcb2fe72 --- /dev/null +++ b/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/MaxImpl.java @@ -0,0 +1,46 @@ +package com.querydsl.codegen.utils; + +import java.lang.annotation.Annotation; + +import javax.validation.Payload; +import javax.validation.constraints.*; + +/** + * @author tiwe + * + */ +@SuppressWarnings("all") +public class MaxImpl implements Max { + + private final long value; + + public MaxImpl(long value) { + this.value = value; + } + + @Override + public Class[] groups() { + return new Class[0]; + } + + @Override + public String message() { + return "{javax.validation.constraints.Max.message}"; + } + + @Override + public Class[] payload() { + return new Class[0]; + } + + @Override + public long value() { + return value; + } + + @Override + public Class annotationType() { + return Max.class; + } + +} diff --git a/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/MemJavaFileObjectTest.java b/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/MemJavaFileObjectTest.java new file mode 100644 index 0000000000..afa63c4a62 --- /dev/null +++ b/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/MemJavaFileObjectTest.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2010 Mysema Ltd. + * All rights reserved. + * + */ +package com.querydsl.codegen.utils; + +import static org.junit.Assert.assertEquals; + +import java.io.IOException; +import java.io.Writer; + +import javax.tools.JavaFileObject.Kind; + +import org.junit.Test; + +public class MemJavaFileObjectTest { + + @Test + public void getCharContent() throws IOException { + MemJavaFileObject obj = new MemJavaFileObject("mem", "Test", Kind.SOURCE); + Writer writer = obj.openWriter(); + writer.write("Hello World"); + writer.flush(); + writer.close(); + assertEquals("Hello World", obj.getCharContent(true).toString()); + } + + @Test + public void openInputStream() throws IOException { + MemJavaFileObject obj = new MemJavaFileObject("mem", "Test", Kind.SOURCE); + obj.openWriter().write("test"); + obj.openInputStream().close(); + } + +} diff --git a/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/MemSourceFileObjectTest.java b/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/MemSourceFileObjectTest.java new file mode 100644 index 0000000000..f7feb6adad --- /dev/null +++ b/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/MemSourceFileObjectTest.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2010 Mysema Ltd. + * All rights reserved. + * + */ +package com.querydsl.codegen.utils; + +import static org.junit.Assert.*; + +import java.io.IOException; + +import org.junit.Test; + +public class MemSourceFileObjectTest { + + @Test + public void Simple() { + MemSourceFileObject obj = new MemSourceFileObject("Test", "Hello World"); + assertEquals("Hello World", obj.getCharContent(true).toString()); + } + + @Test + public void OpenWriter() throws IOException { + MemSourceFileObject obj = new MemSourceFileObject("Test"); + obj.openWriter().write("Hello World"); + assertEquals("Hello World", obj.getCharContent(true).toString()); + } + + @Test + public void OpenWriter2() throws IOException { + MemSourceFileObject obj = new MemSourceFileObject("Test"); + obj.openWriter().append("Hello World"); + assertEquals("Hello World", obj.getCharContent(true).toString()); + } + +} diff --git a/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/MinImpl.java b/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/MinImpl.java new file mode 100644 index 0000000000..5375790685 --- /dev/null +++ b/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/MinImpl.java @@ -0,0 +1,46 @@ +package com.querydsl.codegen.utils; + +import java.lang.annotation.Annotation; + +import javax.validation.Payload; +import javax.validation.constraints.*; + +/** + * @author tiwe + * + */ +@SuppressWarnings("all") +public class MinImpl implements Min { + + private final long value; + + public MinImpl(long value) { + this.value = value; + } + + @Override + public Class[] groups() { + return new Class[0]; + } + + @Override + public String message() { + return "{javax.validation.constraints.Min.message}"; + } + + @Override + public Class[] payload() { + return new Class[0]; + } + + @Override + public long value() { + return value; + } + + @Override + public Class annotationType() { + return Min.class; + } + +} diff --git a/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/NotNullImpl.java b/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/NotNullImpl.java new file mode 100644 index 0000000000..6e3bf29527 --- /dev/null +++ b/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/NotNullImpl.java @@ -0,0 +1,35 @@ +package com.querydsl.codegen.utils; + +import java.lang.annotation.Annotation; + +import javax.validation.Payload; +import javax.validation.constraints.*; + +/** + * @author tiwe + * + */ +@SuppressWarnings("all") +public class NotNullImpl implements NotNull { + + @Override + public Class[] groups() { + return new Class[0]; + } + + @Override + public Class[] payload() { + return new Class[0]; + } + + @Override + public String message() { + return "{javax.validation.constraints.NotNull.message}"; + } + + @Override + public Class annotationType() { + return NotNull.class; + } + +} diff --git a/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/ScalaWriterTest.java b/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/ScalaWriterTest.java new file mode 100644 index 0000000000..f0ccf847d5 --- /dev/null +++ b/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/ScalaWriterTest.java @@ -0,0 +1,424 @@ +package com.querydsl.codegen.utils; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.io.StringWriter; +import java.io.Writer; +import java.lang.annotation.Annotation; +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; +import java.util.Arrays; +import java.util.List; +import java.util.function.Function; + +import javax.validation.constraints.Max; + +import com.querydsl.codegen.utils.model.ClassType; +import com.querydsl.codegen.utils.model.Parameter; +import com.querydsl.codegen.utils.model.SimpleType; +import com.querydsl.codegen.utils.model.Type; +import com.querydsl.codegen.utils.model.TypeCategory; +import com.querydsl.codegen.utils.model.Types; +import org.junit.Before; +import org.junit.Test; + +public class ScalaWriterTest { + + private static final Function transformer = new Function() { + @Override + public Parameter apply(Parameter input) { + return input; + } + }; + + private final Writer w = new StringWriter(); + + private final ScalaWriter writer = new ScalaWriter(w, true); + + private Type testType, testType2, testSuperType, testInterface1, testInterface2; + + @Before + public void setUp() { + testType = new ClassType(JavaWriterTest.class); + testType2 = new SimpleType("com.querydsl.codegen.utils.Test", "com.querydsl.codegen.utils", "Test"); + testSuperType = new SimpleType("com.querydsl.codegen.utils.Superclass", "com.querydsl.codegen.utils", + "Superclass"); + testInterface1 = new SimpleType("com.querydsl.codegen.utils.TestInterface1", "com.querydsl.codegen.utils", + "TestInterface1"); + testInterface2 = new SimpleType("com.querydsl.codegen.utils.TestInterface2", "com.querydsl.codegen.utils", + "TestInterface2"); + } + + @Test + public void Object() throws IOException { + writer.beginObject("Test"); + writer.end(); + assertTrue(w.toString().contains("object Test {")); + } + + @Test + public void Class_With_Interfaces() throws IOException { + writer.beginClass(testType, testType2, testInterface1); + assertTrue(w.toString().contains("class JavaWriterTest extends Test with TestInterface1 {")); + } + + @Test + public void Interface_With_Superinterfaces() throws IOException { + writer.beginInterface(testType, testType2, testInterface1); + assertTrue(w.toString().contains("trait JavaWriterTest extends Test with TestInterface1 {")); + } + + @Test + public void CustomHeader() throws IOException { + // class QDepartment(path: String) extends + // RelationalPathBase[QDepartment](classOf[QDepartment], path){ + // val id = createNumber("ID", classOf[Integer]); + // val company = createNumber("COMPANY", classOf[Integer]); + // val idKey = createPrimaryKey(id); + // val companyKey: ForeignKey[QCompany] = createForeignKey(company, + // "ID"); + // } + writer.beginClass("QDepartment(path: String) extends RelationalPathBase[QDepartment](classOf[QDepartment], path)"); + writer.publicFinal(Types.OBJECT, "id", "createNumber(\"ID\", classOf[Integer])"); + writer.publicFinal(Types.OBJECT, "company", "createNumber(\"COMPANY\", classOf[Integer])"); + writer.publicFinal(Types.OBJECT, "idKey", "createPrimaryKey(id)"); + writer.publicFinal(Types.OBJECT, "companyKey", "createForeignKey(company,\"ID\")"); + writer.end(); + + System.out.println(w); + } + + @Test + public void BeanAccessors() throws IOException { + writer.beginClass(new SimpleType("Person")); + writer.beginPublicMethod(Types.STRING, "getName"); + writer.line("\"Daniel Spiewak\""); + writer.end(); + writer.beginPublicMethod(Types.VOID, "setName", new Parameter("name", Types.STRING)); + writer.line("//"); + writer.end(); + writer.end(); + + System.out.println(w); + } + + @Test + public void Arrays() throws IOException { + // def main(args: Array[String]) { + writer.beginClass(new SimpleType("Main")); + writer.field(Types.STRING.asArrayType(), "stringArray"); + writer.beginPublicMethod(Types.VOID, "main", + new Parameter("args", Types.STRING.asArrayType())); + writer.line("//"); + writer.end(); + writer.beginPublicMethod(Types.VOID, "main2", new Parameter("args", new ClassType( + TypeCategory.ARRAY, String[].class))); + writer.line("//"); + writer.end(); + writer.end(); + + System.out.println(w); + assertTrue(w.toString().contains("var stringArray: Array[String]")); + assertTrue(w.toString().contains("def main(args: Array[String])")); + assertTrue(w.toString().contains("def main2(args: Array[String])")); + } + + @Test + public void Arrays2() throws IOException { + writer.field(Types.BYTE_P.asArrayType(), "byteArray"); + + System.out.println(w); + assertTrue(w.toString().contains("var byteArray: Array[Byte]")); + } + + @Test + public void Trait() throws IOException { + // trait MyTrait + writer.beginInterface(new SimpleType("MyTrait")); + writer.line("//"); + writer.end(); + + System.out.println(w); + assertTrue(w.toString().contains("trait MyTrait")); + } + + @Test + public void Field() throws IOException { + // private val people: List[Person] + writer.imports(List.class); + writer.beginClass(new SimpleType("Main")); + writer.privateFinal(new SimpleType(Types.LIST, new SimpleType("Person")), "people"); + writer.end(); + + System.out.println(w); + assertTrue(w.toString().contains("private val people: List[Person]")); + } + + @Test + public void Basic() throws IOException { + writer.packageDecl("com.querydsl.codegen.utils"); + writer.imports(IOException.class, StringWriter.class, Test.class); + writer.beginClass(testType); + writer.annotation(Test.class); + writer.beginPublicMethod(Types.VOID, "test"); + writer.line("// TODO"); + writer.end(); + writer.end(); + + System.out.println(w); + } + + @Test + public void Extends() throws IOException { + writer.beginClass(testType2, testSuperType); + writer.end(); + + System.out.println(w); + } + + @Test + public void Implements() throws IOException { + writer.beginClass(testType2, null, testInterface1, testInterface2); + writer.end(); + + System.out.println(w); + } + + @Test + public void Interface() throws IOException { + writer.packageDecl("com.querydsl.codegen.utils"); + writer.imports(IOException.class, StringWriter.class, Test.class); + writer.beginInterface(testType); + writer.end(); + + System.out.println(w); + } + + @Test + public void Interface2() throws IOException { + writer.beginInterface(testType2, testInterface1); + writer.end(); + + System.out.println(w); + } + + @Test + public void Javadoc() throws IOException { + writer.packageDecl("com.querydsl.codegen.utils"); + writer.imports(IOException.class, StringWriter.class, Test.class); + writer.javadoc("JavaWriterTest is a test class"); + writer.beginClass(testType); + writer.end(); + + System.out.println(w); + } + + @Test + public void AnnotationConstant() throws IOException { + Max annotation = new MaxImpl(0L) { + @Override + public Class[] groups() { + return new Class[] { Object.class, String.class, int.class }; + } + }; + writer.annotation(annotation); + + System.out.println(w); + } + + @Test + public void Annotation_With_ArrayMethod() throws IOException { + Target annotation = new Target() { + @Override + public ElementType[] value() { + return new ElementType[] { ElementType.FIELD, ElementType.METHOD }; + } + + @Override + public Class annotationType() { + return Target.class; + } + }; + + writer.imports(Target.class.getPackage()); + writer.annotation(annotation); + assertTrue(w.toString().contains("@Target(Array(FIELD, METHOD))")); + } + + @Test + public void Annotations() throws IOException { + writer.packageDecl("com.querydsl.codegen.utils"); + writer.imports(IOException.class, StringWriter.class); + writer.annotation(Entity.class); + writer.beginClass(testType); + writer.annotation(Test.class); + writer.beginPublicMethod(Types.VOID, "test"); + writer.end(); + writer.end(); + + System.out.println(w); + } + + @Test + public void Annotations2() throws IOException { + writer.packageDecl("com.querydsl.codegen.utils"); + writer.imports(IOException.class.getPackage(), StringWriter.class.getPackage()); + writer.annotation(Entity.class); + writer.beginClass(testType); + writer.annotation(new Test() { + @Override + public Class expected() { + // TODO Auto-generated method stub + return null; + } + + @Override + public long timeout() { + + return 0; + } + + @Override + public Class annotationType() { + return Test.class; + } + }); + writer.beginPublicMethod(Types.VOID, "test"); + writer.end(); + writer.end(); + + System.out.println(w); + } + + @Test + public void Fields() throws IOException { + writer.beginClass(testType); + // private + writer.privateField(Types.STRING, "privateField"); + writer.privateStaticFinal(Types.STRING, "privateStaticFinal", "\"val\""); + // protected + writer.protectedField(Types.STRING, "protectedField"); + // field + writer.field(Types.STRING, "field"); + // public + writer.publicField(Types.STRING, "publicField"); + writer.publicStaticFinal(Types.STRING, "publicStaticFinal", "\"val\""); + writer.publicFinal(Types.STRING, "publicFinalField"); + writer.publicFinal(Types.STRING, "publicFinalField2", "\"val\""); + + writer.end(); + + System.out.println(w); + } + + @Test + public void Methods() throws IOException { + writer.beginClass(testType); + // private + + // protected + + // method + + // public + writer.beginPublicMethod(Types.STRING, "publicMethod", + Arrays.asList(new Parameter("a", Types.STRING)), transformer); + writer.line("return null;"); + writer.end(); + + writer.beginStaticMethod(Types.STRING, "staticMethod", + Arrays.asList(new Parameter("a", Types.STRING)), transformer); + writer.line("return null;"); + writer.end(); + + writer.end(); + + System.out.println(w); + } + + @Test + public void Constructors() throws IOException { + writer.beginClass(testType); + + writer.beginConstructor( + Arrays.asList(new Parameter("a", Types.STRING), new Parameter("b", Types.STRING)), + transformer); + writer.end(); + + writer.beginConstructor(new Parameter("a", Types.STRING)); + writer.end(); + + writer.end(); + + System.out.println(w); + + } + + @Test + public void CaseClass() throws IOException { + writer.caseClass("TestType", new Parameter("a", Types.STRING), new Parameter("b", + Types.STRING)); + + System.out.println(w); + assertEquals("case class TestType(a: String, b: String)\n", w.toString()); + } + + @Test + public void ClassConstants() { + assertEquals("classOf[SomeClass]", writer.getClassConstant("SomeClass")); + } + + @Test + public void Primitive() throws IOException { + writer.beginClass(testType); + + writer.beginConstructor(new Parameter("a", Types.INT)); + writer.end(); + + writer.end(); + + System.out.println(w); + + assertTrue(w.toString().contains("def this(a: Int) {")); + } + + @Test + public void Primitive_Types() throws IOException { + writer.field(Types.BOOLEAN_P, "field"); + writer.field(Types.BYTE_P, "field"); + writer.field(Types.CHAR, "field"); + writer.field(Types.INT, "field"); + writer.field(Types.LONG_P, "field"); + writer.field(Types.SHORT_P, "field"); + writer.field(Types.DOUBLE_P, "field"); + writer.field(Types.FLOAT_P, "field"); + + for (String type : Arrays.asList("boolean", "byte", "char", "int", "long", "short", + "double", "float")) { + assertTrue(w.toString().contains("field: " + StringUtils.capitalize(type))); + } + } + + @Test + public void ReservedWords() throws IOException { + writer.beginClass(testType); + + writer.beginConstructor(new Parameter("type", Types.INT)); + writer.end(); + + writer.publicField(testType, "class"); + + writer.beginPublicMethod(testType, "var"); + writer.end(); + + writer.end(); + + System.out.println(w); + + assertTrue(w.toString().contains("`type`: Int")); + assertTrue(w.toString().contains("`class`: JavaWriterTest")); + assertTrue(w.toString().contains("`var`(): JavaWriterTest")); + } +} diff --git a/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/SimpleCompilerTest.java b/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/SimpleCompilerTest.java new file mode 100644 index 0000000000..38ccbe2d02 --- /dev/null +++ b/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/SimpleCompilerTest.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2010 Mysema Ltd. + * All rights reserved. + * + */ +package com.querydsl.codegen.utils; + +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.io.UnsupportedEncodingException; +import java.net.URL; +import java.net.URLClassLoader; +import java.net.URLDecoder; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import javax.tools.JavaCompiler; +import javax.tools.ToolProvider; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Ignore; +import org.junit.Test; + +public class SimpleCompilerTest { + + @After + public void tearDown() { + new File("src/test/java/com/querydsl/codegen/utils/SimpleCompilerTest.class").delete(); + } + + @Test + @Ignore + public void Run() throws UnsupportedEncodingException { + new File("target/out").mkdir(); + JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); + URLClassLoader classLoader = (URLClassLoader) Thread.currentThread().getContextClassLoader(); + + // create classpath + StringBuilder path = new StringBuilder(); + for (URL url : classLoader.getURLs()) { + if (path.length() > 0) { + path.append(File.pathSeparator); + } + String decodedPath = URLDecoder.decode(url.getPath(), "UTF-8"); + path.append(new File(decodedPath).getAbsolutePath()); + } + System.err.println(path); + + // compile + List options = Arrays.asList( + "-classpath", path.toString(), + "-s", "target/out", + "src/test/java/com/querydsl/codegen/utils/SimpleCompilerTest.java"); + int compilationResult = compiler.run(null, null, null, + options.toArray(new String[options.size()])); + if (compilationResult != 0) { + Assert.fail("Compilation Failed"); + } + } + + @Test + public void Run2() { + new File("target/out2").mkdir(); + JavaCompiler compiler = new SimpleCompiler(); + System.out.println(compiler.getClass().getName()); + List options = new ArrayList(3); + options.add("-s"); + options.add("target/out2"); + options.add("src/test/java/com/querydsl/codegen/utils/SimpleCompilerTest.java"); + int compilationResult = compiler.run(null, null, null, + options.toArray(new String[options.size()])); + if (compilationResult != 0) { + Assert.fail("Compilation Failed"); + } + } + + @Test + public void Surefire() { + URLClassLoader cl = (URLClassLoader) Thread.currentThread().getContextClassLoader(); + assertTrue(SimpleCompiler.isSureFireBooter(cl)); + } + + +} diff --git a/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/SurefireBooterTest.java b/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/SurefireBooterTest.java new file mode 100644 index 0000000000..d5cf4b0b4a --- /dev/null +++ b/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/SurefireBooterTest.java @@ -0,0 +1,25 @@ +package com.querydsl.codegen.utils; + +import java.io.IOException; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.jar.Manifest; + +import org.junit.Test; + +public class SurefireBooterTest { + + @Test + public void test() throws IOException { + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + if (classLoader instanceof URLClassLoader) { + URLClassLoader cl = (URLClassLoader) classLoader; + if (cl.getURLs().length == 1 && cl.getURLs()[0].getPath().contains("surefirebooter")) { + URL url = cl.findResource("META-INF/MANIFEST.MF"); + Manifest manifest = new Manifest(url.openStream()); + System.out.println(manifest.getMainAttributes().getValue("Class-Path")); + } + } + } + +} diff --git a/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/model/ClassTypeTest.java b/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/model/ClassTypeTest.java new file mode 100644 index 0000000000..c1e5554154 --- /dev/null +++ b/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/model/ClassTypeTest.java @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2010 Mysema Ltd. + * All rights reserved. + * + */ +package com.querydsl.codegen.utils.model; + +import static org.junit.Assert.*; + +import java.util.Collections; +import java.util.Map; + +import org.junit.Test; + +public class ClassTypeTest { + + public class Inner { + public class Inner2 { + public class Inner3 { + } + } + } + + private final ClassType stringType = new ClassType(TypeCategory.STRING, String.class); + + // @Test + // public void asArrayType(){ + // assertEquals(stringType, stringType.asArrayType().getParameter(0)); + // } + + @Test + public void InnerClass_Name() { + assertEquals("com.querydsl.codegen.utils.model.ClassTypeTest.Inner", + new ClassType(Inner.class).getFullName()); + assertEquals("com.querydsl.codegen.utils.model.ClassTypeTest.Inner[]", new ClassType(Inner.class) + .asArrayType().getFullName()); + } + + @Test + public void ArrayType() { + Type type = new ClassType(TypeCategory.ARRAY, String[].class); + assertEquals("java.lang", type.getPackageName()); + } + + @Test + public void ArrayType_Equals_SimpleType() { + Type type = new ClassType(TypeCategory.ARRAY, String[].class); + Type type2 = new SimpleType("java.lang.String[]", "java.lang", "String[]"); + assertEquals(type, type2); + } + + @Test + public void As() { + assertEquals(TypeCategory.COMPARABLE, stringType.as(TypeCategory.COMPARABLE).getCategory()); + } + + @Test + public void GetParameters() { + ClassType mapType = new ClassType(TypeCategory.MAP, Map.class, stringType, stringType); + assertEquals(2, mapType.getParameters().size()); + assertEquals(stringType, mapType.getParameters().get(0)); + assertEquals(stringType, mapType.getParameters().get(1)); + // assertEquals(stringType, mapType.getSelfOrValueType()); + assertFalse(mapType.isPrimitive()); + } + + @Test + public void GetComponentType() { + assertEquals("java.lang.String", new ClassType(String[].class).getComponentType() + .getFullName()); + } + + @Test + public void Primitive_Arrays() { + ClassType byteArray = new ClassType(byte[].class); + assertEquals( + "byte[]", + byteArray.getRawName(Collections.singleton("java.lang"), + Collections. emptySet())); + assertEquals("byte[]", byteArray.getSimpleName()); + assertEquals("byte[]", byteArray.getFullName()); + } + + @Test + public void Array() { + ClassType byteArray = new ClassType(Byte[].class); + assertEquals( + "Byte[]", + byteArray.getRawName(Collections.singleton("java.lang"), + Collections. emptySet())); + assertEquals("Byte[]", byteArray.getSimpleName()); + assertEquals("java.lang.Byte[]", byteArray.getFullName()); + } + + @Test + public void IsPrimitive() { + assertTrue(Types.CHAR.isPrimitive()); + assertTrue(Types.DOUBLE_P.isPrimitive()); + assertTrue(Types.FLOAT_P.isPrimitive()); + assertTrue(Types.INT.isPrimitive()); + assertTrue(Types.LONG_P.isPrimitive()); + assertTrue(Types.SHORT_P.isPrimitive()); + } + +// @Test +// public void GetPrimitiveName() { +// assertEquals("char", Types.CHARACTER.getPrimitiveName()); +// assertEquals("double", Types.DOUBLE.getPrimitiveName()); +// assertEquals("float", Types.FLOAT.getPrimitiveName()); +// assertEquals("int", Types.INTEGER.getPrimitiveName()); +// assertEquals("long", Types.LONG.getPrimitiveName()); +// assertEquals("short", Types.SHORT.getPrimitiveName()); +// } + + @Test + public void GetEnclosingType() { + Type outer = new ClassType(ClassTypeTest.class); + Type inner = new ClassType(ClassTypeTest.Inner.class); + Type inner2 = new ClassType(ClassTypeTest.Inner.Inner2.class); + Type inner3 = new ClassType(ClassTypeTest.Inner.Inner2.Inner3.class); + + assertEquals(inner2, inner3.getEnclosingType()); + assertEquals(inner, inner2.getEnclosingType()); + assertEquals(outer, inner.getEnclosingType()); + assertNull(outer.getEnclosingType()); + + assertEquals("ClassTypeTest.Inner.Inner2.Inner3", + inner3.getRawName(Collections.singleton(outer.getPackageName()), Collections.emptySet())); + assertEquals("Inner2.Inner3", + inner3.getRawName(Collections.emptySet(), Collections.singleton(inner2.getFullName()))); + assertEquals("Inner3", + inner3.getRawName(Collections.emptySet(), Collections.singleton(inner3.getFullName()))); + } +} diff --git a/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/model/ConstructorTest.java b/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/model/ConstructorTest.java new file mode 100644 index 0000000000..95c819ae10 --- /dev/null +++ b/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/model/ConstructorTest.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2010 Mysema Ltd. + * All rights reserved. + * + */ +package com.querydsl.codegen.utils.model; + +import static org.junit.Assert.assertEquals; + +import java.util.Arrays; + +import org.junit.Test; + +public class ConstructorTest { + + @Test + public void test() { + Parameter firstName = new Parameter("firstName", new ClassType(TypeCategory.STRING, + String.class)); + Parameter lastName = new Parameter("lastName", new ClassType(TypeCategory.STRING, + String.class)); + Constructor c1 = new Constructor(Arrays.asList(firstName, lastName)); + Constructor c2 = new Constructor(Arrays.asList(firstName, lastName)); + assertEquals(c1, c1); + assertEquals(c1, c2); + assertEquals(c1.hashCode(), c2.hashCode()); + } + +} diff --git a/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/model/ParameterTest.java b/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/model/ParameterTest.java new file mode 100644 index 0000000000..265adac9c4 --- /dev/null +++ b/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/model/ParameterTest.java @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2010 Mysema Ltd. + * All rights reserved. + * + */ +package com.querydsl.codegen.utils.model; + +import static org.junit.Assert.assertFalse; + +import org.junit.Test; + +public class ParameterTest { + + @Test + public void test() { + Parameter param1 = new Parameter("test", new ClassType(TypeCategory.STRING, String.class)); + Parameter param2 = new Parameter("test2", new ClassType(TypeCategory.STRING, String.class)); + Parameter param3 = new Parameter("test2", + new ClassType(TypeCategory.NUMERIC, Integer.class)); + + assertFalse(param1.equals(param2)); + assertFalse(param1.equals(param3)); + assertFalse(param2.equals(param3)); + } + +} diff --git a/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/model/SimpleTypeTest.java b/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/model/SimpleTypeTest.java new file mode 100644 index 0000000000..fb9c838ca3 --- /dev/null +++ b/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/model/SimpleTypeTest.java @@ -0,0 +1,97 @@ +package com.querydsl.codegen.utils.model; + +import static org.junit.Assert.*; + +import java.util.Collections; + +import org.junit.Test; + +public class SimpleTypeTest { + + public static class Inner { + public class Inner2 { + public class Inner3 { + } + } + } + + @Test + public void PrimitiveArray() { + Type byteArray = new ClassType(byte[].class); + Type byteArray2 = new SimpleType(byteArray, byteArray.getParameters()); + assertEquals( + "byte[]", + byteArray.getRawName(Collections.singleton("java.lang"), + Collections. emptySet())); + assertEquals( + "byte[]", + byteArray2.getRawName(Collections.singleton("java.lang"), + Collections. emptySet())); + } + + @Test + public void Array_FullName() { + Type type = new SimpleType(new ClassType(String[].class)); + assertEquals("java.lang.String[]", type.getFullName()); + } + + @Test + public void GetComponentType() { + Type type = new SimpleType(new ClassType(String[].class)); + assertEquals("java.lang.String", type.getComponentType().getFullName()); + } + + @Test + public void GetRawName() { + assertEquals("String", new SimpleType(Types.STRING).getRawName( + Collections. emptySet(), Collections.singleton(Types.STRING.getFullName()))); + } + + @Test + public void GetJavaClass_For_Array() { + System.out.println(Inner.class.getName()); + assertEquals(byte[].class, new ClassType(byte[].class).getJavaClass()); + assertEquals(byte[].class, new SimpleType(new ClassType(byte[].class)).getJavaClass()); + } + + @Test + public void GetJavaClass_For_InnerClass() { + assertEquals(Inner.class, new ClassType(Inner.class).getJavaClass()); + assertEquals(Inner.class, new SimpleType(new ClassType(Inner.class)).getJavaClass()); + } + +// @Test +// public void GetPrimitiveName() { +// assertEquals("int", Types.INT.getPrimitiveName()); +// assertEquals("int", new SimpleType(Types.INT).getPrimitiveName()); +// +// assertEquals("int", Types.INTEGER.getPrimitiveName()); +// assertEquals("int", new SimpleType(Types.INTEGER).getPrimitiveName()); +// } + + @Test + public void GetEnclosingType() { + Type outer = new SimpleType(new ClassType(SimpleTypeTest.class)); + Type inner = new SimpleType(new ClassType(SimpleTypeTest.Inner.class)); + Type inner2 = new SimpleType(new ClassType(SimpleTypeTest.Inner.Inner2.class)); + Type inner3 = new SimpleType(new ClassType(SimpleTypeTest.Inner.Inner2.Inner3.class)); + + assertEquals(inner2, inner3.getEnclosingType()); + assertEquals(inner, inner2.getEnclosingType()); + assertEquals(outer, inner.getEnclosingType()); + assertNull(outer.getEnclosingType()); + + assertEquals("SimpleTypeTest.Inner.Inner2.Inner3", + inner3.getRawName(Collections.singleton(outer.getPackageName()), Collections.emptySet())); + assertEquals("Inner2.Inner3", + inner3.getRawName(Collections.emptySet(), Collections.singleton(inner2.getFullName()))); + assertEquals("Inner3", + inner3.getRawName(Collections.emptySet(), Collections.singleton(inner3.getFullName()))); + } + @Test + public void IsMember() { + assertTrue(new SimpleType(new ClassType(SimpleTypeTest.Inner.class)).isMember()); + assertFalse(new SimpleType(new ClassType(SimpleType.class)).isMember()); + } + +} diff --git a/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/model/TypeAdapterTest.java b/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/model/TypeAdapterTest.java new file mode 100644 index 0000000000..b0b5b2e992 --- /dev/null +++ b/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/model/TypeAdapterTest.java @@ -0,0 +1,24 @@ +package com.querydsl.codegen.utils.model; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +public class TypeAdapterTest { + + @Test + public void Delegation() { + Type inner = Types.OBJECT; + Type type = new TypeAdapter(inner); + assertEquals(inner.getCategory(), type.getCategory()); + assertEquals(inner.getComponentType(), type.getComponentType()); + assertEquals(inner.getFullName(), type.getFullName()); + assertEquals(inner.getGenericName(true), type.getGenericName(true)); + assertEquals(inner.getPackageName(), type.getPackageName()); + assertEquals(inner.getParameters(), type.getParameters()); +// assertEquals(inner.getPrimitiveName(), type.getPrimitiveName()); + assertEquals(inner.getSimpleName(), type.getSimpleName()); + assertEquals(inner.isFinal(), type.isFinal()); + assertEquals(inner.isPrimitive(), type.isPrimitive()); + } +} diff --git a/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/model/TypeCategoryTest.java b/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/model/TypeCategoryTest.java new file mode 100644 index 0000000000..f141dd63a3 --- /dev/null +++ b/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/model/TypeCategoryTest.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2010 Mysema Ltd. + * All rights reserved. + * + */ +package com.querydsl.codegen.utils.model; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.sql.Date; +import java.sql.Time; + +import org.junit.Test; + +public class TypeCategoryTest { + + @Test + public void IsSubCategoryOf() { + assertTrue(TypeCategory.BOOLEAN.isSubCategoryOf(TypeCategory.COMPARABLE)); + assertTrue(TypeCategory.STRING.isSubCategoryOf(TypeCategory.COMPARABLE)); + assertTrue(TypeCategory.NUMERIC.isSubCategoryOf(TypeCategory.COMPARABLE)); + assertTrue(TypeCategory.COMPARABLE.isSubCategoryOf(TypeCategory.SIMPLE)); + assertFalse(TypeCategory.ENTITY.isSubCategoryOf(TypeCategory.SIMPLE)); + } + + @Test + public void Get() { + assertEquals(TypeCategory.BOOLEAN, TypeCategory.get(Boolean.class.getName())); + assertEquals(TypeCategory.STRING, TypeCategory.get(String.class.getName())); + assertEquals(TypeCategory.DATE, TypeCategory.get(Date.class.getName())); + assertEquals(TypeCategory.TIME, TypeCategory.get(Time.class.getName())); + } + + @Test + public void Java8() { + assertEquals(TypeCategory.DATETIME, TypeCategory.get("java.time.Instant")); + assertEquals(TypeCategory.DATE, TypeCategory.get("java.time.LocalDate")); + assertEquals(TypeCategory.DATETIME, TypeCategory.get("java.time.LocalDateTime")); + assertEquals(TypeCategory.TIME, TypeCategory.get("java.time.LocalTime")); + assertEquals(TypeCategory.DATETIME, TypeCategory.get("java.time.OffsetDateTime")); + assertEquals(TypeCategory.TIME, TypeCategory.get("java.time.OffsetTime")); + assertEquals(TypeCategory.DATETIME, TypeCategory.get("java.time.ZonedDateTime")); + } + +} diff --git a/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/model/TypeExtendsTest.java b/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/model/TypeExtendsTest.java new file mode 100644 index 0000000000..e0b1621b61 --- /dev/null +++ b/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/model/TypeExtendsTest.java @@ -0,0 +1,31 @@ +package com.querydsl.codegen.utils.model; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +public class TypeExtendsTest { + + @Test + public void GetVarName() { + assertEquals("var", new TypeExtends("var", Types.COLLECTION).getVarName()); + } + + @Test + public void GetGenericName() { + assertEquals("? extends java.util.Collection", new TypeExtends( + Types.COLLECTION).getGenericName(false)); + } + + @Test + public void GetGenericName_As_ArgType() { + assertEquals("java.util.Collection", + new TypeExtends(Types.COLLECTION).getGenericName(true)); + } + + @Test + public void GetGenericName_With_Object() { + assertEquals("?", new TypeExtends(Types.OBJECT).getGenericName(false)); + } + +} diff --git a/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/model/TypeSuperTest.java b/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/model/TypeSuperTest.java new file mode 100644 index 0000000000..95ddee3fcd --- /dev/null +++ b/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/model/TypeSuperTest.java @@ -0,0 +1,33 @@ +package com.querydsl.codegen.utils.model; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +public class TypeSuperTest { + + @Test + public void GetVarName() { + assertEquals("var", new TypeSuper("var", Types.STRING).getVarName()); + } + + @Test + public void GetGenericName() { + assertEquals("? super java.lang.String", new TypeSuper(Types.STRING).getGenericName(false)); + } + + @Test + public void GetGenericName_As_ArgType() { + assertEquals("java.lang.Object", new TypeSuper(Types.STRING).getGenericName(true)); + } + + @Test + public void Comparable() { + // T extends Comparable + Type comparable = new ClassType(Comparable.class); + Type type = new TypeExtends("T", + new SimpleType(comparable, new TypeSuper(new TypeExtends("T", comparable)))); + assertEquals("? extends java.lang.Comparable", type.getGenericName(false)); + } + +} diff --git a/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/model/TypeTest.java b/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/model/TypeTest.java new file mode 100644 index 0000000000..e3e6ab60b2 --- /dev/null +++ b/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/model/TypeTest.java @@ -0,0 +1,188 @@ +/* + * Copyright (c) 2010 Mysema Ltd. + * All rights reserved. + * + */ +package com.querydsl.codegen.utils.model; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.util.Collections; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Set; + +import org.junit.Test; + +public class TypeTest { + + private Set packages = Collections.singleton("java.lang"); + + private Set classes = Collections.emptySet(); + + private ClassType locale = new ClassType(TypeCategory.SIMPLE, Locale.class); + + private Type string = Types.STRING; + + private Type string2 = new SimpleType(string); + + private Type locale2 = new SimpleType(locale); + + private Type stringList = new ClassType(TypeCategory.LIST, List.class, Types.STRING); + + private Type stringList2 = new SimpleType(Types.LIST, Types.STRING); + + private Type stringMap = new ClassType(TypeCategory.MAP, Map.class, Types.STRING, Types.STRING); + + private Type stringMap2 = new SimpleType(Types.MAP, Types.STRING, Types.STRING); + + @Test + public void arrayType() { + assertEquals("Object[]", Types.OBJECTS.getGenericName(true).toString()); + } + + @Test + public void Equals() { + assertEquals(locale, locale2); + assertEquals(locale2, locale); + assertEquals(stringList, stringList2); + assertEquals(stringList2, stringList); + } + + @Test + public void Hashcode() { + assertEquals(locale.hashCode(), locale2.hashCode()); + assertEquals(stringList.hashCode(), stringList2.hashCode()); + } + + @Test + public void GetGenericNameBoolean() { + assertEquals("java.util.Locale", locale.getGenericName(true)); + assertEquals("java.util.Locale", locale2.getGenericName(true)); + assertEquals("java.util.List", stringList.getGenericName(true)); + assertEquals("java.util.List", stringList2.getGenericName(true)); + assertEquals("java.util.Map", stringMap.getGenericName(true)); + assertEquals("java.util.Map", stringMap2.getGenericName(true)); + + assertEquals("String", string.getGenericName(true)); + assertEquals("String", string2.getGenericName(true)); + } + + @Test + public void GetRawName() { + assertEquals("java.util.Locale", locale.getRawName(packages, classes)); + assertEquals("java.util.Locale", locale2.getRawName(packages, classes)); + assertEquals("java.util.List", stringList.getRawName(packages, classes)); + assertEquals("java.util.List", stringList2.getRawName(packages, classes)); + + assertEquals("String", string.getRawName(packages, classes)); + assertEquals("String", string2.getRawName(packages, classes)); + } + + @Test + public void GetGenericNameBooleanSetOfStringSetOfString() { + assertEquals("java.util.Locale", locale.getGenericName(true, packages, classes)); + assertEquals("java.util.Locale", locale2.getGenericName(true, packages, classes)); + assertEquals("java.util.List", stringList.getGenericName(true, packages, classes)); + assertEquals("java.util.List", stringList2.getGenericName(true, packages, classes)); + } + + @Test + public void GetFullName() { + assertEquals("java.util.Locale", locale.getFullName()); + assertEquals("java.util.Locale", locale2.getFullName()); + assertEquals("java.util.List", stringList.getFullName()); + assertEquals("java.util.List", stringList2.getFullName()); + } + + @Test + public void GetPackageName() { + assertEquals("java.util", locale.getPackageName()); + assertEquals("java.util", locale2.getPackageName()); + assertEquals("java.util", stringList.getPackageName()); + assertEquals("java.util", stringList2.getPackageName()); + } + + @Test + public void GetParameters() { + assertEquals(Collections.emptyList(), locale.getParameters()); + assertEquals(Collections.emptyList(), locale2.getParameters()); + assertEquals(Collections.singletonList(Types.STRING), stringList.getParameters()); + assertEquals(Collections.singletonList(Types.STRING), stringList2.getParameters()); + } + + @Test + public void GetSimpleName() { + assertEquals("Locale", locale.getSimpleName()); + assertEquals("Locale", locale2.getSimpleName()); + assertEquals("List", stringList.getSimpleName()); + assertEquals("List", stringList2.getSimpleName()); + } + + @Test + public void GetJavaClass() { + assertEquals(Locale.class, locale.getJavaClass()); + } + + @Test + public void IsFinal() { + assertTrue(locale.isFinal()); + assertTrue(locale2.isFinal()); + assertFalse(stringList.isFinal()); + + assertTrue(Types.STRING.isFinal()); + assertTrue(Types.LONG.isFinal()); + } + + @Test + public void IsPrimitive() { + assertFalse(locale.isPrimitive()); + assertFalse(locale2.isPrimitive()); + assertFalse(stringList.isPrimitive()); + assertFalse(stringList2.isPrimitive()); + } + + @Test + public void GetCategory() { + assertEquals(TypeCategory.SIMPLE, locale.getCategory()); + assertEquals(TypeCategory.SIMPLE, locale2.getCategory()); + assertEquals(TypeCategory.LIST, stringList.getCategory()); + assertEquals(TypeCategory.LIST, stringList2.getCategory()); + } + + @Test + public void As() { + assertEquals(TypeCategory.SIMPLE, stringList.as(TypeCategory.SIMPLE).getCategory()); + assertEquals(TypeCategory.SIMPLE, stringList2.as(TypeCategory.SIMPLE).getCategory()); + } + +// @Test +// public void GetPrimitiveName() { +// assertNull(locale.getPrimitiveName()); +// assertNull(locale2.getPrimitiveName()); +// assertNull(stringList.getPrimitiveName()); +// assertNull(stringList2.getPrimitiveName()); +// } + + @Test + public void ToString() { + assertEquals("java.util.Locale", locale.toString()); + assertEquals("java.util.Locale", locale2.toString()); + assertEquals("java.util.List", stringList.toString()); + assertEquals("java.util.List", stringList2.toString()); + } + + @Test + public void AsArrayType() { + assertEquals("java.util.Locale[]", locale.asArrayType().getFullName()); + assertEquals(TypeCategory.ARRAY, locale.asArrayType().getCategory()); + assertEquals("java.util.Locale[]", locale2.asArrayType().getFullName()); + assertEquals(TypeCategory.ARRAY, locale2.asArrayType().getCategory()); + assertEquals("java.util.List[]", stringList.asArrayType().getFullName()); + assertEquals("java.util.List[]", stringList2.asArrayType().getFullName()); + } + +} diff --git a/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/support/Cat.java b/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/support/Cat.java new file mode 100644 index 0000000000..853acc0aec --- /dev/null +++ b/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/support/Cat.java @@ -0,0 +1,159 @@ +/* + * Copyright 2011, Mysema Ltd + * + * 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. + */ +package com.querydsl.codegen.utils.support; + +import java.util.Arrays; +import java.util.Collections; +import java.util.Date; +import java.util.List; +import java.util.Map; + +public class Cat { + + private int breed; + + private java.sql.Date dateField; + + public enum Color { + BLUE, GREEN, BROWN + } + private Color eyecolor; + + private List kittens; + + private Cat[] kittenArray; + + private Map kittensByName; + + private Cat mate; + + private String stringAsSimple; + + private java.sql.Time timeField; + + private String name; + + public void setName(String name) { + this.name = name; + } + + private Date birthdate; + private int id; + + public Cat() { + this.kittensByName = Collections.emptyMap(); + } + + public Cat(String name) { + Cat kitten = new Cat(); + this.kittens = Arrays.asList(kitten); + this.kittenArray = new Cat[]{kitten}; + this.kittensByName = Collections.singletonMap("Kitty", kitten); + this.name = name; + } + + public Cat(String name, String kittenName) { + this(name); + kittens.get(0).setName(kittenName); + } + + public Cat(String name, int id) { + this(name); + this.id = id; + } + + public Cat(String name, int id, Date birthdate) { + this(name, id); + this.birthdate = new Date(birthdate.getTime()); + this.dateField = new java.sql.Date(birthdate.getTime()); + this.timeField = new java.sql.Time(birthdate.getTime()); + } + + public int getBreed() { + return breed; + } + + public java.sql.Date getDateField() { + return dateField; + } + + public Color getEyecolor() { + return eyecolor; + } + + public List getKittens() { + return kittens; + } + + public Map getKittensByName() { + return kittensByName; + } + + public Cat getMate() { + return mate; + } + + public String getStringAsSimple() { + return stringAsSimple; + } + + public java.sql.Time getTimeField() { + return timeField; + } + + public void setBreed(int breed) { + this.breed = breed; + } + + public void setDateField(java.sql.Date dateField) { + this.dateField = new java.sql.Date(dateField.getTime()); + } + + public void setEyecolor(Color eyecolor) { + this.eyecolor = eyecolor; + } + + public void setKittens(List kittens) { + this.kittens = kittens; + } + + public void setKittensByName(Map kittensByName) { + this.kittensByName = kittensByName; + } + + public void setMate(Cat mate) { + this.mate = mate; + } + + public void setStringAsSimple(String stringAsSimple) { + this.stringAsSimple = stringAsSimple; + } + + public void setTimeField(java.sql.Time timeField) { + this.timeField = timeField; + } + + public Cat[] getKittenArray() { + return kittenArray; + } + + public void setKittenArray(Cat[] kittenArray) { + this.kittenArray = kittenArray.clone(); + } + + public String toString() { + return name; + } + +} diff --git a/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/support/ClassUtilsTest.java b/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/support/ClassUtilsTest.java new file mode 100644 index 0000000000..c9a847ec12 --- /dev/null +++ b/querydsl-codegen-utils/src/test/java/com/querydsl/codegen/utils/support/ClassUtilsTest.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2010 Mysema Ltd. + * All rights reserved. + * + */ +package com.querydsl.codegen.utils.support; + +import static org.junit.Assert.assertEquals; + +import java.util.*; + +import org.junit.Test; +public class ClassUtilsTest { + + @Test + public void GetName() { + assertEquals("int", ClassUtils.getName(int.class)); + assertEquals("int", ClassUtils.getName(int.class, Collections. emptySet(), + Collections. emptySet())); + assertEquals("Object", ClassUtils.getName(Object.class)); + assertEquals("Object[]", ClassUtils.getName(Object[].class)); + assertEquals("int", ClassUtils.getName(int.class)); + assertEquals("int[]", ClassUtils.getName(int[].class)); + assertEquals("void", ClassUtils.getName(void.class)); + assertEquals("java.util.Locale", ClassUtils.getName(Locale.class)); + assertEquals("java.util.Locale[]", ClassUtils.getName(Locale[].class)); + } + + @Test + public void GetName_Packge() { + assertEquals("Locale", ClassUtils.getName(Locale.class, + Collections.singleton("java.util"), Collections.emptySet())); + assertEquals("java.util.Locale", ClassUtils.getName(Locale.class, + Collections.singleton("java.util.gen"), Collections.emptySet())); + } + + @Test + public void Normalize() { + assertEquals(List.class, ClassUtils.normalize(ArrayList.class)); + assertEquals(Set.class, ClassUtils.normalize(HashSet.class)); + assertEquals(Map.class, ClassUtils.normalize(HashMap.class)); +// assertEquals(Collection.class, ClassUtils.normalize(Bag.class)); + } + +} diff --git a/querydsl-codegen-utils/src/test/resources/testAnnotations b/querydsl-codegen-utils/src/test/resources/testAnnotations new file mode 100644 index 0000000000..40e5682067 --- /dev/null +++ b/querydsl-codegen-utils/src/test/resources/testAnnotations @@ -0,0 +1,13 @@ +package com.querydsl.codegen.utils; + +import java.io.IOException; +import java.io.StringWriter; + +@Entity +public class JavaWriterTest { + + @org.junit.Test + public void test() { + } + +} \ No newline at end of file diff --git a/querydsl-codegen-utils/src/test/resources/testAnnotations2 b/querydsl-codegen-utils/src/test/resources/testAnnotations2 new file mode 100644 index 0000000000..2082dd3fe9 --- /dev/null +++ b/querydsl-codegen-utils/src/test/resources/testAnnotations2 @@ -0,0 +1,13 @@ +package com.querydsl.codegen.utils; + +import java.io.*; +import java.io.*; + +@Entity +public class JavaWriterTest { + + @org.junit.Test + public void test() { + } + +} \ No newline at end of file diff --git a/querydsl-codegen-utils/src/test/resources/testBasic b/querydsl-codegen-utils/src/test/resources/testBasic new file mode 100644 index 0000000000..9f9656a21f --- /dev/null +++ b/querydsl-codegen-utils/src/test/resources/testBasic @@ -0,0 +1,14 @@ +package com.querydsl.codegen.utils; + +import java.io.IOException; +import java.io.StringWriter; +import org.junit.Test; + +public class JavaWriterTest { + + @Test + public void test() { + // TODO + } + +} \ No newline at end of file diff --git a/querydsl-codegen-utils/src/test/resources/testConstructors b/querydsl-codegen-utils/src/test/resources/testConstructors new file mode 100644 index 0000000000..ded6f3dfe3 --- /dev/null +++ b/querydsl-codegen-utils/src/test/resources/testConstructors @@ -0,0 +1,9 @@ +public class JavaWriterTest { + + public JavaWriterTest(String a, String b) { + } + + public JavaWriterTest(String a) { + } + +} \ No newline at end of file diff --git a/querydsl-codegen-utils/src/test/resources/testExtends b/querydsl-codegen-utils/src/test/resources/testExtends new file mode 100644 index 0000000000..d2a98860a4 --- /dev/null +++ b/querydsl-codegen-utils/src/test/resources/testExtends @@ -0,0 +1,3 @@ +public class Test extends Superclass { + +} \ No newline at end of file diff --git a/querydsl-codegen-utils/src/test/resources/testFields b/querydsl-codegen-utils/src/test/resources/testFields new file mode 100644 index 0000000000..ef17ae75e3 --- /dev/null +++ b/querydsl-codegen-utils/src/test/resources/testFields @@ -0,0 +1,19 @@ +public class JavaWriterTest { + + private String privateField; + + private static final String privateStaticFinal = "val"; + + protected String protectedField; + + String field; + + public String publicField; + + public static final String publicStaticFinal = "val"; + + public final String publicFinalField; + + public final String publicFinalField2 = "val"; + +} \ No newline at end of file diff --git a/querydsl-codegen-utils/src/test/resources/testImplements b/querydsl-codegen-utils/src/test/resources/testImplements new file mode 100644 index 0000000000..f85cf9519d --- /dev/null +++ b/querydsl-codegen-utils/src/test/resources/testImplements @@ -0,0 +1,3 @@ +public class Test implements TestInterface1, TestInterface2 { + +} \ No newline at end of file diff --git a/querydsl-codegen-utils/src/test/resources/testImports b/querydsl-codegen-utils/src/test/resources/testImports new file mode 100644 index 0000000000..788beac7e4 --- /dev/null +++ b/querydsl-codegen-utils/src/test/resources/testImports @@ -0,0 +1 @@ +import static java.util.Arrays.*; \ No newline at end of file diff --git a/querydsl-codegen-utils/src/test/resources/testImports2 b/querydsl-codegen-utils/src/test/resources/testImports2 new file mode 100644 index 0000000000..9779566dd2 --- /dev/null +++ b/querydsl-codegen-utils/src/test/resources/testImports2 @@ -0,0 +1,2 @@ +import java.lang.reflect.*; +import java.util.*; \ No newline at end of file diff --git a/querydsl-codegen-utils/src/test/resources/testInnerClasses b/querydsl-codegen-utils/src/test/resources/testInnerClasses new file mode 100644 index 0000000000..0a0651554d --- /dev/null +++ b/querydsl-codegen-utils/src/test/resources/testInnerClasses @@ -0,0 +1,10 @@ +public class JavaWriterTest { + + public class Test { + + } + + public JavaWriterTest(String a) { + } + +} \ No newline at end of file diff --git a/querydsl-codegen-utils/src/test/resources/testInterface b/querydsl-codegen-utils/src/test/resources/testInterface new file mode 100644 index 0000000000..ecb168c5aa --- /dev/null +++ b/querydsl-codegen-utils/src/test/resources/testInterface @@ -0,0 +1,9 @@ +package com.querydsl.codegen.utils; + +import java.io.IOException; +import java.io.StringWriter; +import org.junit.Test; + +public interface JavaWriterTest { + +} \ No newline at end of file diff --git a/querydsl-codegen-utils/src/test/resources/testInterface2 b/querydsl-codegen-utils/src/test/resources/testInterface2 new file mode 100644 index 0000000000..72e4517ad4 --- /dev/null +++ b/querydsl-codegen-utils/src/test/resources/testInterface2 @@ -0,0 +1,3 @@ +public interface Test extends TestInterface1 { + +} \ No newline at end of file diff --git a/querydsl-codegen-utils/src/test/resources/testJavadoc b/querydsl-codegen-utils/src/test/resources/testJavadoc new file mode 100644 index 0000000000..684cdaa51d --- /dev/null +++ b/querydsl-codegen-utils/src/test/resources/testJavadoc @@ -0,0 +1,12 @@ +package com.querydsl.codegen.utils; + +import java.io.IOException; +import java.io.StringWriter; +import org.junit.Test; + +/** + * JavaWriterTest is a test class + */ +public class JavaWriterTest { + +} \ No newline at end of file diff --git a/querydsl-codegen-utils/src/test/resources/testMethods b/querydsl-codegen-utils/src/test/resources/testMethods new file mode 100644 index 0000000000..7f13cb4d76 --- /dev/null +++ b/querydsl-codegen-utils/src/test/resources/testMethods @@ -0,0 +1,11 @@ +public class JavaWriterTest { + + public String publicMethod(String a) { + return null; + } + + public static String staticMethod(String a) { + return null; + } + +} \ No newline at end of file diff --git a/querydsl-codegen-utils/src/test/resources/testSuppressWarnings b/querydsl-codegen-utils/src/test/resources/testSuppressWarnings new file mode 100644 index 0000000000..f8902e4aa7 --- /dev/null +++ b/querydsl-codegen-utils/src/test/resources/testSuppressWarnings @@ -0,0 +1,2 @@ +@SuppressWarnings("unused") +private String test; \ No newline at end of file diff --git a/querydsl-codegen-utils/src/test/resources/testSuppressWarnings2 b/querydsl-codegen-utils/src/test/resources/testSuppressWarnings2 new file mode 100644 index 0000000000..cd9e88ce05 --- /dev/null +++ b/querydsl-codegen-utils/src/test/resources/testSuppressWarnings2 @@ -0,0 +1,2 @@ +@SuppressWarnings({"all", "unused"}) +private String test; diff --git a/querydsl-codegen/pom.xml b/querydsl-codegen/pom.xml index de1745e403..e334caf605 100644 --- a/querydsl-codegen/pom.xml +++ b/querydsl-codegen/pom.xml @@ -1,15 +1,15 @@ - + 4.0.0 - com.mysema.querydsl + com.querydsl querydsl-root - 3.4.1.BUILD-SNAPSHOT - ../querydsl-root/pom.xml + 5.1.0 + ../pom.xml - com.mysema.querydsl + com.querydsl querydsl-codegen Querydsl - Codegen module codegen module for querydsl @@ -24,25 +24,34 @@ - com.mysema.querydsl + com.querydsl querydsl-core ${project.version} - + - com.mysema.codegen - codegen - ${codegen.version} - - - - javax.inject - javax.inject - 1 + org.jetbrains + annotations + provided + + + com.querydsl + codegen-utils + ${project.version} + + + javax.inject + javax.inject + 1 + + + io.github.classgraph + classgraph + compile - com.mysema.querydsl + com.querydsl querydsl-core ${project.version} test @@ -54,8 +63,8 @@ - com.springsource.bundlor - com.springsource.bundlor.maven + org.apache.felix + maven-bundle-plugin org.apache.maven.plugins @@ -68,6 +77,13 @@ + + + + com.querydsl.codegen + + + maven-source-plugin @@ -83,4 +99,20 @@ - + + + java-11 + + [11,) + + + + javax.annotation + javax.annotation-api + 1.3.2 + provided + + + + + diff --git a/querydsl-codegen/src/main/java/com/mysema/query/codegen/BeanSerializer.java b/querydsl-codegen/src/main/java/com/mysema/query/codegen/BeanSerializer.java deleted file mode 100644 index b5baff4e45..0000000000 --- a/querydsl-codegen/src/main/java/com/mysema/query/codegen/BeanSerializer.java +++ /dev/null @@ -1,262 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.codegen; - -import javax.annotation.Generated; -import java.io.IOException; -import java.lang.annotation.Annotation; -import java.util.*; - -import com.google.common.base.Function; -import com.google.common.collect.Lists; -import com.mysema.codegen.CodeWriter; -import com.mysema.codegen.model.*; -import com.mysema.util.BeanUtils; - -/** - * BeanSerializer is a {@link Serializer} implementation which serializes {@link EntityType} - * instances into JavaBean classes - * - * @author tiwe - * - */ -public class BeanSerializer implements Serializer{ - - private static final Function propertyToParameter = new Function() { - @Override - public Parameter apply(Property input) { - return new Parameter(input.getName(), input.getType()); - } - }; - - private final boolean propertyAnnotations; - - private final List interfaces = Lists.newArrayList(); - - private final String javadocSuffix; - - private boolean addToString, addFullConstructor; - - private boolean printSupertype = false; - - /** - * Create a new BeanSerializer - */ - public BeanSerializer() { - this(true, " is a Querydsl bean type"); - } - - /** - * Create a new BeanSerializer with the given javadoc suffix - * - * @param javadocSuffix - */ - public BeanSerializer(String javadocSuffix) { - this(true, javadocSuffix); - } - - /** - * Create a new BeanSerializer - * - * @param propertyAnnotations - */ - public BeanSerializer(boolean propertyAnnotations) { - this(propertyAnnotations, " is a Querydsl bean type"); - } - - /** - * Create a new BeanSerializer - * - * @param propertyAnnotations - * @param javadocSuffix - */ - public BeanSerializer(boolean propertyAnnotations, String javadocSuffix) { - this.propertyAnnotations = propertyAnnotations; - this.javadocSuffix = javadocSuffix; - } - - @Override - public void serialize(EntityType model, SerializerConfig serializerConfig, - CodeWriter writer) throws IOException { - String simpleName = model.getSimpleName(); - - // package - if (!model.getPackageName().isEmpty()) { - writer.packageDecl(model.getPackageName()); - } - - // imports - Set importedClasses = getAnnotationTypes(model); - for (Type iface : interfaces) { - importedClasses.add(iface.getFullName()); - } - importedClasses.add(Generated.class.getName()); - if (model.hasLists()) { - importedClasses.add(List.class.getName()); - } - if (model.hasCollections()) { - importedClasses.add(Collection.class.getName()); - } - if (model.hasSets()) { - importedClasses.add(Set.class.getName()); - } - if (model.hasMaps()) { - importedClasses.add(Map.class.getName()); - } - if (addToString && model.hasArrays()) { - importedClasses.add(Arrays.class.getName()); - } - writer.importClasses(importedClasses.toArray(new String[importedClasses.size()])); - - // javadoc - writer.javadoc(simpleName + javadocSuffix); - - // header - for (Annotation annotation : model.getAnnotations()) { - writer.annotation(annotation); - } - - writer.line("@Generated(\"", getClass().getName(), "\")"); - - if (!interfaces.isEmpty()) { - Type superType = null; - if (printSupertype && model.getSuperType() != null) { - superType = model.getSuperType().getType(); - } - Type[] ifaces = interfaces.toArray(new Type[interfaces.size()]); - writer.beginClass(model, superType, ifaces); - } else if (printSupertype && model.getSuperType() != null) { - writer.beginClass(model, model.getSuperType().getType()); - } else { - writer.beginClass(model); - } - - - bodyStart(model, writer); - - if (addFullConstructor) { - addFullConstructor(model, writer); - } - - // fields - for (Property property : model.getProperties()) { - if (propertyAnnotations) { - for (Annotation annotation : property.getAnnotations()) { - writer.annotation(annotation); - } - } - writer.privateField(property.getType(), property.getEscapedName()); - } - - // accessors - for (Property property : model.getProperties()) { - String propertyName = property.getEscapedName(); - // getter - writer.beginPublicMethod(property.getType(), "get"+BeanUtils.capitalize(propertyName)); - writer.line("return ", propertyName, ";"); - writer.end(); - // setter - Parameter parameter = new Parameter(propertyName, property.getType()); - writer.beginPublicMethod(Types.VOID, "set"+BeanUtils.capitalize(propertyName), parameter); - writer.line("this.", propertyName, " = ", propertyName, ";"); - writer.end(); - } - - if (addToString) { - addToString(model, writer); - } - - bodyEnd(model, writer); - - writer.end(); - } - - protected void addFullConstructor(EntityType model, CodeWriter writer) throws IOException { - // public empty constructor - writer.beginConstructor(); - writer.end(); - - // full constructor - writer.beginConstructor(model.getProperties(), propertyToParameter); - for (Property property : model.getProperties()) { - writer.line("this.", property.getEscapedName(), " = ", property.getEscapedName(), ";"); - } - writer.end(); - } - - protected void addToString(EntityType model, CodeWriter writer) throws IOException { - writer.beginPublicMethod(Types.STRING, "toString"); - StringBuilder builder = new StringBuilder(); - for (Property property : model.getProperties()) { - String propertyName = property.getEscapedName(); - if (builder.length() > 0) { - builder.append(" + \", "); - } else { - builder.append("\""); - } - builder.append(propertyName + " = \" + "); - if (property.getType().getCategory() == TypeCategory.ARRAY) { - builder.append("Arrays.toString(" + propertyName + ")"); - } else { - builder.append(propertyName); - } - } - writer.line(" return ", builder.toString(), ";"); - writer.end(); - } - - protected void bodyStart(EntityType model, CodeWriter writer) throws IOException { - // template method - } - - protected void bodyEnd(EntityType model, CodeWriter writer) throws IOException { - // template method - } - - private Set getAnnotationTypes(EntityType model) { - Set imports = new HashSet(); - for (Annotation annotation : model.getAnnotations()) { - imports.add(annotation.annotationType().getName()); - } - if (propertyAnnotations) { - for (Property property : model.getProperties()) { - for (Annotation annotation : property.getAnnotations()) { - imports.add(annotation.annotationType().getName()); - } - } - } - return imports; - } - - public void addInterface(Class iface) { - interfaces.add(new ClassType(iface)); - } - - public void addInterface(Type type) { - interfaces.add(type); - } - - public void setAddToString(boolean addToString) { - this.addToString = addToString; - } - - public void setAddFullConstructor(boolean addFullConstructor) { - this.addFullConstructor = addFullConstructor; - } - - public void setPrintSupertype(boolean printSupertype) { - this.printSupertype = printSupertype; - } - -} diff --git a/querydsl-codegen/src/main/java/com/mysema/query/codegen/CodeGenerationException.java b/querydsl-codegen/src/main/java/com/mysema/query/codegen/CodeGenerationException.java deleted file mode 100644 index a4c68a525a..0000000000 --- a/querydsl-codegen/src/main/java/com/mysema/query/codegen/CodeGenerationException.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.codegen; - -/** - * @author tiwe - * - */ -public class CodeGenerationException extends RuntimeException{ - - private static final long serialVersionUID = -7692082275150033814L; - - CodeGenerationException(String msg) { - super(msg); - } - - CodeGenerationException(String msg, Throwable t) { - super(msg, t); - } - - CodeGenerationException(Throwable t) { - super(t); - } -} diff --git a/querydsl-codegen/src/main/java/com/mysema/query/codegen/CodegenModule.java b/querydsl-codegen/src/main/java/com/mysema/query/codegen/CodegenModule.java deleted file mode 100644 index 16555a1c3e..0000000000 --- a/querydsl-codegen/src/main/java/com/mysema/query/codegen/CodegenModule.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.codegen; - -import java.util.Collections; - -/** - * CodegenModule provides a module general serialization - * - * @author tiwe - * - */ -public class CodegenModule extends AbstractModule { - - public static final String PREFIX = "prefix"; - - public static final String SUFFIX = "suffix"; - - public static final String KEYWORDS = "keywords"; - - public static final String PACKAGE_SUFFIX = "packageSuffix"; - - public static final String IMPORTS = "imports"; - - @Override - protected void configure() { - bind(TypeMappings.class, JavaTypeMappings.class); - bind(QueryTypeFactory.class, QueryTypeFactoryImpl.class); - bind(EntitySerializer.class); - bind(EmbeddableSerializer.class); - bind(ProjectionSerializer.class); - bind(SupertypeSerializer.class); - - // configuration for QueryTypeFactory - bind(PREFIX, "Q"); - bind(SUFFIX, ""); - bind(PACKAGE_SUFFIX, ""); - bind(KEYWORDS, Collections.emptySet()); - bind(IMPORTS, Collections.emptySet()); - } - -} \ No newline at end of file diff --git a/querydsl-codegen/src/main/java/com/mysema/query/codegen/EmbeddableSerializer.java b/querydsl-codegen/src/main/java/com/mysema/query/codegen/EmbeddableSerializer.java deleted file mode 100644 index daf2361549..0000000000 --- a/querydsl-codegen/src/main/java/com/mysema/query/codegen/EmbeddableSerializer.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.codegen; - -import static com.mysema.codegen.Symbols.UNCHECKED; - -import java.io.IOException; -import java.lang.annotation.Annotation; -import java.util.Collection; - -import javax.inject.Inject; -import javax.inject.Named; - -import com.mysema.codegen.CodeWriter; -import com.mysema.codegen.model.ClassType; -import com.mysema.codegen.model.Type; -import com.mysema.codegen.model.TypeCategory; -import com.mysema.codegen.model.Types; -import com.mysema.query.types.Path; -import com.mysema.query.types.path.BeanPath; -import com.mysema.query.types.path.BooleanPath; -import com.mysema.query.types.path.ComparablePath; -import com.mysema.query.types.path.DatePath; -import com.mysema.query.types.path.DateTimePath; -import com.mysema.query.types.path.EnumPath; -import com.mysema.query.types.path.NumberPath; -import com.mysema.query.types.path.StringPath; -import com.mysema.query.types.path.TimePath; - -/** - * EmbeddableSerializer is a {@link Serializer} implementation for embeddable types - * - * @author tiwe - * - */ -public final class EmbeddableSerializer extends EntitySerializer { - - /** - * Create a new EmbeddableSerializer instance - * - * @param typeMappings - * @param keywords - */ - @Inject - public EmbeddableSerializer(TypeMappings typeMappings, @Named("keywords") Collection keywords) { - super(typeMappings, keywords); - } - - @Override - @SuppressWarnings(UNCHECKED) - protected void introClassHeader(CodeWriter writer, EntityType model) throws IOException { - Type queryType = typeMappings.getPathType(model, model, true); - - TypeCategory category = model.getOriginalCategory(); - Class pathType; - if (model.getProperties().isEmpty() ) { - switch(category) { - case COMPARABLE : pathType = ComparablePath.class; break; - case ENUM: pathType = EnumPath.class; break; - case DATE: pathType = DatePath.class; break; - case DATETIME: pathType = DateTimePath.class; break; - case TIME: pathType = TimePath.class; break; - case NUMERIC: pathType = NumberPath.class; break; - case STRING: pathType = StringPath.class; break; - case BOOLEAN: pathType = BooleanPath.class; break; - default : pathType = BeanPath.class; - } - } else { - pathType = BeanPath.class; - } - - for (Annotation annotation : model.getAnnotations()) { - writer.annotation(annotation); - } - - writer.line("@Generated(\"", getClass().getName(), "\")"); - - if (category == TypeCategory.BOOLEAN || category == TypeCategory.STRING) { - writer.beginClass(queryType, new ClassType(pathType)); - } else { - writer.beginClass(queryType, new ClassType(category, pathType, model)); - } - - // TODO : generate proper serialVersionUID here - writer.privateStaticFinal(Types.LONG_P, "serialVersionUID", model.hashCode() + "L"); - } - - @Override - protected void introFactoryMethods(CodeWriter writer, EntityType model) throws IOException { - // no factory methods - } - -} diff --git a/querydsl-codegen/src/main/java/com/mysema/query/codegen/EntitySerializer.java b/querydsl-codegen/src/main/java/com/mysema/query/codegen/EntitySerializer.java deleted file mode 100644 index d4ed16c3eb..0000000000 --- a/querydsl-codegen/src/main/java/com/mysema/query/codegen/EntitySerializer.java +++ /dev/null @@ -1,826 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.codegen; - -import com.google.common.base.Function; -import com.google.common.base.Joiner; -import com.google.common.collect.Lists; -import com.google.common.collect.Sets; -import com.mysema.codegen.CodeWriter; -import com.mysema.codegen.model.*; -import com.mysema.query.types.*; -import com.mysema.query.types.expr.ComparableExpression; -import com.mysema.query.types.expr.SimpleExpression; -import com.mysema.query.types.path.*; - -import javax.annotation.Generated; -import javax.inject.Inject; -import javax.inject.Named; -import java.io.IOException; -import java.lang.annotation.Annotation; -import java.util.*; - -import static com.mysema.codegen.Symbols.*; - -/** - * EntitySerializer is a {@link Serializer} implementation for entity types - * - * @author tiwe - * - */ -public class EntitySerializer implements Serializer { - - private static final Joiner JOINER = Joiner.on("\", \""); - - private static final Parameter PATH_METADATA = new Parameter("metadata", new ClassType(PathMetadata.class, (Type)null)); - - private static final Parameter PATH_INITS = new Parameter("inits", new ClassType(PathInits.class)); - - private static final ClassType PATH_INITS_TYPE = new ClassType(PathInits.class); - - protected final TypeMappings typeMappings; - - protected final Collection keywords; - - /** - * Create a new EntitySerializer instance - * - * @param mappings - * @param keywords - */ - @Inject - public EntitySerializer(TypeMappings mappings, @Named("keywords") Collection keywords) { - this.typeMappings = mappings; - this.keywords = keywords; - } - - protected void constructors(EntityType model, SerializerConfig config, - CodeWriter writer) throws IOException { - String localName = writer.getRawName(model); - String genericName = writer.getGenericName(true, model); - - boolean hasEntityFields = model.hasEntityFields(); - boolean stringOrBoolean = model.getOriginalCategory() == TypeCategory.STRING - || model.getOriginalCategory() == TypeCategory.BOOLEAN; - String thisOrSuper = hasEntityFields ? THIS : SUPER; - String additionalParams = getAdditionalConstructorParameter(model); - String classCast = localName.equals(genericName) ? EMPTY : "(Class)"; - - // String - constructorsForVariables(writer, model); - - // Path - if (!localName.equals(genericName)) { - writer.suppressWarnings("all"); - } - Type simpleModel = new SimpleType(model); - if (model.isFinal()) { - Type type = new ClassType(Path.class, simpleModel); - writer.beginConstructor(new Parameter("path", type)); - } else { - Type type = new ClassType(Path.class, new TypeExtends(simpleModel)); - writer.beginConstructor(new Parameter("path", type)); - } - if (!hasEntityFields) { - if (stringOrBoolean) { - writer.line("super(path.getMetadata());"); - } else { - writer.line("super(", classCast, "path.getType(), path.getMetadata()" +additionalParams+");"); - } - constructorContent(writer, model); - } else { - writer.line("this(", classCast, "path.getType(), path.getMetadata(), path.getMetadata().isRoot() ? INITS : PathInits.DEFAULT);"); - } - writer.end(); - - // PathMetadata - if (hasEntityFields) { - writer.beginConstructor(PATH_METADATA); - writer.line("this(metadata, metadata.isRoot() ? INITS : PathInits.DEFAULT);"); - writer.end(); - } else { - if (!localName.equals(genericName)) { - writer.suppressWarnings("all"); - } - writer.beginConstructor(PATH_METADATA); - if (stringOrBoolean) { - writer.line("super(metadata);"); - } else { - writer.line("super(", classCast, writer.getClassConstant(localName) + COMMA + "metadata" + additionalParams + ");"); - } - constructorContent(writer, model); - writer.end(); - } - - // PathMetadata, PathInits - if (hasEntityFields) { - if (!localName.equals(genericName)) { - writer.suppressWarnings("all"); - } - writer.beginConstructor(PATH_METADATA, PATH_INITS); - writer.line(thisOrSuper, "(", classCast, writer.getClassConstant(localName) + COMMA + "metadata, inits" + additionalParams+ ");"); - if (!hasEntityFields) { - constructorContent(writer, model); - } - writer.end(); - } - - // Class, PathMetadata, PathInits - if (hasEntityFields) { - Type type = new ClassType(Class.class, new TypeExtends(model)); - writer.beginConstructor(new Parameter("type", type), PATH_METADATA, PATH_INITS); - writer.line("super(type, metadata, inits"+additionalParams+");"); - initEntityFields(writer, config, model); - constructorContent(writer, model); - writer.end(); - } - - } - - protected void constructorContent(CodeWriter writer, EntityType model) throws IOException { - // override in subclasses - } - - protected String getAdditionalConstructorParameter(EntityType model) { - return ""; - } - - protected void constructorsForVariables(CodeWriter writer, EntityType model) throws IOException { - String localName = writer.getRawName(model); - String genericName = writer.getGenericName(true, model); - - boolean stringOrBoolean = model.getOriginalCategory() == TypeCategory.STRING - || model.getOriginalCategory() == TypeCategory.BOOLEAN; - boolean hasEntityFields = model.hasEntityFields(); - String thisOrSuper = hasEntityFields ? THIS : SUPER; - String additionalParams = hasEntityFields ? "" : getAdditionalConstructorParameter(model); - - if (!localName.equals(genericName)) { - writer.suppressWarnings("all"); - } - writer.beginConstructor(new Parameter("variable", Types.STRING)); - if (stringOrBoolean) { - writer.line(thisOrSuper,"(forVariable(variable)",additionalParams,");"); - } else { - writer.line(thisOrSuper,"(", localName.equals(genericName) ? EMPTY : "(Class)", - writer.getClassConstant(localName) + COMMA + "forVariable(variable)", hasEntityFields ? ", INITS" : EMPTY, - additionalParams,");"); - } - if (!hasEntityFields) { - constructorContent(writer, model); - } - writer.end(); - } - - protected void entityAccessor(EntityType model, Property field, CodeWriter writer) throws IOException { - Type queryType = typeMappings.getPathType(field.getType(), model, false); - writer.beginPublicMethod(queryType, field.getEscapedName()); - writer.line("if (", field.getEscapedName(), " == null) {"); - writer.line(" ", field.getEscapedName(), " = new ", writer.getRawName(queryType), - "(forProperty(\"", field.getName(), "\"));"); - writer.line("}"); - writer.line(RETURN, field.getEscapedName(), SEMICOLON); - writer.end(); - } - - protected void entityField(EntityType model, Property field, SerializerConfig config, - CodeWriter writer) throws IOException { - Type queryType = typeMappings.getPathType(field.getType(), model, false); - if (field.isInherited()) { - writer.line("// inherited"); - } - if (config.useEntityAccessors()) { - writer.protectedField(queryType, field.getEscapedName()); - } else { - writer.publicFinal(queryType, field.getEscapedName()); - } - } - - protected boolean hasOwnEntityProperties(EntityType model) { - if (model.hasEntityFields()) { - for (Property property : model.getProperties()) { - if (!property.isInherited() && property.getType().getCategory() == TypeCategory.ENTITY) { - return true; - } - } - } - return false; - } - - protected void initEntityFields(CodeWriter writer, SerializerConfig config, - EntityType model) throws IOException { - Supertype superType = model.getSuperType(); - if (superType != null && superType.getEntityType() == null) { - throw new IllegalStateException("No entity type for " + superType.getType().getFullName()); - } - if (superType != null && superType.getEntityType().hasEntityFields()) { - Type superQueryType = typeMappings.getPathType(superType.getEntityType(), model, false); - writer.line("this._super = new " + writer.getRawName(superQueryType) + "(type, metadata, inits);"); - } - - for (Property field : model.getProperties()) { - if (field.getType().getCategory() == TypeCategory.ENTITY) { - initEntityField(writer, config, model, field); - - } else if (field.isInherited() && superType != null && superType.getEntityType().hasEntityFields()) { - writer.line("this.", field.getEscapedName(), " = _super.", field.getEscapedName(), SEMICOLON); - } - } - } - - protected void initEntityField(CodeWriter writer, SerializerConfig config, EntityType model, - Property field) throws IOException { - Type queryType = typeMappings.getPathType(field.getType(), model, false); - if (!field.isInherited()) { - boolean hasEntityFields = field.getType() instanceof EntityType - && ((EntityType)field.getType()).hasEntityFields(); - writer.line("this." + field.getEscapedName() + ASSIGN, - "inits.isInitialized(\""+field.getName()+"\") ? ", - NEW + writer.getRawName(queryType) + "(forProperty(\"" + field.getName() + "\")", - hasEntityFields ? (", inits.get(\""+field.getName()+"\")") : EMPTY, - ") : null;"); - } else if (!config.useEntityAccessors()) { - writer.line("this.", field.getEscapedName(), ASSIGN, "_super.", field.getEscapedName(), SEMICOLON); - } - } - - protected void intro(EntityType model, SerializerConfig config, - CodeWriter writer) throws IOException { - introPackage(writer, model); - introImports(writer, config, model); - - writer.nl(); - - introJavadoc(writer, model); - introClassHeader(writer, model); - - introFactoryMethods(writer, model); - introInits(writer, model); - if (config.createDefaultVariable()) { - introDefaultInstance(writer, model, config.defaultVariableName()); - } - if (model.getSuperType() != null && model.getSuperType().getEntityType() != null) { - introSuper(writer, model); - } - } - - @SuppressWarnings(UNCHECKED) - protected void introClassHeader(CodeWriter writer, EntityType model) throws IOException { - Type queryType = typeMappings.getPathType(model, model, true); - - TypeCategory category = model.getOriginalCategory(); - Class pathType; - - if (model.getProperties().isEmpty()) { - switch(category) { - case COMPARABLE : pathType = ComparablePath.class; break; - case ENUM: pathType = EnumPath.class; break; - case DATE: pathType = DatePath.class; break; - case DATETIME: pathType = DateTimePath.class; break; - case TIME: pathType = TimePath.class; break; - case NUMERIC: pathType = NumberPath.class; break; - case STRING: pathType = StringPath.class; break; - case BOOLEAN: pathType = BooleanPath.class; break; - default : pathType = EntityPathBase.class; - } - } else { - pathType = EntityPathBase.class; - } - - for (Annotation annotation : model.getAnnotations()) { - writer.annotation(annotation); - } - - writer.line("@Generated(\"", getClass().getName(), "\")"); - - if (category == TypeCategory.BOOLEAN || category == TypeCategory.STRING) { - writer.beginClass(queryType, new ClassType(pathType)); - } else { - writer.beginClass(queryType, new ClassType(category, pathType, model)); - } - - // TODO : generate proper serialVersionUID here - long serialVersionUID = model.getFullName().hashCode(); - writer.privateStaticFinal(Types.LONG_P, "serialVersionUID", serialVersionUID + "L"); - } - - protected void introDefaultInstance(CodeWriter writer, EntityType model, String defaultName) throws IOException { - String simpleName = !defaultName.isEmpty() ? defaultName : model.getUncapSimpleName(); - Type queryType = typeMappings.getPathType(model, model, true); - String alias = simpleName; - if (keywords.contains(simpleName.toUpperCase())) { - alias += "1"; - } - writer.publicStaticFinal(queryType, simpleName, NEW + queryType.getSimpleName() + "(\"" + alias + "\")"); - - } - - protected void introFactoryMethods(CodeWriter writer, final EntityType model) throws IOException { - String localName = writer.getRawName(model); - String genericName = writer.getGenericName(true, model); - Set sizes = Sets.newHashSet(); - - for (Constructor c : model.getConstructors()) { - // begin - if (!localName.equals(genericName)) { - writer.suppressWarnings(UNCHECKED); - } - Type returnType = new ClassType(ConstructorExpression.class, model); - final boolean asExpr = sizes.add(c.getParameters().size()); - writer.beginStaticMethod(returnType, "create", c.getParameters(), - new Function() { - @Override - public Parameter apply(Parameter p) { - Type type; - if (!asExpr) { - type = typeMappings.getExprType( - p.getType(), model, false, false, true); - } else if (p.getType().isFinal()) { - type = new ClassType(Expression.class, p.getType()); - } else { - type = new ClassType(Expression.class, new TypeExtends(p.getType())); - } - return new Parameter(p.getName(), type); - } - }); - - // body - // TODO : replace with class reference - writer.beginLine("return new ConstructorExpression<" + genericName + ">("); - if (!localName.equals(genericName)) { - writer.append("(Class)"); - } - writer.append(writer.getClassConstant(localName)); - writer.append(", new Class[]{"); - boolean first = true; - for (Parameter p : c.getParameters()) { - if (!first) { - writer.append(COMMA); - } - if (Types.PRIMITIVES.containsKey(p.getType())) { - Type primitive = Types.PRIMITIVES.get(p.getType()); - writer.append(writer.getClassConstant(primitive.getFullName())); - } else { - writer.append(writer.getClassConstant(writer.getRawName(p.getType()))); - } - first = false; - } - writer.append("}"); - - for (Parameter p : c.getParameters()) { - writer.append(COMMA + p.getName()); - } - - // end - writer.append(");\n"); - writer.end(); - } - } - - protected void introImports(CodeWriter writer, SerializerConfig config, - EntityType model) throws IOException { - writer.staticimports(PathMetadataFactory.class); - - // import package of query type - Type queryType = typeMappings.getPathType(model, model, true); - if (!model.getPackageName().isEmpty() - && !queryType.getPackageName().equals(model.getPackageName()) - && !queryType.getSimpleName().equals(model.getSimpleName())) { - String fullName = model.getFullName(); - String packageName = model.getPackageName(); - if (fullName.substring(packageName.length()+1).contains(".")) { - fullName = fullName.substring(0, fullName.lastIndexOf('.')); - } - writer.importClasses(fullName); - } - - // delegate packages - introDelegatePackages(writer, model); - - // other packages - List packages = Lists.newArrayList(); - packages.add(SimplePath.class.getPackage()); - if (!model.getConstructors().isEmpty()) { - packages.add(SimpleExpression.class.getPackage()); - } - if (isImportExprPackage(model)) { - packages.add(ComparableExpression.class.getPackage()); - } - writer.imports(packages.toArray(new Package[packages.size()])); - - // other classes - List> classes = Lists.>newArrayList(PathMetadata.class, Generated.class); - if (!getUsedClassNames(model).contains("Path")) { - classes.add(Path.class); - } - if (!model.getConstructors().isEmpty()) { - classes.add(ConstructorExpression.class); - classes.add(Expression.class); - } - boolean inits = false; - if (model.hasEntityFields() || model.hasInits()) { - inits = true; - } else { - Set collections = Sets.newHashSet(TypeCategory.COLLECTION, TypeCategory.LIST, TypeCategory.SET); - for (Property property : model.getProperties()) { - if (!property.isInherited() && collections.contains(property.getType().getCategory())) { - inits = true; - break; - } - } - } - if (inits) { - classes.add(PathInits.class); - } - writer.imports(classes.toArray(new Class[classes.size()])); - } - - private Set getUsedClassNames(EntityType model) { - Set result = Sets.newHashSet(); - result.add(model.getSimpleName()); - for (Property property : model.getProperties()) { - result.add(property.getType().getSimpleName()); - for (Type type : property.getType().getParameters()) { - if (type != null) { - result.add(type.getSimpleName()); - } - } - } - return result; - } - - protected boolean isImportExprPackage(EntityType model) { - if (!model.getConstructors().isEmpty() || !model.getDelegates().isEmpty()) { - boolean importExprPackage = false; - for (Constructor c : model.getConstructors()) { - for (Parameter cp : c.getParameters()) { - importExprPackage |= cp.getType().getPackageName() - .equals(ComparableExpression.class.getPackage().getName()); - } - } - for (Delegate d : model.getDelegates()) { - for (Parameter dp : d.getParameters()) { - importExprPackage |= dp.getType().getPackageName() - .equals(ComparableExpression.class.getPackage().getName()); - } - } - return importExprPackage; - - } else { - return false; - } - } - - protected void introDelegatePackages(CodeWriter writer, EntityType model) throws IOException { - Set packages = new HashSet(); - for (Delegate delegate : model.getDelegates()) { - if (!delegate.getDelegateType().getPackageName().equals(model.getPackageName())) { - packages.add(delegate.getDelegateType().getPackageName()); - } - } - writer.importPackages(packages.toArray(new String[packages.size()])); - } - - protected void introInits(CodeWriter writer, EntityType model) throws IOException { - List inits = new ArrayList(); - for (Property property : model.getProperties()) { - for (String init : property.getInits()) { - inits.add(property.getEscapedName() + DOT + init); - } - } - if (!inits.isEmpty()) { - inits.add(0, STAR); - String initsAsString = QUOTE + JOINER.join(inits) + QUOTE; - writer.privateStaticFinal(PATH_INITS_TYPE, "INITS", "new PathInits(" + initsAsString + ")"); - } else if (model.hasEntityFields()) { - writer.privateStaticFinal(PATH_INITS_TYPE, "INITS", "PathInits.DIRECT2"); - } - } - - protected void introJavadoc(CodeWriter writer, EntityType model) throws IOException { - Type queryType = typeMappings.getPathType(model, model, true); - writer.javadoc(queryType.getSimpleName() + " is a Querydsl query type for " + - model.getSimpleName()); - } - - protected void introPackage(CodeWriter writer, EntityType model) throws IOException { - Type queryType = typeMappings.getPathType(model, model, false); - if (!queryType.getPackageName().isEmpty()) { - writer.packageDecl(queryType.getPackageName()); - } - } - - protected void introSuper(CodeWriter writer, EntityType model) throws IOException { - EntityType superType = model.getSuperType().getEntityType(); - Type superQueryType = typeMappings.getPathType(superType, model, false); - if (!superType.hasEntityFields()) { - writer.publicFinal(superQueryType, "_super", NEW + writer.getRawName(superQueryType) + "(this)"); - } else { - writer.publicFinal(superQueryType, "_super"); - } - } - - protected void listAccessor(EntityType model, Property field, CodeWriter writer) throws IOException { - String escapedName = field.getEscapedName(); - Type queryType = typeMappings.getPathType(field.getParameter(0), model, false); - - writer.beginPublicMethod(queryType, escapedName, new Parameter("index", Types.INT)); - writer.line(RETURN + escapedName + ".get(index);").end(); - - writer.beginPublicMethod(queryType, escapedName, new Parameter("index", - new ClassType(Expression.class, Types.INTEGER))); - writer.line(RETURN + escapedName +".get(index);").end(); - } - - protected void mapAccessor(EntityType model, Property field, CodeWriter writer) throws IOException { - String escapedName = field.getEscapedName(); - Type queryType = typeMappings.getPathType(field.getParameter(1), model, false); - - writer.beginPublicMethod(queryType, escapedName, new Parameter("key", field.getParameter(0))); - writer.line(RETURN + escapedName + ".get(key);").end(); - - writer.beginPublicMethod(queryType, escapedName, new Parameter("key", - new ClassType(Expression.class, field.getParameter(0)))); - writer.line(RETURN + escapedName + ".get(key);").end(); - } - - private void delegate(final EntityType model, Delegate delegate, SerializerConfig config, - CodeWriter writer) throws IOException { - Parameter[] params = delegate.getParameters().toArray(new Parameter[delegate.getParameters().size()]); - writer.beginPublicMethod(delegate.getReturnType(), delegate.getName(), params); - - // body start - writer.beginLine(RETURN + delegate.getDelegateType().getSimpleName() + "."+delegate.getName()+"("); - writer.append("this"); - if (!model.equals(delegate.getDeclaringType())) { - int counter = 0; - EntityType type = model; - while (type != null && !type.equals(delegate.getDeclaringType())) { - type = type.getSuperType() != null ? type.getSuperType().getEntityType() : null; - counter++; - } - for (int i = 0; i < counter; i++) { - writer.append("._super"); - } - } - for (Parameter parameter : delegate.getParameters()) { - writer.append(COMMA + parameter.getName()); - } - writer.append(");\n"); - - // body end - writer.end(); - } - - protected void outro(EntityType model, CodeWriter writer) throws IOException { - writer.end(); - } - - @Override - public void serialize(EntityType model, SerializerConfig config, - CodeWriter writer) throws IOException{ - intro(model, config, writer); - - // properties - serializeProperties(model, config, writer); - - // constructors - constructors(model, config, writer); - - // delegates - for (Delegate delegate : model.getDelegates()) { - delegate(model, delegate, config, writer); - } - - // property accessors - for (Property property : model.getProperties()) { - TypeCategory category = property.getType().getCategory(); - if (category == TypeCategory.MAP && config.useMapAccessors()) { - mapAccessor(model, property, writer); - } else if (category == TypeCategory.LIST && config.useListAccessors()) { - listAccessor(model, property, writer); - } else if (category == TypeCategory.ENTITY && config.useEntityAccessors()) { - entityAccessor(model, property, writer); - } - } - outro(model, writer); - } - - protected void serialize(EntityType model, Property field, Type type, CodeWriter writer, - String factoryMethod, String... args) throws IOException { - Supertype superType = model.getSuperType(); - // construct value - StringBuilder value = new StringBuilder(); - if (field.isInherited() && superType != null) { - if (!superType.getEntityType().hasEntityFields()) { - value.append("_super." + field.getEscapedName()); - } - } else { - value.append(factoryMethod + "(\"" + field.getName() + QUOTE); - for (String arg : args) { - value.append(COMMA + arg); - } - value.append(")"); - } - - // serialize it - if (field.isInherited()) { - writer.line("//inherited"); - } - if (value.length() > 0) { - writer.publicFinal(type, field.getEscapedName(), value.toString()); - } else { - writer.publicFinal(type, field.getEscapedName()); - } - } - - protected void customField(EntityType model, Property field, SerializerConfig config, - CodeWriter writer) throws IOException { - Type queryType = typeMappings.getPathType(field.getType(), model, false); - writer.line("// custom"); - if (field.isInherited()) { - writer.line("// inherited"); - Supertype superType = model.getSuperType(); - if (!superType.getEntityType().hasEntityFields()) { - writer.publicFinal(queryType, field.getEscapedName(),"_super." + field.getEscapedName()); - } else { - writer.publicFinal(queryType, field.getEscapedName()); - } - } else { - String value = NEW + writer.getRawName(queryType) + "(forProperty(\"" + field.getName() + "\"))"; - writer.publicFinal(queryType, field.getEscapedName(), value); - } - } - - // TODO move this to codegen - private Type wrap(Type type) { - if (type.equals(Types.BOOLEAN_P)) { - return Types.BOOLEAN; - } else if (type.equals(Types.BYTE_P)) { - return Types.BYTE; - } else if (type.equals(Types.CHAR)) { - return Types.CHARACTER; - } else if (type.equals(Types.DOUBLE_P)) { - return Types.DOUBLE; - } else if (type.equals(Types.FLOAT_P)) { - return Types.FLOAT; - } else if (type.equals(Types.INT)) { - return Types.INTEGER; - } else if (type.equals(Types.LONG_P)) { - return Types.LONG; - } else if (type.equals(Types.SHORT_P)) { - return Types.SHORT; - } else { - return type; - } - } - - protected void serializeProperties(EntityType model, SerializerConfig config, - CodeWriter writer) throws IOException { - for (Property property : model.getProperties()) { - // FIXME : the custom types should have the custom type category - if (typeMappings.isRegistered(property.getType()) - && property.getType().getCategory() != TypeCategory.CUSTOM - && property.getType().getCategory() != TypeCategory.ENTITY) { - customField(model, property, config, writer); - continue; - } - - // strips of "? extends " etc - Type propertyType = new SimpleType(property.getType(), property.getType().getParameters()); - Type queryType = typeMappings.getPathType(propertyType, model, false); - Type genericQueryType = null; - String localRawName = writer.getRawName(property.getType()); - String inits = getInits(property); - - switch(property.getType().getCategory()) { - case STRING: - serialize(model, property, queryType, writer, "createString"); - break; - - case BOOLEAN: - serialize(model, property, queryType, writer, "createBoolean"); - break; - - case SIMPLE: - serialize(model, property, queryType, writer, "createSimple", writer.getClassConstant(localRawName)); - break; - - case COMPARABLE: - serialize(model, property, queryType, writer, "createComparable", writer.getClassConstant(localRawName)); - break; - - case ENUM: - serialize(model, property, queryType, writer, "createEnum", writer.getClassConstant(localRawName)); - break; - - case DATE: - serialize(model, property, queryType, writer, "createDate", writer.getClassConstant(localRawName)); - break; - - case DATETIME: - serialize(model, property, queryType, writer, "createDateTime", writer.getClassConstant(localRawName)); - break; - - case TIME: - serialize(model, property, queryType, writer, "createTime", writer.getClassConstant(localRawName)); - break; - - case NUMERIC: - serialize(model, property, queryType, writer, "createNumber", writer.getClassConstant(localRawName)); - break; - - case CUSTOM: - customField(model, property, config, writer); - break; - - case ARRAY: - serialize(model, property, new ClassType(ArrayPath.class, - property.getType(), - wrap(property.getType().getComponentType())), - writer, "createArray", writer.getClassConstant(localRawName)); - break; - - case COLLECTION: - genericQueryType = typeMappings.getPathType(getRaw(property.getParameter(0)), model, false); - String genericKey = writer.getGenericName(true, property.getParameter(0)); - localRawName = writer.getRawName(property.getParameter(0)); - queryType = typeMappings.getPathType(property.getParameter(0), model, true); - - serialize(model, property, new ClassType(CollectionPath.class, getRaw(property.getParameter(0)), genericQueryType), - writer, "this.<"+genericKey + COMMA + writer.getGenericName(true, genericQueryType) + ">createCollection", - writer.getClassConstant(localRawName), writer.getClassConstant(writer.getRawName(queryType)), inits); - break; - - case SET: - genericQueryType = typeMappings.getPathType(getRaw(property.getParameter(0)), model, false); - genericKey = writer.getGenericName(true, property.getParameter(0)); - localRawName = writer.getRawName(property.getParameter(0)); - queryType = typeMappings.getPathType(property.getParameter(0), model, true); - - serialize(model, property, new ClassType(SetPath.class, getRaw(property.getParameter(0)), genericQueryType), - writer, "this.<"+genericKey + COMMA + writer.getGenericName(true, genericQueryType) + ">createSet", - writer.getClassConstant(localRawName), writer.getClassConstant(writer.getRawName(queryType)), inits); - break; - - case LIST: - genericQueryType = typeMappings.getPathType(getRaw(property.getParameter(0)), model, false); - genericKey = writer.getGenericName(true, property.getParameter(0)); - localRawName = writer.getRawName(property.getParameter(0)); - queryType = typeMappings.getPathType(property.getParameter(0), model, true); - - serialize(model, property, new ClassType(ListPath.class, getRaw(property.getParameter(0)), genericQueryType), - writer, "this.<"+genericKey + COMMA + writer.getGenericName(true, genericQueryType) + ">createList", - writer.getClassConstant(localRawName), writer.getClassConstant(writer.getRawName(queryType)), inits); - break; - - case MAP: - genericKey = writer.getGenericName(true, property.getParameter(0)); - String genericValue = writer.getGenericName(true, property.getParameter(1)); - genericQueryType = typeMappings.getPathType(getRaw(property.getParameter(1)), model, false); - String keyType = writer.getRawName(property.getParameter(0)); - String valueType = writer.getRawName(property.getParameter(1)); - queryType = typeMappings.getPathType(property.getParameter(1), model, true); - - serialize(model, property, new ClassType(MapPath.class, getRaw(property.getParameter(0)), - getRaw(property.getParameter(1)), genericQueryType), - writer, "this.<" + genericKey + COMMA + genericValue + COMMA + - writer.getGenericName(true, genericQueryType) + ">createMap", - writer.getClassConstant(keyType), writer.getClassConstant(valueType), writer.getClassConstant(writer.getRawName(queryType))); - break; - - case ENTITY: - entityField(model, property, config, writer); - break; - } - } - } - - private String getInits(Property property) { - if (!property.getInits().isEmpty()) { - return "INITS.get(\"" + property.getName() + "\")"; - } else { - return "PathInits.DIRECT2"; - } - } - - private Type getRaw(Type type) { - if (type instanceof EntityType && type.getPackageName().startsWith("ext.java")) { - return type; - } else { - return new SimpleType(type, type.getParameters()); - } - } - -} diff --git a/querydsl-codegen/src/main/java/com/mysema/query/codegen/EntityType.java b/querydsl-codegen/src/main/java/com/mysema/query/codegen/EntityType.java deleted file mode 100644 index c1f5c665cb..0000000000 --- a/querydsl-codegen/src/main/java/com/mysema/query/codegen/EntityType.java +++ /dev/null @@ -1,250 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.codegen; - -import java.lang.annotation.Annotation; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.TreeSet; - -import javax.annotation.Nullable; - -import com.mysema.codegen.StringUtils; -import com.mysema.codegen.model.Constructor; -import com.mysema.codegen.model.Type; -import com.mysema.codegen.model.TypeAdapter; -import com.mysema.codegen.model.TypeCategory; -import com.mysema.util.JavaSyntaxUtils; - -/** - * EntityType represents a model of a query domain type with properties - * - * @author tiwe - */ -public class EntityType extends TypeAdapter implements Comparable { - - private final Map,Annotation> annotations = new HashMap,Annotation>(); - - private final Set constructors = new HashSet(); - - private int escapeSuffix = 1; - - private final Set delegates = new HashSet(); - - private final Set properties = new TreeSet(); - - private final Set propertyNames = new HashSet(); - - private final Set escapedPropertyNames = new HashSet(); - - private final Set superTypes; - - private final Map data = new HashMap(); - - private String uncapSimpleName; - - /** - * Create a new EntityType instance for the given type - * - * @param type - */ - public EntityType(Type type) { - this(type, new HashSet()); - } - - /** - * Create a new EntityType instance for the given type and superTypes - * - * @param type - * @param superTypes - */ - public EntityType(Type type, Set superTypes) { - super(type); - this.uncapSimpleName = StringUtils.uncapitalize(type.getSimpleName()); - if (JavaSyntaxUtils.isReserved(uncapSimpleName)) { - this.uncapSimpleName = uncapSimpleName + "$"; - } - this.superTypes = superTypes; - } - - public void addAnnotation(Annotation annotation) { - annotations.put(annotation.annotationType(), annotation); - } - - public void addConstructor(Constructor co) { - constructors.add(co); - } - - public void addDelegate(Delegate delegate) { - delegates.add(delegate); - } - - public void addProperty(Property field) { - propertyNames.add(field.getName()); - escapedPropertyNames.add(field.getEscapedName()); - properties.add(validateField(field)); - } - - public void addSupertype(Supertype entityType) { - superTypes.add(entityType); - } - - @Override - public int compareTo(EntityType o) { - return getType().getSimpleName().compareTo(o.getType().getSimpleName()); - } - - @Override - public boolean equals(Object o) { - if (o == this) { - return true; - } else if (o instanceof Type) { - return getFullName().equals(((Type)o).getFullName()); - } else { - return false; - } - } - - @SuppressWarnings("unchecked") - public T getAnnotation(Class type) { - return (T) annotations.get(type); - } - - public Collection getAnnotations() { - return annotations.values(); - } - - @Override - public TypeCategory getCategory() { - if (getType().getCategory() == TypeCategory.ENTITY || !properties.isEmpty()) { - return TypeCategory.ENTITY; - } else { - return TypeCategory.CUSTOM; - } - } - - public Set getConstructors() { - return constructors; - } - - public Map getData() { - return data; - } - - public Set getDelegates() { - return delegates; - } - - public TypeCategory getOriginalCategory() { - return super.getCategory(); - } - - public Set getProperties() { - return properties; - } - - @Nullable - public Supertype getSuperType() { - return superTypes.size() == 1 ? superTypes.iterator().next() : null; - } - - public Set getSuperTypes() { - return superTypes; - } - - public String getUncapSimpleName() { - return uncapSimpleName; - } - - @Override - public int hashCode() { - return getFullName().hashCode(); - } - - public boolean hasArrays() { - return hasPropertyWithType(TypeCategory.ARRAY); - } - - public boolean hasEntityFields() { - return hasPropertyWithType(TypeCategory.ENTITY); - } - - public boolean hasInits() { - for (Property property : properties) { - if (!property.getInits().isEmpty()) { - return true; - } - } - return false; - } - - public boolean hasLists() { - return hasPropertyWithType(TypeCategory.LIST); - } - - public boolean hasCollections() { - return hasPropertyWithType(TypeCategory.COLLECTION); - } - - public boolean hasSets() { - return hasPropertyWithType(TypeCategory.SET); - } - - public boolean hasMaps() { - return hasPropertyWithType(TypeCategory.MAP); - } - - private boolean hasPropertyWithType(TypeCategory category) { - for (Property property : properties) { - if (property.getType().getCategory() == category) { - return true; - } - } - return false; - } - - public void include(Supertype supertype) { - EntityType entityType = supertype.getEntityType(); - for (Delegate delegate : entityType.getDelegates()) { - addDelegate(delegate); - } - for (Property property : entityType.getProperties()) { - addProperty(property.createCopy(this)); - } - } - - private Property validateField(Property field) { - if (field.getName().equals(uncapSimpleName) || field.getEscapedName().equals(uncapSimpleName)) { - do { - uncapSimpleName = StringUtils.uncapitalize(getType().getSimpleName()) + (escapeSuffix++); - } while (propertyNames.contains(uncapSimpleName)); - } - return field; - } - - public Set getPropertyNames() { - return propertyNames; - } - - public Set getEscapedPropertyNames() { - return escapedPropertyNames; - } - - public Type getInnerType() { - return type; - } -} diff --git a/querydsl-codegen/src/main/java/com/mysema/query/codegen/GenericExporter.java b/querydsl-codegen/src/main/java/com/mysema/query/codegen/GenericExporter.java deleted file mode 100644 index bc6d57799a..0000000000 --- a/querydsl-codegen/src/main/java/com/mysema/query/codegen/GenericExporter.java +++ /dev/null @@ -1,720 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.codegen; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStreamWriter; -import java.io.Writer; -import java.lang.annotation.Annotation; -import java.lang.reflect.AnnotatedElement; -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.nio.charset.Charset; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import javax.annotation.Nullable; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; -import com.mysema.codegen.CodeWriter; -import com.mysema.codegen.JavaWriter; -import com.mysema.codegen.ScalaWriter; -import com.mysema.codegen.model.Parameter; -import com.mysema.codegen.model.Type; -import com.mysema.codegen.model.TypeCategory; -import com.mysema.codegen.support.ClassUtils; -import com.mysema.query.QueryException; -import com.mysema.query.annotations.Config; -import com.mysema.query.annotations.PropertyType; -import com.mysema.query.annotations.QueryEmbeddable; -import com.mysema.query.annotations.QueryEmbedded; -import com.mysema.query.annotations.QueryEntity; -import com.mysema.query.annotations.QueryExclude; -import com.mysema.query.annotations.QueryInit; -import com.mysema.query.annotations.QueryProjection; -import com.mysema.query.annotations.QuerySupertype; -import com.mysema.query.annotations.QueryTransient; -import com.mysema.query.annotations.QueryType; -import com.mysema.util.BeanUtils; -import com.mysema.util.ClassPathUtils; -import com.mysema.util.ReflectionUtils; - -/** - * GenericExporter provides query type serialization logic for cases where APT annotation processors - * can't be used. GenericExporter scans the classpath for classes annotated with specified annotations - * in specific packages and mirrors them into Querydsl expression types. - * - *

Example with Querydsl annotations:

- *
- * {@code
- * GenericExporter exporter = new GenericExporter();
- * exporter.setTargetFolder(new File("target/generated-sources/java"));
- * exporter.export(com.example.domain.Entity.class.getPackage());}
- * 
- * - *

Example with JPA annotations:

- *
- * {@code
- * GenericExporter exporter = new GenericExporter();
- * exporter.setKeywords(Keywords.JPA);
- * exporter.setEntityAnnotation(Entity.class);
- * exporter.setEmbeddableAnnotation(Embeddable.class);
- * exporter.setEmbeddedAnnotation(Embedded.class);
- * exporter.setSupertypeAnnotation(MappedSuperclass.class);
- * exporter.setSkipAnnotation(Transient.class);
- * exporter.setTargetFolder(new File("target/generated-sources/java"));
- * exporter.export(com.example.domain.Entity.class.getPackage());}
- * 
- * - * @author tiwe - * - */ -public class GenericExporter { - - private Class entityAnnotation = QueryEntity.class; - - private Class supertypeAnnotation = QuerySupertype.class; - - private Class embeddableAnnotation = QueryEmbeddable.class; - - private Class embeddedAnnotation = QueryEmbedded.class; - - private Class skipAnnotation = QueryTransient.class; - - private boolean createScalaSources = false; - - private final Set> stopClasses = Sets.newHashSet(); - - private final Map allTypes = Maps.newHashMap(); - - private final Map, EntityType> entityTypes = Maps.newHashMap(); - - private final Map, EntityType> superTypes = Maps.newHashMap(); - - private final Map, EntityType> embeddableTypes = Maps.newHashMap(); - - private final Map, EntityType> projectionTypes = Maps.newHashMap(); - - private final CodegenModule codegenModule = new CodegenModule(); - - private final SerializerConfig serializerConfig = SimpleSerializerConfig.DEFAULT; - - private boolean handleFields = true, handleMethods = true; - - @Nullable - private File targetFolder; - - @Nullable - private TypeFactory typeFactory; - - @Nullable - private TypeMappings typeMappings; - - @Nullable - private QueryTypeFactory queryTypeFactory; - - @Nullable - private Class serializerClass; - - private final Charset charset; - - private final ClassLoader classLoader; - - private Set generatedFiles = new HashSet(); - - /** - * Create a GenericExporter instance using the given classloader and charset for serializing - * source files - * - * @param classLoader - * @param charset - */ - public GenericExporter(ClassLoader classLoader, Charset charset) { - this.classLoader = classLoader; - this.charset = charset; - stopClasses.add(Object.class); - stopClasses.add(Enum.class); - } - - /** - * Create a GenericExporter instance using the given classloader and default charset - * - * @param classLoader - */ - public GenericExporter(ClassLoader classLoader) { - this(classLoader, Charset.defaultCharset()); - } - - /** - * Create a GenericExporter instance using the context classloader and the given charset - * - * @param charset - */ - public GenericExporter(Charset charset) { - this(Thread.currentThread().getContextClassLoader(), charset); - } - - /** - * Create a GenericExporter instance using the context classloader and default charset - */ - public GenericExporter() { - this(Thread.currentThread().getContextClassLoader(), Charset.defaultCharset()); - } - - /** - * Export the given packages - * - * @param packages - */ - public void export(Package... packages) { - String[] pkgs = new String[packages.length]; - for (int i = 0; i < packages.length; i++) { - pkgs[i] = packages[i].getName(); - } - export(pkgs); - } - - /** - * Export the given packages - * - * @param packages - */ - public void export(String... packages) { - scanPackages(packages); - innerExport(); - } - - /** - * Export the given classes - * - * @param classes - */ - public void export(Class...classes) { - for (Class cl : classes) { - handleClass(cl); - } - innerExport(); - } - - @SuppressWarnings("unchecked") - private void innerExport() { - typeMappings = codegenModule.get(TypeMappings.class); - queryTypeFactory = codegenModule.get(QueryTypeFactory.class); - typeFactory = new TypeFactory(ImmutableList.of(entityAnnotation, supertypeAnnotation, embeddableAnnotation)); - - // process supertypes - for (Class cl : superTypes.keySet()) { - createEntityType(cl, superTypes); - } - - // process embeddables - for (Class cl : embeddableTypes.keySet()) { - createEntityType(cl, embeddableTypes); - } - - // process entities - for (Class cl : entityTypes.keySet()) { - createEntityType(cl, entityTypes); - } - - // process projections - for (Class cl : projectionTypes.keySet()) { - createEntityType(cl, projectionTypes); - } - - // add constructors and properties - for (Map, EntityType> entries : Arrays.asList(superTypes, embeddableTypes, entityTypes, projectionTypes)) { - for (Map.Entry, EntityType> entry : Sets.newHashSet(entries.entrySet())) { - addConstructors(entry.getKey(), entry.getValue()); - addProperties(entry.getKey(), entry.getValue()); - } - } - - // merge supertype fields into subtypes - Set handled = new HashSet(); - for (EntityType type : superTypes.values()) { - addSupertypeFields(type, allTypes, handled); - } - for (EntityType type : entityTypes.values()) { - addSupertypeFields(type, allTypes, handled); - } - for (EntityType type : embeddableTypes.values()) { - addSupertypeFields(type, allTypes, handled); - } - - // extend types - typeFactory.extendTypes(); - - try { - Serializer supertypeSerializer, entitySerializer, embeddableSerializer, projectionSerializer; - - if (serializerClass != null) { - Serializer serializer = codegenModule.get(serializerClass); - supertypeSerializer = serializer; - entitySerializer = serializer; - embeddableSerializer = serializer; - projectionSerializer = serializer; - } else { - supertypeSerializer = codegenModule.get(SupertypeSerializer.class); - entitySerializer = codegenModule.get(EntitySerializer.class); - embeddableSerializer = codegenModule.get(EmbeddableSerializer.class); - projectionSerializer = codegenModule.get(ProjectionSerializer.class); - } - - // serialize super types - serialize(supertypeSerializer, superTypes); - - // serialze entity types - serialize(entitySerializer, entityTypes); - - // serialize embeddables - serialize(embeddableSerializer, embeddableTypes); - - // serialize projections - serialize(projectionSerializer, projectionTypes); - - } catch (IOException e) { - throw new QueryException(e); - } - - } - - private void addSupertypeFields(EntityType model, Map superTypes, - Set handled) { - if (handled.add(model)) { - for (Supertype supertype : model.getSuperTypes()) { - EntityType entityType = superTypes.get(supertype.getType().getFullName()); - if (entityType == null) { - if (supertype.getType().getPackageName().startsWith("java.")) { - // skip internal supertypes - continue; - } - // FIXME this misses the generics - Class cl = supertype.getType().getJavaClass(); - typeFactory.addEmbeddableType(cl); - entityType = createEntityType(cl, new HashMap, EntityType>()); - addProperties(cl, entityType); - - } - addSupertypeFields(entityType, superTypes, handled); - supertype.setEntityType(entityType); - model.include(supertype); - } - } - } - - private EntityType createEntityType(Class cl, Map, EntityType> types) { - if (types.get(cl) != null) { - return types.get(cl); - } else { - EntityType type = allTypes.get(ClassUtils.getFullName(cl)); - if (type == null) { - type = typeFactory.getEntityType(cl); - } - types.put(cl, type); - String fullName = ClassUtils.getFullName(cl); - if (!allTypes.containsKey(fullName)) { - allTypes.put(fullName, type); - } - - typeMappings.register(type, queryTypeFactory.create(type)); - if (cl.getSuperclass() != null && !stopClasses.contains(cl.getSuperclass()) - && !cl.getSuperclass().isAnnotationPresent(QueryExclude.class)) { - type.addSupertype(new Supertype(typeFactory.get(cl.getSuperclass(), cl.getGenericSuperclass()))); - } - if (cl.isInterface()) { - for (Class iface : cl.getInterfaces()) { - if (!stopClasses.contains(iface) && !iface.isAnnotationPresent(QueryExclude.class)) { - type.addSupertype(new Supertype(typeFactory.get(iface))); - } - } - } - - return type; - } - } - - private void addConstructors(Class cl, EntityType type) { - for (Constructor constructor : cl.getConstructors()) { - if (constructor.getAnnotation(QueryProjection.class) != null) { - List parameters = Lists.newArrayList(); - for (int i = 0; i < constructor.getParameterTypes().length; i++) { - Type parameterType = typeFactory.get( - constructor.getParameterTypes()[i], - constructor.getGenericParameterTypes()[i]); - for (Annotation annotation : constructor.getParameterAnnotations()[i]) { - if (annotation.annotationType().equals(QueryType.class)) { - QueryType queryType = (QueryType)annotation; - parameterType = parameterType.as(TypeCategory.valueOf(queryType.value().name())); - } - } - parameters.add(new Parameter("param" + i, parameterType)); - } - type.addConstructor(new com.mysema.codegen.model.Constructor(parameters)); - } - } - } - - private void addProperties(Class cl, EntityType type) { - Set handled = new HashSet(); - - // fields - if (handleFields) { - for (Field field : cl.getDeclaredFields()) { - if (!Modifier.isStatic(field.getModifiers())) { - if (Modifier.isTransient(field.getModifiers()) && !field.isAnnotationPresent(QueryType.class)) { - continue; - } - AnnotatedElement annotated = ReflectionUtils.getAnnotatedElement(cl, field.getName(), field.getType()); - Method method = ReflectionUtils.getGetterOrNull(cl, field.getName(), field.getType()); - Type propertyType = null; - if (method != null) { - propertyType = getPropertyType(cl, annotated, method.getReturnType(), method.getGenericReturnType()); - } else { - propertyType = getPropertyType(cl, annotated, field.getType(), field.getGenericType()); - } - Property property = createProperty(type, field.getName(), propertyType, field); - if (property != null) { - type.addProperty(property); - } - handled.add(field.getName()); - } - } - } - - // getters - if (handleMethods) { - for (Method method : cl.getDeclaredMethods()) { - String name = method.getName(); - if (method.getParameterTypes().length == 0 - && ((name.startsWith("get") && name.length() > 3) - || (name.startsWith("is") && name.length() > 2))) { - String propertyName; - if (name.startsWith("get")) { - propertyName = BeanUtils.uncapitalize(name.substring(3)); - } else { - propertyName = BeanUtils.uncapitalize(name.substring(2)); - } - if (handled.contains(propertyName)) { - continue; - } - Type propertyType = getPropertyType(cl, method, method.getReturnType(), method.getGenericReturnType()); - Property property = createProperty(type, propertyName, propertyType, method); - if (property != null) { - type.addProperty(property); - } - } - } - } - } - - private Type getPropertyType(Class cl, AnnotatedElement annotated, Class type, - java.lang.reflect.Type genericType) { - Type propertyType = null; - if (annotated.isAnnotationPresent(embeddedAnnotation)) { - Class embeddableType = type; - if (Collection.class.isAssignableFrom(type)) { - embeddableType = ReflectionUtils.getTypeParameterAsClass(genericType, 0); - } else if (Map.class.isAssignableFrom(type)) { - embeddableType = ReflectionUtils.getTypeParameterAsClass(genericType, 1); - } - if (!embeddableType.getName().startsWith("java.")) { - typeFactory.addEmbeddableType(embeddableType); - if (!embeddableTypes.containsKey(embeddableType) - && !entityTypes.containsKey(embeddableType) - && !superTypes.containsKey(embeddableType)) { - EntityType entityType = createEntityType(embeddableType, embeddableTypes); - addProperties(embeddableType, entityType); - if (embeddableType == type) { - propertyType = entityType; - } - } - } - } - if (propertyType == null) { - propertyType = typeFactory.get(type, genericType); - if (propertyType instanceof EntityType && !allTypes.containsKey(ClassUtils.getFullName(type))) { - String fullName = ClassUtils.getFullName(type); - if (!allTypes.containsKey(fullName)) { - allTypes.put(fullName, (EntityType)propertyType); - } - } - } - return propertyType; - } - - @Nullable - private Property createProperty(EntityType entityType, String propertyName, Type propertyType, - AnnotatedElement annotated) { - List inits = Collections.emptyList(); - if (annotated.isAnnotationPresent(skipAnnotation) - && !annotated.isAnnotationPresent(QueryType.class)) { - return null; - } - if (annotated.isAnnotationPresent(QueryInit.class)) { - inits = ImmutableList.copyOf(annotated.getAnnotation(QueryInit.class).value()); - } - if (annotated.isAnnotationPresent(QueryType.class)) { - QueryType queryType = annotated.getAnnotation(QueryType.class); - if (queryType.value().equals(PropertyType.NONE)) { - return null; - } - propertyType = propertyType.as(TypeCategory.valueOf(queryType.value().name())); - } - return new Property(entityType, propertyName, propertyType, inits); - } - - private void scanPackages(String... packages) { - if (packages == null) { - return; - } - for (String pkg : packages) { - try { - for (Class cl : ClassPathUtils.scanPackage(classLoader, pkg)) { - handleClass(cl); - } - } catch (IOException e) { - throw new QueryException(e); - } - } - } - - private void handleClass(Class cl) { - if (stopClasses.contains(cl) || cl.isAnnotationPresent(QueryExclude.class)) { - return; - } else if (cl.getAnnotation(entityAnnotation) != null) { - entityTypes.put(cl, null); - } else if (cl.getAnnotation(embeddableAnnotation) != null) { - embeddableTypes.put(cl, null); - } else if (cl.getAnnotation(supertypeAnnotation) != null) { - superTypes.put(cl, null); - } else { - for (Constructor constructor : cl.getConstructors()) { - if (constructor.getAnnotation(QueryProjection.class) != null) { - projectionTypes.put(cl, null); - break; - } - } - } - } - - private void serialize(Serializer serializer, Map, EntityType> types) throws IOException { - for (Map.Entry, EntityType> entityType : types.entrySet()) { - Type type = typeMappings.getPathType(entityType.getValue(), entityType.getValue(), true); - String packageName = type.getPackageName(); - String className = packageName.length() > 0 ? (packageName + "." + type.getSimpleName()) : type.getSimpleName(); - SerializerConfig config = serializerConfig; - if (entityType.getKey().isAnnotationPresent(Config.class)) { - config = SimpleSerializerConfig.getConfig(entityType.getKey().getAnnotation(Config.class)); - } - String fileSuffix = createScalaSources ? ".scala" : ".java"; - write(serializer, className.replace('.', '/') + fileSuffix, config, entityType.getValue()); - } - } - - private void write(Serializer serializer, String path, SerializerConfig serializerConfig, - EntityType type) throws IOException { - File targetFile = new File(targetFolder, path); - generatedFiles.add(targetFile); - Writer w = writerFor(targetFile); - try { - CodeWriter writer = createScalaSources ? new ScalaWriter(w) : new JavaWriter(w); - serializer.serialize(type, serializerConfig, writer); - } finally { - w.close(); - } - } - - private Writer writerFor(File file) { - if (!file.getParentFile().exists() && !file.getParentFile().mkdirs()) { - System.err.println("Folder " + file.getParent() + " could not be created"); - } - try { - return new OutputStreamWriter(new FileOutputStream(file), charset); - } catch (FileNotFoundException e) { - throw new RuntimeException(e.getMessage(), e); - } - } - - - /** - * @return - */ - public Set getGeneratedFiles() { - return generatedFiles; - } - - /** - * Set the entity annotation - * - * @param entityAnnotation - */ - public void setEntityAnnotation(Class entityAnnotation) { - this.entityAnnotation = entityAnnotation; - } - - /** - * Set the supertype annotation - * - * @param supertypeAnnotation - */ - public void setSupertypeAnnotation( - Class supertypeAnnotation) { - this.supertypeAnnotation = supertypeAnnotation; - } - - /** - * Set the embeddable annotation - * - * @param embeddableAnnotation - */ - public void setEmbeddableAnnotation( - Class embeddableAnnotation) { - this.embeddableAnnotation = embeddableAnnotation; - } - - /** - * Set the embedded annotation - * - * @param embeddedAnnotation - */ - public void setEmbeddedAnnotation(Class embeddedAnnotation) { - this.embeddedAnnotation = embeddedAnnotation; - } - - /** - * Set the skip annotation - * - * @param skipAnnotation - */ - public void setSkipAnnotation(Class skipAnnotation) { - this.skipAnnotation = skipAnnotation; - } - - /** - * Set the target folder for generated sources - * - * @param targetFolder - */ - public void setTargetFolder(File targetFolder) { - this.targetFolder = targetFolder; - } - - /** - * Set the serializer class to be used - * - * @param serializerClass - */ - public void setSerializerClass(Class serializerClass) { - codegenModule.bind(serializerClass); - this.serializerClass = serializerClass; - } - - /** - * Set the typemappings class to be used - * - * @param typeMappingsClass - */ - public void setTypeMappingsClass(Class typeMappingsClass) { - codegenModule.bind(TypeMappings.class, typeMappingsClass); - } - - /** - * Set whether Scala sources are generated - * - * @param createScalaSources - */ - public void setCreateScalaSources(boolean createScalaSources) { - this.createScalaSources = createScalaSources; - } - - /** - * Set the keywords to be used - * - * @param keywords - */ - public void setKeywords(Collection keywords) { - codegenModule.bind(CodegenModule.KEYWORDS, keywords); - } - - /** - * Set the name prefix - * - * @param prefix - */ - public void setNamePrefix(String prefix) { - codegenModule.bind(CodegenModule.PREFIX, prefix); - } - - /** - * Set the name suffix - * - * @param suffix - */ - public void setNameSuffix(String suffix) { - codegenModule.bind(CodegenModule.SUFFIX, suffix); - } - - /** - * Set the package suffix - * - * @param suffix - */ - public void setPackageSuffix(String suffix) { - codegenModule.bind(CodegenModule.PACKAGE_SUFFIX, suffix); - } - - /** - * Set whether fields are handled (default true) - * - * @param b - */ - public void setHandleFields(boolean b) { - handleFields = b; - } - - /** - * Set whether fields are handled (default true) - * - * @param b - */ - public void setHandleMethods(boolean b) { - handleMethods = b; - } - - /** - * Add a stop class to be used (default Object.class and Enum.class) - * - * @param cl - */ - public void addStopClass(Class cl) { - stopClasses.add(cl); - } - - -} diff --git a/querydsl-codegen/src/main/java/com/mysema/query/codegen/JavaTypeMappings.java b/querydsl-codegen/src/main/java/com/mysema/query/codegen/JavaTypeMappings.java deleted file mode 100644 index 84930e9d79..0000000000 --- a/querydsl-codegen/src/main/java/com/mysema/query/codegen/JavaTypeMappings.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2012, Mysema Ltd - * - * 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. - */ -package com.mysema.query.codegen; - -import com.mysema.codegen.model.TypeCategory; -import com.mysema.query.types.Expression; -import com.mysema.query.types.Path; -import com.mysema.query.types.expr.BooleanExpression; -import com.mysema.query.types.expr.ComparableExpression; -import com.mysema.query.types.expr.EnumExpression; -import com.mysema.query.types.expr.NumberExpression; -import com.mysema.query.types.expr.StringExpression; -import com.mysema.query.types.expr.TemporalExpression; -import com.mysema.query.types.path.BooleanPath; -import com.mysema.query.types.path.ComparablePath; -import com.mysema.query.types.path.DatePath; -import com.mysema.query.types.path.DateTimePath; -import com.mysema.query.types.path.EnumPath; -import com.mysema.query.types.path.NumberPath; -import com.mysema.query.types.path.SimplePath; -import com.mysema.query.types.path.StringPath; -import com.mysema.query.types.path.TimePath; -import com.mysema.query.types.template.BooleanTemplate; -import com.mysema.query.types.template.ComparableTemplate; -import com.mysema.query.types.template.DateTemplate; -import com.mysema.query.types.template.DateTimeTemplate; -import com.mysema.query.types.template.EnumTemplate; -import com.mysema.query.types.template.NumberTemplate; -import com.mysema.query.types.template.SimpleTemplate; -import com.mysema.query.types.template.StringTemplate; -import com.mysema.query.types.template.TimeTemplate; - -/** - * JavaTypeMappings defines mappings from {@link TypeCategory} instances to {@link Expression} types - * - * @author tiwe - * - */ -public class JavaTypeMappings extends TypeMappings { - - public JavaTypeMappings() { - register(TypeCategory.STRING, StringExpression.class, StringPath.class, StringTemplate.class); - register(TypeCategory.BOOLEAN, BooleanExpression.class, BooleanPath.class, BooleanTemplate.class); - register(TypeCategory.COMPARABLE, ComparableExpression.class, ComparablePath.class, ComparableTemplate.class); - register(TypeCategory.ENUM, EnumExpression.class, EnumPath.class, EnumTemplate.class); - register(TypeCategory.DATE, TemporalExpression.class, DatePath.class, DateTemplate.class); - register(TypeCategory.DATETIME, TemporalExpression.class, DateTimePath.class, DateTimeTemplate.class); - register(TypeCategory.TIME, TemporalExpression.class, TimePath.class, TimeTemplate.class); - register(TypeCategory.NUMERIC, NumberExpression.class, NumberPath.class, NumberTemplate.class); - register(TypeCategory.SIMPLE, Expression.class, SimplePath.class, SimpleTemplate.class); - - register(TypeCategory.ARRAY, Expression.class, SimplePath.class, SimpleTemplate.class); - register(TypeCategory.COLLECTION, Expression.class, SimplePath.class, SimpleTemplate.class); - register(TypeCategory.SET, Expression.class, SimplePath.class, SimpleTemplate.class); - register(TypeCategory.LIST, Expression.class, SimplePath.class, SimpleTemplate.class); - register(TypeCategory.MAP, Expression.class, SimplePath.class, SimpleTemplate.class); - - register(TypeCategory.CUSTOM, Expression.class, Path.class, SimpleTemplate.class); - register(TypeCategory.ENTITY, Expression.class, Path.class, SimpleTemplate.class); - } - - -} diff --git a/querydsl-codegen/src/main/java/com/mysema/query/codegen/Keywords.java b/querydsl-codegen/src/main/java/com/mysema/query/codegen/Keywords.java deleted file mode 100644 index 905777aa16..0000000000 --- a/querydsl-codegen/src/main/java/com/mysema/query/codegen/Keywords.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2012, Mysema Ltd - * - * 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. - */ -package com.mysema.query.codegen; - -import java.util.Collection; - -import com.google.common.collect.ImmutableList; - -/** - * Keywords sets in capitalized form to be used in GenericExporter and the APT processors - * - * @author tiwe - * - */ -public final class Keywords { - - private Keywords() {} - - public static final Collection JPA = ImmutableList.of( - "ABS","ALL","AND","ANY","AS","ASC","AVG","BETWEEN", - "BIT_LENGTH[51]","BOTH","BY","CASE","CHAR_LENGTH", - "CHARACTER_LENGTH","CLASS", - "COALESCE","CONCAT","COUNT","CURRENT_DATE","CURRENT_TIME", - "CURRENT_TIMESTAMP", - "DELETE","DESC","DISTINCT","ELSE","EMPTY","END","ENTRY", - "ESCAPE","EXISTS","FALSE","FETCH", - "FROM","GROUP","HAVING","IN","INDEX","INNER","IS","JOIN", - "KEY","LEADING","LEFT","LENGTH","LIKE", - "LOCATE","LOWER","MAX","MEMBER","MIN","MOD","NEW","NOT", - "NULL","NULLIF","OBJECT","OF","OR", - "ORDER","OUTER","POSITION","SELECT","SET","SIZE","SOME", - "SQRT","SUBSTRING","SUM","THEN", - "TRAILING","TRIM","TRUE","TYPE","UNKNOWN","UPDATE","UPPER", - "VALUE","WHEN","WHERE"); - - public static final Collection JDO = ImmutableList.of( - "AS","ASC", "ASCENDING","AVG", - "BY","COUNT", "DESC","DESCENDING", - "DISTINCT","EXCLUDE", "FROM","GROUP", - "HAVING","INTO","MAX","MIN", - "ORDER","PARAMETERS","RANGE","SELECT", - "SUBCLASSES","SUM","UNIQUE","VARIABLES","WHERE"); - -} diff --git a/querydsl-codegen/src/main/java/com/mysema/query/codegen/ProjectionSerializer.java b/querydsl-codegen/src/main/java/com/mysema/query/codegen/ProjectionSerializer.java deleted file mode 100644 index 8a7fa9f8e7..0000000000 --- a/querydsl-codegen/src/main/java/com/mysema/query/codegen/ProjectionSerializer.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.codegen; - -import com.google.common.base.Function; -import com.google.common.collect.Sets; -import com.mysema.codegen.CodeWriter; -import com.mysema.codegen.model.*; -import com.mysema.query.types.ConstructorExpression; -import com.mysema.query.types.Expression; -import com.mysema.query.types.expr.NumberExpression; - -import javax.annotation.Generated; -import javax.inject.Inject; -import java.io.IOException; -import java.util.Set; - -/** - * ProjectionSerializer is a {@link Serializer} implementation for projection types - * - * @author tiwe - * - */ -public final class ProjectionSerializer implements Serializer{ - - private final TypeMappings typeMappings; - - /** - * Create a new ProjectionSerializer instance - * - * @param typeMappings - */ - @Inject - public ProjectionSerializer(TypeMappings typeMappings) { - this.typeMappings = typeMappings; - } - - protected void intro(EntityType model, CodeWriter writer) throws IOException { - String simpleName = model.getSimpleName(); - Type queryType = typeMappings.getPathType(model, model, false); - - // package - if (!queryType.getPackageName().isEmpty()) { - writer.packageDecl(queryType.getPackageName()); - } - - // imports - writer.imports(NumberExpression.class.getPackage()); - writer.imports(Expression.class, ConstructorExpression.class, Generated.class); - - // javadoc - writer.javadoc(queryType + " is a Querydsl Projection type for " + simpleName); - - writer.line("@Generated(\"", getClass().getName(), "\")"); - - // class header -// writer.suppressWarnings("serial"); - Type superType = new ClassType(TypeCategory.SIMPLE, ConstructorExpression.class, model); - writer.beginClass(queryType, superType); - writer.privateStaticFinal(Types.LONG_P, "serialVersionUID", model.hashCode() + "L"); - } - - protected void outro(EntityType model, CodeWriter writer) throws IOException { - writer.end(); - } - - @Override - public void serialize(final EntityType model, SerializerConfig serializerConfig, - CodeWriter writer) throws IOException{ - // intro - intro(model, writer); - - String localName = writer.getRawName(model); - Set sizes = Sets.newHashSet(); - - for (Constructor c : model.getConstructors()) { - final boolean asExpr = sizes.add(c.getParameters().size()); - // begin - writer.beginConstructor(c.getParameters(), new Function() { - @Override - public Parameter apply(Parameter p) { - Type type; - if (!asExpr) { - type = typeMappings.getExprType(p.getType(), - model, false, false, true); - } else if (p.getType().isFinal()) { - type = new ClassType(Expression.class, p.getType()); - } else { - type = new ClassType(Expression.class, new TypeExtends(p.getType())); - } - return new Parameter(p.getName(), type); - } - }); - - // body - writer.beginLine("super(" + writer.getClassConstant(localName)); - // TODO: Fix for Scala (Array[Class]) - writer.append(", new Class[]{"); - boolean first = true; - - for (Parameter p : c.getParameters()) { - if (!first) { - writer.append(", "); - } - if (Types.PRIMITIVES.containsKey(p.getType())) { - Type primitive = Types.PRIMITIVES.get(p.getType()); - writer.append(writer.getClassConstant(primitive.getFullName())); - } else { - writer.append(writer.getClassConstant(writer.getRawName(p.getType()))); - } - first = false; - } - writer.append("}"); - - for (Parameter p : c.getParameters()) { - writer.append(", " + p.getName()); - } - - // end - writer.append(");\n"); - writer.end(); - } - - // outro - outro(model, writer); - } - -} diff --git a/querydsl-codegen/src/main/java/com/mysema/query/codegen/QueryTypeFactory.java b/querydsl-codegen/src/main/java/com/mysema/query/codegen/QueryTypeFactory.java deleted file mode 100644 index 43363db9c2..0000000000 --- a/querydsl-codegen/src/main/java/com/mysema/query/codegen/QueryTypeFactory.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.codegen; - -import com.mysema.codegen.model.Type; - -/** - * QueryTypeFactory defines an interface for mapping domain types to Querydsl expression types - * - * @author tiwe - * - */ -public interface QueryTypeFactory { - - /** - * @param type - * @return - */ - Type create(Type type); - -} \ No newline at end of file diff --git a/querydsl-codegen/src/main/java/com/mysema/query/codegen/QueryTypeFactoryImpl.java b/querydsl-codegen/src/main/java/com/mysema/query/codegen/QueryTypeFactoryImpl.java deleted file mode 100644 index e71ffe2219..0000000000 --- a/querydsl-codegen/src/main/java/com/mysema/query/codegen/QueryTypeFactoryImpl.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.codegen; - -import javax.inject.Inject; -import javax.inject.Named; - -import com.mysema.codegen.model.SimpleType; -import com.mysema.codegen.model.Type; - -/** - * QueryTypeFactoryImpl is the default implementation of the {@link QueryTypeFactory} interface - * - * @author tiwe - * - */ -public class QueryTypeFactoryImpl implements QueryTypeFactory { - - private final String prefix, suffix, packageSuffix; - - @Inject - public QueryTypeFactoryImpl( - @Named(CodegenModule.PREFIX) String prefix, - @Named(CodegenModule.SUFFIX) String suffix, - @Named(CodegenModule.PACKAGE_SUFFIX) String packageSuffix) { - this.prefix = prefix; - this.suffix = suffix; - this.packageSuffix = packageSuffix; - } - - @Override - public Type create(Type type) { - if (type.getPackageName().isEmpty()) { - return createWithoutPackage(type); - } else { - return createWithPackage(type); - } - } - - private Type createWithPackage(Type type) { - String packageName = type.getPackageName(); - String simpleName = prefix + normalizeName(type.getFullName() - .substring(packageName.length()+1)) + suffix; - packageName = (packageName.startsWith("java") ? "ext." : "") - + packageName + packageSuffix; - return new SimpleType(type.getCategory(), packageName+"."+simpleName, - packageName, simpleName, false, false); - } - - private Type createWithoutPackage(Type type) { - String simpleName = prefix + normalizeName(type.getFullName()) + suffix; - return new SimpleType(type.getCategory(), simpleName, "", simpleName, false, false); - } - - private String normalizeName(String name) { - return name.replace('.', '_').replace('$', '_'); - } - - -} diff --git a/querydsl-codegen/src/main/java/com/mysema/query/codegen/SerializerConfig.java b/querydsl-codegen/src/main/java/com/mysema/query/codegen/SerializerConfig.java deleted file mode 100644 index 76f0755b7a..0000000000 --- a/querydsl-codegen/src/main/java/com/mysema/query/codegen/SerializerConfig.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.codegen; - -/** - * SerializerConfig defines serialization options to be used in the {@link Serializer} - * - * @author tiwe - * - */ -public interface SerializerConfig { - - /** - * @return if accessors are used for entity fields - */ - boolean useEntityAccessors(); - - /** - * @return if indexed list accessors are used - */ - boolean useListAccessors(); - - /** - * @return if keyed map accessors are used - */ - boolean useMapAccessors(); - - /** - * @return if the default variable is created - */ - boolean createDefaultVariable(); - - /** - * @return the name of the default variable - */ - String defaultVariableName(); -} diff --git a/querydsl-codegen/src/main/java/com/mysema/query/codegen/Supertype.java b/querydsl-codegen/src/main/java/com/mysema/query/codegen/Supertype.java deleted file mode 100644 index cdcb7c3df0..0000000000 --- a/querydsl-codegen/src/main/java/com/mysema/query/codegen/Supertype.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.codegen; - -import javax.annotation.Nullable; - -import com.mysema.codegen.model.Type; - -/** - * Supertype defines a tuple of a {@link Type} and an optional {@link EntityType} instance used for - * supertype references in EntityType instances - * - * @author tiwe - * - */ -public class Supertype { - - @Nullable - private EntityType entityType; - - private final Type type; - - public Supertype(Type type) { - this.type = type; - } - - public Supertype(Type type, EntityType entityType) { - this.type = type; - this.entityType = entityType; - } - - @Nullable - public EntityType getEntityType() { - return entityType; - } - - public Type getType() { - return type; - } - - public void setEntityType(EntityType entityType) { - this.entityType = entityType; - } - - @Override - public int hashCode() { - return type.hashCode(); - } - - @Override - public boolean equals(Object o) { - if (o == this) { - return true; - } else if (o instanceof Supertype) { - return ((Supertype)o).type.equals(type); - } else { - return false; - } - } - - @Override - public String toString() { - return type.toString(); - } - -} diff --git a/querydsl-codegen/src/main/java/com/mysema/query/codegen/SupertypeSerializer.java b/querydsl-codegen/src/main/java/com/mysema/query/codegen/SupertypeSerializer.java deleted file mode 100644 index 509bbbb339..0000000000 --- a/querydsl-codegen/src/main/java/com/mysema/query/codegen/SupertypeSerializer.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.codegen; - -import java.util.Collection; - -import javax.inject.Inject; -import javax.inject.Named; - -/** - * SupertypeSerializer is a {@link Serializer} implementation for supertypes - * - * @author tiwe - * - */ -public final class SupertypeSerializer extends EntitySerializer{ - - /** - * Create a new SupertypeSerializer instance - * - * @param typeMappings - * @param keywords - */ - @Inject - public SupertypeSerializer(TypeMappings typeMappings, @Named("keywords") Collection keywords) { - super(typeMappings, keywords); - } - -} diff --git a/querydsl-codegen/src/main/java/com/mysema/query/codegen/TypeFactory.java b/querydsl-codegen/src/main/java/com/mysema/query/codegen/TypeFactory.java deleted file mode 100644 index 8f675985c2..0000000000 --- a/querydsl-codegen/src/main/java/com/mysema/query/codegen/TypeFactory.java +++ /dev/null @@ -1,250 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.codegen; - -import java.lang.annotation.Annotation; -import java.lang.reflect.Array; -import java.lang.reflect.TypeVariable; -import java.lang.reflect.WildcardType; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import com.google.common.collect.Lists; -import com.google.common.primitives.Primitives; -import com.mysema.codegen.model.ClassType; -import com.mysema.codegen.model.SimpleType; -import com.mysema.codegen.model.Type; -import com.mysema.codegen.model.TypeCategory; -import com.mysema.codegen.model.TypeExtends; -import com.mysema.codegen.model.TypeSuper; -import com.mysema.codegen.model.Types; -import com.mysema.util.ReflectionUtils; - -/** - * TypeFactory is a factory class for {@link Type} instances - * - * @author tiwe - * - */ -public final class TypeFactory { - - private static final Type ANY = new TypeExtends(Types.OBJECT); - - private final Map, Type> cache = new HashMap, Type>(); - - private final List> entityAnnotations; - - private final Set> embeddableTypes = new HashSet>(); - - private boolean unknownAsEntity = false; - - public TypeFactory() { - this(Lists.>newArrayList()); - } - - public TypeFactory(List> entityAnnotations) { - this.entityAnnotations = entityAnnotations; - } - - public EntityType getEntityType(Class cl) { - java.lang.reflect.Type generic = cl; - if (cl.getTypeParameters().length > 0) { - generic = new ParameterizedTypeImpl(cl, cl.getTypeParameters()); - } - return (EntityType) get(true, cl, generic); - } - - public Type get(Class cl) { - return get(isEntityClass(cl), cl, cl); - } - - public Type get(Class cl, java.lang.reflect.Type genericType) { - return get(isEntityClass(cl), cl, genericType); - } - - public Type get(boolean entity, Class cl, java.lang.reflect.Type genericType) { - List key = Arrays. asList(cl, genericType); - if (cache.containsKey(key)) { - Type value = cache.get(key); - if (entity && !(value instanceof EntityType)) { - value = new EntityType(value); - cache.put(key, value); - } - return value; - - } else { - Type value = create(entity, cl, genericType, key); - cache.put(key, value); - return value; - } - } - - private Type create(boolean entity, Class cl, java.lang.reflect.Type genericType, - List key) { - if (cl.isPrimitive()) { - cl = Primitives.wrap(cl); - } - Type value; - Type[] tempParams = (Type[]) Array.newInstance(Type.class, - ReflectionUtils.getTypeParameterCount(genericType)); - cache.put(key, new ClassType(cl, tempParams)); - Type[] parameters = getParameters(cl, genericType); - - if (cl.isArray()) { - Type componentType = get(cl.getComponentType()); - if (cl.getComponentType().isPrimitive()) { - componentType = Types.PRIMITIVES.get(componentType); - } - value = componentType.asArrayType(); - } else if (cl.isEnum()) { - value = new ClassType(TypeCategory.ENUM, cl); - } else if (Number.class.isAssignableFrom(cl) && Comparable.class.isAssignableFrom(cl)) { - value = new ClassType(TypeCategory.NUMERIC, cl, parameters); - } else if (entity) { - value = createOther(cl, entity, parameters); - } else if (Map.class.isAssignableFrom(cl)) { - value = new SimpleType(Types.MAP, parameters[0], asGeneric(parameters[1])); - } else if (List.class.isAssignableFrom(cl)) { - value = new SimpleType(Types.LIST, asGeneric(parameters[0])); - } else if (Set.class.isAssignableFrom(cl)) { - value = new SimpleType(Types.SET, asGeneric(parameters[0])); - } else if (Collection.class.isAssignableFrom(cl)) { - value = new SimpleType(Types.COLLECTION, asGeneric(parameters[0])); - } else { - value = createOther(cl, entity, parameters); - } - - if (genericType instanceof TypeVariable) { - TypeVariable tv = (TypeVariable)genericType; - if (tv.getBounds().length == 1 && tv.getBounds()[0].equals(Object.class)) { - value = new TypeSuper(tv.getName(), value); - } else { - value = new TypeExtends(tv.getName(), value); - } - } - - if (entity && !(value instanceof EntityType)) { - value = new EntityType(value); - } - return value; - } - - private Type asGeneric(Type type) { - if (type.getParameters().size() == 0) { - int count = type.getJavaClass().getTypeParameters().length; - if (count > 0) { - return new SimpleType(type, new Type[count]); - } - } - return type; - } - - private Type createOther(Class cl, boolean entity, Type[] parameters) { - TypeCategory typeCategory = TypeCategory.get(cl.getName()); - if (!typeCategory.isSubCategoryOf(TypeCategory.COMPARABLE) && Comparable.class.isAssignableFrom(cl) - && !cl.equals(Comparable.class)) { - typeCategory = TypeCategory.COMPARABLE; - } else if (embeddableTypes.contains(cl)) { - typeCategory = TypeCategory.CUSTOM; - } else if (typeCategory == TypeCategory.SIMPLE && entity) { - typeCategory = TypeCategory.ENTITY; - } else if (unknownAsEntity && typeCategory == TypeCategory.SIMPLE && !cl.getName().startsWith("java")) { - typeCategory = TypeCategory.CUSTOM; - } - return new ClassType(typeCategory, cl, parameters); - } - - private Type[] getParameters(Class cl, java.lang.reflect.Type genericType) { - int parameterCount = ReflectionUtils.getTypeParameterCount(genericType); - if (parameterCount > 0) { - return getGenericParameters(cl, genericType, parameterCount); - } else if (Map.class.isAssignableFrom(cl)) { - return new Type[]{ Types.OBJECT, Types.OBJECT }; - } else if (Collection.class.isAssignableFrom(cl)) { - return new Type[]{ Types.OBJECT }; - } else { - return new Type[0]; - } - } - - private Type[] getGenericParameters(Class cl, java.lang.reflect.Type genericType, - int parameterCount) { - Type[] types = new Type[parameterCount]; - for (int i = 0; i < types.length; i++) { - types[i] = getGenericParameter(cl, genericType, i); - } - return types; - } - - @SuppressWarnings("rawtypes") - private Type getGenericParameter(Class cl, java.lang.reflect.Type genericType, int i) { - java.lang.reflect.Type parameter = ReflectionUtils.getTypeParameter(genericType, i); - if (parameter instanceof TypeVariable) { - TypeVariable variable = (TypeVariable)parameter; - Type rv = get(ReflectionUtils.getTypeParameterAsClass(genericType, i), parameter); - return new TypeExtends(variable.getName(), rv); - } else if (parameter instanceof WildcardType - && ((WildcardType)parameter).getUpperBounds()[0].equals(Object.class) - && ((WildcardType)parameter).getLowerBounds().length == 0) { - return ANY; - } else { - Type rv = get(ReflectionUtils.getTypeParameterAsClass(genericType, i), parameter); - if (parameter instanceof WildcardType) { - rv = new TypeExtends(rv); - } - return rv; - } - } - - private boolean isEntityClass(Class cl) { - for (Class clazz : entityAnnotations) { - if (cl.getAnnotation(clazz) != null) { - return true; - } - } - return embeddableTypes.contains(cl); - } - - public void extendTypes() { - for (Map.Entry, Type> entry : cache.entrySet()) { - if (entry.getValue() instanceof EntityType) { - EntityType entityType = (EntityType)entry.getValue(); - if (entityType.getProperties().isEmpty()) { - for (Type type : cache.values()) { - if (type.getFullName().equals(entityType.getFullName()) && type instanceof EntityType) { - EntityType base = (EntityType)type; - for (Property property : base.getProperties()) { - entityType.addProperty(property); - } - } - } - } - } - } - } - - public void setUnknownAsEntity(boolean unknownAsEntity) { - this.unknownAsEntity = unknownAsEntity; - } - - public void addEmbeddableType(Class cl) { - embeddableTypes.add(cl); - } - -} diff --git a/querydsl-codegen/src/main/java/com/mysema/query/codegen/TypeResolver.java b/querydsl-codegen/src/main/java/com/mysema/query/codegen/TypeResolver.java deleted file mode 100644 index 884b94ff65..0000000000 --- a/querydsl-codegen/src/main/java/com/mysema/query/codegen/TypeResolver.java +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.codegen; - -import com.google.common.base.Objects; -import com.mysema.codegen.model.SimpleType; -import com.mysema.codegen.model.Type; -import com.mysema.codegen.model.TypeExtends; -import com.mysema.codegen.model.TypeSuper; - -/** - * TypeResolver provides type resolving functionality for resolving generic type variables to - * concrete types - * - * @author tiwe - * - */ -public final class TypeResolver { - - /** - * Resolve type declared in declaringType for context - * - * @param type type - * @param declaringType - * @param context - * @return - */ - public static Type resolve(Type type, Type declaringType, EntityType context) { - Type resolved = unwrap(type); - - String varName = getVarName(resolved); - if (varName != null) { - resolved = resolveVar(resolved, varName, declaringType, context); - } else if (!resolved.getParameters().isEmpty()) { - resolved = resolveWithParameters(resolved, declaringType, context); - } - - // rewrap entity type - if (type instanceof EntityType) { - if (!unwrap(type).equals(resolved)) { - resolved = new EntityType(resolved, ((EntityType)type).getSuperTypes()); - } else { - // reset to original type - resolved = type; - } - } - - return resolved; - } - - /** - * @param resolved - * @param varName - * @param declaringType - * @param context - * @return - */ - private static Type resolveVar(Type resolved, String varName, Type declaringType, EntityType context) { - // get parameter index of var in declaring type - int index = -1; - for (int i = 0; i < declaringType.getParameters().size(); i++) { - Type param = unwrap(declaringType.getParameters().get(i)); - if (param instanceof TypeExtends && Objects.equal(((TypeExtends)param).getVarName(), varName)) { - index = i; - } - } - - if (index == -1) { - throw new IllegalStateException("Did not find type " + varName - + " in " + declaringType.getParameters()); - } - - Supertype type = context.getSuperType(); - while (!type.getEntityType().equals(declaringType)) { - type = type.getEntityType().getSuperType(); - } - if (!type.getType().getParameters().isEmpty()) { - return type.getType().getParameters().get(index); - } else { - // raw type - return resolved; - } - } - - /** - * @param type - * @param declaringType - * @param context - * @return - */ - private static Type resolveWithParameters(Type type, Type declaringType, EntityType context) { - Type[] params = new Type[type.getParameters().size()]; - boolean transformed = false; - for (int i = 0; i < type.getParameters().size(); i++) { - Type param = type.getParameters().get(i); - if (param != null && !param.getFullName().equals(type.getFullName())) { - params[i] = resolve(param, declaringType, context); - if (!params[i].equals(param)) { - transformed = true; - } - } - } - if (transformed) { - return new SimpleType(type, params); - } else { - return type; - } - } - - /** - * @param type - * @return - */ - private static String getVarName(Type type) { - if (type instanceof TypeExtends) { - return ((TypeExtends)type).getVarName(); - } else if (type instanceof TypeSuper) { - return ((TypeSuper)type).getVarName(); - } else { - return null; - } - } - - /** - * @param type - * @return - */ - private static Type unwrap(Type type) { - if (type instanceof EntityType) { - return ((EntityType)type).getInnerType(); - } else { - return type; - } - } - - private TypeResolver() {} -} diff --git a/querydsl-codegen/src/main/java/com/mysema/query/codegen/package-info.java b/querydsl-codegen/src/main/java/com/mysema/query/codegen/package-info.java deleted file mode 100644 index 297f98c74f..0000000000 --- a/querydsl-codegen/src/main/java/com/mysema/query/codegen/package-info.java +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ - -/** - * Code generations models and serializers - */ -package com.mysema.query.codegen; diff --git a/querydsl-codegen/src/main/java/com/mysema/query/codegen/AbstractModule.java b/querydsl-codegen/src/main/java/com/querydsl/codegen/AbstractModule.java similarity index 83% rename from querydsl-codegen/src/main/java/com/mysema/query/codegen/AbstractModule.java rename to querydsl-codegen/src/main/java/com/querydsl/codegen/AbstractModule.java index 1257503692..7581d6fcff 100644 --- a/querydsl-codegen/src/main/java/com/mysema/query/codegen/AbstractModule.java +++ b/querydsl-codegen/src/main/java/com/querydsl/codegen/AbstractModule.java @@ -1,5 +1,5 @@ /* - * Copyright 2011, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,19 +11,20 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.codegen; +package com.querydsl.codegen; import java.lang.annotation.Annotation; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.util.HashMap; import java.util.Map; +import java.util.ServiceLoader; import javax.inject.Inject; import javax.inject.Named; /** - * AbstractModule provides a base class for annotation based dependency injection + * {@code AbstractModule} provides a base class for annotation based dependency injection * * @author tiwe * @@ -75,15 +76,23 @@ public final AbstractModule bind(Class iface, T implementation) { return this; } + public final void loadExtensions() { + ServiceLoader loader = ServiceLoader.load(Extension.class, Extension.class.getClassLoader()); + + for (Extension extension : loader) { + extension.addSupport(this); + } + } + protected abstract void configure(); @SuppressWarnings("unchecked") public final T get(Class iface) { if (instances.containsKey(iface)) { - return (T)instances.get(iface); + return (T) instances.get(iface); } else if (bindings.containsKey(iface)) { Class implementation = bindings.get(iface); - T instance = (T)createInstance(implementation); + T instance = (T) createInstance(implementation); instances.put(iface, instance); return instance; } else { @@ -94,11 +103,11 @@ public final T get(Class iface) { @SuppressWarnings("unchecked") public final T get(Class iface, String name) { if (namedInstances.containsKey(name)) { - return (T)namedInstances.get(name); + return (T) namedInstances.get(name); } else if (namedBindings.containsKey(name)) { Class implementation = namedBindings.get(name); if (implementation != null) { - T instance = (T)createInstance(implementation); + T instance = (T) createInstance(implementation); namedInstances.put(name, instance); return instance; } else { @@ -113,7 +122,7 @@ public final T get(Class iface, String name) { private T createInstance(Class implementation) { Constructor constructor = null; for (Constructor c : implementation.getConstructors()) { - if (c.getAnnotation(Inject.class) != null) { + if (c.isAnnotationPresent(Inject.class)) { constructor = c; break; } @@ -123,9 +132,7 @@ private T createInstance(Class implementation) { if (constructor == null) { try { constructor = implementation.getConstructor(); - } catch (SecurityException e) { - throw new RuntimeException(e); - } catch (NoSuchMethodException e) { + } catch (SecurityException | NoSuchMethodException e) { throw new RuntimeException(e); } } @@ -143,11 +150,7 @@ private T createInstance(Class implementation) { try { return (T) constructor.newInstance(args); // TODO : populate fields as well?!? - } catch (InstantiationException e) { - throw new RuntimeException(e); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } catch (InvocationTargetException e) { + } catch (InstantiationException | InvocationTargetException | IllegalAccessException e) { throw new RuntimeException(e); } @@ -160,7 +163,7 @@ private T createInstance(Class implementation) { private Named getNamedAnnotation(Annotation[] annotations) { for (Annotation annotation : annotations) { if (annotation.annotationType().equals(Named.class)) { - return (Named)annotation; + return (Named) annotation; } } return null; diff --git a/querydsl-codegen/src/main/java/com/querydsl/codegen/AnnotationHelper.java b/querydsl-codegen/src/main/java/com/querydsl/codegen/AnnotationHelper.java new file mode 100644 index 0000000000..c61a0fc6f3 --- /dev/null +++ b/querydsl-codegen/src/main/java/com/querydsl/codegen/AnnotationHelper.java @@ -0,0 +1,49 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.codegen; + +import java.lang.annotation.Annotation; + +import com.querydsl.codegen.utils.model.TypeCategory; + +/** + * {@code AnnotationHelper} defines a interface to provide custom annotation processing + * for {@link TypeFactory}. + * + * @author dyorgio + */ +public interface AnnotationHelper { + + /** + * Verify if AnnotationHelper instance can handle the annotation. + * @param annotationClass Annotation class. + * @return {@code true} if this AnnotationHelper can handle the annotation. + */ + boolean isSupported(Class annotationClass); + + /** + * Get specific object that will be used as part of type cache key. + * @param annotation Annotation instance. + * @return Any object, normally a annotation param. Can be {@code null}. + */ + Object getCustomKey(Annotation annotation); + + /** + * Get the {@link TypeCategory} according with object Class and Annotation. + * @param cl Class of type. + * @param annotation Annotation found on element. + * @return Custom {@link TypeCategory}. + */ + TypeCategory getTypeByAnnotation(Class cl, Annotation annotation); +} diff --git a/querydsl-codegen/src/main/java/com/querydsl/codegen/BeanSerializer.java b/querydsl-codegen/src/main/java/com/querydsl/codegen/BeanSerializer.java new file mode 100644 index 0000000000..7d4200d2ba --- /dev/null +++ b/querydsl-codegen/src/main/java/com/querydsl/codegen/BeanSerializer.java @@ -0,0 +1,305 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.codegen; + +import com.querydsl.codegen.utils.CodeWriter; +import com.querydsl.codegen.utils.model.ClassType; +import com.querydsl.codegen.utils.model.Parameter; +import com.querydsl.codegen.utils.model.Type; +import com.querydsl.codegen.utils.model.TypeCategory; +import com.querydsl.codegen.utils.model.Types; +import com.querydsl.core.util.BeanUtils; + +import javax.inject.Inject; +import javax.inject.Named; +import java.io.IOException; +import java.lang.annotation.Annotation; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Function; + +/** + * {@code BeanSerializer} is a {@link Serializer} implementation which serializes {@link EntityType} + * instances into JavaBean classes + * + * @author tiwe + */ +public class BeanSerializer implements Serializer { + + public static final String DEFAULT_JAVADOC_SUFFIX = " is a Querydsl bean type"; + + public static final boolean DEFAULT_PROPERTY_ANNOTATIONS = true; + + private static final Function propertyToParameter = new Function() { + @Override + public Parameter apply(Property input) { + return new Parameter(input.getName(), input.getType()); + } + }; + private final Class generatedAnnotationClass; + + private final boolean propertyAnnotations; + + private final List interfaces = new ArrayList<>(); + + private final String javadocSuffix; + + private boolean addToString, addFullConstructor; + + private boolean printSupertype = false; + + /** + * Create a new BeanSerializer + */ + public BeanSerializer() { + this(DEFAULT_PROPERTY_ANNOTATIONS, DEFAULT_JAVADOC_SUFFIX, GeneratedAnnotationResolver.resolveDefault()); + } + + /** + * Create a new BeanSerializer with the given javadoc suffix + * + * @param javadocSuffix suffix to be used after the simple name in class level javadoc + */ + public BeanSerializer(String javadocSuffix) { + this(DEFAULT_PROPERTY_ANNOTATIONS, javadocSuffix); + } + + /** + * Create a new BeanSerializer with the given javadoc suffix and generatedAnnotationClass + * + * @param javadocSuffix suffix to be used after the simple name in class level javadoc + * @param generatedAnnotationClass the fully qualified class name of the Single-Element Annotation (with {@code String} element) to be used on the generated classes. + * @see Single-Element Annotation + */ + @Inject + public BeanSerializer( + @Named(CodegenModule.JAVADOC_SUFFIX) String javadocSuffix, + @Named(CodegenModule.GENERATED_ANNOTATION_CLASS) Class generatedAnnotationClass) { + this(DEFAULT_PROPERTY_ANNOTATIONS, javadocSuffix, generatedAnnotationClass); + } + + /** + * Create a new BeanSerializer + * + * @param propertyAnnotations true, to serialize property annotations + */ + public BeanSerializer(boolean propertyAnnotations) { + this(propertyAnnotations, DEFAULT_JAVADOC_SUFFIX); + } + + /** + * Create a new BeanSerializer + * + * @param propertyAnnotations true, to serialize property annotations + * @param javadocSuffix suffix to be used after the simple name in class level javadoc + */ + public BeanSerializer(boolean propertyAnnotations, String javadocSuffix) { + this(propertyAnnotations, javadocSuffix, GeneratedAnnotationResolver.resolveDefault()); + } + + /** + * Create a new BeanSerializer + * + * @param propertyAnnotations true, to serialize property annotations + * @param javadocSuffix suffix to be used after the simple name in class level javadoc + * @param generatedAnnotationClass the fully qualified class name of the Single-Element Annotation (with {@code String} element) to be used on the generated classes. + * * @see Single-Element Annotation + */ + public BeanSerializer(boolean propertyAnnotations, String javadocSuffix, Class generatedAnnotationClass) { + this.propertyAnnotations = propertyAnnotations; + this.javadocSuffix = javadocSuffix; + this.generatedAnnotationClass = generatedAnnotationClass; + } + + @Override + public void serialize( + EntityType model, SerializerConfig serializerConfig, + CodeWriter writer) throws IOException { + String simpleName = model.getSimpleName(); + + // package + if (!model.getPackageName().isEmpty()) { + writer.packageDecl(model.getPackageName()); + } + + // imports + Set importedClasses = getAnnotationTypes(model); + for (Type iface : interfaces) { + importedClasses.add(iface.getFullName()); + } + importedClasses.add(generatedAnnotationClass.getName()); + if (model.hasLists()) { + importedClasses.add(List.class.getName()); + } + if (model.hasCollections()) { + importedClasses.add(Collection.class.getName()); + } + if (model.hasSets()) { + importedClasses.add(Set.class.getName()); + } + if (model.hasMaps()) { + importedClasses.add(Map.class.getName()); + } + if (addToString && model.hasArrays()) { + importedClasses.add(Arrays.class.getName()); + } + writer.importClasses(importedClasses.toArray(new String[0])); + + // javadoc + writer.javadoc(simpleName + javadocSuffix); + + // header + for (Annotation annotation : model.getAnnotations()) { + writer.annotation(annotation); + } + + writer.line("@", generatedAnnotationClass.getSimpleName(), "(\"", getClass().getName(), "\")"); + + if (!interfaces.isEmpty()) { + Type superType = null; + if (printSupertype && model.getSuperType() != null) { + superType = model.getSuperType().getType(); + } + Type[] ifaces = interfaces.toArray(new Type[0]); + writer.beginClass(model, superType, ifaces); + } else if (printSupertype && model.getSuperType() != null) { + writer.beginClass(model, model.getSuperType().getType()); + } else { + writer.beginClass(model); + } + + + bodyStart(model, writer); + + if (addFullConstructor) { + addFullConstructor(model, writer); + } + + // fields + for (Property property : model.getProperties()) { + if (propertyAnnotations) { + for (Annotation annotation : property.getAnnotations()) { + writer.annotation(annotation); + } + } + writer.privateField(property.getType(), property.getEscapedName()); + } + + // accessors + for (Property property : model.getProperties()) { + String propertyName = property.getEscapedName(); + // getter + writer.beginPublicMethod(property.getType(), "get" + BeanUtils.capitalize(propertyName)); + writer.line("return ", propertyName, ";"); + writer.end(); + // setter + Parameter parameter = new Parameter(propertyName, property.getType()); + writer.beginPublicMethod(Types.VOID, "set" + BeanUtils.capitalize(propertyName), parameter); + writer.line("this.", propertyName, " = ", propertyName, ";"); + writer.end(); + } + + if (addToString) { + addToString(model, writer); + } + + bodyEnd(model, writer); + + writer.end(); + } + + protected void addFullConstructor(EntityType model, CodeWriter writer) throws IOException { + // public empty constructor + writer.beginConstructor(); + writer.end(); + + // full constructor + writer.beginConstructor(model.getProperties(), propertyToParameter::apply); + for (Property property : model.getProperties()) { + writer.line("this.", property.getEscapedName(), " = ", property.getEscapedName(), ";"); + } + writer.end(); + } + + protected void addToString(EntityType model, CodeWriter writer) throws IOException { + writer.line("@Override"); + writer.beginPublicMethod(Types.STRING, "toString"); + StringBuilder builder = new StringBuilder(); + for (Property property : model.getProperties()) { + String propertyName = property.getEscapedName(); + if (builder.length() > 0) { + builder.append(" + \", "); + } else { + builder.append("\""); + } + builder.append(propertyName).append(" = \" + "); + if (property.getType().getCategory() == TypeCategory.ARRAY) { + builder.append("Arrays.toString(").append(propertyName).append(")"); + } else { + builder.append(propertyName); + } + } + writer.line(" return ", builder.toString(), ";"); + writer.end(); + } + + protected void bodyStart(EntityType model, CodeWriter writer) throws IOException { + // template method + } + + protected void bodyEnd(EntityType model, CodeWriter writer) throws IOException { + // template method + } + + private Set getAnnotationTypes(EntityType model) { + Set imports = new HashSet(); + for (Annotation annotation : model.getAnnotations()) { + imports.add(annotation.annotationType().getName()); + } + if (propertyAnnotations) { + for (Property property : model.getProperties()) { + for (Annotation annotation : property.getAnnotations()) { + imports.add(annotation.annotationType().getName()); + } + } + } + return imports; + } + + public void addInterface(Class iface) { + interfaces.add(new ClassType(iface)); + } + + public void addInterface(Type type) { + interfaces.add(type); + } + + public void setAddToString(boolean addToString) { + this.addToString = addToString; + } + + public void setAddFullConstructor(boolean addFullConstructor) { + this.addFullConstructor = addFullConstructor; + } + + public void setPrintSupertype(boolean printSupertype) { + this.printSupertype = printSupertype; + } + +} diff --git a/querydsl-codegen/src/main/java/com/querydsl/codegen/ClassPathUtils.java b/querydsl-codegen/src/main/java/com/querydsl/codegen/ClassPathUtils.java new file mode 100644 index 0000000000..803d87adb2 --- /dev/null +++ b/querydsl-codegen/src/main/java/com/querydsl/codegen/ClassPathUtils.java @@ -0,0 +1,81 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.codegen; + +import io.github.classgraph.ClassGraph; + +import java.io.IOException; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * {@code ClassPathUtils} provides classpath scanning functionality + * + * @author tiwe + */ +public final class ClassPathUtils { + + /** + * Return the classes from the given package and subpackages using the supplied classloader + * + * @param classLoader classloader to be used + * @param pkg package to scan + * @return set of found classes + * @throws IOException + */ + public static Set> scanPackage(ClassLoader classLoader, Package pkg) throws IOException { + return scanPackage(classLoader, pkg.getName()); + } + + /** + * Return the classes from the given package and subpackages using the supplied classloader + * + * @param classLoader classloader to be used + * @param pkg package to scan + * @return set of found classes + * @throws IOException + */ + public static Set> scanPackage(ClassLoader classLoader, String pkg) throws IOException { + return new ClassGraph() + .enableClassInfo() + .acceptPackages(pkg) + .rejectPackages("com.sun", "com.apple") + .overrideClassLoaders(classLoader) + .scan() + .getAllClasses() + .stream().map(info -> safeClassForName(classLoader, info.getName())) + .collect(Collectors.toSet()); + } + + /** + * Get the class for the given className via the given classLoader + * + * @param classLoader classloader to be used + * @param className fully qualified class name + * @return {@code Class} instance matching the class name or null if not found + */ + public static Class safeClassForName(ClassLoader classLoader, String className) { + try { + if (className.startsWith("com.sun.") || className.startsWith("com.apple.")) { + return null; + } else { + return Class.forName(className, true, classLoader); + } + } catch (ClassNotFoundException | NoClassDefFoundError e) { + return null; + } + } + + private ClassPathUtils() { } +} diff --git a/querydsl-codegen/src/main/java/com/querydsl/codegen/CodegenModule.java b/querydsl-codegen/src/main/java/com/querydsl/codegen/CodegenModule.java new file mode 100644 index 0000000000..4bd5bd7698 --- /dev/null +++ b/querydsl-codegen/src/main/java/com/querydsl/codegen/CodegenModule.java @@ -0,0 +1,87 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.codegen; + +import static com.querydsl.codegen.BeanSerializer.DEFAULT_JAVADOC_SUFFIX; + +import java.util.Collections; + +/** + * {@code CodegenModule} provides a module for general serialization + * + * @author tiwe + * + */ +public class CodegenModule extends AbstractModule { + + /** + * key for the query type name prefix + */ + public static final String PREFIX = "prefix"; + + /** + * key for the query type name suffix + */ + public static final String SUFFIX = "suffix"; + + /** + * key for the keywords set + */ + public static final String KEYWORDS = "keywords"; + + /** + * key for the package suffix + */ + public static final String PACKAGE_SUFFIX = "packageSuffix"; + + /** + * key for the custom imports set + */ + public static final String IMPORTS = "imports"; + + /** + * key for the variable name function class + */ + public static final String VARIABLE_NAME_FUNCTION_CLASS = "variableNameFunction"; + + /** + * the fully qualified class name of the Single-Element Annotation (with {@code String} element) + * to indicate that these have been generated. Defaults to java's {@code Generated} annotation (depending on java version) + */ + public static final String GENERATED_ANNOTATION_CLASS = "generatedAnnotationClass"; + + protected static final String JAVADOC_SUFFIX = "javadocSuffix"; + + @Override + protected void configure() { + bind(TypeMappings.class, JavaTypeMappings.class); + bind(QueryTypeFactory.class, QueryTypeFactoryImpl.class); + bind(EntitySerializer.class, DefaultEntitySerializer.class); + bind(EmbeddableSerializer.class, DefaultEmbeddableSerializer.class); + bind(ProjectionSerializer.class, DefaultProjectionSerializer.class); + bind(SupertypeSerializer.class, DefaultSupertypeSerializer.class); + bind(Filer.class, DefaultFiler.class); + + // configuration for QueryTypeFactory + bind(PREFIX, "Q"); + bind(SUFFIX, ""); + bind(PACKAGE_SUFFIX, ""); + bind(KEYWORDS, Collections.emptySet()); + bind(IMPORTS, Collections.emptySet()); + bind(VARIABLE_NAME_FUNCTION_CLASS, DefaultVariableNameFunction.INSTANCE); + bindInstance(GENERATED_ANNOTATION_CLASS, GeneratedAnnotationResolver.resolveDefault()); + bind(JAVADOC_SUFFIX, DEFAULT_JAVADOC_SUFFIX); + } + +} diff --git a/querydsl-codegen/src/main/java/com/querydsl/codegen/DefaultEmbeddableSerializer.java b/querydsl-codegen/src/main/java/com/querydsl/codegen/DefaultEmbeddableSerializer.java new file mode 100644 index 0000000000..819c18147e --- /dev/null +++ b/querydsl-codegen/src/main/java/com/querydsl/codegen/DefaultEmbeddableSerializer.java @@ -0,0 +1,108 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.codegen; + +import static com.querydsl.codegen.utils.Symbols.UNCHECKED; + +import java.io.IOException; +import java.lang.annotation.Annotation; +import java.util.Collection; + +import javax.inject.Inject; +import javax.inject.Named; + +import com.querydsl.codegen.utils.CodeWriter; +import com.querydsl.codegen.utils.model.ClassType; +import com.querydsl.codegen.utils.model.Type; +import com.querydsl.codegen.utils.model.TypeCategory; +import com.querydsl.codegen.utils.model.Types; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.dsl.*; + +/** + * {@code EmbeddableSerializer} is a {@link Serializer} implementation for embeddable types + * + * @author tiwe + * + */ +public final class DefaultEmbeddableSerializer extends DefaultEntitySerializer implements EmbeddableSerializer { + + /** + * Create a new {@code EmbeddableSerializer} instance + * + * @param typeMappings type mappings to be used + * @param keywords keywords to be used + * @param generatedAnnotationClass the fully qualified class name of the Single-Element Annotation (with {@code String} element) to be used on the generated classes. + * @see Single-Element Annotation + */ + @Inject + public DefaultEmbeddableSerializer( + TypeMappings typeMappings, + @Named(CodegenModule.KEYWORDS) Collection keywords, + @Named(CodegenModule.GENERATED_ANNOTATION_CLASS) Class generatedAnnotationClass) { + super(typeMappings, keywords, generatedAnnotationClass); + } + + /** + * Create a new {@code EmbeddableSerializer} instance. + * + * @param typeMappings type mappings to be used + * @param keywords keywords to be used + */ + public DefaultEmbeddableSerializer( + TypeMappings typeMappings, + Collection keywords) { + this(typeMappings, keywords, GeneratedAnnotationResolver.resolveDefault()); + } + + @Override + @SuppressWarnings(UNCHECKED) + protected void introClassHeader(CodeWriter writer, EntityType model) throws IOException { + Type queryType = typeMappings.getPathType(model, model, true); + + TypeCategory category = model.getOriginalCategory(); + Class pathType; + if (model.getProperties().isEmpty()) { + switch (category) { + case COMPARABLE : pathType = ComparablePath.class; break; + case ENUM: pathType = EnumPath.class; break; + case DATE: pathType = DatePath.class; break; + case DATETIME: pathType = DateTimePath.class; break; + case TIME: pathType = TimePath.class; break; + case NUMERIC: pathType = NumberPath.class; break; + case STRING: pathType = StringPath.class; break; + case BOOLEAN: pathType = BooleanPath.class; break; + default : pathType = BeanPath.class; + } + } else { + pathType = BeanPath.class; + } + + for (Annotation annotation : model.getAnnotations()) { + writer.annotation(annotation); + } + + writer.line("@", generatedAnnotationClass.getSimpleName(), "(\"", getClass().getName(), "\")"); + + if (category == TypeCategory.BOOLEAN || category == TypeCategory.STRING) { + writer.beginClass(queryType, new ClassType(pathType)); + } else { + writer.beginClass(queryType, new ClassType(category, pathType, model)); + } + + // TODO : generate proper serialVersionUID here + writer.privateStaticFinal(Types.LONG_P, "serialVersionUID", model.hashCode() + "L"); + } + +} diff --git a/querydsl-codegen/src/main/java/com/querydsl/codegen/DefaultEntitySerializer.java b/querydsl-codegen/src/main/java/com/querydsl/codegen/DefaultEntitySerializer.java new file mode 100644 index 0000000000..1dbe0b7955 --- /dev/null +++ b/querydsl-codegen/src/main/java/com/querydsl/codegen/DefaultEntitySerializer.java @@ -0,0 +1,847 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.codegen; + +import static com.querydsl.codegen.utils.Symbols.*; + +import java.io.IOException; +import java.lang.annotation.Annotation; +import java.util.*; +import java.util.function.Function; + +import javax.inject.Inject; +import javax.inject.Named; + +import com.querydsl.codegen.utils.CodeWriter; +import com.querydsl.codegen.utils.model.*; +import com.querydsl.core.types.*; +import com.querydsl.core.types.dsl.*; + +/** + * {@code EntitySerializer} is a {@link Serializer} implementation for entity types + * + * @author tiwe + * + */ +public class DefaultEntitySerializer implements EntitySerializer { + + private static final Parameter PATH_METADATA = new Parameter("metadata", new ClassType(PathMetadata.class)); + + private static final Parameter PATH_INITS = new Parameter("inits", new ClassType(PathInits.class)); + + private static final ClassType PATH_INITS_TYPE = new ClassType(PathInits.class); + + protected final TypeMappings typeMappings; + + protected final Collection keywords; + + protected final Class generatedAnnotationClass; + + /** + * Create a new {@code EntitySerializer} instance + * + * @param mappings type mappings to be used + * @param keywords keywords to be used + * @param generatedAnnotationClass the fully qualified class name of the Single-Element Annotation (with {@code String} element) to be used on the generated classes. + * @see Single-Element Annotation + */ + @Inject + public DefaultEntitySerializer( + TypeMappings mappings, + @Named(CodegenModule.KEYWORDS) Collection keywords, + @Named(CodegenModule.GENERATED_ANNOTATION_CLASS) Class generatedAnnotationClass) { + this.typeMappings = mappings; + this.keywords = keywords; + this.generatedAnnotationClass = generatedAnnotationClass; + } + + /** + * Create a new {@code EntitySerializer} instance + * + * @param mappings type mappings to be used + * @param keywords keywords to be used + */ + public DefaultEntitySerializer(TypeMappings mappings, Collection keywords) { + this(mappings, keywords, GeneratedAnnotationResolver.resolveDefault()); + } + + private boolean superTypeHasEntityFields(EntityType model) { + Supertype superType = model.getSuperType(); + return null != superType && null != superType.getEntityType() + && superType.getEntityType().hasEntityFields(); + } + + protected void constructors(EntityType model, SerializerConfig config, + CodeWriter writer) throws IOException { + + String localName = writer.getRawName(model); + String genericName = writer.getGenericName(true, model); + + boolean hasEntityFields = model.hasEntityFields() || superTypeHasEntityFields(model); + boolean stringOrBoolean = model.getOriginalCategory() == TypeCategory.STRING + || model.getOriginalCategory() == TypeCategory.BOOLEAN; + String thisOrSuper = hasEntityFields ? THIS : SUPER; + String additionalParams = getAdditionalConstructorParameter(model); + String classCast = localName.equals(genericName) ? EMPTY : "(Class) "; + + + // String + constructorsForVariables(writer, model); + + // Path + if (!localName.equals(genericName)) { + suppressAllWarnings(writer); + } + Type simpleModel = new SimpleType(model); + if (model.isFinal()) { + Type type = new ClassType(Path.class, simpleModel); + writer.beginConstructor(new Parameter("path", type)); + } else { + Type type = new ClassType(Path.class, new TypeExtends(simpleModel)); + writer.beginConstructor(new Parameter("path", type)); + } + + if (!hasEntityFields) { + if (stringOrBoolean) { + writer.line("super(path.getMetadata());"); + } else { + writer.line("super(", classCast, "path.getType(), path.getMetadata()" + additionalParams + ");"); + } + constructorContent(writer, model); + } else { + writer.line("this(", classCast, "path.getType(), path.getMetadata(), PathInits.getFor(path.getMetadata(), INITS));"); + } + writer.end(); + + // PathMetadata + if (hasEntityFields) { + writer.beginConstructor(PATH_METADATA); + writer.line("this(metadata, PathInits.getFor(metadata, INITS));"); + writer.end(); + } else { + if (!localName.equals(genericName)) { + suppressAllWarnings(writer); + } + writer.beginConstructor(PATH_METADATA); + if (stringOrBoolean) { + writer.line("super(metadata);"); + } else { + writer.line("super(", classCast, writer.getClassConstant(localName) + COMMA + "metadata" + additionalParams + ");"); + } + constructorContent(writer, model); + writer.end(); + } + + // PathMetadata, PathInits + if (hasEntityFields) { + if (!localName.equals(genericName)) { + suppressAllWarnings(writer); + } + writer.beginConstructor(PATH_METADATA, PATH_INITS); + writer.line(thisOrSuper, "(", classCast, writer.getClassConstant(localName) + COMMA + "metadata, inits" + additionalParams + ");"); + if (!hasEntityFields) { + constructorContent(writer, model); + } + writer.end(); + } + + // Class, PathMetadata, PathInits + if (hasEntityFields) { + Type type = new ClassType(Class.class, new TypeExtends(model)); + writer.beginConstructor(new Parameter("type", type), PATH_METADATA, PATH_INITS); + writer.line("super(type, metadata, inits" + additionalParams + ");"); + initEntityFields(writer, config, model); + constructorContent(writer, model); + writer.end(); + } + + } + + protected void constructorContent(CodeWriter writer, EntityType model) throws IOException { + // override in subclasses + } + + protected String getAdditionalConstructorParameter(EntityType model) { + return ""; + } + + protected void constructorsForVariables(CodeWriter writer, EntityType model) throws IOException { + String localName = writer.getRawName(model); + String genericName = writer.getGenericName(true, model); + + boolean stringOrBoolean = model.getOriginalCategory() == TypeCategory.STRING + || model.getOriginalCategory() == TypeCategory.BOOLEAN; + boolean hasEntityFields = model.hasEntityFields() || superTypeHasEntityFields(model); + String thisOrSuper = hasEntityFields ? THIS : SUPER; + String additionalParams = hasEntityFields ? "" : getAdditionalConstructorParameter(model); + + if (!localName.equals(genericName)) { + suppressAllWarnings(writer); + } + writer.beginConstructor(new Parameter("variable", Types.STRING)); + if (stringOrBoolean) { + writer.line(thisOrSuper,"(forVariable(variable)",additionalParams,");"); + } else { + writer.line(thisOrSuper,"(", localName.equals(genericName) ? EMPTY : "(Class) ", + writer.getClassConstant(localName) + COMMA + "forVariable(variable)", hasEntityFields ? ", INITS" : EMPTY, + additionalParams,");"); + } + if (!hasEntityFields) { + constructorContent(writer, model); + } + writer.end(); + } + + protected void entityAccessor(EntityType model, Property field, CodeWriter writer) throws IOException { + Type queryType = typeMappings.getPathType(field.getType(), model, false); + writer.beginPublicMethod(queryType, field.getEscapedName()); + writer.line("if (", field.getEscapedName(), " == null) {"); + writer.line(" ", field.getEscapedName(), " = new ", writer.getRawName(queryType), + "(forProperty(\"", field.getName(), "\"));"); + writer.line("}"); + writer.line(RETURN, field.getEscapedName(), SEMICOLON); + writer.end(); + } + + protected void entityField(EntityType model, Property field, SerializerConfig config, + CodeWriter writer) throws IOException { + Type queryType = typeMappings.getPathType(field.getType(), model, false); + if (field.isInherited()) { + writer.line("// inherited"); + } + if (config.useEntityAccessors()) { + writer.protectedField(queryType, field.getEscapedName()); + } else { + writer.publicFinal(queryType, field.getEscapedName()); + } + } + + protected boolean hasOwnEntityProperties(EntityType model) { + if (model.hasEntityFields()) { + for (Property property : model.getProperties()) { + if (!property.isInherited() && property.getType().getCategory() == TypeCategory.ENTITY) { + return true; + } + } + } + return false; + } + + protected void initEntityFields(CodeWriter writer, SerializerConfig config, + EntityType model) throws IOException { + Supertype superType = model.getSuperType(); + if (superType != null) { + EntityType entityType = superType.getEntityType(); + if (entityType != null && entityType.hasEntityFields()) { + Type superQueryType = typeMappings.getPathType(entityType, model, false); + writer.line("this._super = new " + writer.getRawName(superQueryType) + "(type, metadata, inits);"); + } + } + + for (Property field : model.getProperties()) { + if (field.getType().getCategory() == TypeCategory.ENTITY) { + initEntityField(writer, config, model, field); + + } else if (field.isInherited() && superType != null && superType.getEntityType().hasEntityFields()) { + writer.line("this.", field.getEscapedName(), " = _super.", field.getEscapedName(), SEMICOLON); + } + } + } + + protected void initEntityField(CodeWriter writer, SerializerConfig config, EntityType model, + Property field) throws IOException { + Type queryType = typeMappings.getPathType(field.getType(), model, false); + if (!field.isInherited()) { + boolean hasEntityFields = field.getType() instanceof EntityType + && ((EntityType) field.getType()).hasEntityFields(); + writer.line("this." + field.getEscapedName() + ASSIGN, + "inits.isInitialized(\"" + field.getName() + "\") ? ", + NEW + writer.getRawName(queryType) + "(forProperty(\"" + field.getName() + "\")", + hasEntityFields ? (", inits.get(\"" + field.getName() + "\")") : EMPTY, + ") : null;"); + } else if (!config.useEntityAccessors()) { + writer.line("this.", field.getEscapedName(), ASSIGN, "_super.", field.getEscapedName(), SEMICOLON); + } + } + + protected void intro(EntityType model, SerializerConfig config, + CodeWriter writer) throws IOException { + introPackage(writer, model); + introImports(writer, config, model); + + writer.nl(); + + introJavadoc(writer, model); + introClassHeader(writer, model); + + introFactoryMethods(writer, model); + introInits(writer, model); + if (config.createDefaultVariable()) { + introDefaultInstance(writer, model, config.defaultVariableName()); + } + if (model.getSuperType() != null && model.getSuperType().getEntityType() != null) { + introSuper(writer, model); + } + } + + @SuppressWarnings(UNCHECKED) + protected void introClassHeader(CodeWriter writer, EntityType model) throws IOException { + Type queryType = typeMappings.getPathType(model, model, true); + + TypeCategory category = model.getOriginalCategory(); + Class pathType; + + if (model.getProperties().isEmpty()) { + switch (category) { + case COMPARABLE : pathType = ComparablePath.class; break; + case ENUM: pathType = EnumPath.class; break; + case DATE: pathType = DatePath.class; break; + case DATETIME: pathType = DateTimePath.class; break; + case TIME: pathType = TimePath.class; break; + case NUMERIC: pathType = NumberPath.class; break; + case STRING: pathType = StringPath.class; break; + case BOOLEAN: pathType = BooleanPath.class; break; + default : pathType = EntityPathBase.class; + } + } else { + pathType = EntityPathBase.class; + } + + for (Annotation annotation : model.getAnnotations()) { + writer.annotation(annotation); + } + + writer.line("@", generatedAnnotationClass.getSimpleName(), "(\"", getClass().getName(), "\")"); + + if (category == TypeCategory.BOOLEAN || category == TypeCategory.STRING) { + writer.beginClass(queryType, new ClassType(pathType)); + } else { + writer.beginClass(queryType, new ClassType(category, pathType, model)); + } + + // TODO : generate proper serialVersionUID here + long serialVersionUID = model.getFullName().hashCode(); + writer.privateStaticFinal(Types.LONG_P, "serialVersionUID", serialVersionUID + "L"); + } + + protected void introDefaultInstance(CodeWriter writer, EntityType model, String defaultName) throws IOException { + String simpleName = !defaultName.isEmpty() ? defaultName : model.getModifiedSimpleName(); + Type queryType = typeMappings.getPathType(model, model, true); + String alias = simpleName; + if (keywords.contains(simpleName.toUpperCase())) { + alias += "1"; + } + writer.publicStaticFinal(queryType, simpleName, NEW + queryType.getSimpleName() + "(\"" + alias + "\")"); + + } + + protected void introFactoryMethods(CodeWriter writer, final EntityType model) throws IOException { + String localName = writer.getRawName(model); + String genericName = writer.getGenericName(true, model); + Set sizes = new HashSet<>(); + + for (Constructor c : model.getConstructors()) { + // begin + if (!localName.equals(genericName)) { + writer.suppressWarnings(UNCHECKED); + } + Type returnType = new ClassType(ConstructorExpression.class, model); + final boolean asExpr = sizes.add(c.getParameters().size()); + writer.beginStaticMethod(returnType, "create", c.getParameters(), + new Function() { + @Override + public Parameter apply(Parameter p) { + Type type; + if (!asExpr) { + type = typeMappings.getExprType( + p.getType(), model, false, false, true); + } else if (p.getType().isFinal()) { + type = new ClassType(Expression.class, p.getType()); + } else { + type = new ClassType(Expression.class, new TypeExtends(p.getType())); + } + return new Parameter(p.getName(), type); + } + }); + + // body + // TODO : replace with class reference + writer.beginLine("return Projections.constructor("); +// if (!localName.equals(genericName)) { +// writer.append("(Class)"); +// } + writer.append(writer.getClassConstant(localName)); + writer.append(", new Class[]{"); + boolean first = true; + for (Parameter p : c.getParameters()) { + if (!first) { + writer.append(COMMA); + } + if (Types.PRIMITIVES.containsKey(p.getType())) { + Type primitive = Types.PRIMITIVES.get(p.getType()); + writer.append(writer.getClassConstant(primitive.getFullName())); + } else { + writer.append(writer.getClassConstant(writer.getRawName(p.getType()))); + } + first = false; + } + writer.append("}"); + + for (Parameter p : c.getParameters()) { + writer.append(COMMA).append(p.getName()); + } + + // end + writer.append(");\n"); + writer.end(); + } + } + + protected void introImports(CodeWriter writer, SerializerConfig config, + EntityType model) throws IOException { + writer.staticimports(PathMetadataFactory.class); + + // import package of query type + Type queryType = typeMappings.getPathType(model, model, true); + if (!model.getPackageName().isEmpty() + && !queryType.getPackageName().equals(model.getPackageName()) + && !queryType.getSimpleName().equals(model.getSimpleName())) { + String fullName = model.getFullName(); + String packageName = model.getPackageName(); + if (fullName.substring(packageName.length() + 1).contains(".")) { + fullName = fullName.substring(0, fullName.lastIndexOf('.')); + } + writer.importClasses(fullName); + } + + // delegate packages + introDelegatePackages(writer, model); + + // other packages + writer.imports(SimpleExpression.class.getPackage()); + + // other classes + List> classes = new ArrayList<>(); + classes.add(PathMetadata.class); + classes.add(generatedAnnotationClass); + + if (!getUsedClassNames(model).contains("Path")) { + classes.add(Path.class); + } + if (!model.getConstructors().isEmpty()) { + classes.add(ConstructorExpression.class); + classes.add(Projections.class); + classes.add(Expression.class); + } + boolean inits = false; + if (model.hasEntityFields() || model.hasInits()) { + inits = true; + } else { + Set collections = EnumSet.of(TypeCategory.COLLECTION, TypeCategory.LIST, TypeCategory.SET); + for (Property property : model.getProperties()) { + if (!property.isInherited() && collections.contains(property.getType().getCategory())) { + inits = true; + break; + } + } + } + if (inits) { + classes.add(PathInits.class); + } + writer.imports(classes.toArray(new Class[0])); + } + + private Set getUsedClassNames(EntityType model) { + Set result = new HashSet<>(); + result.add(model.getSimpleName()); + for (Property property : model.getProperties()) { + result.add(property.getType().getSimpleName()); + for (Type type : property.getType().getParameters()) { + if (type != null) { + result.add(type.getSimpleName()); + } + } + } + return result; + } + + protected boolean isImportExprPackage(EntityType model) { + if (!model.getConstructors().isEmpty() || !model.getDelegates().isEmpty()) { + boolean importExprPackage = false; + for (Constructor c : model.getConstructors()) { + for (Parameter cp : c.getParameters()) { + importExprPackage |= cp.getType().getPackageName() + .equals(ComparableExpression.class.getPackage().getName()); + } + } + for (Delegate d : model.getDelegates()) { + for (Parameter dp : d.getParameters()) { + importExprPackage |= dp.getType().getPackageName() + .equals(ComparableExpression.class.getPackage().getName()); + } + } + return importExprPackage; + + } else { + return false; + } + } + + protected void introDelegatePackages(CodeWriter writer, EntityType model) throws IOException { + Set packages = new HashSet(); + for (Delegate delegate : model.getDelegates()) { + if (!delegate.getDelegateType().getPackageName().equals(model.getPackageName())) { + packages.add(delegate.getDelegateType().getPackageName()); + } + } + writer.importPackages(packages.toArray(new String[0])); + } + + protected void introInits(CodeWriter writer, EntityType model) throws IOException { + List inits = new ArrayList(); + for (Property property : model.getProperties()) { + for (String init : property.getInits()) { + inits.add(property.getEscapedName() + DOT + init); + } + } + if (!inits.isEmpty()) { + inits.add(0, STAR); + String initsAsString = QUOTE + String.join("\", \"", inits) + QUOTE; + writer.privateStaticFinal(PATH_INITS_TYPE, "INITS", "new PathInits(" + initsAsString + ")"); + } else if (model.hasEntityFields() || superTypeHasEntityFields(model)) { + writer.privateStaticFinal(PATH_INITS_TYPE, "INITS", "PathInits.DIRECT2"); + } + } + + protected void introJavadoc(CodeWriter writer, EntityType model) throws IOException { + Type queryType = typeMappings.getPathType(model, model, true); + writer.javadoc(queryType.getSimpleName() + " is a Querydsl query type for " + + model.getSimpleName()); + } + + protected void introPackage(CodeWriter writer, EntityType model) throws IOException { + Type queryType = typeMappings.getPathType(model, model, false); + if (!queryType.getPackageName().isEmpty()) { + writer.packageDecl(queryType.getPackageName()); + } + } + + protected void introSuper(CodeWriter writer, EntityType model) throws IOException { + EntityType superType = model.getSuperType().getEntityType(); + Type superQueryType = typeMappings.getPathType(superType, model, false); + if (!superType.hasEntityFields()) { + writer.publicFinal(superQueryType, "_super", NEW + writer.getRawName(superQueryType) + "(this)"); + } else { + writer.publicFinal(superQueryType, "_super"); + } + } + + protected void listAccessor(EntityType model, Property field, CodeWriter writer) throws IOException { + String escapedName = field.getEscapedName(); + Type queryType = typeMappings.getPathType(field.getParameter(0), model, false); + + writer.beginPublicMethod(queryType, escapedName, new Parameter("index", Types.INT)); + writer.line(RETURN + escapedName + ".get(index);").end(); + + writer.beginPublicMethod(queryType, escapedName, new Parameter("index", + new ClassType(Expression.class, Types.INTEGER))); + writer.line(RETURN + escapedName + ".get(index);").end(); + } + + protected void mapAccessor(EntityType model, Property field, CodeWriter writer) throws IOException { + String escapedName = field.getEscapedName(); + Type queryType = typeMappings.getPathType(field.getParameter(1), model, false); + + writer.beginPublicMethod(queryType, escapedName, new Parameter("key", field.getParameter(0))); + writer.line(RETURN + escapedName + ".get(key);").end(); + + writer.beginPublicMethod(queryType, escapedName, new Parameter("key", + new ClassType(Expression.class, field.getParameter(0)))); + writer.line(RETURN + escapedName + ".get(key);").end(); + } + + private void delegate(final EntityType model, Delegate delegate, SerializerConfig config, + CodeWriter writer) throws IOException { + Parameter[] params = delegate.getParameters().toArray(new Parameter[0]); + writer.beginPublicMethod(delegate.getReturnType(), delegate.getName(), params); + + // body start + writer.beginLine(RETURN + writer.getRawName(delegate.getDelegateType()) + "." + delegate.getName() + "("); + writer.append("this"); + if (!model.equals(delegate.getDeclaringType())) { + int counter = 0; + EntityType type = model; + while (type != null && !type.equals(delegate.getDeclaringType())) { + type = type.getSuperType() != null ? type.getSuperType().getEntityType() : null; + counter++; + } + for (int i = 0; i < counter; i++) { + writer.append("._super"); + } + } + for (Parameter parameter : delegate.getParameters()) { + writer.append(COMMA).append(parameter.getName()); + } + writer.append(");\n"); + + // body end + writer.end(); + } + + protected void outro(EntityType model, CodeWriter writer) throws IOException { + writer.end(); + } + + @Override + public void serialize(EntityType model, SerializerConfig config, + CodeWriter writer) throws IOException { + intro(model, config, writer); + + // properties + serializeProperties(model, config, writer); + + // constructors + constructors(model, config, writer); + + // delegates + for (Delegate delegate : model.getDelegates()) { + delegate(model, delegate, config, writer); + } + + // property accessors + for (Property property : model.getProperties()) { + TypeCategory category = property.getType().getCategory(); + if (category == TypeCategory.MAP && config.useMapAccessors()) { + mapAccessor(model, property, writer); + } else if (category == TypeCategory.LIST && config.useListAccessors()) { + listAccessor(model, property, writer); + } else if (category == TypeCategory.ENTITY && config.useEntityAccessors()) { + entityAccessor(model, property, writer); + } + } + outro(model, writer); + } + + protected void serialize(EntityType model, Property field, Type type, CodeWriter writer, + String factoryMethod, String... args) throws IOException { + Supertype superType = model.getSuperType(); + // construct value + StringBuilder value = new StringBuilder(); + if (field.isInherited() && superType != null) { + if (!superType.getEntityType().hasEntityFields()) { + value.append("_super.").append(field.getEscapedName()); + } + } else { + value.append(factoryMethod).append("(\"").append(field.getName()).append(QUOTE); + for (String arg : args) { + value.append(COMMA).append(arg); + } + value.append(")"); + } + + // serialize it + if (field.isInherited()) { + writer.line("//inherited"); + } + if (value.length() > 0) { + writer.publicFinal(type, field.getEscapedName(), value.toString()); + } else { + writer.publicFinal(type, field.getEscapedName()); + } + } + + protected void customField(EntityType model, Property field, SerializerConfig config, + CodeWriter writer) throws IOException { + Type queryType = typeMappings.getPathType(field.getType(), model, false); + writer.line("// custom"); + if (field.isInherited()) { + writer.line("// inherited"); + Supertype superType = model.getSuperType(); + if (!superType.getEntityType().hasEntityFields()) { + String value = NEW + writer.getRawName(queryType) + "(_super." + field.getEscapedName() + ")"; + writer.publicFinal(queryType, field.getEscapedName(), value); + } else { + writer.publicFinal(queryType, field.getEscapedName()); + } + } else { + String value = NEW + writer.getRawName(queryType) + "(forProperty(\"" + field.getName() + "\"))"; + writer.publicFinal(queryType, field.getEscapedName(), value); + } + } + + // TODO move this to codegen + private Type wrap(Type type) { + if (type.equals(Types.BOOLEAN_P)) { + return Types.BOOLEAN; + } else if (type.equals(Types.BYTE_P)) { + return Types.BYTE; + } else if (type.equals(Types.CHAR)) { + return Types.CHARACTER; + } else if (type.equals(Types.DOUBLE_P)) { + return Types.DOUBLE; + } else if (type.equals(Types.FLOAT_P)) { + return Types.FLOAT; + } else if (type.equals(Types.INT)) { + return Types.INTEGER; + } else if (type.equals(Types.LONG_P)) { + return Types.LONG; + } else if (type.equals(Types.SHORT_P)) { + return Types.SHORT; + } else { + return type; + } + } + + protected void serializeProperties(EntityType model, SerializerConfig config, + CodeWriter writer) throws IOException { + for (Property property : model.getProperties()) { + // FIXME : the custom types should have the custom type category + if (typeMappings.isRegistered(property.getType()) + && property.getType().getCategory() != TypeCategory.CUSTOM + && property.getType().getCategory() != TypeCategory.ENTITY) { + customField(model, property, config, writer); + continue; + } + + // strips of "? extends " etc + Type propertyType = new SimpleType(property.getType(), property.getType().getParameters()); + Type queryType = typeMappings.getPathType(propertyType, model, false); + Type genericQueryType = null; + String localRawName = writer.getRawName(property.getType()); + String inits = getInits(property); + + switch (property.getType().getCategory()) { + case STRING: + serialize(model, property, queryType, writer, "createString"); + break; + + case BOOLEAN: + serialize(model, property, queryType, writer, "createBoolean"); + break; + + case SIMPLE: + serialize(model, property, queryType, writer, "createSimple", writer.getClassConstant(localRawName)); + break; + + case COMPARABLE: + serialize(model, property, queryType, writer, "createComparable", writer.getClassConstant(localRawName)); + break; + + case ENUM: + serialize(model, property, queryType, writer, "createEnum", writer.getClassConstant(localRawName)); + break; + + case DATE: + serialize(model, property, queryType, writer, "createDate", writer.getClassConstant(localRawName)); + break; + + case DATETIME: + serialize(model, property, queryType, writer, "createDateTime", writer.getClassConstant(localRawName)); + break; + + case TIME: + serialize(model, property, queryType, writer, "createTime", writer.getClassConstant(localRawName)); + break; + + case NUMERIC: + serialize(model, property, queryType, writer, "createNumber", writer.getClassConstant(localRawName)); + break; + + case CUSTOM: + customField(model, property, config, writer); + break; + + case ARRAY: + serialize(model, property, new ClassType(ArrayPath.class, + property.getType(), + wrap(property.getType().getComponentType())), + writer, "createArray", writer.getClassConstant(localRawName)); + break; + + case COLLECTION: + genericQueryType = typeMappings.getPathType(getRaw(property.getParameter(0)), model, false); + String genericKey = writer.getGenericName(true, property.getParameter(0)); + localRawName = writer.getRawName(property.getParameter(0)); + queryType = typeMappings.getPathType(property.getParameter(0), model, true); + + serialize(model, property, new ClassType(CollectionPath.class, getRaw(property.getParameter(0)), genericQueryType), + writer, "this.<" + genericKey + COMMA + writer.getGenericName(true, genericQueryType) + ">createCollection", + writer.getClassConstant(localRawName), writer.getClassConstant(writer.getRawName(queryType)), inits); + break; + + case SET: + genericQueryType = typeMappings.getPathType(getRaw(property.getParameter(0)), model, false); + genericKey = writer.getGenericName(true, property.getParameter(0)); + localRawName = writer.getRawName(property.getParameter(0)); + queryType = typeMappings.getPathType(property.getParameter(0), model, true); + + serialize(model, property, new ClassType(SetPath.class, getRaw(property.getParameter(0)), genericQueryType), + writer, "this.<" + genericKey + COMMA + writer.getGenericName(true, genericQueryType) + ">createSet", + writer.getClassConstant(localRawName), writer.getClassConstant(writer.getRawName(queryType)), inits); + break; + + case LIST: + genericQueryType = typeMappings.getPathType(getRaw(property.getParameter(0)), model, false); + genericKey = writer.getGenericName(true, property.getParameter(0)); + localRawName = writer.getRawName(property.getParameter(0)); + queryType = typeMappings.getPathType(property.getParameter(0), model, true); + + serialize(model, property, new ClassType(ListPath.class, getRaw(property.getParameter(0)), genericQueryType), + writer, "this.<" + genericKey + COMMA + writer.getGenericName(true, genericQueryType) + ">createList", + writer.getClassConstant(localRawName), writer.getClassConstant(writer.getRawName(queryType)), inits); + break; + + case MAP: + genericKey = writer.getGenericName(true, property.getParameter(0)); + String genericValue = writer.getGenericName(true, property.getParameter(1)); + genericQueryType = typeMappings.getPathType(getRaw(property.getParameter(1)), model, false); + String keyType = writer.getRawName(property.getParameter(0)); + String valueType = writer.getRawName(property.getParameter(1)); + queryType = typeMappings.getPathType(property.getParameter(1), model, true); + + serialize(model, property, new ClassType(MapPath.class, getRaw(property.getParameter(0)), + getRaw(property.getParameter(1)), genericQueryType), + writer, "this.<" + genericKey + COMMA + genericValue + COMMA + + writer.getGenericName(true, genericQueryType) + ">createMap", + writer.getClassConstant(keyType), writer.getClassConstant(valueType), writer.getClassConstant(writer.getRawName(queryType))); + break; + + case ENTITY: + entityField(model, property, config, writer); + break; + } + } + } + + private String getInits(Property property) { + if (!property.getInits().isEmpty()) { + return "INITS.get(\"" + property.getName() + "\")"; + } else { + return "PathInits.DIRECT2"; + } + } + + private Type getRaw(Type type) { + if (type instanceof EntityType && type.getPackageName().startsWith("ext.java")) { + return type; + } else { + return new SimpleType(type, type.getParameters()); + } + } + + private static CodeWriter suppressAllWarnings(CodeWriter writer) throws IOException { + return writer.suppressWarnings("all", "rawtypes", "unchecked"); + } + +} diff --git a/querydsl-codegen/src/main/java/com/querydsl/codegen/DefaultFiler.java b/querydsl-codegen/src/main/java/com/querydsl/codegen/DefaultFiler.java new file mode 100644 index 0000000000..c40f905ea1 --- /dev/null +++ b/querydsl-codegen/src/main/java/com/querydsl/codegen/DefaultFiler.java @@ -0,0 +1,32 @@ +/* + * Copyright 2021, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.codegen; + +import javax.annotation.processing.ProcessingEnvironment; +import javax.lang.model.element.Element; +import java.io.IOException; +import java.io.Writer; +import java.util.Collection; + +/** + * creates files with {@link javax.annotation.processing.Filer}. + * + * @author f43nd1r + */ +public class DefaultFiler implements Filer { + @Override + public Writer createFile(ProcessingEnvironment processingEnvironment, String classname, Collection elements) throws IOException { + return processingEnvironment.getFiler().createSourceFile(classname, elements.toArray(new Element[0])).openWriter(); + } +} diff --git a/querydsl-codegen/src/main/java/com/querydsl/codegen/DefaultProjectionSerializer.java b/querydsl-codegen/src/main/java/com/querydsl/codegen/DefaultProjectionSerializer.java new file mode 100644 index 0000000000..0010e6b260 --- /dev/null +++ b/querydsl-codegen/src/main/java/com/querydsl/codegen/DefaultProjectionSerializer.java @@ -0,0 +1,165 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.codegen; + +import java.io.IOException; + +import java.util.HashSet; +import java.lang.annotation.Annotation; +import java.util.Set; +import java.util.function.Function; + +import javax.inject.Inject; +import javax.inject.Named; + +import com.querydsl.codegen.utils.CodeWriter; +import com.querydsl.codegen.utils.model.*; +import com.querydsl.core.types.ConstructorExpression; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.dsl.NumberExpression; + +/** + * {@code ProjectionSerializer} is a {@link Serializer} implementation for projection types + * + * @author tiwe + * + */ +public final class DefaultProjectionSerializer implements ProjectionSerializer { + + private final Class generatedAnnotationClass; + private final TypeMappings typeMappings; + + /** + * Create a new {@code ProjectionSerializer} instance + * + * @param typeMappings type mappings to be used + */ + public DefaultProjectionSerializer(TypeMappings typeMappings) { + this(typeMappings, GeneratedAnnotationResolver.resolveDefault()); + } + + /** + * Create a new {@code ProjectionSerializer} instance + * + * @param typeMappings type mappings to be used + * @param generatedAnnotationClass the fully qualified class name of the Single-Element Annotation (with {@code String} element) to be used on the generated classes. + * @see Single-Element Annotation + */ + @Inject + public DefaultProjectionSerializer( + TypeMappings typeMappings, + @Named(CodegenModule.GENERATED_ANNOTATION_CLASS) Class generatedAnnotationClass) { + this.typeMappings = typeMappings; + this.generatedAnnotationClass = generatedAnnotationClass; + } + + protected void intro(EntityType model, CodeWriter writer) throws IOException { + String simpleName = model.getSimpleName(); + Type queryType = typeMappings.getPathType(model, model, false); + + // package + if (!queryType.getPackageName().isEmpty()) { + writer.packageDecl(queryType.getPackageName()); + } + + // imports + writer.imports(NumberExpression.class.getPackage()); + writer.imports(ConstructorExpression.class, generatedAnnotationClass); + + Set sizes = new HashSet<>(); + for (Constructor c : model.getConstructors()) { + sizes.add(c.getParameters().size()); + } + if (sizes.size() != model.getConstructors().size()) { + writer.imports(Expression.class); + } + + // javadoc + writer.javadoc(queryType + " is a Querydsl Projection type for " + simpleName); + + writer.line("@", generatedAnnotationClass.getSimpleName(), "(\"", getClass().getName(), "\")"); + + // class header +// writer.suppressWarnings("serial"); + Type superType = new ClassType(TypeCategory.SIMPLE, ConstructorExpression.class, model); + writer.beginClass(queryType, superType); + writer.privateStaticFinal(Types.LONG_P, "serialVersionUID", model.hashCode() + "L"); + } + + protected void outro(EntityType model, CodeWriter writer) throws IOException { + writer.end(); + } + + @Override + public void serialize(final EntityType model, SerializerConfig serializerConfig, + CodeWriter writer) throws IOException { + // intro + intro(model, writer); + + String localName = writer.getRawName(model); + Set sizes = new HashSet<>(); + + for (Constructor c : model.getConstructors()) { + final boolean asExpr = sizes.add(c.getParameters().size()); + // begin + writer.beginConstructor(c.getParameters(), new Function() { + @Override + public Parameter apply(Parameter p) { + Type type; + if (!asExpr) { + type = typeMappings.getExprType(p.getType(), + model, false, false, true); + } else if (p.getType().isFinal()) { + type = new ClassType(Expression.class, p.getType()); + } else { + type = new ClassType(Expression.class, new TypeExtends(p.getType())); + } + return new Parameter(p.getName(), type); + } + }); + + // body + writer.beginLine("super(" + writer.getClassConstant(localName)); + // TODO: Fix for Scala (Array[Class]) + writer.append(", new Class[]{"); + boolean first = true; + + for (Parameter p : c.getParameters()) { + if (!first) { + writer.append(", "); + } + if (Types.PRIMITIVES.containsKey(p.getType())) { + Type primitive = Types.PRIMITIVES.get(p.getType()); + writer.append(writer.getClassConstant(primitive.getFullName())); + } else { + writer.append(writer.getClassConstant(writer.getRawName(p.getType()))); + } + first = false; + } + writer.append("}"); + + for (Parameter p : c.getParameters()) { + writer.append(", ").append(p.getName()); + } + + // end + writer.append(");\n"); + writer.end(); + } + + // outro + outro(model, writer); + } + +} diff --git a/querydsl-codegen/src/main/java/com/querydsl/codegen/DefaultSupertypeSerializer.java b/querydsl-codegen/src/main/java/com/querydsl/codegen/DefaultSupertypeSerializer.java new file mode 100644 index 0000000000..06d236bafa --- /dev/null +++ b/querydsl-codegen/src/main/java/com/querydsl/codegen/DefaultSupertypeSerializer.java @@ -0,0 +1,54 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.codegen; + +import java.lang.annotation.Annotation; +import java.util.Collection; + +import javax.inject.Inject; +import javax.inject.Named; + +/** + * {@code SupertypeSerializer} is a {@link Serializer} implementation for supertypes + * + * @author tiwe + * + */ +public final class DefaultSupertypeSerializer extends DefaultEntitySerializer implements SupertypeSerializer { + + /** + * Create a new SupertypeSerializer instance + * + * @param typeMappings type mappings to be used + * @param keywords keywords to be used + * @param generatedAnnotationClass fully qualified class name to be used as class level "@Generated" annotation. + */ + @Inject + public DefaultSupertypeSerializer( + TypeMappings typeMappings, + @Named(CodegenModule.KEYWORDS) Collection keywords, + @Named(CodegenModule.GENERATED_ANNOTATION_CLASS) Class generatedAnnotationClass) { + super(typeMappings, keywords, generatedAnnotationClass); + } + /** + * Create a new SupertypeSerializer instance + * + * @param typeMappings type mappings to be used + * @param keywords keywords to be used + */ + public DefaultSupertypeSerializer(TypeMappings typeMappings, Collection keywords) { + super(typeMappings, keywords, GeneratedAnnotationResolver.resolveDefault()); + } + +} diff --git a/querydsl-codegen/src/main/java/com/querydsl/codegen/DefaultVariableNameFunction.java b/querydsl-codegen/src/main/java/com/querydsl/codegen/DefaultVariableNameFunction.java new file mode 100644 index 0000000000..790c62ae5c --- /dev/null +++ b/querydsl-codegen/src/main/java/com/querydsl/codegen/DefaultVariableNameFunction.java @@ -0,0 +1,39 @@ +/* + * Copyright 2016, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.codegen; + +import com.querydsl.codegen.utils.StringUtils; + +import javax.lang.model.SourceVersion; +import java.util.function.Function; + +/** + * Default variable name generation strategy which un-capitalizes the first letter of the class name. + * + */ +public final class DefaultVariableNameFunction implements Function { + + public static final DefaultVariableNameFunction INSTANCE = new DefaultVariableNameFunction(); + + @Override + public String apply(EntityType entity) { + String uncapSimpleName = StringUtils.uncapitalize(entity.getInnerType().getSimpleName()); + if (SourceVersion.isKeyword(uncapSimpleName)) { + uncapSimpleName = uncapSimpleName + "$"; + } + return uncapSimpleName; + } +} diff --git a/querydsl-codegen/src/main/java/com/mysema/query/codegen/Delegate.java b/querydsl-codegen/src/main/java/com/querydsl/codegen/Delegate.java similarity index 81% rename from querydsl-codegen/src/main/java/com/mysema/query/codegen/Delegate.java rename to querydsl-codegen/src/main/java/com/querydsl/codegen/Delegate.java index c402923e1e..322a7362ec 100644 --- a/querydsl-codegen/src/main/java/com/mysema/query/codegen/Delegate.java +++ b/querydsl-codegen/src/main/java/com/querydsl/codegen/Delegate.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,17 +11,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.codegen; +package com.querydsl.codegen; import java.util.List; +import java.util.Objects; -import com.google.common.base.Objects; -import com.mysema.codegen.model.Parameter; -import com.mysema.codegen.model.Type; +import com.querydsl.codegen.utils.model.Parameter; +import com.querydsl.codegen.utils.model.Type; /** - * Delegate defines a delegate method which dispatches to an external static method - * + * {@code Delegate} defines a delegate method which dispatches to an external static method + * * @author tiwe * */ @@ -37,7 +37,7 @@ public class Delegate { private final Type returnType; - public Delegate(Type declaringType, Type delegateType, String name, List params, + public Delegate(Type declaringType, Type delegateType, String name, List params, Type returnType) { this.declaringType = declaringType; this.delegateType = delegateType; @@ -51,7 +51,7 @@ public boolean equals(Object o) { if (o == this) { return true; } else if (o instanceof Delegate) { - Delegate m = (Delegate)o; + Delegate m = (Delegate) o; return m.name.equals(name) && m.parameters.equals(parameters); } else { return false; @@ -80,7 +80,7 @@ public Type getReturnType() { @Override public int hashCode() { - return Objects.hashCode(name, parameters); + return Objects.hash(name, parameters); } @Override diff --git a/querydsl-codegen/src/main/java/com/querydsl/codegen/EmbeddableSerializer.java b/querydsl-codegen/src/main/java/com/querydsl/codegen/EmbeddableSerializer.java new file mode 100644 index 0000000000..9528ba18c8 --- /dev/null +++ b/querydsl-codegen/src/main/java/com/querydsl/codegen/EmbeddableSerializer.java @@ -0,0 +1,22 @@ +/* + * Copyright 2021, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.codegen; + +/** + * {@code EmbeddableSerializer} is a {@link Serializer} for entity types + * + * @author f43nd1r + */ +public interface EmbeddableSerializer extends Serializer { +} diff --git a/querydsl-codegen/src/main/java/com/querydsl/codegen/EntitySerializer.java b/querydsl-codegen/src/main/java/com/querydsl/codegen/EntitySerializer.java new file mode 100644 index 0000000000..5fb66291e3 --- /dev/null +++ b/querydsl-codegen/src/main/java/com/querydsl/codegen/EntitySerializer.java @@ -0,0 +1,22 @@ +/* + * Copyright 2021, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.codegen; + +/** + * {@code EntitySerializer} is a {@link Serializer} for entity types + * + * @author f43nd1r + */ +public interface EntitySerializer extends Serializer { +} diff --git a/querydsl-codegen/src/main/java/com/querydsl/codegen/EntityType.java b/querydsl-codegen/src/main/java/com/querydsl/codegen/EntityType.java new file mode 100644 index 0000000000..04e68b87e5 --- /dev/null +++ b/querydsl-codegen/src/main/java/com/querydsl/codegen/EntityType.java @@ -0,0 +1,287 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.codegen; + +import com.querydsl.codegen.utils.StringUtils; +import com.querydsl.codegen.utils.model.Constructor; +import com.querydsl.codegen.utils.model.Type; +import com.querydsl.codegen.utils.model.TypeAdapter; +import com.querydsl.codegen.utils.model.TypeCategory; + +import java.lang.annotation.Annotation; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; +import java.util.function.Function; +import org.jetbrains.annotations.Nullable; +/** + * {@code EntityType} represents a model of a query domain type with properties + * + * @author tiwe + */ +public class EntityType extends TypeAdapter implements Comparable { + + private final Map,Annotation> annotations = new HashMap,Annotation>(); + + private final Set constructors = new LinkedHashSet(); + + private int escapeSuffix = 1; + + private final Set delegates = new HashSet(); + + private final Set properties = new TreeSet(); + + private final Set propertyNames = new HashSet(); + + private final Set escapedPropertyNames = new HashSet(); + + private final Set superTypes; + + private final Map data = new HashMap(); + + private String modifiedSimpleName; + + /** + * Create a new {@code EntityType} instance for the given type + * + * @param type + */ + public EntityType(Type type) { + this(type, new LinkedHashSet(), DefaultVariableNameFunction.INSTANCE); + } + + /** + * Create a new {@code EntityType} instance for the given type + * + * @param type the type to be used + * @param variableNameFunction the variable name function to be used + */ + public EntityType(Type type, Function variableNameFunction) { + this(type, new LinkedHashSet(), variableNameFunction); + } + + /** + * Create a new {@code EntityType} instance for the given type and superTypes + * + * @param type + * @param superTypes + */ + public EntityType(Type type, Set superTypes) { + this(type, superTypes, DefaultVariableNameFunction.INSTANCE); + } + + /** + * Create a new {@code EntityType} instance for the given type and superTypes + * + * @param type the type to be used + * @param superTypes the super types to be used + * @param variableNameFunction the variable name function to be used + */ + private EntityType(Type type, Set superTypes, Function variableNameFunction) { + super(type); + this.superTypes = superTypes; + this.modifiedSimpleName = variableNameFunction.apply(this); + } + + public void addAnnotation(Annotation annotation) { + annotations.put(annotation.annotationType(), annotation); + } + + public void addConstructor(Constructor co) { + constructors.add(co); + } + + public void addDelegate(Delegate delegate) { + delegates.add(delegate); + } + + public void addProperty(Property field) { + if (!propertyNames.contains(field.getName())) { + propertyNames.add(field.getName()); + escapedPropertyNames.add(field.getEscapedName()); + properties.add(validateField(field)); + } + } + + public void addSupertype(Supertype entityType) { + superTypes.add(entityType); + } + + @Override + public int compareTo(EntityType o) { + return getType().getSimpleName().compareTo(o.getType().getSimpleName()); + } + + @Override + public boolean equals(Object o) { + if (o == this) { + return true; + } else if (o instanceof Type) { + return getFullName().equals(((Type) o).getFullName()); + } else { + return false; + } + } + + @SuppressWarnings("unchecked") + public T getAnnotation(Class type) { + return (T) annotations.get(type); + } + + public Collection getAnnotations() { + return annotations.values(); + } + + @Override + public Type as(TypeCategory category) { + if (getCategory() == category) { + return this; + } else { + return super.as(category); + } + } + + @Override + public TypeCategory getCategory() { + if (getType().getCategory() == TypeCategory.ENTITY || !properties.isEmpty()) { + return TypeCategory.ENTITY; + } else { + return TypeCategory.CUSTOM; + } + } + + public Set getConstructors() { + return constructors; + } + + public Map getData() { + return data; + } + + public Set getDelegates() { + return delegates; + } + + public TypeCategory getOriginalCategory() { + return super.getCategory(); + } + + public Set getProperties() { + return properties; + } + + @Nullable + public Supertype getSuperType() { + return superTypes.size() == 1 ? superTypes.iterator().next() : null; + } + + public Set getSuperTypes() { + return superTypes; + } + + /** + * Use {@link #getModifiedSimpleName()} + */ + @Deprecated + public String getUncapSimpleName() { + return modifiedSimpleName; + } + + public String getModifiedSimpleName() { + return modifiedSimpleName; + } + + @Override + public int hashCode() { + return getFullName().hashCode(); + } + + public boolean hasArrays() { + return hasPropertyWithType(TypeCategory.ARRAY); + } + + public boolean hasEntityFields() { + return hasPropertyWithType(TypeCategory.ENTITY); + } + + public boolean hasInits() { + for (Property property : properties) { + if (!property.getInits().isEmpty()) { + return true; + } + } + return false; + } + + public boolean hasLists() { + return hasPropertyWithType(TypeCategory.LIST); + } + + public boolean hasCollections() { + return hasPropertyWithType(TypeCategory.COLLECTION); + } + + public boolean hasSets() { + return hasPropertyWithType(TypeCategory.SET); + } + + public boolean hasMaps() { + return hasPropertyWithType(TypeCategory.MAP); + } + + private boolean hasPropertyWithType(TypeCategory category) { + for (Property property : properties) { + if (property.getType().getCategory() == category) { + return true; + } + } + return false; + } + + public void include(Supertype supertype) { + EntityType entityType = supertype.getEntityType(); + for (Delegate delegate : entityType.getDelegates()) { + addDelegate(delegate); + } + for (Property property : entityType.getProperties()) { + addProperty(property.createCopy(this)); + } + } + + private Property validateField(Property field) { + if (field.getName().equals(modifiedSimpleName) || field.getEscapedName().equals(modifiedSimpleName)) { + do { + modifiedSimpleName = StringUtils.uncapitalize(getType().getSimpleName()) + (escapeSuffix++); + } while (propertyNames.contains(modifiedSimpleName)); + } + return field; + } + + public Set getPropertyNames() { + return propertyNames; + } + + public Set getEscapedPropertyNames() { + return escapedPropertyNames; + } + + public Type getInnerType() { + return type; + } + +} diff --git a/querydsl-codegen/src/main/java/com/querydsl/codegen/Extension.java b/querydsl-codegen/src/main/java/com/querydsl/codegen/Extension.java new file mode 100644 index 0000000000..7dfca17eaa --- /dev/null +++ b/querydsl-codegen/src/main/java/com/querydsl/codegen/Extension.java @@ -0,0 +1,31 @@ +/* + * Copyright 2016, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.codegen; + +/** + * {@code Extension} allows for custom code generation extensions to be registered as service provider + * + * @author Jan-Willem Gmelig Meyling + * + */ +public interface Extension { + + /** + * Register custom types to the given codegen module + * + * @param module module to be customized + */ + void addSupport(AbstractModule module); + +} diff --git a/querydsl-codegen/src/main/java/com/querydsl/codegen/Filer.java b/querydsl-codegen/src/main/java/com/querydsl/codegen/Filer.java new file mode 100644 index 0000000000..139df581a4 --- /dev/null +++ b/querydsl-codegen/src/main/java/com/querydsl/codegen/Filer.java @@ -0,0 +1,29 @@ +/* + * Copyright 2021, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.codegen; + +import javax.annotation.processing.ProcessingEnvironment; +import javax.lang.model.element.Element; +import java.io.IOException; +import java.io.Writer; +import java.util.Collection; + +/** + * provides files in annotation processing to write classes to + * + * @author f43nd1r + */ +public interface Filer { + Writer createFile(ProcessingEnvironment processingEnvironment, String classname, Collection elements) throws IOException; +} diff --git a/querydsl-codegen/src/main/java/com/querydsl/codegen/GeneratedAnnotationResolver.java b/querydsl-codegen/src/main/java/com/querydsl/codegen/GeneratedAnnotationResolver.java new file mode 100644 index 0000000000..4f517411c2 --- /dev/null +++ b/querydsl-codegen/src/main/java/com/querydsl/codegen/GeneratedAnnotationResolver.java @@ -0,0 +1,72 @@ +package com.querydsl.codegen; + +import org.jetbrains.annotations.Nullable; + +import java.lang.annotation.Annotation; + +/** + * {@code GeneratedAnnotationClassResolver} provides class name resolving functionality for resolving the annotation + * type to be used on {@link Serializer}s generated sources. + */ +public final class GeneratedAnnotationResolver { + + private static final Class DEFAULT_GENERATED_ANNOTATION_CLASS = resolveJavaDefault(); + + /** + * Use the {@code generatedAnnotationClass} or use the JDK one. + *

+ * A {@code null generatedAnnotationClass} will resolve to the java {@code @Generated} annotation (can be of type {@code javax.annotation.Generated} + * or {@code javax.annotation.processing.Generated} depending on the java version. + * + * @param generatedAnnotationClass the fully qualified class name of the Single-Element Annotation (with {@code String} element) + * to use or {@code null}. + * @return the provided {@code generatedAnnotationClass} if not {@code null} or the one from java. Never {@code null}. + * @see Single-Element Annotation + */ + public static Class resolve(@Nullable String generatedAnnotationClass) { + if (generatedAnnotationClass != null) { + try { + return (Class) Class.forName(generatedAnnotationClass); + } catch (Exception e) { + // Try next one + } + } + + return resolveDefault(); + } + + /** + * Resolve the java {@code @Generated} annotation (can be of type {@code javax.annotation.Generated} + * or {@code javax.annotation.processing.Generated} depending on the java version. + * + * @return the Generated annotation class from java. Never {@code null}. + */ + public static Class resolveDefault() { + return DEFAULT_GENERATED_ANNOTATION_CLASS; + } + + @SuppressWarnings("unchecked") + private static Class resolveJavaDefault() { + try { + return (Class) Class.forName("javax.annotation.processing.Generated"); + } catch (Exception e) { + // Try next one + } + + try { + return (Class) Class.forName("javax.annotation.Generated"); + } catch (Exception e) { + // Try next one + } + + try { + return (Class) Class.forName("jakarta.annotation.Generated"); + } catch (Exception e) { + // Try next one + } + + throw new IllegalStateException("Can't find Generated annotation"); + } + + private GeneratedAnnotationResolver() { } +} diff --git a/querydsl-codegen/src/main/java/com/querydsl/codegen/GenericExporter.java b/querydsl-codegen/src/main/java/com/querydsl/codegen/GenericExporter.java new file mode 100644 index 0000000000..1764e2a8c2 --- /dev/null +++ b/querydsl-codegen/src/main/java/com/querydsl/codegen/GenericExporter.java @@ -0,0 +1,829 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.codegen; + +import com.querydsl.codegen.utils.CodeWriter; +import com.querydsl.codegen.utils.JavaWriter; +import com.querydsl.codegen.utils.ScalaWriter; +import com.querydsl.codegen.utils.model.Parameter; +import com.querydsl.codegen.utils.model.Type; +import com.querydsl.codegen.utils.model.TypeCategory; +import com.querydsl.codegen.utils.support.ClassUtils; +import com.querydsl.core.QueryException; +import com.querydsl.core.annotations.Config; +import com.querydsl.core.annotations.PropertyType; +import com.querydsl.core.annotations.QueryEmbeddable; +import com.querydsl.core.annotations.QueryEmbedded; +import com.querydsl.core.annotations.QueryEntity; +import com.querydsl.core.annotations.QueryExclude; +import com.querydsl.core.annotations.QueryInit; +import com.querydsl.core.annotations.QueryProjection; +import com.querydsl.core.annotations.QuerySupertype; +import com.querydsl.core.annotations.QueryTransient; +import com.querydsl.core.annotations.QueryType; +import com.querydsl.core.util.Annotations; +import com.querydsl.core.util.BeanUtils; +import com.querydsl.core.util.ReflectionUtils; +import org.jetbrains.annotations.Nullable; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.lang.annotation.Annotation; +import java.lang.reflect.AnnotatedElement; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Function; + +/** + * {@code GenericExporter} provides query type serialization logic for cases where APT annotation processors + * can't be used. {@code GenericExporter} scans the classpath for classes annotated with specified annotations + * in specific packages and mirrors them into Querydsl expression types. + * + *

Example with Querydsl annotations:

+ *
+ * {@code
+ * GenericExporter exporter = new GenericExporter();
+ * exporter.setTargetFolder(new File("target/generated-sources/java"));
+ * exporter.export(com.example.domain.Entity.class.getPackage());}
+ * 
+ * + *

Example with JPA annotations:

+ *
+ * {@code
+ * GenericExporter exporter = new GenericExporter();
+ * exporter.setKeywords(Keywords.JPA);
+ * exporter.setEntityAnnotation(Entity.class);
+ * exporter.setEmbeddableAnnotation(Embeddable.class);
+ * exporter.setEmbeddedAnnotation(Embedded.class);
+ * exporter.setSupertypeAnnotation(MappedSuperclass.class);
+ * exporter.setSkipAnnotation(Transient.class);
+ * exporter.setTargetFolder(new File("target/generated-sources/java"));
+ * exporter.export(com.example.domain.Entity.class.getPackage());}
+ * 
+ * + * @author tiwe + * + */ +public class GenericExporter { + + private Class entityAnnotation = QueryEntity.class; + + private Class supertypeAnnotation = QuerySupertype.class; + + private Class embeddableAnnotation = QueryEmbeddable.class; + + private Class embeddedAnnotation = QueryEmbedded.class; + + private Class skipAnnotation = QueryTransient.class; + + private boolean createScalaSources = false; + + private final Set> stopClasses = new HashSet<>(); + + private final Map allTypes = new HashMap<>(); + + private final Map, EntityType> entityTypes = new HashMap<>(); + + private final Map, EntityType> superTypes = new HashMap<>(); + + private final Map, EntityType> embeddableTypes = new HashMap<>(); + + private final Map, EntityType> projectionTypes = new HashMap<>(); + + private final CodegenModule codegenModule = new CodegenModule(); + + private SerializerConfig serializerConfig = SimpleSerializerConfig.DEFAULT; + + @Deprecated + private boolean handleFields = true, handleMethods = true; + + private PropertyHandling propertyHandling = PropertyHandling.ALL; + + private boolean useFieldTypes = false; + + @Nullable + private File targetFolder; + + @Nullable + private TypeFactory typeFactory; + + private final List annotationHelpers = new ArrayList<>(); + + @Nullable + private TypeMappings typeMappings; + + @Nullable + private QueryTypeFactory queryTypeFactory; + + @Nullable + private Class serializerClass; + + private final Charset charset; + + private final ClassLoader classLoader; + + private Set generatedFiles = new HashSet(); + + private boolean strictMode; + + + /** + * Create a GenericExporter instance using the given classloader and charset for serializing + * source files + * + * @param classLoader classloader to use + * @param charset charset of target sources + */ + public GenericExporter(ClassLoader classLoader, Charset charset) { + this.classLoader = classLoader; + this.charset = charset; + stopClasses.add(Object.class); + stopClasses.add(Enum.class); + } + + /** + * Create a GenericExporter instance using the given classloader and default charset + * + * @param classLoader classloader to use + */ + public GenericExporter(ClassLoader classLoader) { + this(classLoader, Charset.defaultCharset()); + } + + /** + * Create a GenericExporter instance using the context classloader and the given charset + * + * @param charset charset of target sources + */ + public GenericExporter(Charset charset) { + this(Thread.currentThread().getContextClassLoader(), charset); + } + + /** + * Create a GenericExporter instance using the context classloader and default charset + */ + public GenericExporter() { + this(Thread.currentThread().getContextClassLoader(), Charset.defaultCharset()); + } + + /** + * Export the given packages + * + * @param packages packages to be scanned + */ + public void export(Package... packages) { + String[] pkgs = new String[packages.length]; + for (int i = 0; i < packages.length; i++) { + pkgs[i] = packages[i].getName(); + } + export(pkgs); + } + + /** + * Export the given packages + * + * @param packages packages to be scanned + */ + public void export(String... packages) { + scanPackages(packages); + innerExport(); + } + + /** + * Export the given classes + * + * @param classes classes to be scanned + */ + public void export(Class...classes) { + for (Class cl : classes) { + handleClass(cl); + } + innerExport(); + } + + @SuppressWarnings("unchecked") + private void innerExport() { + typeMappings = codegenModule.get(TypeMappings.class); + queryTypeFactory = codegenModule.get(QueryTypeFactory.class); + typeFactory = new TypeFactory(Arrays.asList(entityAnnotation, supertypeAnnotation, embeddableAnnotation), codegenModule.get(Function.class, CodegenModule.VARIABLE_NAME_FUNCTION_CLASS)); + + // copy annotations helpers to typeFactory + for (AnnotationHelper helper : annotationHelpers) { + typeFactory.addAnnotationHelper(helper); + } + + // process supertypes + for (Class cl : superTypes.keySet()) { + createEntityType(cl, superTypes); + } + + // process embeddables + for (Class cl : embeddableTypes.keySet()) { + createEntityType(cl, embeddableTypes); + } + + // process entities + for (Class cl : entityTypes.keySet()) { + createEntityType(cl, entityTypes); + } + + // process projections + for (Class cl : projectionTypes.keySet()) { + createEntityType(cl, projectionTypes); + } + + // add constructors and properties + for (Map, EntityType> entries : Arrays.asList(superTypes, embeddableTypes, entityTypes, projectionTypes)) { + for (Map.Entry, EntityType> entry : new HashSet<>(entries.entrySet())) { + addConstructors(entry.getKey(), entry.getValue()); + addProperties(entry.getKey(), entry.getValue()); + } + } + + // merge supertype fields into subtypes + Set handled = new HashSet(); + for (EntityType type : superTypes.values()) { + addSupertypeFields(type, allTypes, handled); + } + for (EntityType type : entityTypes.values()) { + addSupertypeFields(type, allTypes, handled); + } + for (EntityType type : embeddableTypes.values()) { + addSupertypeFields(type, allTypes, handled); + } + + // extend types + typeFactory.extendTypes(); + + try { + Serializer supertypeSerializer, entitySerializer, embeddableSerializer, projectionSerializer; + + if (serializerClass != null) { + Serializer serializer = codegenModule.get(serializerClass); + supertypeSerializer = serializer; + entitySerializer = serializer; + embeddableSerializer = serializer; + projectionSerializer = serializer; + } else { + supertypeSerializer = codegenModule.get(SupertypeSerializer.class); + entitySerializer = codegenModule.get(EntitySerializer.class); + embeddableSerializer = codegenModule.get(EmbeddableSerializer.class); + projectionSerializer = codegenModule.get(ProjectionSerializer.class); + } + + // serialize super types + serialize(supertypeSerializer, superTypes); + + // serialize entity types + serialize(entitySerializer, entityTypes); + + // serialize embeddable types + serialize(embeddableSerializer, embeddableTypes); + + // serialize projection types + serialize(projectionSerializer, projectionTypes); + + } catch (IOException e) { + throw new QueryException(e); + } + + } + + private void addSupertypeFields(EntityType model, Map superTypes, + Set handled) { + if (handled.add(model)) { + for (Supertype supertype : model.getSuperTypes()) { + EntityType entityType = superTypes.get(supertype.getType().getFullName()); + if (entityType == null) { + if (supertype.getType().getPackageName().startsWith("java.")) { + // skip internal supertypes + continue; + } + // FIXME this misses the generics + Class cl = supertype.getType().getJavaClass(); + typeFactory.addEmbeddableType(cl); + entityType = createEntityType(cl, new HashMap, EntityType>()); + addProperties(cl, entityType); + + } + addSupertypeFields(entityType, superTypes, handled); + supertype.setEntityType(entityType); + model.include(supertype); + } + } + } + + private boolean containsAny(Class clazz, Class... annotations) { + for (Class annType : annotations) { + if (clazz.isAnnotationPresent(annType)) { + return true; + } + } + return false; + } + + private EntityType createEntityType(Class cl, Map, EntityType> types) { + if (types.get(cl) != null) { + return types.get(cl); + } else { + EntityType type = allTypes.get(ClassUtils.getFullName(cl)); + if (type == null) { + type = typeFactory.getEntityType(cl); + } + types.put(cl, type); + String fullName = ClassUtils.getFullName(cl); + if (!allTypes.containsKey(fullName)) { + allTypes.put(fullName, type); + } + + typeMappings.register(type, queryTypeFactory.create(type)); + + if (strictMode && cl.getSuperclass() != null) { + @SuppressWarnings("unchecked") + Class[] annotations = + (Class[]) new Class[] {entityAnnotation, supertypeAnnotation, embeddableAnnotation}; + if (!containsAny(cl.getSuperclass(), annotations)) { + // skip supertype handling + return type; + } + } + + if (cl.getSuperclass() != null && !stopClasses.contains(cl.getSuperclass()) + && !cl.getSuperclass().isAnnotationPresent(QueryExclude.class)) { + type.addSupertype(new Supertype(typeFactory.get(cl.getSuperclass(), cl.getGenericSuperclass()))); + } + if (cl.isInterface()) { + for (Class iface : cl.getInterfaces()) { + if (!stopClasses.contains(iface) && !iface.isAnnotationPresent(QueryExclude.class)) { + type.addSupertype(new Supertype(typeFactory.get(iface))); + } + } + } + + return type; + } + } + + private void addConstructors(Class cl, EntityType type) { + for (Constructor constructor : cl.getConstructors()) { + if (constructor.isAnnotationPresent(QueryProjection.class)) { + List parameters = new ArrayList<>(); + for (int i = 0; i < constructor.getParameterTypes().length; i++) { + Type parameterType = typeFactory.get( + constructor.getParameterTypes()[i], + constructor.getGenericParameterTypes()[i]); + for (Annotation annotation : constructor.getParameterAnnotations()[i]) { + if (annotation.annotationType().equals(QueryType.class)) { + QueryType queryType = (QueryType) annotation; + parameterType = parameterType.as(TypeCategory.valueOf(queryType.value().name())); + } + } + parameters.add(new Parameter("param" + i, parameterType)); + } + type.addConstructor(new com.querydsl.codegen.utils.model.Constructor(parameters)); + } + } + } + + private void addProperties(Class cl, EntityType type) { + Map types = new HashMap<>(); + Map annotations = new HashMap<>(); + + PropertyHandling.Config config = propertyHandling.getConfig(cl); + + // fields + if (config.isFields()) { + for (Field field : cl.getDeclaredFields()) { + if (!Modifier.isStatic(field.getModifiers())) { + if (Modifier.isTransient(field.getModifiers()) && !field.isAnnotationPresent(QueryType.class)) { + continue; + } + AnnotatedElement annotated = ReflectionUtils.getAnnotatedElement(cl, field.getName(), field.getType()); + Type propertyType = getPropertyType(cl, annotated, field.getType(), field.getGenericType()); + Annotations ann = new Annotations(field); + types.put(field.getName(), propertyType); + annotations.put(field.getName(), ann); + } + } + } + + // getters + if (config.isMethods()) { + for (Method method : cl.getDeclaredMethods()) { + String name = method.getName(); + if (method.getParameterTypes().length == 0 + && !Modifier.isStatic(method.getModifiers()) + && !method.isBridge() + && ((name.startsWith("get") && name.length() > 3) + || (name.startsWith("is") && name.length() > 2))) { + String propertyName; + if (name.startsWith("get")) { + propertyName = BeanUtils.uncapitalize(name.substring(3)); + } else { + propertyName = BeanUtils.uncapitalize(name.substring(2)); + } + Type propertyType = getPropertyType(cl, method, method.getReturnType(), method.getGenericReturnType()); + if (!types.containsKey(propertyName) || !useFieldTypes) { + types.put(propertyName, propertyType); + } + Annotations ann = annotations.get(propertyName); + if (ann == null) { + ann = new Annotations(); + annotations.put(propertyName, ann); + } + ann.addAnnotations(method); + } + } + } + + for (Map.Entry entry : types.entrySet()) { + Annotations ann = annotations.get(entry.getKey()); + Property property = createProperty(type, entry.getKey(), entry.getValue(), ann); + if (property != null) { + type.addProperty(property); + } + } + } + + private Type getPropertyType(Class cl, AnnotatedElement annotated, Class type, + java.lang.reflect.Type genericType) { + Type propertyType = null; + if (annotated.isAnnotationPresent(embeddedAnnotation)) { + Class embeddableType = type; + if (Collection.class.isAssignableFrom(type)) { + embeddableType = ReflectionUtils.getTypeParameterAsClass(genericType, 0); + } else if (Map.class.isAssignableFrom(type)) { + embeddableType = ReflectionUtils.getTypeParameterAsClass(genericType, 1); + } + if (!embeddableType.getName().startsWith("java.")) { + typeFactory.addEmbeddableType(embeddableType); + if (!embeddableTypes.containsKey(embeddableType) + && !entityTypes.containsKey(embeddableType) + && !superTypes.containsKey(embeddableType)) { + EntityType entityType = createEntityType(embeddableType, embeddableTypes); + addProperties(embeddableType, entityType); + if (embeddableType == type) { + propertyType = entityType; + } + } + } + } + if (propertyType == null) { + propertyType = typeFactory.get(type, annotated, genericType); + if (propertyType instanceof EntityType && !allTypes.containsKey(ClassUtils.getFullName(type))) { + String fullName = ClassUtils.getFullName(type); + if (!allTypes.containsKey(fullName)) { + allTypes.put(fullName, (EntityType) propertyType); + } + } + } + return propertyType; + } + + @Nullable + private Property createProperty(EntityType entityType, String propertyName, Type propertyType, + AnnotatedElement annotated) { + List inits = Collections.emptyList(); + if (annotated.isAnnotationPresent(skipAnnotation) + && !annotated.isAnnotationPresent(QueryType.class)) { + return null; + } + if (annotated.isAnnotationPresent(QueryInit.class)) { + inits = Arrays.asList(annotated.getAnnotation(QueryInit.class).value()); + } + if (annotated.isAnnotationPresent(QueryType.class)) { + QueryType queryType = annotated.getAnnotation(QueryType.class); + if (queryType.value().equals(PropertyType.NONE)) { + return null; + } + propertyType = propertyType.as(TypeCategory.valueOf(queryType.value().name())); + } + return new Property(entityType, propertyName, propertyType, inits); + } + + private void scanPackages(String... packages) { + if (packages == null) { + return; + } + for (String pkg : packages) { + try { + for (Class cl : ClassPathUtils.scanPackage(classLoader, pkg)) { + handleClass(cl); + } + } catch (IOException e) { + throw new QueryException(e); + } + } + } + + private void handleClass(Class cl) { + if (stopClasses.contains(cl) || cl.isAnnotationPresent(QueryExclude.class)) { + return; + } else if (cl.isAnnotationPresent(entityAnnotation)) { + entityTypes.put(cl, null); + } else if (cl.isAnnotationPresent(embeddableAnnotation)) { + embeddableTypes.put(cl, null); + } else if (cl.isAnnotationPresent(supertypeAnnotation)) { + superTypes.put(cl, null); + } else { + for (Constructor constructor : cl.getConstructors()) { + if (constructor.isAnnotationPresent(QueryProjection.class)) { + projectionTypes.put(cl, null); + break; + } + } + } + } + + private void serialize(Serializer serializer, Map, EntityType> types) throws IOException { + for (Map.Entry, EntityType> entityType : types.entrySet()) { + Type type = typeMappings.getPathType(entityType.getValue(), entityType.getValue(), true); + String packageName = type.getPackageName(); + String className = packageName.length() > 0 ? (packageName + "." + type.getSimpleName()) : type.getSimpleName(); + SerializerConfig config = serializerConfig; + if (entityType.getKey().isAnnotationPresent(Config.class)) { + config = SimpleSerializerConfig.getConfig(entityType.getKey().getAnnotation(Config.class)); + } + String fileSuffix = createScalaSources ? ".scala" : ".java"; + write(serializer, className.replace('.', '/') + fileSuffix, config, entityType.getValue()); + } + } + + private void write(Serializer serializer, String path, SerializerConfig serializerConfig, + EntityType type) throws IOException { + File targetFile = new File(targetFolder, path); + generatedFiles.add(targetFile); + try (Writer w = writerFor(targetFile)) { + CodeWriter writer = createScalaSources ? new ScalaWriter(w) : new JavaWriter(w); + serializer.serialize(type, serializerConfig, writer); + } + } + + private Writer writerFor(File file) { + if (!file.getParentFile().exists() && !file.getParentFile().mkdirs()) { + System.err.println("Folder " + file.getParent() + " could not be created"); + } + try { + return new OutputStreamWriter(new FileOutputStream(file), charset); + } catch (FileNotFoundException e) { + throw new RuntimeException(e.getMessage(), e); + } + } + + + /** + * Return the set of generated files + * + * @return a set of generated files + */ + public Set getGeneratedFiles() { + return generatedFiles; + } + + /** + * Set the entity annotation + * + * @param entityAnnotation entity annotation + */ + public void setEntityAnnotation(Class entityAnnotation) { + this.entityAnnotation = entityAnnotation; + } + + /** + * Set the supertype annotation + * + * @param supertypeAnnotation supertype annotation + */ + public void setSupertypeAnnotation( + Class supertypeAnnotation) { + this.supertypeAnnotation = supertypeAnnotation; + } + + /** + * Set the embeddable annotation + * + * @param embeddableAnnotation embeddable annotation + */ + public void setEmbeddableAnnotation( + Class embeddableAnnotation) { + this.embeddableAnnotation = embeddableAnnotation; + } + + /** + * Set the embedded annotation + * + * @param embeddedAnnotation embedded annotation + */ + public void setEmbeddedAnnotation(Class embeddedAnnotation) { + this.embeddedAnnotation = embeddedAnnotation; + } + + /** + * Set the skip annotation + * + * @param skipAnnotation skip annotation + */ + public void setSkipAnnotation(Class skipAnnotation) { + this.skipAnnotation = skipAnnotation; + } + + /** + * Set the target folder for generated sources + * + * @param targetFolder + */ + public void setTargetFolder(File targetFolder) { + this.targetFolder = targetFolder; + } + + /** + * Set the serializer class to be used + * + * @param serializerClass + */ + public void setSerializerClass(Class serializerClass) { + codegenModule.bind(serializerClass); + this.serializerClass = serializerClass; + } + + /** + * Set the typemappings class to be used + * + * @param typeMappingsClass + */ + public void setTypeMappingsClass(Class typeMappingsClass) { + codegenModule.bind(TypeMappings.class, typeMappingsClass); + } + + /** + * Set whether Scala sources are generated + * + * @param createScalaSources + */ + public void setCreateScalaSources(boolean createScalaSources) { + this.createScalaSources = createScalaSources; + } + + /** + * Set the keywords to be used + * + * @param keywords + */ + public void setKeywords(Collection keywords) { + codegenModule.bind(CodegenModule.KEYWORDS, keywords); + } + + /** + * Set the name prefix + * + * @param prefix + */ + public void setNamePrefix(String prefix) { + codegenModule.bind(CodegenModule.PREFIX, prefix); + } + + /** + * Set the name suffix + * + * @param suffix + */ + public void setNameSuffix(String suffix) { + codegenModule.bind(CodegenModule.SUFFIX, suffix); + } + + /** + * Set the package suffix + * + * @param suffix + */ + public void setPackageSuffix(String suffix) { + codegenModule.bind(CodegenModule.PACKAGE_SUFFIX, suffix); + } + + /** + * Set whether fields are handled (default true) + * + * @param b + * @deprecated Use {@link #setPropertyHandling(PropertyHandling)} instead + */ + @Deprecated + public void setHandleFields(boolean b) { + handleFields = b; + setPropertyHandling(); + } + + /** + * Set whether methods are handled (default true) + * + * @param b + * @deprecated Use {@link #setPropertyHandling(PropertyHandling)} instead + */ + @Deprecated + public void setHandleMethods(boolean b) { + handleMethods = b; + setPropertyHandling(); + } + + private void setPropertyHandling() { + if (handleFields) { + propertyHandling = handleMethods ? PropertyHandling.ALL : PropertyHandling.FIELDS; + } else if (handleMethods) { + propertyHandling = PropertyHandling.METHODS; + } else { + propertyHandling = PropertyHandling.NONE; + } + } + + /** + * Set the property handling mode + * + * @param propertyHandling + */ + public void setPropertyHandling(PropertyHandling propertyHandling) { + this.propertyHandling = propertyHandling; + } + + /** + * Set whether field types should be used instead of getter return types (default false) + * + * @param b + */ + public void setUseFieldTypes(boolean b) { + useFieldTypes = b; + } + + /** + * Add a stop class to be used (default Object.class and Enum.class) + * + * @param cl + */ + public void addStopClass(Class cl) { + stopClasses.add(cl); + } + + /** + * Set whether annotationless superclasses are handled or not (default: true) + * + * @param s + */ + public void setStrictMode(boolean s) { + strictMode = s; + } + + /** + * Set the serializer configuration to use + * + * @param serializerConfig + */ + public void setSerializerConfig(SerializerConfig serializerConfig) { + this.serializerConfig = serializerConfig; + } + + /** + * Add a annotation helper object to process custom annotations + * + * @param annotationHelper + */ + public void addAnnotationHelper(AnnotationHelper annotationHelper) { + annotationHelpers.add(annotationHelper); + } + + /** + * Set the Generated annotation class. Will default to java {@code @Generated} + * + * @param generatedAnnotationClass the fully qualified class name of the Single-Element Annotation (with {@code String} element) to be used on + * the generated sources, or {@code null} (defaulting to {@code javax.annotation.Generated} or + * {@code javax.annotation.processing.Generated} depending on the java version). + * @see Single-Element Annotation + */ + public void setGeneratedAnnotationClass(@Nullable String generatedAnnotationClass) { + codegenModule.bindInstance(CodegenModule.GENERATED_ANNOTATION_CLASS, GeneratedAnnotationResolver.resolve(generatedAnnotationClass)); + } +} diff --git a/querydsl-codegen/src/main/java/com/mysema/query/codegen/GroovyBeanSerializer.java b/querydsl-codegen/src/main/java/com/querydsl/codegen/GroovyBeanSerializer.java similarity index 79% rename from querydsl-codegen/src/main/java/com/mysema/query/codegen/GroovyBeanSerializer.java rename to querydsl-codegen/src/main/java/com/querydsl/codegen/GroovyBeanSerializer.java index 7f95865229..057ff1f0aa 100644 --- a/querydsl-codegen/src/main/java/com/mysema/query/codegen/GroovyBeanSerializer.java +++ b/querydsl-codegen/src/main/java/com/querydsl/codegen/GroovyBeanSerializer.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,63 +11,59 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.codegen; +package com.querydsl.codegen; import java.io.IOException; import java.lang.annotation.Annotation; -import java.util.Collection; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; -import com.mysema.codegen.CodeWriter; +import com.querydsl.codegen.utils.CodeWriter; /** - * GroovyBeanSerializer is a {@link Serializer} implementation which serializes {@link EntityType} + * {@code GroovyBeanSerializer} is a {@link Serializer} implementation which serializes {@link EntityType} * instances into Groovy classes * * @author tiwe * */ public class GroovyBeanSerializer implements Serializer { - + private final boolean propertyAnnotations; - + private final String javadocSuffix; - + private boolean printSupertype = false; /** - * Create a new GroovyBeanSerializer instance + * Create a new {@code GroovyBeanSerializer} instance */ public GroovyBeanSerializer() { this(true, " is a Querydsl bean type"); } /** - * Create a new GroovyBeanSerializer instance - * - * @param javadocSuffix + * Create a new {@code GroovyBeanSerializer} instance + * + * @param javadocSuffix suffix to be used after the simple name in class level javadoc */ public GroovyBeanSerializer(String javadocSuffix) { this(true, javadocSuffix); } - + /** - * Create a new GroovyBeanSerializer instance - * - * @param propertyAnnotations + * Create a new {@code GroovyBeanSerializer} instance + * + * @param propertyAnnotations true, to serialize property annotations */ public GroovyBeanSerializer(boolean propertyAnnotations) { this(propertyAnnotations, " is a Querydsl bean type"); } /** - * Create a new GroovyBeanSerializer instance - * - * @param propertyAnnotations - * @param javadocSuffix + * Create a new {@code GroovyBeanSerializer} instance + * + * @param propertyAnnotations true, to serialize property annotations + * @param javadocSuffix suffix to be used after the simple name in class level javadoc */ public GroovyBeanSerializer(boolean propertyAnnotations, String javadocSuffix) { this.propertyAnnotations = propertyAnnotations; @@ -75,7 +71,7 @@ public GroovyBeanSerializer(boolean propertyAnnotations, String javadocSuffix) { } @Override - public void serialize(EntityType model, SerializerConfig serializerConfig, + public void serialize(EntityType model, SerializerConfig serializerConfig, CodeWriter writer) throws IOException { String simpleName = model.getSimpleName(); @@ -98,7 +94,7 @@ public void serialize(EntityType model, SerializerConfig serializerConfig, if (model.hasMaps()) { importedClasses.add(Map.class.getName()); } - writer.importClasses(importedClasses.toArray(new String[importedClasses.size()])); + writer.importClasses(importedClasses.toArray(new String[0])); // javadoc writer.javadoc(simpleName + javadocSuffix); @@ -112,30 +108,30 @@ public void serialize(EntityType model, SerializerConfig serializerConfig, } else { writer.beginClass(model); } - + bodyStart(model, writer); - + // fields for (Property property : model.getProperties()) { if (propertyAnnotations) { for (Annotation annotation : property.getAnnotations()) { writer.annotation(annotation); - } - } + } + } writer.field(property.getType(), property.getEscapedName()); } - + bodyEnd(model, writer); - + writer.end(); } protected void bodyStart(EntityType model, CodeWriter writer) throws IOException { - // template method + // template method } protected void bodyEnd(EntityType model, CodeWriter writer) throws IOException { - // template method + // template method } private Set getAnnotationTypes(EntityType model) { @@ -148,13 +144,13 @@ private Set getAnnotationTypes(EntityType model) { for (Annotation annotation : property.getAnnotations()) { imports.add(annotation.annotationType().getName()); } - } - } + } + } return imports; } public void setPrintSupertype(boolean printSupertype) { this.printSupertype = printSupertype; } - + } diff --git a/querydsl-codegen/src/main/java/com/querydsl/codegen/JavaTypeMappings.java b/querydsl-codegen/src/main/java/com/querydsl/codegen/JavaTypeMappings.java new file mode 100644 index 0000000000..78e5ba7ae4 --- /dev/null +++ b/querydsl-codegen/src/main/java/com/querydsl/codegen/JavaTypeMappings.java @@ -0,0 +1,52 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.codegen; + +import com.querydsl.codegen.utils.model.TypeCategory; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.dsl.*; +import com.querydsl.core.types.dsl.StringTemplate; + +/** + * {@code JavaTypeMappings} defines mappings from {@link TypeCategory} instances to {@link Expression} types + * + * @author tiwe + * + */ +public class JavaTypeMappings extends TypeMappings { + + public JavaTypeMappings() { + register(TypeCategory.STRING, StringExpression.class, StringPath.class, StringTemplate.class); + register(TypeCategory.BOOLEAN, BooleanExpression.class, BooleanPath.class, BooleanTemplate.class); + register(TypeCategory.COMPARABLE, ComparableExpression.class, ComparablePath.class, ComparableTemplate.class); + register(TypeCategory.ENUM, EnumExpression.class, EnumPath.class, EnumTemplate.class); + register(TypeCategory.DATE, TemporalExpression.class, DatePath.class, DateTemplate.class); + register(TypeCategory.DATETIME, TemporalExpression.class, DateTimePath.class, DateTimeTemplate.class); + register(TypeCategory.TIME, TemporalExpression.class, TimePath.class, TimeTemplate.class); + register(TypeCategory.NUMERIC, NumberExpression.class, NumberPath.class, NumberTemplate.class); + register(TypeCategory.SIMPLE, SimpleExpression.class, SimplePath.class, SimpleTemplate.class); + + register(TypeCategory.ARRAY, Expression.class, SimplePath.class, SimpleTemplate.class); + register(TypeCategory.COLLECTION, Expression.class, SimplePath.class, SimpleTemplate.class); + register(TypeCategory.SET, Expression.class, SimplePath.class, SimpleTemplate.class); + register(TypeCategory.LIST, Expression.class, SimplePath.class, SimpleTemplate.class); + register(TypeCategory.MAP, Expression.class, SimplePath.class, SimpleTemplate.class); + + register(TypeCategory.CUSTOM, Expression.class, Path.class, SimpleTemplate.class); + register(TypeCategory.ENTITY, Expression.class, Path.class, SimpleTemplate.class); + } + + +} diff --git a/querydsl-codegen/src/main/java/com/querydsl/codegen/Keywords.java b/querydsl-codegen/src/main/java/com/querydsl/codegen/Keywords.java new file mode 100644 index 0000000000..ed78f227f4 --- /dev/null +++ b/querydsl-codegen/src/main/java/com/querydsl/codegen/Keywords.java @@ -0,0 +1,56 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.codegen; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; + +/** + * {@code Keywords} provides keywords sets in capitalized form to + * be used in {@link GenericExporter} and the APT processors + * + * @author tiwe + * + */ +public final class Keywords { + + private Keywords() { } + + public static final Collection JPA = Collections.unmodifiableList(Arrays.asList( + "ABS", "ALL", "AND", "ANY", "AS", "ASC", "AVG", "BETWEEN", + "BIT_LENGTH[51]", "BOTH", "BY", "CASE", "CHAR_LENGTH", + "CHARACTER_LENGTH", "CLASS", + "COALESCE", "CONCAT", "COUNT", "CURRENT_DATE", "CURRENT_TIME", + "CURRENT_TIMESTAMP", + "DELETE", "DESC", "DISTINCT", "ELSE", "EMPTY", "END", "ENTRY", + "ESCAPE", "EXISTS", "FALSE", "FETCH", + "FROM", "GROUP", "HAVING", "IN", "INDEX", "INNER", "IS", "JOIN", + "KEY", "LEADING", "LEFT", "LENGTH", "LIKE", + "LOCATE", "LOWER", "MAX", "MEMBER", "MIN", "MOD", "NEW", "NOT", + "NULL", "NULLIF", "OBJECT", "OF", "OR", + "ORDER", "OUTER", "POSITION", "SELECT", "SET", "SIZE", "SOME", + "SQRT", "SUBSTRING", "SUM", "THEN", + "TRAILING", "TRIM", "TRUE", "TYPE", "UNKNOWN", "UPDATE", "UPPER", + "VALUE", "WHEN", "WHERE")); + + public static final Collection JDO = Collections.unmodifiableList(Arrays.asList( + "AS","ASC", "ASCENDING","AVG", + "BY","COUNT", "DESC","DESCENDING", + "DISTINCT","EXCLUDE", "FROM","GROUP", + "HAVING","INTO","MAX","MIN", + "ORDER","PARAMETERS","RANGE","SELECT", + "SUBCLASSES","SUM","UNIQUE","VARIABLES","WHERE")); + +} diff --git a/querydsl-codegen/src/main/java/com/querydsl/codegen/NamingFunction.java b/querydsl-codegen/src/main/java/com/querydsl/codegen/NamingFunction.java new file mode 100644 index 0000000000..6aee3f4028 --- /dev/null +++ b/querydsl-codegen/src/main/java/com/querydsl/codegen/NamingFunction.java @@ -0,0 +1,26 @@ +/* + * Copyright 2016, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.codegen; + +import java.util.function.Function; + +/** + * The {@link Function} signature to convert {@link EntityType} to {@code String}. + * + * @author Shredder121 + */ +public interface NamingFunction extends Function { +} diff --git a/querydsl-codegen/src/main/java/com/mysema/query/codegen/ParameterizedTypeImpl.java b/querydsl-codegen/src/main/java/com/querydsl/codegen/ParameterizedTypeImpl.java similarity index 83% rename from querydsl-codegen/src/main/java/com/mysema/query/codegen/ParameterizedTypeImpl.java rename to querydsl-codegen/src/main/java/com/querydsl/codegen/ParameterizedTypeImpl.java index b4a656c4ea..81cc0dda14 100644 --- a/querydsl-codegen/src/main/java/com/mysema/query/codegen/ParameterizedTypeImpl.java +++ b/querydsl-codegen/src/main/java/com/querydsl/codegen/ParameterizedTypeImpl.java @@ -1,6 +1,6 @@ /* - * Copyright 2012, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,27 +11,29 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.codegen; +package com.querydsl.codegen; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.Arrays; /** + * {@code ParameterizedTypeImpl} provides an implementation of the {@link ParameterizedType} interface + * * @author tiwe * */ public class ParameterizedTypeImpl implements ParameterizedType { private final Type rawType; - + private final Type[] arguments; - + public ParameterizedTypeImpl(Type rawType, Type[] arguments) { this.rawType = rawType; this.arguments = arguments; } - + @Override public Type[] getActualTypeArguments() { return arguments; @@ -46,23 +48,23 @@ public Type getRawType() { public Type getOwnerType() { return rawType; } - + @Override - public boolean equals(Object o) { + public boolean equals(Object o) { if (o == this) { return true; } else if (o instanceof ParameterizedTypeImpl) { - ParameterizedTypeImpl other = (ParameterizedTypeImpl)o; - return other.rawType.equals(rawType) + ParameterizedTypeImpl other = (ParameterizedTypeImpl) o; + return other.rawType.equals(rawType) && Arrays.equals(other.arguments, arguments); } else { return false; } } - + @Override public int hashCode() { return rawType.hashCode(); } - + } diff --git a/querydsl-codegen/src/main/java/com/querydsl/codegen/ProjectionSerializer.java b/querydsl-codegen/src/main/java/com/querydsl/codegen/ProjectionSerializer.java new file mode 100644 index 0000000000..f0571ff5ef --- /dev/null +++ b/querydsl-codegen/src/main/java/com/querydsl/codegen/ProjectionSerializer.java @@ -0,0 +1,23 @@ +/* + * Copyright 2021, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.codegen; + +/** + * {@code ProjectionSerializer} is a {@link Serializer} for projection types + * + * @author f43nd1r + * + */ +public interface ProjectionSerializer extends Serializer { +} diff --git a/querydsl-codegen/src/main/java/com/mysema/query/codegen/Property.java b/querydsl-codegen/src/main/java/com/querydsl/codegen/Property.java similarity index 85% rename from querydsl-codegen/src/main/java/com/mysema/query/codegen/Property.java rename to querydsl-codegen/src/main/java/com/querydsl/codegen/Property.java index ee4ec7c30e..79f8dea6d8 100644 --- a/querydsl-codegen/src/main/java/com/mysema/query/codegen/Property.java +++ b/querydsl-codegen/src/main/java/com/querydsl/codegen/Property.java @@ -1,5 +1,5 @@ /* - * Copyright 2011, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,21 +11,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.codegen; +package com.querydsl.codegen; import java.lang.annotation.Annotation; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; -import com.google.common.base.Objects; -import com.mysema.codegen.model.Type; -import com.mysema.util.JavaSyntaxUtils; +import javax.lang.model.SourceVersion; + +import com.querydsl.codegen.utils.model.Type; /** - * Property represents a property in a query domain type. + * {@code Property} represents a property in a query domain type. * * @author tiwe */ @@ -55,8 +51,7 @@ public Property(EntityType declaringType, String name, Type type, List i public Property(EntityType declaringType, String name, Type type, List inits, boolean inherited) { - this(declaringType, name, JavaSyntaxUtils.isReserved(name) ? (name + "$") : name, type, - inits, inherited); + this(declaringType, name, escapeName(name), type, inits, inherited); } public Property(EntityType declaringType, String name, String escapedName, Type type, @@ -69,6 +64,15 @@ public Property(EntityType declaringType, String name, String escapedName, Type this.inherited = inherited; } + private static String escapeName(String name) { + if (SourceVersion.isKeyword(name)) { + name = name + "$"; + } else if (!Character.isJavaIdentifierStart(name.charAt(0))) { + name = "_" + name; + } + return name; + } + public void addAnnotation(Annotation annotation) { annotations.put(annotation.annotationType(), annotation); } @@ -107,7 +111,7 @@ public Collection getAnnotations() { @Override public int hashCode() { - return Objects.hashCode(name, type); + return Objects.hash(name, type); } @Override @@ -115,7 +119,7 @@ public boolean equals(Object o) { if (o == this) { return true; } else if (o instanceof Property) { - Property p = (Property)o; + Property p = (Property) o; return p.name.equals(name) && p.type.equals(type); } else { return false; diff --git a/querydsl-codegen/src/main/java/com/querydsl/codegen/PropertyHandling.java b/querydsl-codegen/src/main/java/com/querydsl/codegen/PropertyHandling.java new file mode 100644 index 0000000000..6257cc9b4a --- /dev/null +++ b/querydsl-codegen/src/main/java/com/querydsl/codegen/PropertyHandling.java @@ -0,0 +1,149 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.codegen; + +import java.lang.annotation.Annotation; +import java.lang.reflect.AnnotatedElement; +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +import com.querydsl.core.annotations.QueryInit; +import com.querydsl.core.annotations.QueryType; + +/** + * Defines handling of fields and getters in property extractions + */ +public enum PropertyHandling { + /** + * Inspect fields and methods + */ + ALL { + @Override + public Config getConfig(Class type) { + return Config.ALL; + } + }, + /** + * Inspect fields only + */ + FIELDS { + @Override + public Config getConfig(Class type) { + return Config.FIELDS; + } + }, + /** + * Inspect methods only + */ + METHODS { + @Override + public Config getConfig(Class type) { + return Config.METHODS; + } + }, + /** + * No member inspection + */ + NONE { + @Override + public Config getConfig(Class type) { + return Config.NONE; + } + }, + /** + * JDO compatibility + */ + JDO { + @Override + public Config getConfig(Class type) { + boolean fields = false; + boolean methods = false; + for (Field field : type.getDeclaredFields()) { + fields |= hasAnnotations(field, "javax.jdo.annotations."); + } + for (Method method : type.getDeclaredMethods()) { + methods |= hasAnnotations(method, "javax.jdo.annotations."); + } + return Config.of(fields, methods, Config.FIELDS); + } + }, + /** + * JPA compatibility + */ + JPA { + @Override + public Config getConfig(Class type) { + boolean fields = false; + boolean methods = false; + for (Field field : type.getDeclaredFields()) { + fields |= hasAnnotations(field, "javax.persistence."); + fields |= hasAnnotations(field, "jakarta.persistence."); + } + for (Method method : type.getDeclaredMethods()) { + methods |= hasAnnotations(method, "javax.persistence."); + methods |= hasAnnotations(method, "jakarta.persistence."); + } + return Config.of(fields, methods, Config.ALL); + } + }; + + private static boolean hasAnnotations(AnnotatedElement element, String packagePrefix) { + for (Annotation ann : element.getAnnotations()) { + if (ann.annotationType().getName().startsWith(packagePrefix)) { + return true; + } + } + return element.isAnnotationPresent(QueryType.class) + || element.isAnnotationPresent(QueryInit.class); + } + + public abstract Config getConfig(Class type); + + /** + * Property handling options + */ + public enum Config { + ALL(true, true), + FIELDS(true, false), + METHODS(false, true), + NONE(false, false); + + private final boolean fields, methods; + + Config(boolean fields, boolean methods) { + this.fields = fields; + this.methods = methods; + } + + public boolean isFields() { + return fields; + } + + public boolean isMethods() { + return methods; + } + + public static Config of(boolean fields, boolean methods, Config defaultConfig) { + if (fields && methods) { + return ALL; + } else if (fields) { + return FIELDS; + } else if (methods) { + return METHODS; + } else { + return defaultConfig; + } + } + } +} diff --git a/querydsl-codegen/src/main/java/com/querydsl/codegen/QueryTypeFactory.java b/querydsl-codegen/src/main/java/com/querydsl/codegen/QueryTypeFactory.java new file mode 100644 index 0000000000..5990a3703f --- /dev/null +++ b/querydsl-codegen/src/main/java/com/querydsl/codegen/QueryTypeFactory.java @@ -0,0 +1,34 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.codegen; + +import com.querydsl.codegen.utils.model.Type; + +/** + * {@code QueryTypeFactory} defines an interface for mapping domain types to Querydsl expression types + * + * @author tiwe + * + */ +public interface QueryTypeFactory { + + /** + * Create an expression type based on the given actual type + * + * @param type actual type + * @return expression type + */ + Type create(Type type); + +} \ No newline at end of file diff --git a/querydsl-codegen/src/main/java/com/querydsl/codegen/QueryTypeFactoryImpl.java b/querydsl-codegen/src/main/java/com/querydsl/codegen/QueryTypeFactoryImpl.java new file mode 100644 index 0000000000..b82a79c881 --- /dev/null +++ b/querydsl-codegen/src/main/java/com/querydsl/codegen/QueryTypeFactoryImpl.java @@ -0,0 +1,71 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.codegen; + +import javax.inject.Inject; +import javax.inject.Named; + +import com.querydsl.codegen.utils.model.SimpleType; +import com.querydsl.codegen.utils.model.Type; + +/** + * {@code QueryTypeFactoryImpl} is the default implementation of the {@link QueryTypeFactory} interface + * + * @author tiwe + * + */ +public class QueryTypeFactoryImpl implements QueryTypeFactory { + + private final String prefix, suffix, packageSuffix; + + @Inject + public QueryTypeFactoryImpl( + @Named(CodegenModule.PREFIX) String prefix, + @Named(CodegenModule.SUFFIX) String suffix, + @Named(CodegenModule.PACKAGE_SUFFIX) String packageSuffix) { + this.prefix = prefix; + this.suffix = suffix; + this.packageSuffix = packageSuffix; + } + + @Override + public Type create(Type type) { + if (type.getPackageName().isEmpty()) { + return createWithoutPackage(type); + } else { + return createWithPackage(type); + } + } + + private Type createWithPackage(Type type) { + String packageName = type.getPackageName(); + String simpleName = prefix + normalizeName(type.getFullName() + .substring(packageName.length() + 1)) + suffix; + packageName = (packageName.startsWith("java") ? "ext." : "") + + packageName + packageSuffix; + return new SimpleType(type.getCategory(), packageName + "." + simpleName, + packageName, simpleName, false, false); + } + + private Type createWithoutPackage(Type type) { + String simpleName = prefix + normalizeName(type.getFullName()) + suffix; + return new SimpleType(type.getCategory(), simpleName, "", simpleName, false, false); + } + + private String normalizeName(String name) { + return name.replace('.', '_').replace('$', '_'); + } + + +} diff --git a/querydsl-codegen/src/main/java/com/mysema/query/codegen/Serializer.java b/querydsl-codegen/src/main/java/com/querydsl/codegen/Serializer.java similarity index 76% rename from querydsl-codegen/src/main/java/com/mysema/query/codegen/Serializer.java rename to querydsl-codegen/src/main/java/com/querydsl/codegen/Serializer.java index 1e4fe80c9f..139f213ce4 100644 --- a/querydsl-codegen/src/main/java/com/mysema/query/codegen/Serializer.java +++ b/querydsl-codegen/src/main/java/com/querydsl/codegen/Serializer.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,14 +11,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.codegen; +package com.querydsl.codegen; import java.io.IOException; -import com.mysema.codegen.CodeWriter; +import com.querydsl.codegen.utils.CodeWriter; /** - * Serializer defines a common interface for {@link EntityType} serializers + * {@code Serializer} defines a common interface for {@link EntityType} serializers * * @author tiwe * @@ -29,7 +29,7 @@ public interface Serializer { * Serialize the given {@link EntityType} * * @param type EntityType to serialize - * @param serializerConfig TODO + * @param serializerConfig serializer configuration * @param writer serialization target * @throws IOException */ diff --git a/querydsl-codegen/src/main/java/com/querydsl/codegen/SerializerConfig.java b/querydsl-codegen/src/main/java/com/querydsl/codegen/SerializerConfig.java new file mode 100644 index 0000000000..eb912bdc9b --- /dev/null +++ b/querydsl-codegen/src/main/java/com/querydsl/codegen/SerializerConfig.java @@ -0,0 +1,58 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.codegen; + +/** + * {@code SerializerConfig} defines serialization options to be used in the {@link Serializer} + * + * @author tiwe + * + */ +public interface SerializerConfig { + + /** + * accessors are used for entity fields + * + * @return if accessors are used for entity fields + */ + boolean useEntityAccessors(); + + /** + * indexed list accessors are used + * + * @return if indexed list accessors are used + */ + boolean useListAccessors(); + + /** + * keyed map accessors are used + * + * @return if keyed map accessors are used + */ + boolean useMapAccessors(); + + /** + * the default variable is created + * + * @return if the default variable is created + */ + boolean createDefaultVariable(); + + /** + * the name of the default variable + * + * @return the name of the default variable + */ + String defaultVariableName(); +} diff --git a/querydsl-codegen/src/main/java/com/mysema/query/codegen/SimpleSerializerConfig.java b/querydsl-codegen/src/main/java/com/querydsl/codegen/SimpleSerializerConfig.java similarity index 89% rename from querydsl-codegen/src/main/java/com/mysema/query/codegen/SimpleSerializerConfig.java rename to querydsl-codegen/src/main/java/com/querydsl/codegen/SimpleSerializerConfig.java index 46d1cde371..3c600ee221 100644 --- a/querydsl-codegen/src/main/java/com/mysema/query/codegen/SimpleSerializerConfig.java +++ b/querydsl-codegen/src/main/java/com/querydsl/codegen/SimpleSerializerConfig.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,17 +11,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.codegen; +package com.querydsl.codegen; -import com.mysema.query.annotations.Config; +import com.querydsl.core.annotations.Config; /** - * SimpleSerializerConfig is the default implementation of the {@link SerializerConfig} interface - * + * {@code SimpleSerializerConfig} is the default implementation of the {@link SerializerConfig} interface + * * @author tiwe * */ -public final class SimpleSerializerConfig implements SerializerConfig{ +public final class SimpleSerializerConfig implements SerializerConfig { public static final SerializerConfig DEFAULT = new SimpleSerializerConfig(false, false, false, true, ""); @@ -35,6 +35,7 @@ public static SerializerConfig getConfig(Config annotation) { } private final boolean entityAccessors, listAccessors, mapAccessors, createDefaultVariable; + private final String defaultVariableName; public SimpleSerializerConfig( diff --git a/querydsl-codegen/src/main/java/com/querydsl/codegen/Supertype.java b/querydsl-codegen/src/main/java/com/querydsl/codegen/Supertype.java new file mode 100644 index 0000000000..3bce3dd95e --- /dev/null +++ b/querydsl-codegen/src/main/java/com/querydsl/codegen/Supertype.java @@ -0,0 +1,77 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.codegen; + +import org.jetbrains.annotations.Nullable; + +import com.querydsl.codegen.utils.model.Type; + +/** + * {@code Supertype} defines a tuple of a {@link Type} and an optional {@link EntityType} instance used for + * supertype references in {@link EntityType} instances + * + * @author tiwe + * + */ +public class Supertype { + + @Nullable + private EntityType entityType; + + private final Type type; + + public Supertype(Type type) { + this.type = type; + } + + public Supertype(Type type, EntityType entityType) { + this.type = type; + this.entityType = entityType; + } + + @Nullable + public EntityType getEntityType() { + return entityType; + } + + public Type getType() { + return type; + } + + public void setEntityType(EntityType entityType) { + this.entityType = entityType; + } + + @Override + public int hashCode() { + return type.hashCode(); + } + + @Override + public boolean equals(Object o) { + if (o == this) { + return true; + } else if (o instanceof Supertype) { + return ((Supertype) o).type.equals(type); + } else { + return false; + } + } + + @Override + public String toString() { + return type.toString(); + } + +} diff --git a/querydsl-codegen/src/main/java/com/querydsl/codegen/SupertypeSerializer.java b/querydsl-codegen/src/main/java/com/querydsl/codegen/SupertypeSerializer.java new file mode 100644 index 0000000000..0316405521 --- /dev/null +++ b/querydsl-codegen/src/main/java/com/querydsl/codegen/SupertypeSerializer.java @@ -0,0 +1,23 @@ +/* + * Copyright 2021, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.codegen; + +/** + * {@code SupertypeSerializer} is a {@link Serializer} for supertypes + * + * @author tiwe + * + */ +public interface SupertypeSerializer extends EntitySerializer { +} diff --git a/querydsl-codegen/src/main/java/com/querydsl/codegen/TypeFactory.java b/querydsl-codegen/src/main/java/com/querydsl/codegen/TypeFactory.java new file mode 100644 index 0000000000..60e928ee6c --- /dev/null +++ b/querydsl-codegen/src/main/java/com/querydsl/codegen/TypeFactory.java @@ -0,0 +1,292 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.codegen; + +import com.querydsl.codegen.utils.model.ClassType; +import com.querydsl.codegen.utils.model.SimpleType; +import com.querydsl.codegen.utils.model.Type; +import com.querydsl.codegen.utils.model.TypeCategory; +import com.querydsl.codegen.utils.model.TypeExtends; +import com.querydsl.codegen.utils.model.TypeSuper; +import com.querydsl.codegen.utils.model.Types; +import com.querydsl.core.util.PrimitiveUtils; +import com.querydsl.core.util.ReflectionUtils; + +import java.lang.annotation.Annotation; +import java.lang.reflect.AnnotatedElement; +import java.lang.reflect.Array; +import java.lang.reflect.TypeVariable; +import java.lang.reflect.WildcardType; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Function; + +/** + * {@code TypeFactory} is a factory class for {@link Type} instances + * + * @author tiwe + * + */ +public final class TypeFactory { + + private static final Type ANY = new TypeExtends(Types.OBJECT); + + private final Map, Type> cache = new HashMap<>(); + + private final List> entityAnnotations; + + private final List annotationHelpers = new ArrayList<>(); + + private final Set> embeddableTypes = new HashSet<>(); + + private boolean unknownAsEntity = false; + + private Function variableNameFunction; + + public TypeFactory() { + this(new ArrayList<>(), DefaultVariableNameFunction.INSTANCE); + } + + public TypeFactory(List> entityAnnotations) { + this(entityAnnotations, DefaultVariableNameFunction.INSTANCE); + } + + public TypeFactory(List> entityAnnotations, Function variableNameFunction) { + this.entityAnnotations = entityAnnotations; + this.variableNameFunction = variableNameFunction; + } + + public EntityType getEntityType(Class cl) { + java.lang.reflect.Type generic = cl; + if (cl.getTypeParameters().length > 0) { + generic = new ParameterizedTypeImpl(cl, cl.getTypeParameters()); + } + return (EntityType) get(true, cl, null, generic); + } + + public Type get(Class cl) { + return get(cl, cl); + } + + public Type get(Class cl, java.lang.reflect.Type genericType) { + return get(isEntityClass(cl), cl, null, genericType); + } + + public Type get(Class cl, AnnotatedElement annotated, java.lang.reflect.Type genericType) { + return get(isEntityClass(cl), cl, annotated, genericType); + } + + public Type get(boolean entity, Class cl, java.lang.reflect.Type genericType) { + return get(entity, cl, null, genericType); + } + + public Type get(boolean entity, Class cl, AnnotatedElement annotated, java.lang.reflect.Type genericType) { + List key = new ArrayList<>(); + key.add(genericType); + AnnotationHelper annotationHelper = null; + Annotation selectedAnnotation = null; + if (annotated != null) { + for (Annotation annotation : annotated.getDeclaredAnnotations()) { + for (AnnotationHelper helper : annotationHelpers) { + if (helper.isSupported(annotation.annotationType())) { + key.add(annotation.annotationType()); + selectedAnnotation = annotated.getAnnotation(annotation.annotationType()); + annotationHelper = helper; + key.add(helper.getCustomKey(selectedAnnotation)); + break; + } + } + } + } + key = Collections.unmodifiableList(key); + if (cache.containsKey(key)) { + Type value = cache.get(key); + if (entity && !(value instanceof EntityType)) { + value = new EntityType(value, variableNameFunction); + cache.put(key, value); + } + return value; + + } else { + Type value = create(entity, cl, annotationHelper, selectedAnnotation, genericType, key); + cache.put(key, value); + return value; + } + } + + private Type create(boolean entity, Class cl, AnnotationHelper annotationHelper, Annotation annotation, java.lang.reflect.Type genericType, + List key) { + if (cl.isPrimitive()) { + cl = PrimitiveUtils.wrap(cl); + } + Type value; + Type[] tempParams = (Type[]) Array.newInstance(Type.class, + ReflectionUtils.getTypeParameterCount(genericType)); + cache.put(key, new ClassType(cl, tempParams)); + Type[] parameters = getParameters(cl, genericType); + + if (cl.isArray()) { + Type componentType = get(cl.getComponentType()); + if (cl.getComponentType().isPrimitive()) { + componentType = Types.PRIMITIVES.get(componentType); + } + value = componentType.asArrayType(); + } else if (cl.isEnum()) { + value = new ClassType(TypeCategory.ENUM, cl); + } else if (Number.class.isAssignableFrom(cl) && Comparable.class.isAssignableFrom(cl)) { + value = new ClassType(TypeCategory.NUMERIC, cl, parameters); + } else if (entity) { + value = createOther(cl, entity, annotationHelper, annotation, parameters); + } else if (Map.class.isAssignableFrom(cl)) { + value = new SimpleType(Types.MAP, parameters[0], asGeneric(parameters[1])); + } else if (List.class.isAssignableFrom(cl)) { + value = new SimpleType(Types.LIST, asGeneric(parameters[0])); + } else if (Set.class.isAssignableFrom(cl)) { + value = new SimpleType(Types.SET, asGeneric(parameters[0])); + } else if (Collection.class.isAssignableFrom(cl)) { + value = new SimpleType(Types.COLLECTION, asGeneric(parameters[0])); + } else { + value = createOther(cl, entity, annotationHelper, annotation, parameters); + } + + if (genericType instanceof TypeVariable) { + TypeVariable tv = (TypeVariable) genericType; + if (tv.getBounds().length == 1 && tv.getBounds()[0].equals(Object.class)) { + value = new TypeSuper(tv.getName(), value); + } else { + value = new TypeExtends(tv.getName(), value); + } + } + + if (entity && !(value instanceof EntityType)) { + value = new EntityType(value, variableNameFunction); + } + return value; + } + + private Type asGeneric(Type type) { + if (type.getParameters().size() == 0) { + int count = type.getJavaClass().getTypeParameters().length; + if (count > 0) { + return new SimpleType(type, new Type[count]); + } + } + return type; + } + + private Type createOther(Class cl, boolean entity, AnnotationHelper annotationHelper, Annotation annotation, Type[] parameters) { + TypeCategory typeCategory = TypeCategory.get(cl.getName()); + if (annotationHelper != null) { + typeCategory = annotationHelper.getTypeByAnnotation(cl, annotation); + } else if (embeddableTypes.contains(cl)) { + typeCategory = TypeCategory.CUSTOM; + } else if (unknownAsEntity && typeCategory == TypeCategory.SIMPLE && !cl.getName().startsWith("java")) { + typeCategory = TypeCategory.CUSTOM; + } else if (typeCategory == TypeCategory.SIMPLE && entity) { + typeCategory = TypeCategory.ENTITY; + } else if (!typeCategory.isSubCategoryOf(TypeCategory.COMPARABLE) && Comparable.class.isAssignableFrom(cl) + && !cl.equals(Comparable.class)) { + typeCategory = TypeCategory.COMPARABLE; + } + + return new ClassType(typeCategory, cl, parameters); + } + + private Type[] getParameters(Class cl, java.lang.reflect.Type genericType) { + int parameterCount = ReflectionUtils.getTypeParameterCount(genericType); + if (parameterCount > 0) { + return getGenericParameters(cl, genericType, parameterCount); + } else if (Map.class.isAssignableFrom(cl)) { + return new Type[]{Types.OBJECT, Types.OBJECT}; + } else if (Collection.class.isAssignableFrom(cl)) { + return new Type[]{Types.OBJECT}; + } else { + return new Type[0]; + } + } + + private Type[] getGenericParameters(Class cl, java.lang.reflect.Type genericType, + int parameterCount) { + Type[] types = new Type[parameterCount]; + for (int i = 0; i < types.length; i++) { + types[i] = getGenericParameter(cl, genericType, i); + } + return types; + } + + @SuppressWarnings("rawtypes") + private Type getGenericParameter(Class cl, java.lang.reflect.Type genericType, int i) { + java.lang.reflect.Type parameter = ReflectionUtils.getTypeParameter(genericType, i); + if (parameter instanceof TypeVariable) { + TypeVariable variable = (TypeVariable) parameter; + Type rv = get(ReflectionUtils.getTypeParameterAsClass(genericType, i), null, parameter); + return new TypeExtends(variable.getName(), rv); + } else if (parameter instanceof WildcardType + && ((WildcardType) parameter).getUpperBounds()[0].equals(Object.class) + && ((WildcardType) parameter).getLowerBounds().length == 0) { + return ANY; + } else { + Type rv = get(ReflectionUtils.getTypeParameterAsClass(genericType, i), null, parameter); + if (parameter instanceof WildcardType) { + rv = new TypeExtends(rv); + } + return rv; + } + } + + private boolean isEntityClass(Class cl) { + for (Class clazz : entityAnnotations) { + if (cl.isAnnotationPresent(clazz)) { + return true; + } + } + return embeddableTypes.contains(cl); + } + + public void extendTypes() { + for (Map.Entry, Type> entry : cache.entrySet()) { + if (entry.getValue() instanceof EntityType) { + EntityType entityType = (EntityType) entry.getValue(); + if (entityType.getProperties().isEmpty()) { + for (Type type : cache.values()) { + if (type.getFullName().equals(entityType.getFullName()) && type instanceof EntityType) { + EntityType base = (EntityType) type; + for (Property property : base.getProperties()) { + entityType.addProperty(property); + } + } + } + } + } + } + } + + public void setUnknownAsEntity(boolean unknownAsEntity) { + this.unknownAsEntity = unknownAsEntity; + } + + public void addEmbeddableType(Class cl) { + embeddableTypes.add(cl); + } + + public void addAnnotationHelper(AnnotationHelper annotationHelper) { + annotationHelpers.add(annotationHelper); + } +} diff --git a/querydsl-codegen/src/main/java/com/mysema/query/codegen/TypeMappings.java b/querydsl-codegen/src/main/java/com/querydsl/codegen/TypeMappings.java similarity index 81% rename from querydsl-codegen/src/main/java/com/mysema/query/codegen/TypeMappings.java rename to querydsl-codegen/src/main/java/com/querydsl/codegen/TypeMappings.java index f3ba67c19b..1dac1e5d94 100644 --- a/querydsl-codegen/src/main/java/com/mysema/query/codegen/TypeMappings.java +++ b/querydsl-codegen/src/main/java/com/querydsl/codegen/TypeMappings.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,25 +11,21 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.codegen; +package com.querydsl.codegen; -import java.util.HashMap; import java.util.EnumMap; +import java.util.HashMap; import java.util.Map; -import javax.annotation.Nullable; +import org.jetbrains.annotations.Nullable; -import com.mysema.codegen.model.ClassType; -import com.mysema.codegen.model.SimpleType; -import com.mysema.codegen.model.Type; -import com.mysema.codegen.model.TypeCategory; -import com.mysema.codegen.model.TypeExtends; -import com.mysema.query.types.Expression; -import com.mysema.query.types.Path; -import com.mysema.query.types.TemplateExpression; +import com.querydsl.codegen.utils.model.*; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.TemplateExpression; /** - * TypeMappings defines mappings from Java types to {@link Expression}, {@link Path} and + * {@code TypeMappings} defines mappings from Java types to {@link Expression}, {@link Path} and * {@link TemplateExpression} types * * @author tiwe @@ -37,6 +33,8 @@ */ public abstract class TypeMappings { + private final Map genericQueryTypes = new HashMap(); + private final Map queryTypes = new HashMap(); private final Map exprTypes @@ -47,7 +45,7 @@ public abstract class TypeMappings { private final Map templateTypes = new EnumMap(TypeCategory.class); - + public Type getTemplateType(Type type, EntityType model, boolean raw) { return getTemplateType(type, model, raw, false, false); } @@ -61,7 +59,9 @@ public Type getExprType(Type type, EntityType model, boolean raw) { } public Type getExprType(Type type, EntityType model, boolean raw, boolean rawParameters, boolean extend) { - if (queryTypes.containsKey(type.getFullName())) { + if (genericQueryTypes.containsKey(type)) { + return genericQueryTypes.get(type); + } else if (queryTypes.containsKey(type.getFullName())) { return queryTypes.get(type.getFullName()); } else { return getQueryType(exprTypes, type, model, raw, rawParameters, extend); @@ -73,20 +73,22 @@ public Type getPathType(Type type, EntityType model, boolean raw) { } public Type getPathType(Type type, EntityType model, boolean raw, boolean rawParameters, boolean extend) { - if (queryTypes.containsKey(type.getFullName())) { + if (genericQueryTypes.containsKey(type)) { + return genericQueryTypes.get(type); + } else if (queryTypes.containsKey(type.getFullName())) { return queryTypes.get(type.getFullName()); } else { return getQueryType(pathTypes, type, model, raw, rawParameters, extend); } } - private Type getQueryType(Map types, Type type, EntityType model, boolean raw, + private Type getQueryType(Map types, Type type, EntityType model, boolean raw, boolean rawParameters, boolean extend) { Type exprType = types.get(type.getCategory()); return getQueryType(type, model, exprType, raw, rawParameters, extend); } - public Type getQueryType(Type type, EntityType model, Type exprType, boolean raw, + public Type getQueryType(Type type, EntityType model, Type exprType, boolean raw, boolean rawParameters, boolean extend) { TypeCategory category = type.getCategory(); if (raw && category != TypeCategory.ENTITY && category != TypeCategory.CUSTOM) { @@ -106,7 +108,7 @@ public Type getQueryType(Type type, EntityType model, Type exprType, boolean raw } } - + @SuppressWarnings("rawtypes") public void register(TypeCategory category, @Nullable Class expr, @@ -125,9 +127,11 @@ public void register(TypeCategory category, public void register(Type type, Type queryType) { queryTypes.put(type.getFullName(), queryType); + genericQueryTypes.put(type, queryType); } public boolean isRegistered(Type type) { return queryTypes.containsKey(type.getFullName()); } + } diff --git a/querydsl-codegen/src/main/java/com/querydsl/codegen/TypeResolver.java b/querydsl-codegen/src/main/java/com/querydsl/codegen/TypeResolver.java new file mode 100644 index 0000000000..5bed50c757 --- /dev/null +++ b/querydsl-codegen/src/main/java/com/querydsl/codegen/TypeResolver.java @@ -0,0 +1,128 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.codegen; + +import com.querydsl.codegen.utils.model.SimpleType; +import com.querydsl.codegen.utils.model.Type; +import com.querydsl.codegen.utils.model.TypeExtends; +import com.querydsl.codegen.utils.model.TypeSuper; + +import java.util.Objects; + +/** + * {@code TypeResolver} provides type resolving functionality for resolving generic type variables to + * concrete types + * + * @author tiwe + * + */ +final class TypeResolver { + + /** + * Resolve type declared in declaringType for context + * + * @param type type to be resolved + * @param declaringType declaration context of type + * @param context target context of type + * @return resolved type + */ + public static Type resolve(Type type, Type declaringType, EntityType context) { + Type resolved = unwrap(type); + + String varName = getVarName(resolved); + if (varName != null) { + resolved = resolveVar(resolved, varName, declaringType, context); + } else if (!resolved.getParameters().isEmpty()) { + resolved = resolveWithParameters(resolved, declaringType, context); + } + + // rewrap entity type + if (type instanceof EntityType) { + if (!unwrap(type).equals(resolved)) { + resolved = new EntityType(resolved, ((EntityType) type).getSuperTypes()); + } else { + // reset to original type + resolved = type; + } + } + + return resolved; + } + + private static Type resolveVar(Type resolved, String varName, Type declaringType, EntityType context) { + // get parameter index of var in declaring type + int index = -1; + for (int i = 0; i < declaringType.getParameters().size(); i++) { + Type param = unwrap(declaringType.getParameters().get(i)); + if (Objects.equals(getVarName(param), varName)) { + index = i; + } + } + + if (index == -1) { + throw new IllegalStateException("Did not find type " + varName + + " in " + declaringType + " for " + context); + } + + Supertype type = context.getSuperType(); + while (!type.getEntityType().equals(declaringType)) { + type = type.getEntityType().getSuperType(); + } + if (!type.getType().getParameters().isEmpty()) { + return type.getType().getParameters().get(index); + } else { + // raw type + return resolved; + } + } + + private static Type resolveWithParameters(Type type, Type declaringType, EntityType context) { + Type[] params = new Type[type.getParameters().size()]; + boolean transformed = false; + for (int i = 0; i < type.getParameters().size(); i++) { + Type param = type.getParameters().get(i); + if (param != null && !param.getFullName().equals(type.getFullName())) { + params[i] = resolve(param, declaringType, context); + if (!params[i].equals(param)) { + transformed = true; + } + } + } + if (transformed) { + return new SimpleType(type, params); + } else { + return type; + } + } + + private static String getVarName(Type type) { + if (type instanceof TypeExtends) { + return ((TypeExtends) type).getVarName(); + } else if (type instanceof TypeSuper) { + return ((TypeSuper) type).getVarName(); + } else { + return null; + } + } + + private static Type unwrap(Type type) { + if (type instanceof EntityType) { + return ((EntityType) type).getInnerType(); + } else { + return type; + } + } + + private TypeResolver() { } +} diff --git a/querydsl-codegen/src/main/java/com/querydsl/codegen/package-info.java b/querydsl-codegen/src/main/java/com/querydsl/codegen/package-info.java new file mode 100644 index 0000000000..ea768ab1e4 --- /dev/null +++ b/querydsl-codegen/src/main/java/com/querydsl/codegen/package-info.java @@ -0,0 +1,18 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ + +/** + * Code generations models and serializers + */ +package com.querydsl.codegen; diff --git a/querydsl-codegen/src/test/java/Entity.java b/querydsl-codegen/src/test/java/Entity.java new file mode 100644 index 0000000000..fba51de198 --- /dev/null +++ b/querydsl-codegen/src/test/java/Entity.java @@ -0,0 +1,17 @@ + +public class Entity { + + private String name; + + public static String test(Object o) { + return null; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/querydsl-codegen/src/test/java/Entity2.java b/querydsl-codegen/src/test/java/Entity2.java new file mode 100644 index 0000000000..6c355cec1c --- /dev/null +++ b/querydsl-codegen/src/test/java/Entity2.java @@ -0,0 +1,13 @@ + +public class Entity2 { + + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/querydsl-core/src/test/java/com/SomeClass.java b/querydsl-codegen/src/test/java/com/SomeClass.java similarity index 89% rename from querydsl-core/src/test/java/com/SomeClass.java rename to querydsl-codegen/src/test/java/com/SomeClass.java index 79be9b3fbf..a9b89077d5 100644 --- a/querydsl-core/src/test/java/com/SomeClass.java +++ b/querydsl-codegen/src/test/java/com/SomeClass.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 diff --git a/querydsl-codegen/src/test/java/com/applejuice/ShouldBeLoaded.java b/querydsl-codegen/src/test/java/com/applejuice/ShouldBeLoaded.java new file mode 100644 index 0000000000..8402147751 --- /dev/null +++ b/querydsl-codegen/src/test/java/com/applejuice/ShouldBeLoaded.java @@ -0,0 +1,4 @@ +package com.applejuice; + +public class ShouldBeLoaded { +} diff --git a/querydsl-codegen/src/test/java/com/mysema/query/codegen/BeanSerializerTest.java b/querydsl-codegen/src/test/java/com/mysema/query/codegen/BeanSerializerTest.java deleted file mode 100644 index f00802f4cd..0000000000 --- a/querydsl-codegen/src/test/java/com/mysema/query/codegen/BeanSerializerTest.java +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.codegen; - -import java.io.IOException; -import java.io.Serializable; -import java.io.StringWriter; -import java.io.Writer; -import java.util.Arrays; -import java.util.Date; - -import com.mysema.codegen.JavaWriter; -import com.mysema.codegen.StringUtils; -import com.mysema.codegen.model.*; -import org.junit.Before; -import org.junit.Test; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -public class BeanSerializerTest { - - private Type typeModel; - - private EntityType type; - - private final Writer writer = new StringWriter(); - - @Before - public void setUp() { - typeModel = new SimpleType(TypeCategory.ENTITY, "com.mysema.query.DomainClass", "com.mysema.query", "DomainClass", false,false); - type = new EntityType(typeModel); - } - - @Test - public void Annotations() throws IOException{ - type.addAnnotation(new QueryEntityImpl()); - - BeanSerializer serializer = new BeanSerializer(); - serializer.serialize(type, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); - String str = writer.toString(); - - assertTrue(str.contains("import com.mysema.query.annotations.QueryEntity;")); - assertTrue(str.contains("@QueryEntity")); - } - - @Test - public void Annotated_Property() throws IOException{ - Property property = new Property(type, "entityField", type); - property.addAnnotation(new QueryEntityImpl()); - type.addProperty(property); - - BeanSerializer serializer = new BeanSerializer(); - serializer.serialize(type, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); - String str = writer.toString(); - - assertTrue(str.contains("import com.mysema.query.annotations.QueryEntity;")); - assertTrue(str.contains("@QueryEntity")); - } - - @Test - public void Annotated_Property_Not_Serialized() throws IOException{ - Property property = new Property(type, "entityField", type); - property.addAnnotation(new QueryEntityImpl()); - type.addProperty(property); - - BeanSerializer serializer = new BeanSerializer(false); - serializer.serialize(type, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); - String str = writer.toString(); - - assertFalse(str.contains("import com.mysema.query.annotations.QueryEntity;")); - assertFalse(str.contains("@QueryEntity")); - } - - @Test - public void Capitalization() throws IOException{ - // property - type.addProperty(new Property(type, "cId", type)); - - BeanSerializer serializer = new BeanSerializer(); - serializer.serialize(type, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); - assertTrue(writer.toString().contains("public DomainClass getcId() {")); - } - - @Test - public void Interfaces() throws IOException { - BeanSerializer serializer = new BeanSerializer(); - serializer.addInterface(new ClassType(Serializable.class)); - serializer.serialize(type, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); - assertTrue(writer.toString().contains("public class DomainClass implements Serializable {")); - } - - @Test - public void Interfaces2() throws IOException { - BeanSerializer serializer = new BeanSerializer(); - serializer.addInterface(Serializable.class); - serializer.serialize(type, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); - assertTrue(writer.toString().contains("public class DomainClass implements Serializable {")); - } - - @Test - public void ToString() throws IOException{ - // property - type.addProperty(new Property(type, "entityField", type)); - type.addProperty(new Property(type, "collection", new SimpleType(Types.COLLECTION, typeModel))); - type.addProperty(new Property(type, "listField", new SimpleType(Types.LIST, typeModel))); - type.addProperty(new Property(type, "setField", new SimpleType(Types.SET, typeModel))); - type.addProperty(new Property(type, "arrayField", new ClassType(TypeCategory.ARRAY, String[].class))); - type.addProperty(new Property(type, "mapField", new SimpleType(Types.MAP, typeModel, typeModel))); - - BeanSerializer serializer = new BeanSerializer(); - serializer.setAddToString(true); - serializer.serialize(type, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); - //System.out.println(writer.toString()); - } - - @Test - public void FullConstructor() throws IOException{ - // property - type.addProperty(new Property(type, "entityField", type)); - type.addProperty(new Property(type, "collection", new SimpleType(Types.COLLECTION, typeModel))); - type.addProperty(new Property(type, "listField", new SimpleType(Types.LIST, typeModel))); - type.addProperty(new Property(type, "setField", new SimpleType(Types.SET, typeModel))); - type.addProperty(new Property(type, "arrayField", new ClassType(TypeCategory.ARRAY, String[].class))); - type.addProperty(new Property(type, "mapField", new SimpleType(Types.MAP, typeModel, typeModel))); - - BeanSerializer serializer = new BeanSerializer(); - serializer.setAddFullConstructor(true); - serializer.serialize(type, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); - //System.out.println(writer.toString()); - } - - @Test - public void Properties() throws IOException{ - // property - type.addProperty(new Property(type, "entityField", type)); - type.addProperty(new Property(type, "collection", new SimpleType(Types.COLLECTION, typeModel))); - type.addProperty(new Property(type, "listField", new SimpleType(Types.LIST, typeModel))); - type.addProperty(new Property(type, "setField", new SimpleType(Types.SET, typeModel))); - type.addProperty(new Property(type, "arrayField", new ClassType(TypeCategory.ARRAY, String[].class))); - type.addProperty(new Property(type, "mapField", new SimpleType(Types.MAP, typeModel, typeModel))); - - for (Class cl : Arrays.>asList(Boolean.class, Comparable.class, Integer.class, Date.class, java.sql.Date.class, java.sql.Time.class)) { - Type classType = new ClassType(TypeCategory.get(cl.getName()), cl); - type.addProperty(new Property(type, StringUtils.uncapitalize(cl.getSimpleName()), classType)); - } - - BeanSerializer serializer = new BeanSerializer(); - serializer.serialize(type, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); - String str = writer.toString(); - //System.err.println(str); - for (String prop : Arrays.asList( - "String[] arrayField;", - "Boolean boolean$;", - "Collection collection;", - "Comparable comparable;", - "java.util.Date date;", - "DomainClass entityField;", - "Integer integer;", - "List listField;", - "Map mapField;", - "Set setField;", - "java.sql.Time time;")) { - assertTrue(prop + " was not contained", str.contains(prop)); - } - } - -} diff --git a/querydsl-codegen/src/test/java/com/mysema/query/codegen/CodegenModuleTest.java b/querydsl-codegen/src/test/java/com/mysema/query/codegen/CodegenModuleTest.java deleted file mode 100644 index 1ec1a7e95b..0000000000 --- a/querydsl-codegen/src/test/java/com/mysema/query/codegen/CodegenModuleTest.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.codegen; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -import org.junit.Test; - -public class CodegenModuleTest { - - private final CodegenModule module = new CodegenModule(); - - @Test - public void DefaultPrefix() { - assertEquals("Q", module.get(String.class, CodegenModule.PREFIX)); - } - - @Test - public void TypeMappings() { - assertNotNull(module.get(TypeMappings.class)); - } - - @Test(expected=IllegalArgumentException.class) - public void Get_With_Unknown_Key() { - module.get(String.class, "XXX"); - } - -} diff --git a/querydsl-codegen/src/test/java/com/mysema/query/codegen/CustomTypeTest.java b/querydsl-codegen/src/test/java/com/mysema/query/codegen/CustomTypeTest.java deleted file mode 100644 index 6ae90eebe5..0000000000 --- a/querydsl-codegen/src/test/java/com/mysema/query/codegen/CustomTypeTest.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.codegen; - -import static org.junit.Assert.assertTrue; - -import java.io.IOException; -import java.io.StringWriter; -import java.util.Collections; - -import org.junit.Test; - -import com.mysema.codegen.JavaWriter; -import com.mysema.codegen.model.ClassType; -import com.mysema.codegen.model.SimpleType; -import com.mysema.codegen.model.TypeCategory; - -public class CustomTypeTest { - - private final QueryTypeFactory queryTypeFactory = new QueryTypeFactoryImpl("Q", "", ""); - - private final TypeMappings typeMappings = new JavaTypeMappings(); - - private final EntitySerializer serializer = new EntitySerializer(typeMappings, Collections.emptySet()); - - private final StringWriter writer = new StringWriter(); - - @Test - public void CustomType() throws IOException{ - SimpleType type = new SimpleType(TypeCategory.ENTITY, "Entity", "", "Entity",false,false); - EntityType entityType = new EntityType(type); - entityType.addProperty(new Property(entityType, "property", new ClassType(Double[].class))); - typeMappings.register(new ClassType(Double[].class), new ClassType(Point.class)); - typeMappings.register(entityType, queryTypeFactory.create(entityType)); - assertTrue(typeMappings.isRegistered(entityType.getProperties().iterator().next().getType())); - - serializer.serialize(entityType, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); - assertTrue(writer.toString().contains( - "public final com.mysema.query.codegen.Point property = " + - "new com.mysema.query.codegen.Point(forProperty(\"property\"));")); - } - -} diff --git a/querydsl-codegen/src/test/java/com/mysema/query/codegen/DelegateTest.java b/querydsl-codegen/src/test/java/com/mysema/query/codegen/DelegateTest.java deleted file mode 100644 index dd1112361c..0000000000 --- a/querydsl-codegen/src/test/java/com/mysema/query/codegen/DelegateTest.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.codegen; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; - -import java.util.Collections; - -import org.junit.Test; - -import com.mysema.codegen.model.Parameter; -import com.mysema.codegen.model.Types; - -public class DelegateTest { - - @Test - public void Equals_Object() { - Delegate delegate = new Delegate(Types.STRING, Types.STRING, "delegate", Collections.emptyList(), Types.STRING); - Delegate delegate2 = new Delegate(Types.STRING, Types.STRING, "delegate", Collections.emptyList(), Types.STRING); - assertEquals(delegate, delegate2); - } - - @Test - public void Not_Equals_Object() { - Delegate delegate = new Delegate(Types.STRING, Types.STRING, "delegate", Collections.emptyList(), Types.STRING); - Delegate delegate2 = new Delegate(Types.STRING, Types.STRING, "delegate2", Collections.emptyList(), Types.STRING); - assertFalse(delegate.equals(delegate2)); - } - -} diff --git a/querydsl-codegen/src/test/java/com/mysema/query/codegen/EmbeddableSerializerTest.java b/querydsl-codegen/src/test/java/com/mysema/query/codegen/EmbeddableSerializerTest.java deleted file mode 100644 index bc0f1acb3a..0000000000 --- a/querydsl-codegen/src/test/java/com/mysema/query/codegen/EmbeddableSerializerTest.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.codegen; - -import static org.junit.Assert.assertTrue; - -import java.io.IOException; -import java.io.StringWriter; -import java.sql.Time; -import java.util.Collections; -import java.util.Date; -import java.util.EnumMap; -import java.util.Map; - -import com.mysema.codegen.JavaWriter; -import com.mysema.codegen.model.*; -import com.mysema.query.annotations.PropertyType; -import org.junit.Test; - -public class EmbeddableSerializerTest { - - private final QueryTypeFactory queryTypeFactory = new QueryTypeFactoryImpl("Q", "", ""); - - private final TypeMappings typeMappings = new JavaTypeMappings(); - - private final EntitySerializer serializer = new EmbeddableSerializer(typeMappings, Collections.emptySet()); - - private final StringWriter writer = new StringWriter(); - - @Test - public void Properties() throws IOException{ - SimpleType type = new SimpleType(TypeCategory.ENTITY, "Entity", "", "Entity",false,false); - EntityType entityType = new EntityType(type); - entityType.addProperty(new Property(entityType, "b", new ClassType(TypeCategory.BOOLEAN, Boolean.class))); - entityType.addProperty(new Property(entityType, "c", new ClassType(TypeCategory.COMPARABLE, String.class))); - entityType.addProperty(new Property(entityType, "cu", new ClassType(TypeCategory.CUSTOM, PropertyType.class))); - entityType.addProperty(new Property(entityType, "d", new ClassType(TypeCategory.DATE, Date.class))); - entityType.addProperty(new Property(entityType, "e", new ClassType(TypeCategory.ENUM, PropertyType.class))); - entityType.addProperty(new Property(entityType, "dt", new ClassType(TypeCategory.DATETIME, Date.class))); - entityType.addProperty(new Property(entityType, "i", new ClassType(TypeCategory.NUMERIC, Integer.class))); - entityType.addProperty(new Property(entityType, "s", new ClassType(TypeCategory.STRING, String.class))); - entityType.addProperty(new Property(entityType, "t", new ClassType(TypeCategory.TIME, Time.class))); - - serializer.serialize(entityType, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); - // TODO : assertions - } - - @Test - public void OriginalCategory() throws IOException{ - Map categoryToSuperClass - = new EnumMap(TypeCategory.class); - categoryToSuperClass.put(TypeCategory.COMPARABLE, "ComparablePath"); - categoryToSuperClass.put(TypeCategory.ENUM, "EnumPath"); - categoryToSuperClass.put(TypeCategory.DATE, "DatePath"); - categoryToSuperClass.put(TypeCategory.DATETIME, "DateTimePath"); - categoryToSuperClass.put(TypeCategory.TIME, "TimePath"); - categoryToSuperClass.put(TypeCategory.NUMERIC, "NumberPath"); - categoryToSuperClass.put(TypeCategory.STRING, "StringPath"); - categoryToSuperClass.put(TypeCategory.BOOLEAN, "BooleanPath"); - - for (Map.Entry entry : categoryToSuperClass.entrySet()) { - SimpleType type = new SimpleType(entry.getKey(), "Entity", "", "Entity",false,false); - EntityType entityType = new EntityType(type); - typeMappings.register(entityType, queryTypeFactory.create(entityType)); - - serializer.serialize(entityType, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); - assertTrue(entry.toString(), writer.toString().contains("public class QEntity extends "+entry.getValue()+" {")); - } - - } - - @Test - public void Empty() throws IOException{ - SimpleType type = new SimpleType(TypeCategory.ENTITY, "Entity", "", "Entity",false,false); - EntityType entityType = new EntityType(type); - - serializer.serialize(entityType, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); - // TODO : assertions - } - - @Test - public void No_Package() throws IOException { - SimpleType type = new SimpleType(TypeCategory.ENTITY, "Entity", "", "Entity",false,false); - EntityType entityType = new EntityType(type); - typeMappings.register(entityType, queryTypeFactory.create(entityType)); - serializer.serialize(entityType, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); - assertTrue(writer.toString().contains("public class QEntity extends BeanPath {")); - } - - @Test - public void Correct_Superclass() throws IOException { - SimpleType type = new SimpleType(TypeCategory.ENTITY, "java.util.Locale", "java.util", "Locale",false,false); - EntityType entityType = new EntityType(type); - typeMappings.register(entityType, queryTypeFactory.create(entityType)); - serializer.serialize(entityType, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); - //System.out.println(writer); - assertTrue(writer.toString().contains("public class QLocale extends BeanPath {")); - } - - @Test - public void Primitive_Array() throws IOException{ - SimpleType type = new SimpleType(TypeCategory.ENTITY, "Entity", "", "Entity",false,false); - EntityType entityType = new EntityType(type); - entityType.addProperty(new Property(entityType, "bytes", new ClassType(byte[].class))); - serializer.serialize(entityType, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); - assertTrue(writer.toString().contains("public final SimplePath bytes")); - } - - @Test - public void Include() throws IOException{ - SimpleType type = new SimpleType(TypeCategory.ENTITY, "Entity", "", "Entity",false,false); - EntityType entityType = new EntityType(type); - entityType.addProperty(new Property(entityType, "b", new ClassType(TypeCategory.BOOLEAN, Boolean.class))); - entityType.addProperty(new Property(entityType, "c", new ClassType(TypeCategory.COMPARABLE, String.class))); - entityType.addProperty(new Property(entityType, "cu", new ClassType(TypeCategory.CUSTOM, PropertyType.class))); - entityType.addProperty(new Property(entityType, "d", new ClassType(TypeCategory.DATE, Date.class))); - entityType.addProperty(new Property(entityType, "e", new ClassType(TypeCategory.ENUM, PropertyType.class))); - entityType.addProperty(new Property(entityType, "dt", new ClassType(TypeCategory.DATETIME, Date.class))); - entityType.addProperty(new Property(entityType, "i", new ClassType(TypeCategory.NUMERIC, Integer.class))); - entityType.addProperty(new Property(entityType, "s", new ClassType(TypeCategory.STRING, String.class))); - entityType.addProperty(new Property(entityType, "t", new ClassType(TypeCategory.TIME, Time.class))); - - EntityType subType = new EntityType(new SimpleType(TypeCategory.ENTITY, "Entity2", "", "Entity2",false,false)); - subType.include(new Supertype(type,entityType)); - - serializer.serialize(subType, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); - // TODO : assertions - } - - @Test - public void SuperType() throws IOException{ - EntityType superType = new EntityType(new SimpleType(TypeCategory.ENTITY, "Entity2", "", "Entity2",false,false)); - SimpleType type = new SimpleType(TypeCategory.ENTITY, "Entity", "", "Entity",false,false); - EntityType entityType = new EntityType(type, Collections.singleton(new Supertype(superType, superType))); - typeMappings.register(superType, queryTypeFactory.create(superType)); - typeMappings.register(entityType, queryTypeFactory.create(entityType)); - - serializer.serialize(entityType, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); - assertTrue(writer.toString().contains("public final QEntity2 _super = new QEntity2(this);")); - } - - @Test - public void Delegates() throws IOException{ - SimpleType type = new SimpleType(TypeCategory.ENTITY, "Entity", "", "Entity",false,false); - EntityType entityType = new EntityType(type); - Delegate delegate = new Delegate(type, type, "test", Collections.emptyList(), Types.STRING); - entityType.addDelegate(delegate); - - serializer.serialize(entityType, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); - assertTrue(writer.toString().contains("return Entity.test(this);")); - } - -} diff --git a/querydsl-codegen/src/test/java/com/mysema/query/codegen/Embedded2Test.java b/querydsl-codegen/src/test/java/com/mysema/query/codegen/Embedded2Test.java deleted file mode 100644 index 5a9e226f81..0000000000 --- a/querydsl-codegen/src/test/java/com/mysema/query/codegen/Embedded2Test.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.codegen; - -import java.io.Serializable; - -import com.mysema.query.annotations.QueryEmbeddable; -import com.mysema.query.annotations.QueryEmbedded; -import com.mysema.query.annotations.QueryEntity; -import com.mysema.query.annotations.QuerySupertype; - -public class Embedded2Test extends AbstractExporterTest { - - @QuerySupertype - public static class EntityCode { - - public String code; - - } - - @QuerySupertype - public static abstract class AbstractEntity { - - @QueryEmbedded - public C code; - - } - - @QuerySupertype - public static class AbstractMultilingualEntity extends AbstractEntity { - - } - - @QuerySupertype - public static abstract class AbstractNamedEntity extends AbstractMultilingualEntity { - - public String nameEn; - - public String nameNl; - - } - - @QueryEntity - public static class Brand extends AbstractNamedEntity { - - public Long id; - - } - - public interface Entity extends Serializable { - - boolean sameIdentityAs(T other); - - } - - @QueryEmbeddable - public static class BrandCode extends EntityCode { - - } - - -} diff --git a/querydsl-codegen/src/test/java/com/mysema/query/codegen/EmbeddedTest.java b/querydsl-codegen/src/test/java/com/mysema/query/codegen/EmbeddedTest.java deleted file mode 100644 index ba8af58f95..0000000000 --- a/querydsl-codegen/src/test/java/com/mysema/query/codegen/EmbeddedTest.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.mysema.query.codegen; - -import com.mysema.query.annotations.QueryEmbeddable; -import com.mysema.query.annotations.QueryEmbedded; -import com.mysema.query.annotations.QueryEntity; -import com.mysema.query.annotations.QuerySupertype; - -public class EmbeddedTest extends AbstractExporterTest { - - @QueryEntity - public static class EntityClass extends AbstractEntity { - - } - - @QuerySupertype - public static abstract class AbstractEntity { - - @QueryEmbedded - public C code; - } - - @QuerySupertype - public static class EntityCode { - - public String code; - - } - - @QueryEmbeddable - public static class SubEntityCode extends EntityCode { - - public String property; - - } - -} \ No newline at end of file diff --git a/querydsl-codegen/src/test/java/com/mysema/query/codegen/EntityInheritanceTest.java b/querydsl-codegen/src/test/java/com/mysema/query/codegen/EntityInheritanceTest.java deleted file mode 100644 index ad68e019d8..0000000000 --- a/querydsl-codegen/src/test/java/com/mysema/query/codegen/EntityInheritanceTest.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.mysema.query.codegen; - -import com.mysema.query.annotations.QueryEntity; -import com.mysema.query.annotations.QuerySupertype; - -public class EntityInheritanceTest extends AbstractExporterTest { - - @QuerySupertype - public static class TreeEntity> { - - public Integer id; - - public T parent; - - } - - @QueryEntity - public static class TestEntity extends TreeEntity { - - public String name; - - } - -} diff --git a/querydsl-codegen/src/test/java/com/mysema/query/codegen/EntitySerializerTest.java b/querydsl-codegen/src/test/java/com/mysema/query/codegen/EntitySerializerTest.java deleted file mode 100644 index 58c5a2baaf..0000000000 --- a/querydsl-codegen/src/test/java/com/mysema/query/codegen/EntitySerializerTest.java +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.codegen; - -import static org.junit.Assert.assertTrue; - -import java.io.IOException; -import java.io.StringWriter; -import java.sql.Time; -import java.util.Collections; -import java.util.Date; -import java.util.EnumMap; -import java.util.Map; - -import org.junit.Test; - -import com.mysema.codegen.JavaWriter; -import com.mysema.codegen.model.ClassType; -import com.mysema.codegen.model.Parameter; -import com.mysema.codegen.model.SimpleType; -import com.mysema.codegen.model.TypeCategory; -import com.mysema.codegen.model.Types; -import com.mysema.query.annotations.PropertyType; - -public class EntitySerializerTest { - - private QueryTypeFactory queryTypeFactory = new QueryTypeFactoryImpl("Q", "", ""); - - private final TypeMappings typeMappings = new JavaTypeMappings(); - - private final EntitySerializer serializer = new EntitySerializer(typeMappings, Collections.emptySet()); - - private final StringWriter writer = new StringWriter(); - - public class Entity { - - } - - @Test - public void Javadocs_For_InnerClass() throws IOException{ - EntityType entityType = new EntityType(new ClassType(Entity.class)); - typeMappings.register(entityType, queryTypeFactory.create(entityType)); - - serializer.serialize(entityType, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); - assertTrue(writer.toString().contains("QEntitySerializerTest_Entity is a Querydsl query type for Entity")); - } - - @Test - public void Different_Package() throws IOException { - queryTypeFactory = new QueryTypeFactoryImpl("Q", "", ".gen"); - - EntityType entityType = new EntityType(new ClassType(Entity.class)); - typeMappings.register(entityType, queryTypeFactory.create(entityType)); - - serializer.serialize(entityType, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); -// System.err.println(writer.toString()); - assertTrue(writer.toString().contains("public class QEntitySerializerTest_Entity " + - "extends EntityPathBase")); - } - - @Test - public void No_Package() throws IOException { - SimpleType type = new SimpleType(TypeCategory.ENTITY, "Entity", "", "Entity",false,false); - EntityType entityType = new EntityType(type); - typeMappings.register(entityType, queryTypeFactory.create(entityType)); - - serializer.serialize(entityType, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); - assertTrue(writer.toString().contains("public class QEntity extends EntityPathBase {")); - } - - @Test - public void OriginalCategory() throws IOException{ - Map categoryToSuperClass - = new EnumMap(TypeCategory.class); - categoryToSuperClass.put(TypeCategory.COMPARABLE, "ComparablePath"); - categoryToSuperClass.put(TypeCategory.ENUM, "EnumPath"); - categoryToSuperClass.put(TypeCategory.DATE, "DatePath"); - categoryToSuperClass.put(TypeCategory.DATETIME, "DateTimePath"); - categoryToSuperClass.put(TypeCategory.TIME, "TimePath"); - categoryToSuperClass.put(TypeCategory.NUMERIC, "NumberPath"); - categoryToSuperClass.put(TypeCategory.STRING, "StringPath"); - categoryToSuperClass.put(TypeCategory.BOOLEAN, "BooleanPath"); - - for (Map.Entry entry : categoryToSuperClass.entrySet()) { - SimpleType type = new SimpleType(entry.getKey(), "Entity", "", "Entity",false,false); - EntityType entityType = new EntityType(type); - typeMappings.register(entityType, queryTypeFactory.create(entityType)); - - serializer.serialize(entityType, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); - assertTrue(entry.toString(), writer.toString().contains("public class QEntity extends "+entry.getValue()+" {")); - } - - } - - @Test - public void Correct_Superclass() throws IOException { - SimpleType type = new SimpleType(TypeCategory.ENTITY, "java.util.Locale", "java.util", "Locale",false,false); - EntityType entityType = new EntityType(type); - typeMappings.register(entityType, queryTypeFactory.create(entityType)); - - serializer.serialize(entityType, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); -// System.out.println(writer); - assertTrue(writer.toString().contains("public class QLocale extends EntityPathBase {")); - } - - @Test - public void Primitive_Array() throws IOException{ - SimpleType type = new SimpleType(TypeCategory.ENTITY, "Entity", "", "Entity",false,false); - EntityType entityType = new EntityType(type); - entityType.addProperty(new Property(entityType, "bytes", new ClassType(byte[].class))); - serializer.serialize(entityType, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); - assertTrue(writer.toString().contains("public final SimplePath bytes")); - } - - @Test - public void Include() throws IOException{ - SimpleType type = new SimpleType(TypeCategory.ENTITY, "Entity", "", "Entity",false,false); - EntityType entityType = new EntityType(type); - entityType.addProperty(new Property(entityType, "b", new ClassType(TypeCategory.BOOLEAN, Boolean.class))); - entityType.addProperty(new Property(entityType, "c", new ClassType(TypeCategory.COMPARABLE, String.class))); - entityType.addProperty(new Property(entityType, "cu", new ClassType(TypeCategory.CUSTOM, PropertyType.class))); - entityType.addProperty(new Property(entityType, "d", new ClassType(TypeCategory.DATE, Date.class))); - entityType.addProperty(new Property(entityType, "e", new ClassType(TypeCategory.ENUM, PropertyType.class))); - entityType.addProperty(new Property(entityType, "dt", new ClassType(TypeCategory.DATETIME, Date.class))); - entityType.addProperty(new Property(entityType, "i", new ClassType(TypeCategory.NUMERIC, Integer.class))); - entityType.addProperty(new Property(entityType, "s", new ClassType(TypeCategory.STRING, String.class))); - entityType.addProperty(new Property(entityType, "t", new ClassType(TypeCategory.TIME, Time.class))); - - EntityType subType = new EntityType(new SimpleType(TypeCategory.ENTITY, "Entity2", "", "Entity2",false,false)); - subType.include(new Supertype(type,entityType)); - - serializer.serialize(subType, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); - // TODO : assertions - } - - @Test - public void Properties() throws IOException{ - SimpleType type = new SimpleType(TypeCategory.ENTITY, "Entity", "", "Entity",false,false); - EntityType entityType = new EntityType(type); - entityType.addProperty(new Property(entityType, "b", new ClassType(TypeCategory.BOOLEAN, Boolean.class))); - entityType.addProperty(new Property(entityType, "c", new ClassType(TypeCategory.COMPARABLE, String.class))); - entityType.addProperty(new Property(entityType, "cu", new ClassType(TypeCategory.CUSTOM, PropertyType.class))); - entityType.addProperty(new Property(entityType, "d", new ClassType(TypeCategory.DATE, Date.class))); - entityType.addProperty(new Property(entityType, "e", new ClassType(TypeCategory.ENUM, PropertyType.class))); - entityType.addProperty(new Property(entityType, "dt", new ClassType(TypeCategory.DATETIME, Date.class))); - entityType.addProperty(new Property(entityType, "i", new ClassType(TypeCategory.NUMERIC, Integer.class))); - entityType.addProperty(new Property(entityType, "s", new ClassType(TypeCategory.STRING, String.class))); - entityType.addProperty(new Property(entityType, "t", new ClassType(TypeCategory.TIME, Time.class))); - - serializer.serialize(entityType, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); - // TODO : assertions - } - - @Test - public void SuperType() throws IOException{ - EntityType superType = new EntityType(new SimpleType(TypeCategory.ENTITY, "Entity2", "", "Entity2",false,false)); - SimpleType type = new SimpleType(TypeCategory.ENTITY, "Entity", "", "Entity",false,false); - EntityType entityType = new EntityType(type, Collections.singleton(new Supertype(superType, superType))); - typeMappings.register(superType, queryTypeFactory.create(superType)); - typeMappings.register(entityType, queryTypeFactory.create(entityType)); - - serializer.serialize(entityType, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); - assertTrue(writer.toString().contains("public final QEntity2 _super = new QEntity2(this);")); - } - - @Test - public void Delegates() throws IOException{ - SimpleType type = new SimpleType(TypeCategory.ENTITY, "Entity", "", "Entity",false,false); - EntityType entityType = new EntityType(type); - Delegate delegate = new Delegate(type, type, "test", Collections.emptyList(), Types.STRING); - entityType.addDelegate(delegate); - - serializer.serialize(entityType, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); - assertTrue(writer.toString().contains("return Entity.test(this);")); - } - -} diff --git a/querydsl-codegen/src/test/java/com/mysema/query/codegen/EntityTypeTest.java b/querydsl-codegen/src/test/java/com/mysema/query/codegen/EntityTypeTest.java deleted file mode 100644 index 5ea061bb74..0000000000 --- a/querydsl-codegen/src/test/java/com/mysema/query/codegen/EntityTypeTest.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.codegen; - -import static org.junit.Assert.assertEquals; - -import java.util.Collections; - -import org.junit.Test; - -import com.mysema.codegen.model.ClassType; -import com.mysema.codegen.model.TypeCategory; - -public class EntityTypeTest { - - @Test - public void UncapSimpleName_Escaped() { - ClassType typeModel = new ClassType(TypeCategory.ENTITY, Object.class); - EntityType entityModel = new EntityType(typeModel); - assertEquals("object", entityModel.getUncapSimpleName()); - - entityModel.addProperty(new Property(entityModel, "object", typeModel)); - assertEquals("object1", entityModel.getUncapSimpleName()); - } - - @Test - public void UncapSimpleName_Escaped2() { - ClassType typeModel = new ClassType(TypeCategory.ENTITY, Object.class); - EntityType entityModel = new EntityType(typeModel); - assertEquals("object", entityModel.getUncapSimpleName()); - - entityModel.addProperty(new Property(entityModel, "OBJECT", "object", typeModel, - Collections. emptyList(), false)); - assertEquals("object1", entityModel.getUncapSimpleName()); - } - - @Test - public void UncapSimpleName_Escaped3() { - ClassType typeModel = new ClassType(TypeCategory.ENTITY, Void.class); - EntityType entityModel = new EntityType(typeModel); - assertEquals("void$", entityModel.getUncapSimpleName()); - } - -} diff --git a/querydsl-codegen/src/test/java/com/mysema/query/codegen/ExampleEntity.java b/querydsl-codegen/src/test/java/com/mysema/query/codegen/ExampleEntity.java deleted file mode 100644 index 2dd06575a5..0000000000 --- a/querydsl-codegen/src/test/java/com/mysema/query/codegen/ExampleEntity.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.codegen; - -import java.util.List; -import java.util.Map; - -import com.mysema.query.annotations.QueryEmbedded; -import com.mysema.query.annotations.QueryEntity; - -@QueryEntity -public class ExampleEntity extends ExampleSupertype { - - private String name; - - private ExampleEntity mate; - - private List mates; - - private Map matesByName; - - private ExampleEmbeddable embeddable; - - @QueryEmbedded - private ExampleEmbedded embedded; - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public ExampleEntity getMate() { - return mate; - } - - public void setMate(ExampleEntity mate) { - this.mate = mate; - } - - public ExampleEmbeddable getEmbeddable() { - return embeddable; - } - - public void setEmbeddable(ExampleEmbeddable embeddable) { - this.embeddable = embeddable; - } - - public List getMates() { - return mates; - } - - public void setMates(List mates) { - this.mates = mates; - } - - public Map getMatesByName() { - return matesByName; - } - - public void setMatesByName(Map matesByName) { - this.matesByName = matesByName; - } - - public ExampleEmbedded getEmbedded() { - return embedded; - } - - public void setEmbedded(ExampleEmbedded embedded) { - this.embedded = embedded; - } - - - -} diff --git a/querydsl-codegen/src/test/java/com/mysema/query/codegen/Examples.java b/querydsl-codegen/src/test/java/com/mysema/query/codegen/Examples.java deleted file mode 100644 index 22a8570ad6..0000000000 --- a/querydsl-codegen/src/test/java/com/mysema/query/codegen/Examples.java +++ /dev/null @@ -1,120 +0,0 @@ -package com.mysema.query.codegen; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import com.mysema.query.DefaultQueryMetadata; -import com.mysema.query.annotations.QueryEmbedded; -import com.mysema.query.annotations.QueryEntity; -import com.mysema.query.types.OrderSpecifier; - - -public class Examples { - - public static class Supertype { - - public String supertypeProperty; - } - - @QueryEntity - public static class SimpleEntity extends Supertype{ - - } - - @QueryEntity - public static abstract class AbstractEntity { - - public Id id; - - public String first; - - } - - @QueryEntity - public static class SubEntity extends AbstractEntity { - - public String second; - - } - - - @QueryEntity - public static class ComplexCollections { - - @QueryEmbedded - public List> list; - - @QueryEmbedded - public Map> map; - - @QueryEmbedded - public Map> map2; - - @QueryEmbedded - public Map> map3; - - - } - - - public static class Complex> implements Comparable> { - - public T a; - - @Override - public int compareTo(Complex arg0) { - return 0; - } - - public boolean equals(Object o) { - return o == this; - } - } - - @QueryEntity - public static class Reference { - - } - - @QueryEntity - public static class GenericRelations{ - public Collection> col1; - public Collection> col2; - public Collection> col3; - public Collection> col4; - - public Set> set1; - public Set> set2; - public Set> set3; - public Set> set4; - - public Map> map1; - public Map,String> map2; - public Map> map3; - public Map,String> map4; - } - - @QueryEntity - public static class Subtype extends DefaultQueryMetadata{ - - private static final long serialVersionUID = -218949941713252847L; - - } - - @QueryEntity - public static class OrderBys { - - List> orderBy = new ArrayList>(); - - } - - @QueryEntity - public static class SimpleTypes { - - List> classList5; - } -} diff --git a/querydsl-codegen/src/test/java/com/mysema/query/codegen/ExternalEmbeddableTest.java b/querydsl-codegen/src/test/java/com/mysema/query/codegen/ExternalEmbeddableTest.java deleted file mode 100644 index 1865d97e77..0000000000 --- a/querydsl-codegen/src/test/java/com/mysema/query/codegen/ExternalEmbeddableTest.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.mysema.query.codegen; - -import org.junit.Ignore; - -import com.mysema.query.annotations.QueryEmbedded; -import com.mysema.query.annotations.QueryEntity; -import com.mysema.query.domain.EmbeddableWithoutQType; - -@Ignore -public class ExternalEmbeddableTest { - - @QueryEntity - public static class EntityWithExternalEmbeddable { - - @QueryEmbedded - EmbeddableWithoutQType embeddable; - - } - -} diff --git a/querydsl-codegen/src/test/java/com/mysema/query/codegen/Generic2Test.java b/querydsl-codegen/src/test/java/com/mysema/query/codegen/Generic2Test.java deleted file mode 100644 index fe520c2da3..0000000000 --- a/querydsl-codegen/src/test/java/com/mysema/query/codegen/Generic2Test.java +++ /dev/null @@ -1,63 +0,0 @@ -package com.mysema.query.codegen; - -import static org.junit.Assert.*; - -import java.io.File; -import java.lang.annotation.Annotation; -import java.util.Collection; -import java.util.Collections; -import java.util.List; - -import org.junit.Test; - -import com.mysema.codegen.model.Type; -import com.mysema.query.annotations.QueryEntity; - -public class Generic2Test { - - @QueryEntity - public static class AbstractCollectionAttribute> { - - T value; - - } - - @QueryEntity - public static class ListAttribute extends AbstractCollectionAttribute> { - - String name; - - } - - @QueryEntity - public static class Product { - - ListAttribute integerAttributes; - ListAttribute stringAttributes; - - } - - @Test - public void Resolve() { - TypeFactory factory = new TypeFactory(Collections.>emptyList()); - Type type = factory.get(AbstractCollectionAttribute.class); - assertEquals("com.mysema.query.codegen.Generic2Test.AbstractCollectionAttribute", type.getGenericName(false)); - assertEquals("com.mysema.query.codegen.Generic2Test.AbstractCollectionAttribute", type.getGenericName(true)); - } - - @Test - public void Resolve2() { - TypeFactory factory = new TypeFactory(Collections.>emptyList()); - Type type = factory.getEntityType(AbstractCollectionAttribute.class); - assertEquals("com.mysema.query.codegen.Generic2Test.AbstractCollectionAttribute>", type.getGenericName(false)); - assertEquals("com.mysema.query.codegen.Generic2Test.AbstractCollectionAttribute>", type.getGenericName(true)); - } - - - @Test - public void Export() { - GenericExporter exporter = new GenericExporter(); - exporter.setTargetFolder(new File("target/Generic2Test")); - exporter.export(Generic2Test.class.getClasses()); - } -} diff --git a/querydsl-codegen/src/test/java/com/mysema/query/codegen/GenericExporterTest.java b/querydsl-codegen/src/test/java/com/mysema/query/codegen/GenericExporterTest.java deleted file mode 100644 index 286858ff55..0000000000 --- a/querydsl-codegen/src/test/java/com/mysema/query/codegen/GenericExporterTest.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.codegen; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import java.io.File; -import java.io.IOException; - -import org.junit.Before; -import org.junit.Test; - -import com.google.common.base.Charsets; -import com.google.common.io.Files; -import com.mysema.query.domain.Cat; - -public class GenericExporterTest { - - private GenericExporter exporter; - - @Before - public void setUp() { - exporter = new GenericExporter(); - } - - @Test - public void Export() { - exporter.setTargetFolder(new File("target/gen1")); - exporter.export(getClass().getPackage()); - assertTrue(new File("target/gen1/com/mysema/query/codegen/QExampleEmbeddable.java").exists()); - assertTrue(new File("target/gen1/com/mysema/query/codegen/QExampleEmbedded.java").exists()); - assertTrue(new File("target/gen1/com/mysema/query/codegen/QExampleEntity.java").exists()); - assertTrue(new File("target/gen1/com/mysema/query/codegen/QExampleEntityInterface.java").exists()); - assertTrue(new File("target/gen1/com/mysema/query/codegen/QExampleSupertype.java").exists()); - assertTrue(new File("target/gen1/com/mysema/query/codegen/sub/QExampleEntity2.java").exists()); - } - - @Test - public void Export_With_Keywords() throws IOException { - exporter.setKeywords(Keywords.JPA); - exporter.setTargetFolder(new File("target/gen1_jpa")); - exporter.export(getClass().getPackage()); - String str = Files.toString(new File("target/gen1_jpa/com/mysema/query/codegen/QGroup.java"), Charsets.UTF_8); - assertTrue(str.contains("QGroup group = new QGroup(\"group1\");")); - } - - @Test - public void Export_With_Stopclass() { - exporter.setTargetFolder(new File("target/gen1_stop")); - exporter.addStopClass(Examples.Supertype.class); - exporter.export(getClass().getPackage()); - assertFalse(new File("target/gen1_stop/com/mysema/query/codegen/QExamples_Supertype.java").exists()); - } - - @Test - public void OverrideSerializer() { - exporter.setTargetFolder(new File("target/gen2")); - exporter.setSerializerClass(EntitySerializer.class); - exporter.export(getClass().getPackage()); - assertTrue(new File("target/gen2/com/mysema/query/codegen/QExampleEmbeddable.java").exists()); - assertTrue(new File("target/gen2/com/mysema/query/codegen/QExampleEmbedded.java").exists()); - assertTrue(new File("target/gen2/com/mysema/query/codegen/QExampleEntity.java").exists()); - assertTrue(new File("target/gen2/com/mysema/query/codegen/QExampleEntityInterface.java").exists()); - assertTrue(new File("target/gen2/com/mysema/query/codegen/QExampleSupertype.java").exists()); - assertTrue(new File("target/gen2/com/mysema/query/codegen/sub/QExampleEntity2.java").exists()); - } - - @Test - public void Export_Package_as_String() { - exporter.setTargetFolder(new File("target/gen3")); - exporter.export(getClass().getPackage().getName()); - assertTrue(new File("target/gen3/com/mysema/query/codegen/QExampleEmbeddable.java").exists()); - assertTrue(new File("target/gen3/com/mysema/query/codegen/QExampleEmbedded.java").exists()); - assertTrue(new File("target/gen3/com/mysema/query/codegen/QExampleEntity.java").exists()); - assertTrue(new File("target/gen3/com/mysema/query/codegen/QExampleEntityInterface.java").exists()); - assertTrue(new File("target/gen3/com/mysema/query/codegen/QExampleSupertype.java").exists()); - assertTrue(new File("target/gen3/com/mysema/query/codegen/sub/QExampleEntity2.java").exists()); - } - - @Test - public void Export_With_Package_Suffix() { - exporter.setTargetFolder(new File("target/gen4")); - exporter.setPackageSuffix("types"); - exporter.export(getClass().getPackage()); - assertTrue(new File("target/gen4/com/mysema/query/codegentypes/QExampleEmbeddable.java").exists()); - assertTrue(new File("target/gen4/com/mysema/query/codegentypes/QExampleEmbedded.java").exists()); - assertTrue(new File("target/gen4/com/mysema/query/codegentypes/QExampleEntity.java").exists()); - assertTrue(new File("target/gen4/com/mysema/query/codegentypes/QExampleEntityInterface.java").exists()); - assertTrue(new File("target/gen4/com/mysema/query/codegentypes/QExampleSupertype.java").exists()); - assertTrue(new File("target/gen4/com/mysema/query/codegen/subtypes/QExampleEntity2.java").exists()); - } - - @Test - public void Export_Handle_No_Methods_Nor_Fields() { - exporter.setTargetFolder(new File("target/gen5")); - exporter.setHandleFields(false); - exporter.setHandleMethods(false); - exporter.export(getClass().getPackage()); - assertTrue(new File("target/gen5/com/mysema/query/codegen/QExampleEmbeddable.java").exists()); - } - - @Test - public void Export_Domain_Package() { - exporter.setTargetFolder(new File("target/gen6")); - exporter.export(Cat.class.getPackage()); - } - - -} diff --git a/querydsl-codegen/src/test/java/com/mysema/query/codegen/GenericTest.java b/querydsl-codegen/src/test/java/com/mysema/query/codegen/GenericTest.java deleted file mode 100644 index 5ba655d037..0000000000 --- a/querydsl-codegen/src/test/java/com/mysema/query/codegen/GenericTest.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.mysema.query.codegen; - -import org.junit.Test; - -import com.mysema.codegen.model.Type; - - -public class GenericTest { - - public static abstract class CapiBCKeyedByGrundstueck { - - } - - public static abstract class HidaBez, G extends HidaBezGruppe> extends CapiBCKeyedByGrundstueck { - - } - - public static abstract class HidaBezGruppe, B extends HidaBez> extends - CapiBCKeyedByGrundstueck { - } - - private TypeFactory typeFactory = new TypeFactory(); - - @Test - public void HidaBez() { - Type type = typeFactory.getEntityType(HidaBez.class); - //System.out.println(type.getGenericName(true)); - } - - @Test - public void HidaBezGruppe() { - Type type = typeFactory.getEntityType(HidaBezGruppe.class); - //System.out.println(type.getGenericName(true)); - } - -} diff --git a/querydsl-codegen/src/test/java/com/mysema/query/codegen/Group.java b/querydsl-codegen/src/test/java/com/mysema/query/codegen/Group.java deleted file mode 100644 index a6ca9df9a7..0000000000 --- a/querydsl-codegen/src/test/java/com/mysema/query/codegen/Group.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.mysema.query.codegen; - -import com.mysema.query.annotations.QueryEntity; - -@QueryEntity -public class Group { - -} diff --git a/querydsl-codegen/src/test/java/com/mysema/query/codegen/Inheritance2Test.java b/querydsl-codegen/src/test/java/com/mysema/query/codegen/Inheritance2Test.java deleted file mode 100644 index 4dd26476c8..0000000000 --- a/querydsl-codegen/src/test/java/com/mysema/query/codegen/Inheritance2Test.java +++ /dev/null @@ -1,73 +0,0 @@ -package com.mysema.query.codegen; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; - -import java.io.File; -import java.lang.reflect.Field; - -import org.junit.Test; - -import com.mysema.codegen.model.Type; -import com.mysema.codegen.model.TypeExtends; -import com.mysema.query.annotations.QueryEntity; - -public class Inheritance2Test { - - @QueryEntity - public abstract class Base> { - @SuppressWarnings("unchecked") - Base2 base; - Base2 base2; - } - - @QueryEntity - public abstract class Base2,U extends IFace> { - - } - - @QueryEntity - public abstract class BaseSub extends Base { - - } - - @QueryEntity - public abstract class BaseSub2> extends Base { - - } - - @QueryEntity - public abstract class Base2Sub extends Base2,T> { - - } - - public interface IFace { - - } - - @Test - public void Base_base() throws SecurityException, NoSuchFieldException { - TypeFactory typeFactory = new TypeFactory(); - Field field = Base.class.getDeclaredField("base"); - Type type = typeFactory.get(field.getType(), field.getGenericType()); - assertEquals(0, type.getParameters().size()); - } - - @Test - public void Base_base2() throws SecurityException, NoSuchFieldException { - TypeFactory typeFactory = new TypeFactory(); - Field field = Base.class.getDeclaredField("base2"); - Type type = typeFactory.get(field.getType(), field.getGenericType()); - assertEquals(2, type.getParameters().size()); - assertNull(((TypeExtends)type.getParameters().get(0)).getVarName()); - assertNull(((TypeExtends)type.getParameters().get(1)).getVarName()); - } - - @Test - public void test() { - GenericExporter exporter = new GenericExporter(); - exporter.setTargetFolder(new File("target/" + getClass().getSimpleName())); - exporter.export(getClass().getClasses()); - } - -} \ No newline at end of file diff --git a/querydsl-codegen/src/test/java/com/mysema/query/codegen/PackageSuffixTest.java b/querydsl-codegen/src/test/java/com/mysema/query/codegen/PackageSuffixTest.java deleted file mode 100644 index 344a8b21cf..0000000000 --- a/querydsl-codegen/src/test/java/com/mysema/query/codegen/PackageSuffixTest.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.codegen; - -import static org.junit.Assert.assertTrue; - -import java.io.IOException; -import java.io.StringWriter; -import java.util.Collections; - -import org.junit.Test; - -import com.mysema.codegen.JavaWriter; -import com.mysema.codegen.model.SimpleType; -import com.mysema.codegen.model.TypeCategory; - -public class PackageSuffixTest { - - private final QueryTypeFactory queryTypeFactory = new QueryTypeFactoryImpl("Q", "", ".query"); - - private final TypeMappings typeMappings = new JavaTypeMappings(); - - private final EntitySerializer serializer = new EntitySerializer(typeMappings, Collections.emptySet()); - - private final StringWriter writer = new StringWriter(); - - @Test - public void Correct_Imports() throws IOException { - SimpleType type = new SimpleType(TypeCategory.ENTITY, "test.Entity", "test", "Entity",false,false); - EntityType entityType = new EntityType(type); - typeMappings.register(entityType, queryTypeFactory.create(entityType)); - - serializer.serialize(entityType, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); - assertTrue(writer.toString().contains("import test.Entity;")); - assertTrue(writer.toString().contains("public class QEntity extends EntityPathBase {")); - } - -} diff --git a/querydsl-codegen/src/test/java/com/mysema/query/codegen/Point.java b/querydsl-codegen/src/test/java/com/mysema/query/codegen/Point.java deleted file mode 100644 index 80067fe691..0000000000 --- a/querydsl-codegen/src/test/java/com/mysema/query/codegen/Point.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.codegen; - -import com.mysema.query.types.Path; -import com.mysema.query.types.PathMetadata; -import com.mysema.query.types.path.ArrayPath; - - -public class Point extends ArrayPath{ - - private static final long serialVersionUID = 1776628530121566388L; - - public Point(String variable) { - super(Double[].class, variable); - } - - public Point(Path parent, String property) { - super(Double[].class, parent, property); - } - - public Point(PathMetadata metadata) { - super(Double[].class, metadata); - } - -} diff --git a/querydsl-codegen/src/test/java/com/mysema/query/codegen/ProjectionSerializerTest.java b/querydsl-codegen/src/test/java/com/mysema/query/codegen/ProjectionSerializerTest.java deleted file mode 100644 index b30990ce81..0000000000 --- a/querydsl-codegen/src/test/java/com/mysema/query/codegen/ProjectionSerializerTest.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.codegen; - -import com.mysema.codegen.JavaWriter; -import com.mysema.codegen.model.*; -import org.junit.Test; - -import java.io.IOException; -import java.io.StringWriter; -import java.io.Writer; -import java.util.Arrays; - -import static org.junit.Assert.assertTrue; - - -public class ProjectionSerializerTest { - - @Test - public void Constructors() throws IOException{ - Type typeModel = new SimpleType(TypeCategory.ENTITY, "com.mysema.query.DomainClass", "com.mysema.query", "DomainClass", false,false); - EntityType type = new EntityType(typeModel); - - // constructor - Parameter firstName = new Parameter("firstName", Types.STRING); - Parameter lastName = new Parameter("lastName", Types.STRING); - Parameter age = new Parameter("age", Types.INTEGER); - type.addConstructor(new Constructor(Arrays.asList(firstName, lastName, age))); - - Writer writer = new StringWriter(); - ProjectionSerializer serializer = new ProjectionSerializer(new JavaTypeMappings()); - serializer.serialize(type, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); - assertTrue(writer.toString().contains("Expression firstName")); - assertTrue(writer.toString().contains("Expression lastName")); - assertTrue(writer.toString().contains("Expression age")); - } - -} diff --git a/querydsl-codegen/src/test/java/com/mysema/query/codegen/QueryEmbeddable2Test.java b/querydsl-codegen/src/test/java/com/mysema/query/codegen/QueryEmbeddable2Test.java deleted file mode 100644 index 283dc08246..0000000000 --- a/querydsl-codegen/src/test/java/com/mysema/query/codegen/QueryEmbeddable2Test.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.mysema.query.codegen; - -import com.mysema.query.annotations.QueryEmbeddable; -import com.mysema.query.annotations.QueryEntity; - -public class QueryEmbeddable2Test extends AbstractExporterTest { - - @QueryEntity - public static class User { - - Complex complex; - - } - - @QueryEmbeddable - public static class Complex> implements Comparable> { - - T a; - - @Override - public int compareTo(Complex arg0) { - return 0; - } - - public boolean equals(Object o) { - return o == this; - } - - } - -} \ No newline at end of file diff --git a/querydsl-codegen/src/test/java/com/mysema/query/codegen/QueryTypeFactoryTest.java b/querydsl-codegen/src/test/java/com/mysema/query/codegen/QueryTypeFactoryTest.java deleted file mode 100644 index b17ad6575f..0000000000 --- a/querydsl-codegen/src/test/java/com/mysema/query/codegen/QueryTypeFactoryTest.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.codegen; - -import static org.junit.Assert.*; - -import org.junit.Test; - -import com.mysema.codegen.model.ClassType; -import com.mysema.codegen.model.Type; - -public class QueryTypeFactoryTest { - - private Type type = new ClassType(Point.class); - - @Test - public void Prefix_Only() { - QueryTypeFactory factory = new QueryTypeFactoryImpl("Q", "", ""); - assertEquals("com.mysema.query.codegen.QPoint", factory.create(type).getFullName()); - } - - @Test - public void Prefix_And_Suffix() { - QueryTypeFactory factory = new QueryTypeFactoryImpl("Q", "Type", ""); - assertEquals("com.mysema.query.codegen.QPointType", factory.create(type).getFullName()); - } - - @Test - public void Suffix_Only() { - QueryTypeFactory factory = new QueryTypeFactoryImpl("", "Type", ""); - assertEquals("com.mysema.query.codegen.PointType", factory.create(type).getFullName()); - } - - @Test - public void Prefix_And_Package_Suffix() { - QueryTypeFactory factory = new QueryTypeFactoryImpl("Q", "", ".query"); - assertEquals("com.mysema.query.codegen.query.QPoint", factory.create(type).getFullName()); - } - -} diff --git a/querydsl-codegen/src/test/java/com/mysema/query/codegen/SerializerTest.java b/querydsl-codegen/src/test/java/com/mysema/query/codegen/SerializerTest.java deleted file mode 100644 index 08f0416860..0000000000 --- a/querydsl-codegen/src/test/java/com/mysema/query/codegen/SerializerTest.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.codegen; - -import java.io.IOException; -import java.io.StringWriter; -import java.io.Writer; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Date; -import java.util.List; -import java.util.Set; - -import org.junit.Before; -import org.junit.Test; - -import com.mysema.codegen.JavaWriter; -import com.mysema.codegen.StringUtils; -import com.mysema.codegen.model.ClassType; -import com.mysema.codegen.model.Constructor; -import com.mysema.codegen.model.Parameter; -import com.mysema.codegen.model.SimpleType; -import com.mysema.codegen.model.Type; -import com.mysema.codegen.model.TypeCategory; -import com.mysema.codegen.model.TypeExtends; -import com.mysema.codegen.model.TypeSuper; - -public class SerializerTest { - - private EntityType type; - - private Writer writer = new StringWriter(); - - private TypeMappings typeMappings = new JavaTypeMappings(); - - @SuppressWarnings("unchecked") - @Before - public void setUp() { - // type - Type typeModel = new SimpleType(TypeCategory.ENTITY, "com.mysema.query.DomainClass", "com.mysema.query", "DomainClass", false, false); - type = new EntityType(typeModel); - - // property - type.addProperty(new Property(type, "entityField", type)); - type.addProperty(new Property(type, "collection", new ClassType(TypeCategory.COLLECTION, Collection.class, typeModel))); - type.addProperty(new Property(type, "listField", new ClassType(TypeCategory.LIST, List.class, typeModel))); - type.addProperty(new Property(type, "setField", new ClassType(TypeCategory.SET, Set.class, typeModel))); - type.addProperty(new Property(type, "arrayField", new ClassType(TypeCategory.ARRAY, String[].class, typeModel))); - type.addProperty(new Property(type, "mapField", new ClassType(TypeCategory.MAP, List.class, typeModel, typeModel))); - type.addProperty(new Property(type, "superTypeField", new TypeExtends(new ClassType(TypeCategory.MAP, List.class, typeModel, typeModel)))); - type.addProperty(new Property(type, "extendsTypeField", new TypeSuper(new ClassType(TypeCategory.MAP, List.class, typeModel, typeModel)))); - - for (Class cl : Arrays.asList(Boolean.class, Comparable.class, Integer.class, Date.class, java.sql.Date.class, java.sql.Time.class)) { - Type classType = new ClassType(TypeCategory.get(cl.getName()), cl); - type.addProperty(new Property(type, StringUtils.uncapitalize(cl.getSimpleName()), classType)); - } - - // constructor - Parameter firstName = new Parameter("firstName", new ClassType(TypeCategory.STRING, String.class)); - Parameter lastName = new Parameter("lastName", new ClassType(TypeCategory.STRING, String.class)); - type.addConstructor(new Constructor(Arrays.asList(firstName, lastName))); - } - - @Test - public void EntitySerializer() throws Exception { - new EntitySerializer(typeMappings, Collections.emptyList()) - .serialize(type, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); - } - - @Test - public void EntitySerializer2() throws Exception { - new EntitySerializer(typeMappings,Collections.emptyList()) - .serialize(type, new SimpleSerializerConfig(true,true,true,true,""), new JavaWriter(writer)); - } - - @Test - public void EmbeddableSerializer() throws Exception { - new EmbeddableSerializer(typeMappings,Collections.emptyList()) - .serialize(type, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); - } - - @Test - public void SupertypeSerializer() throws IOException{ - new SupertypeSerializer(typeMappings,Collections.emptyList()) - .serialize(type, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); - } - - @Test - public void DTOSerializer() throws IOException{ - new ProjectionSerializer(typeMappings) - .serialize(type, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); - } -} diff --git a/querydsl-codegen/src/test/java/com/mysema/query/codegen/TypeMappingsTest.java b/querydsl-codegen/src/test/java/com/mysema/query/codegen/TypeMappingsTest.java deleted file mode 100644 index 2298f1b909..0000000000 --- a/querydsl-codegen/src/test/java/com/mysema/query/codegen/TypeMappingsTest.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.codegen; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import org.junit.Test; - -import com.mysema.codegen.model.ClassType; -import com.mysema.codegen.model.Type; - -public class TypeMappingsTest { - - static class Entity { } - - @Test - public void GetPathType_Of_InnerClass() { - TypeMappings typeMappings = new JavaTypeMappings(); - EntityType model = new EntityType(new ClassType(TypeMappingsTest.class)); - EntityType type = new EntityType(new ClassType(Entity.class)); - typeMappings.register(type, new QueryTypeFactoryImpl("Q","","").create(type)); - - Type pathType = typeMappings.getPathType(type, model, false); - assertEquals("QTypeMappingsTest_Entity", pathType.getSimpleName()); - } - - @Test - public void IsRegistered() { - TypeMappings typeMappings = new JavaTypeMappings(); - typeMappings.register(new ClassType(Double[].class), new ClassType(Point.class)); - assertTrue(typeMappings.isRegistered(new ClassType(Double[].class))); - - } - -} diff --git a/querydsl-codegen/src/test/java/com/mysema/query/codegen/TypeResolverTest.java b/querydsl-codegen/src/test/java/com/mysema/query/codegen/TypeResolverTest.java deleted file mode 100644 index 1f4c35d080..0000000000 --- a/querydsl-codegen/src/test/java/com/mysema/query/codegen/TypeResolverTest.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.mysema.query.codegen; - -public class TypeResolverTest { - - // generic parameter - -} diff --git a/querydsl-codegen/src/test/java/com/mysema/query/codegen/sub/ExampleEntity2.java b/querydsl-codegen/src/test/java/com/mysema/query/codegen/sub/ExampleEntity2.java deleted file mode 100644 index 04c354e2d1..0000000000 --- a/querydsl-codegen/src/test/java/com/mysema/query/codegen/sub/ExampleEntity2.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.codegen.sub; - -import com.mysema.query.annotations.QueryEntity; - -@QueryEntity -public class ExampleEntity2 { - - private int id; - - public int getId() { - return id; - } - - public void setId(int id) { - this.id = id; - } - -} diff --git a/querydsl-codegen/src/test/java/com/mysema/query/codegen/AbstractExporterTest.java b/querydsl-codegen/src/test/java/com/querydsl/codegen/AbstractExporterTest.java similarity index 89% rename from querydsl-codegen/src/test/java/com/mysema/query/codegen/AbstractExporterTest.java rename to querydsl-codegen/src/test/java/com/querydsl/codegen/AbstractExporterTest.java index b5156f9d15..b7830e4939 100644 --- a/querydsl-codegen/src/test/java/com/mysema/query/codegen/AbstractExporterTest.java +++ b/querydsl-codegen/src/test/java/com/querydsl/codegen/AbstractExporterTest.java @@ -1,11 +1,11 @@ -package com.mysema.query.codegen; +package com.querydsl.codegen; import java.io.File; import org.junit.Test; public abstract class AbstractExporterTest { - + @Test public void test() { GenericExporter exporter = new GenericExporter(); diff --git a/querydsl-codegen/src/test/java/com/querydsl/codegen/BeanSerializerTest.java b/querydsl-codegen/src/test/java/com/querydsl/codegen/BeanSerializerTest.java new file mode 100644 index 0000000000..afa7945288 --- /dev/null +++ b/querydsl-codegen/src/test/java/com/querydsl/codegen/BeanSerializerTest.java @@ -0,0 +1,206 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.codegen; + +import com.querydsl.codegen.utils.JavaWriter; +import com.querydsl.codegen.utils.StringUtils; +import com.querydsl.codegen.utils.model.ClassType; +import com.querydsl.codegen.utils.model.SimpleType; +import com.querydsl.codegen.utils.model.Type; +import com.querydsl.codegen.utils.model.TypeCategory; +import com.querydsl.codegen.utils.model.Types; +import com.querydsl.core.annotations.Generated; +import org.junit.Before; +import org.junit.Test; + +import java.io.IOException; +import java.io.Serializable; +import java.io.StringWriter; +import java.io.Writer; +import java.util.Arrays; +import java.util.Date; + +import static org.hamcrest.Matchers.containsString; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; + +public class BeanSerializerTest { + + private Type typeModel; + + private EntityType type; + + private final Writer writer = new StringWriter(); + + @Before + public void setUp() { + typeModel = new SimpleType(TypeCategory.ENTITY, "com.querydsl.DomainClass", "com.querydsl", "DomainClass", false,false); + type = new EntityType(typeModel); + } + + @Test + public void annotations() throws IOException { + type.addAnnotation(new QueryEntityImpl()); + + BeanSerializer serializer = new BeanSerializer(); + serializer.serialize(type, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); + String str = writer.toString(); + + assertTrue(str.contains("import com.querydsl.core.annotations.QueryEntity;")); + assertTrue(str.contains("@QueryEntity")); + } + + @Test + public void annotated_property() throws IOException { + Property property = new Property(type, "entityField", type); + property.addAnnotation(new QueryEntityImpl()); + type.addProperty(property); + + BeanSerializer serializer = new BeanSerializer(); + serializer.serialize(type, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); + String str = writer.toString(); + + assertTrue(str.contains("import com.querydsl.core.annotations.QueryEntity;")); + assertTrue(str.contains("@QueryEntity")); + } + + @Test + public void annotated_property_not_serialized() throws IOException { + Property property = new Property(type, "entityField", type); + property.addAnnotation(new QueryEntityImpl()); + type.addProperty(property); + + BeanSerializer serializer = new BeanSerializer(false); + serializer.serialize(type, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); + String str = writer.toString(); + + assertFalse(str.contains("import com.querydsl.core.annotations.QueryEntity;")); + assertFalse(str.contains("@QueryEntity")); + } + + @Test + public void capitalization() throws IOException { + // property + type.addProperty(new Property(type, "cId", type)); + + BeanSerializer serializer = new BeanSerializer(); + serializer.serialize(type, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); + assertTrue(writer.toString().contains("public DomainClass getcId() {")); + } + + @Test + public void interfaces() throws IOException { + BeanSerializer serializer = new BeanSerializer(); + serializer.addInterface(new ClassType(Serializable.class)); + serializer.serialize(type, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); + assertTrue(writer.toString().contains("public class DomainClass implements Serializable {")); + } + + @Test + public void interfaces2() throws IOException { + BeanSerializer serializer = new BeanSerializer(); + serializer.addInterface(Serializable.class); + serializer.serialize(type, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); + assertTrue(writer.toString().contains("public class DomainClass implements Serializable {")); + } + + @Test + public void toString_() throws IOException { + // property + type.addProperty(new Property(type, "entityField", type)); + type.addProperty(new Property(type, "collection", new SimpleType(Types.COLLECTION, typeModel))); + type.addProperty(new Property(type, "listField", new SimpleType(Types.LIST, typeModel))); + type.addProperty(new Property(type, "setField", new SimpleType(Types.SET, typeModel))); + type.addProperty(new Property(type, "arrayField", new ClassType(TypeCategory.ARRAY, String[].class))); + type.addProperty(new Property(type, "mapField", new SimpleType(Types.MAP, typeModel, typeModel))); + + BeanSerializer serializer = new BeanSerializer(); + serializer.setAddToString(true); + serializer.serialize(type, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); + assertTrue(String.valueOf(writer).contains( + " @Override\n" + + " public String toString()")); + } + + @Test + public void fullConstructor() throws IOException { + // property + type.addProperty(new Property(type, "entityField", type)); + type.addProperty(new Property(type, "collection", new SimpleType(Types.COLLECTION, typeModel))); + type.addProperty(new Property(type, "listField", new SimpleType(Types.LIST, typeModel))); + type.addProperty(new Property(type, "setField", new SimpleType(Types.SET, typeModel))); + type.addProperty(new Property(type, "arrayField", new ClassType(TypeCategory.ARRAY, String[].class))); + type.addProperty(new Property(type, "mapField", new SimpleType(Types.MAP, typeModel, typeModel))); + + BeanSerializer serializer = new BeanSerializer(); + serializer.setAddFullConstructor(true); + serializer.serialize(type, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); + //System.out.println(writer.toString()); + } + + @Test + public void properties() throws IOException { + // property + type.addProperty(new Property(type, "entityField", type)); + type.addProperty(new Property(type, "collection", new SimpleType(Types.COLLECTION, typeModel))); + type.addProperty(new Property(type, "listField", new SimpleType(Types.LIST, typeModel))); + type.addProperty(new Property(type, "setField", new SimpleType(Types.SET, typeModel))); + type.addProperty(new Property(type, "arrayField", new ClassType(TypeCategory.ARRAY, String[].class))); + type.addProperty(new Property(type, "mapField", new SimpleType(Types.MAP, typeModel, typeModel))); + + for (Class cl : Arrays.>asList(Boolean.class, Comparable.class, Integer.class, Date.class, java.sql.Date.class, java.sql.Time.class)) { + Type classType = new ClassType(TypeCategory.get(cl.getName()), cl); + type.addProperty(new Property(type, StringUtils.uncapitalize(cl.getSimpleName()), classType)); + } + + BeanSerializer serializer = new BeanSerializer(); + serializer.serialize(type, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); + String str = writer.toString(); + //System.err.println(str); + for (String prop : Arrays.asList( + "String[] arrayField;", + "Boolean boolean$;", + "Collection collection;", + "Comparable comparable;", + "java.util.Date date;", + "DomainClass entityField;", + "Integer integer;", + "List listField;", + "Map mapField;", + "Set setField;", + "java.sql.Time time;")) { + assertTrue(prop + " was not contained", str.contains(prop)); + } + } + + @Test + public void defaultsGeneratedAnnotation() throws IOException { + Serializer serializer = new BeanSerializer(); + serializer.serialize(type, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); + String generatedSource = String.valueOf(writer); + assertThat(generatedSource, containsString(String.format("import %s;", GeneratedAnnotationResolver.resolveDefault().getName()))); + assertThat(generatedSource, containsString("@Generated(\"com.querydsl.codegen.BeanSerializer\")\npublic class")); + } + + @Test + public void customGeneratedAnnotation() throws IOException { + Serializer serializer = new BeanSerializer(BeanSerializer.DEFAULT_JAVADOC_SUFFIX, Generated.class); + serializer.serialize(type, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); + String generatedSource = String.valueOf(writer); + assertThat(generatedSource, containsString("import com.querydsl.core.annotations.Generated;")); + assertThat(generatedSource, containsString("@Generated(\"com.querydsl.codegen.BeanSerializer\")\npublic class")); + } + +} diff --git a/querydsl-codegen/src/test/java/com/querydsl/codegen/ClassPathUtilsTest.java b/querydsl-codegen/src/test/java/com/querydsl/codegen/ClassPathUtilsTest.java new file mode 100644 index 0000000000..910219fe77 --- /dev/null +++ b/querydsl-codegen/src/test/java/com/querydsl/codegen/ClassPathUtilsTest.java @@ -0,0 +1,53 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.codegen; + +import static org.junit.Assert.*; + +import java.io.IOException; +import java.util.Set; + +import org.junit.Test; + +import com.SomeClass; + +public class ClassPathUtilsTest { + + @Test + public void scanPackage() throws IOException { + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + Set> classes = ClassPathUtils.scanPackage(classLoader, SomeClass.class.getPackage()); + assertFalse(classes.isEmpty()); + } + + @Test + public void scanPackage_check_initialized() throws IOException { + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + Set> classes = ClassPathUtils.scanPackage(classLoader, getClass().getPackage()); + assertFalse(classes.isEmpty()); + assertEquals("XXX", SomeOtherClass2.property); + } + + @Test + public void safeClassForName() { + assertNull(safeForName("com.sun.nio.file.ExtendedOpenOption")); + assertNotNull(safeForName("com.suntanning.ShouldBeLoaded")); + assertNotNull(safeForName("com.applejuice.ShouldBeLoaded")); + } + + private Class safeForName(String className) { + return ClassPathUtils.safeClassForName(ClassPathUtilsTest.class.getClassLoader(), className); + } + +} diff --git a/querydsl-codegen/src/test/java/com/querydsl/codegen/CodegenModuleTest.java b/querydsl-codegen/src/test/java/com/querydsl/codegen/CodegenModuleTest.java new file mode 100644 index 0000000000..14a1e31d4e --- /dev/null +++ b/querydsl-codegen/src/test/java/com/querydsl/codegen/CodegenModuleTest.java @@ -0,0 +1,54 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.codegen; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import org.junit.Test; + +import java.lang.annotation.Annotation; + +public class CodegenModuleTest { + + private final CodegenModule module = new CodegenModule(); + + @Test + public void defaultPrefix() { + assertEquals("Q", module.get(String.class, CodegenModule.PREFIX)); + } + + @Test + public void typeMappings() { + assertNotNull(module.get(TypeMappings.class)); + } + + @Test(expected = IllegalArgumentException.class) + public void get_with_unknown_key() { + module.get(String.class, "XXX"); + } + + @Test + public void defaultGeneratedClass() { + Class o = module.get(Class.class, CodegenModule.GENERATED_ANNOTATION_CLASS); + assertEquals(o, GeneratedAnnotationResolver.resolveDefault()); + } + + @Test + public void javadocSuffixForBeanSerializerOverloadedConstructorInjection() { + String o = module.get(String.class, CodegenModule.JAVADOC_SUFFIX); + assertEquals(o, BeanSerializer.DEFAULT_JAVADOC_SUFFIX); + } + +} diff --git a/querydsl-codegen/src/test/java/com/querydsl/codegen/CompileUtils.java b/querydsl-codegen/src/test/java/com/querydsl/codegen/CompileUtils.java new file mode 100644 index 0000000000..04b80eab41 --- /dev/null +++ b/querydsl-codegen/src/test/java/com/querydsl/codegen/CompileUtils.java @@ -0,0 +1,40 @@ +package com.querydsl.codegen; + +import java.io.StringWriter; +import java.io.Writer; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import javax.tools.JavaCompiler; +import javax.tools.SimpleJavaFileObject; + +import org.junit.Assert; + +import com.querydsl.codegen.utils.MemFileManager; +import com.querydsl.codegen.utils.MemSourceFileObject; +import com.querydsl.codegen.utils.SimpleCompiler; + +public final class CompileUtils { + + private CompileUtils() { } + + public static void assertCompiles(String name, String source) { + ClassLoader parent = CompileUtils.class.getClassLoader(); + SimpleCompiler compiler = new SimpleCompiler(); + MemFileManager fileManager = new MemFileManager(parent, compiler.getStandardFileManager(null, null, null)); + String classpath = SimpleCompiler.getClassPath(parent); + List compilationOptions = Arrays.asList("-classpath", classpath, "-g:none"); + + // compile + SimpleJavaFileObject javaFileObject = new MemSourceFileObject(name, source); + Writer out = new StringWriter(); + JavaCompiler.CompilationTask task = compiler.getTask(out, fileManager, null, compilationOptions, null, + Collections.singletonList(javaFileObject)); + if (!task.call()) { + Assert.fail("Compilation of " + source + " failed.\n" + out.toString()); + } + + } + +} diff --git a/querydsl-codegen/src/test/java/com/querydsl/codegen/CustomTypeTest.java b/querydsl-codegen/src/test/java/com/querydsl/codegen/CustomTypeTest.java new file mode 100644 index 0000000000..25f8f241b3 --- /dev/null +++ b/querydsl-codegen/src/test/java/com/querydsl/codegen/CustomTypeTest.java @@ -0,0 +1,54 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.codegen; + +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.io.StringWriter; +import java.util.Collections; + +import org.junit.Test; + +import com.querydsl.codegen.utils.JavaWriter; +import com.querydsl.codegen.utils.model.ClassType; +import com.querydsl.codegen.utils.model.SimpleType; +import com.querydsl.codegen.utils.model.TypeCategory; + +public class CustomTypeTest { + + private final QueryTypeFactory queryTypeFactory = new QueryTypeFactoryImpl("Q", "", ""); + + private final TypeMappings typeMappings = new JavaTypeMappings(); + + private final EntitySerializer serializer = new DefaultEntitySerializer(typeMappings, Collections.emptySet()); + + private final StringWriter writer = new StringWriter(); + + @Test + public void customType() throws IOException { + SimpleType type = new SimpleType(TypeCategory.ENTITY, "Entity", "", "Entity",false,false); + EntityType entityType = new EntityType(type); + entityType.addProperty(new Property(entityType, "property", new ClassType(Double[].class))); + typeMappings.register(new ClassType(Double[].class), new ClassType(Point.class)); + typeMappings.register(entityType, queryTypeFactory.create(entityType)); + assertTrue(typeMappings.isRegistered(entityType.getProperties().iterator().next().getType())); + + serializer.serialize(entityType, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); + assertTrue(writer.toString().contains( + "public final com.querydsl.codegen.Point property = " + + "new com.querydsl.codegen.Point(forProperty(\"property\"));")); + } + +} diff --git a/querydsl-codegen/src/test/java/com/querydsl/codegen/DelegateTest.java b/querydsl-codegen/src/test/java/com/querydsl/codegen/DelegateTest.java new file mode 100644 index 0000000000..373ca5cffa --- /dev/null +++ b/querydsl-codegen/src/test/java/com/querydsl/codegen/DelegateTest.java @@ -0,0 +1,42 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.codegen; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; + +import java.util.Collections; + +import org.junit.Test; + +import com.querydsl.codegen.utils.model.Parameter; +import com.querydsl.codegen.utils.model.Types; + +public class DelegateTest { + + @Test + public void equals_object() { + Delegate delegate = new Delegate(Types.STRING, Types.STRING, "delegate", Collections.emptyList(), Types.STRING); + Delegate delegate2 = new Delegate(Types.STRING, Types.STRING, "delegate", Collections.emptyList(), Types.STRING); + assertEquals(delegate, delegate2); + } + + @Test + public void not_equals_object() { + Delegate delegate = new Delegate(Types.STRING, Types.STRING, "delegate", Collections.emptyList(), Types.STRING); + Delegate delegate2 = new Delegate(Types.STRING, Types.STRING, "delegate2", Collections.emptyList(), Types.STRING); + assertFalse(delegate.equals(delegate2)); + } + +} diff --git a/querydsl-codegen/src/test/java/com/querydsl/codegen/EmbeddableSerializerTest.java b/querydsl-codegen/src/test/java/com/querydsl/codegen/EmbeddableSerializerTest.java new file mode 100644 index 0000000000..bae7f3edef --- /dev/null +++ b/querydsl-codegen/src/test/java/com/querydsl/codegen/EmbeddableSerializerTest.java @@ -0,0 +1,204 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.codegen; + +import static org.hamcrest.Matchers.containsString; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.io.StringWriter; +import java.sql.Time; +import java.util.Collections; +import java.util.Date; +import java.util.EnumMap; +import java.util.Map; + +import org.junit.Test; + +import com.querydsl.codegen.utils.JavaWriter; +import com.querydsl.codegen.utils.model.*; +import com.querydsl.core.annotations.PropertyType; + +public class EmbeddableSerializerTest { + + private final QueryTypeFactory queryTypeFactory = new QueryTypeFactoryImpl("Q", "", ""); + + private final TypeMappings typeMappings = new JavaTypeMappings(); + + private final EntitySerializer serializer = new DefaultEmbeddableSerializer(typeMappings, Collections.emptySet()); + + private final StringWriter writer = new StringWriter(); + + @Test + public void properties() throws IOException { + SimpleType type = new SimpleType(TypeCategory.ENTITY, "Entity", "", "Entity",false,false); + EntityType entityType = new EntityType(type); + entityType.addProperty(new Property(entityType, "b", new ClassType(TypeCategory.BOOLEAN, Boolean.class))); + entityType.addProperty(new Property(entityType, "c", new ClassType(TypeCategory.COMPARABLE, String.class))); + //entityType.addProperty(new Property(entityType, "cu", new ClassType(TypeCategory.CUSTOM, PropertyType.class))); + entityType.addProperty(new Property(entityType, "d", new ClassType(TypeCategory.DATE, Date.class))); + entityType.addProperty(new Property(entityType, "e", new ClassType(TypeCategory.ENUM, PropertyType.class))); + entityType.addProperty(new Property(entityType, "dt", new ClassType(TypeCategory.DATETIME, Date.class))); + entityType.addProperty(new Property(entityType, "i", new ClassType(TypeCategory.NUMERIC, Integer.class))); + entityType.addProperty(new Property(entityType, "s", new ClassType(TypeCategory.STRING, String.class))); + entityType.addProperty(new Property(entityType, "t", new ClassType(TypeCategory.TIME, Time.class))); + typeMappings.register(entityType, queryTypeFactory.create(entityType)); + + serializer.serialize(entityType, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); + CompileUtils.assertCompiles("QEntity", writer.toString()); + } + + @Test + public void originalCategory() throws IOException { + Map categoryToSuperClass + = new EnumMap(TypeCategory.class); + categoryToSuperClass.put(TypeCategory.COMPARABLE, "ComparablePath"); + categoryToSuperClass.put(TypeCategory.ENUM, "EnumPath"); + categoryToSuperClass.put(TypeCategory.DATE, "DatePath"); + categoryToSuperClass.put(TypeCategory.DATETIME, "DateTimePath"); + categoryToSuperClass.put(TypeCategory.TIME, "TimePath"); + categoryToSuperClass.put(TypeCategory.NUMERIC, "NumberPath"); + categoryToSuperClass.put(TypeCategory.STRING, "StringPath"); + categoryToSuperClass.put(TypeCategory.BOOLEAN, "BooleanPath"); + + for (Map.Entry entry : categoryToSuperClass.entrySet()) { + StringWriter w = new StringWriter(); + SimpleType type = new SimpleType(entry.getKey(), "Entity", "", "Entity",false,false); + EntityType entityType = new EntityType(type); + typeMappings.register(entityType, queryTypeFactory.create(entityType)); + + serializer.serialize(entityType, SimpleSerializerConfig.DEFAULT, new JavaWriter(w)); + assertTrue(entry.getValue() + " is missing from " + w, w.toString().contains("public class QEntity extends " + entry.getValue() + " {")); + } + + } + + @Test + public void empty() throws IOException { + SimpleType type = new SimpleType(TypeCategory.ENTITY, "Entity", "", "Entity",false,false); + EntityType entityType = new EntityType(type); + typeMappings.register(entityType, queryTypeFactory.create(entityType)); + + serializer.serialize(entityType, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); + CompileUtils.assertCompiles("QEntity", writer.toString()); + } + + @Test + public void no_package() throws IOException { + SimpleType type = new SimpleType(TypeCategory.ENTITY, "Entity", "", "Entity",false,false); + EntityType entityType = new EntityType(type); + typeMappings.register(entityType, queryTypeFactory.create(entityType)); + serializer.serialize(entityType, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); + assertTrue(writer.toString().contains("public class QEntity extends BeanPath {")); + CompileUtils.assertCompiles("QEntity", writer.toString()); + } + + @Test + public void correct_superclass() throws IOException { + SimpleType type = new SimpleType(TypeCategory.ENTITY, "java.util.Locale", "java.util", "Locale",false,false); + EntityType entityType = new EntityType(type); + typeMappings.register(entityType, queryTypeFactory.create(entityType)); + serializer.serialize(entityType, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); + assertTrue(writer.toString().contains("public class QLocale extends BeanPath {")); + CompileUtils.assertCompiles("QLocale", writer.toString()); + } + + @Test + public void primitive_array() throws IOException { + SimpleType type = new SimpleType(TypeCategory.ENTITY, "Entity", "", "Entity",false,false); + EntityType entityType = new EntityType(type); + entityType.addProperty(new Property(entityType, "bytes", new ClassType(byte[].class))); + typeMappings.register(entityType, queryTypeFactory.create(entityType)); + serializer.serialize(entityType, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); + + assertTrue(writer.toString().contains("public final SimplePath bytes")); + CompileUtils.assertCompiles("QEntity", writer.toString()); + } + + @Test + public void include() throws IOException { + SimpleType type = new SimpleType(TypeCategory.ENTITY, "Entity", "", "Entity",false,false); + EntityType entityType = new EntityType(type); + entityType.addProperty(new Property(entityType, "b", new ClassType(TypeCategory.BOOLEAN, Boolean.class))); + entityType.addProperty(new Property(entityType, "c", new ClassType(TypeCategory.COMPARABLE, String.class))); + //entityType.addProperty(new Property(entityType, "cu", new ClassType(TypeCategory.CUSTOM, PropertyType.class))); + entityType.addProperty(new Property(entityType, "d", new ClassType(TypeCategory.DATE, Date.class))); + entityType.addProperty(new Property(entityType, "e", new ClassType(TypeCategory.ENUM, PropertyType.class))); + entityType.addProperty(new Property(entityType, "dt", new ClassType(TypeCategory.DATETIME, Date.class))); + entityType.addProperty(new Property(entityType, "i", new ClassType(TypeCategory.NUMERIC, Integer.class))); + entityType.addProperty(new Property(entityType, "s", new ClassType(TypeCategory.STRING, String.class))); + entityType.addProperty(new Property(entityType, "t", new ClassType(TypeCategory.TIME, Time.class))); + + EntityType subType = new EntityType(new SimpleType(TypeCategory.ENTITY, "Entity2", "", "Entity2",false,false)); + subType.include(new Supertype(type,entityType)); + + typeMappings.register(entityType, queryTypeFactory.create(entityType)); + typeMappings.register(subType, queryTypeFactory.create(subType)); + + serializer.serialize(subType, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); + CompileUtils.assertCompiles("QEntity2", writer.toString()); + } + + @Test + public void superType() throws IOException { + EntityType superType = new EntityType(new SimpleType(TypeCategory.ENTITY, "Entity2", "", "Entity2",false,false)); + SimpleType type = new SimpleType(TypeCategory.ENTITY, "Entity", "", "Entity",false,false); + EntityType entityType = new EntityType(type, Collections.singleton(new Supertype(superType, superType))); + typeMappings.register(superType, queryTypeFactory.create(superType)); + typeMappings.register(entityType, queryTypeFactory.create(entityType)); + + serializer.serialize(entityType, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); + assertTrue(writer.toString().contains("public final QEntity2 _super = new QEntity2(this);")); + //CompileUtils.assertCompiles("QEntity", writer.toString()); + } + + @Test + public void delegates() throws IOException { + SimpleType type = new SimpleType(TypeCategory.ENTITY, "Entity", "", "Entity",false,false); + EntityType entityType = new EntityType(type); + Delegate delegate = new Delegate(type, type, "test", Collections.emptyList(), Types.STRING); + entityType.addDelegate(delegate); + typeMappings.register(entityType, queryTypeFactory.create(entityType)); + + serializer.serialize(entityType, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); + assertTrue(writer.toString().contains("return Entity.test(this);")); + CompileUtils.assertCompiles("QEntity", writer.toString()); + } + + @Test + public void defaultGeneratedAnnotation() throws IOException { + SimpleType type = new SimpleType(TypeCategory.ENTITY, "Entity", "", "Entity", false, false); + EntityType entityType = new EntityType(type); + typeMappings.register(entityType, queryTypeFactory.create(entityType)); + + serializer.serialize(entityType, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); + final String generatedSource = writer.toString(); + assertThat(generatedSource, containsString(String.format("import %s;", GeneratedAnnotationResolver.resolveDefault().getName()))); + assertThat(generatedSource, containsString("@Generated(\"com.querydsl.codegen.DefaultEmbeddableSerializer\")\npublic class")); + CompileUtils.assertCompiles("QEntity", generatedSource); + } + + @Test + public void customGeneratedAnnotation() throws IOException { + SimpleType type = new SimpleType(TypeCategory.ENTITY, "Entity", "", "Entity", false, false); + EntityType entityType = new EntityType(type); + typeMappings.register(entityType, queryTypeFactory.create(entityType)); + + new DefaultEmbeddableSerializer(typeMappings, Collections.emptySet(), com.querydsl.core.annotations.Generated.class).serialize(entityType, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); + String generatedSourceCode = writer.toString(); + assertThat(generatedSourceCode, containsString("@Generated(\"com.querydsl.codegen.DefaultEmbeddableSerializer\")\npublic class")); + CompileUtils.assertCompiles("QEntity", generatedSourceCode); + } +} diff --git a/querydsl-codegen/src/test/java/com/querydsl/codegen/Embedded2Test.java b/querydsl-codegen/src/test/java/com/querydsl/codegen/Embedded2Test.java new file mode 100644 index 0000000000..c9d7de9ff2 --- /dev/null +++ b/querydsl-codegen/src/test/java/com/querydsl/codegen/Embedded2Test.java @@ -0,0 +1,73 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.codegen; + +import java.io.Serializable; + +import com.querydsl.core.annotations.QueryEmbeddable; +import com.querydsl.core.annotations.QueryEmbedded; +import com.querydsl.core.annotations.QueryEntity; +import com.querydsl.core.annotations.QuerySupertype; + +public class Embedded2Test extends AbstractExporterTest { + + @QuerySupertype + public static class EntityCode { + + public String code; + + } + + @QuerySupertype + public abstract static class AbstractEntity { + + @QueryEmbedded + public C code; + + } + + @QuerySupertype + public static class AbstractMultilingualEntity extends AbstractEntity { + + } + + @QuerySupertype + public abstract static class AbstractNamedEntity extends AbstractMultilingualEntity { + + public String nameEn; + + public String nameNl; + + } + + @QueryEntity + public static class Brand extends AbstractNamedEntity { + + public Long id; + + } + + public interface Entity extends Serializable { + + boolean sameIdentityAs(T other); + + } + + @QueryEmbeddable + public static class BrandCode extends EntityCode { + + } + + +} diff --git a/querydsl-codegen/src/test/java/com/querydsl/codegen/EmbeddedTest.java b/querydsl-codegen/src/test/java/com/querydsl/codegen/EmbeddedTest.java new file mode 100644 index 0000000000..5d502351da --- /dev/null +++ b/querydsl-codegen/src/test/java/com/querydsl/codegen/EmbeddedTest.java @@ -0,0 +1,36 @@ +package com.querydsl.codegen; + +import com.querydsl.core.annotations.QueryEmbeddable; +import com.querydsl.core.annotations.QueryEmbedded; +import com.querydsl.core.annotations.QueryEntity; +import com.querydsl.core.annotations.QuerySupertype; + +public class EmbeddedTest extends AbstractExporterTest { + + @QueryEntity + public static class EntityClass extends AbstractEntity { + + } + + @QuerySupertype + public abstract static class AbstractEntity { + + @QueryEmbedded + public C code; + } + + @QuerySupertype + public static class EntityCode { + + public String code; + + } + + @QueryEmbeddable + public static class SubEntityCode extends EntityCode { + + public String property; + + } + +} \ No newline at end of file diff --git a/querydsl-codegen/src/test/java/com/querydsl/codegen/EntityInheritanceTest.java b/querydsl-codegen/src/test/java/com/querydsl/codegen/EntityInheritanceTest.java new file mode 100644 index 0000000000..efdac87af0 --- /dev/null +++ b/querydsl-codegen/src/test/java/com/querydsl/codegen/EntityInheritanceTest.java @@ -0,0 +1,24 @@ +package com.querydsl.codegen; + +import com.querydsl.core.annotations.QueryEntity; +import com.querydsl.core.annotations.QuerySupertype; + +public class EntityInheritanceTest extends AbstractExporterTest { + + @QuerySupertype + public static class TreeEntity> { + + public Integer id; + + public T parent; + + } + + @QueryEntity + public static class TestEntity extends TreeEntity { + + public String name; + + } + +} diff --git a/querydsl-codegen/src/test/java/com/querydsl/codegen/EntitySerializerTest.java b/querydsl-codegen/src/test/java/com/querydsl/codegen/EntitySerializerTest.java new file mode 100644 index 0000000000..eb1801aadb --- /dev/null +++ b/querydsl-codegen/src/test/java/com/querydsl/codegen/EntitySerializerTest.java @@ -0,0 +1,217 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.codegen; + +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.io.StringWriter; +import java.sql.Time; +import java.util.Collections; +import java.util.Date; +import java.util.EnumMap; +import java.util.Map; + +import org.junit.Test; + +import com.querydsl.codegen.utils.JavaWriter; +import com.querydsl.codegen.utils.model.*; +import com.querydsl.core.annotations.PropertyType; + +public class EntitySerializerTest { + + private QueryTypeFactory queryTypeFactory = new QueryTypeFactoryImpl("Q", "", ""); + + private final TypeMappings typeMappings = new JavaTypeMappings(); + + private final EntitySerializer serializer = new DefaultEntitySerializer(typeMappings, Collections.emptySet()); + + private final StringWriter writer = new StringWriter(); + + public static class Entity { + + } + + @Test + public void javadocs_for_innerClass() throws IOException { + EntityType entityType = new EntityType(new ClassType(Entity.class)); + typeMappings.register(entityType, queryTypeFactory.create(entityType)); + + serializer.serialize(entityType, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); + assertTrue(writer.toString().contains("QEntitySerializerTest_Entity is a Querydsl query type for Entity")); + CompileUtils.assertCompiles("QEntitySerializerTest_Entity", writer.toString()); + } + + @Test + public void different_package() throws IOException { + queryTypeFactory = new QueryTypeFactoryImpl("Q", "", ".gen"); + + EntityType entityType = new EntityType(new ClassType(Entity.class)); + typeMappings.register(entityType, queryTypeFactory.create(entityType)); + + serializer.serialize(entityType, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); + assertTrue(writer.toString().contains("public class QEntitySerializerTest_Entity " + + "extends EntityPathBase")); + CompileUtils.assertCompiles("QEntitySerializerTest_Entity", writer.toString()); + } + + @Test + public void no_package() throws IOException { + SimpleType type = new SimpleType(TypeCategory.ENTITY, "Entity", "", "Entity",false,false); + EntityType entityType = new EntityType(type); + typeMappings.register(entityType, queryTypeFactory.create(entityType)); + + serializer.serialize(entityType, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); + assertTrue(writer.toString().contains("public class QEntity extends EntityPathBase {")); + CompileUtils.assertCompiles("QEntity", writer.toString()); + } + + @Test + public void original_category() throws IOException { + Map categoryToSuperClass + = new EnumMap(TypeCategory.class); + categoryToSuperClass.put(TypeCategory.COMPARABLE, "ComparablePath"); + categoryToSuperClass.put(TypeCategory.ENUM, "EnumPath"); + categoryToSuperClass.put(TypeCategory.DATE, "DatePath"); + categoryToSuperClass.put(TypeCategory.DATETIME, "DateTimePath"); + categoryToSuperClass.put(TypeCategory.TIME, "TimePath"); + categoryToSuperClass.put(TypeCategory.NUMERIC, "NumberPath"); + categoryToSuperClass.put(TypeCategory.STRING, "StringPath"); + categoryToSuperClass.put(TypeCategory.BOOLEAN, "BooleanPath"); + + for (Map.Entry entry : categoryToSuperClass.entrySet()) { + SimpleType type = new SimpleType(entry.getKey(), "Entity", "", "Entity",false,false); + EntityType entityType = new EntityType(type); + typeMappings.register(entityType, queryTypeFactory.create(entityType)); + + serializer.serialize(entityType, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); + assertTrue(entry.toString(), writer.toString().contains("public class QEntity extends " + entry.getValue() + " {")); + } + + } + + @Test + public void correct_superclass() throws IOException { + SimpleType type = new SimpleType(TypeCategory.ENTITY, "java.util.Locale", "java.util", "Locale",false,false); + EntityType entityType = new EntityType(type); + typeMappings.register(entityType, queryTypeFactory.create(entityType)); + + serializer.serialize(entityType, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); + assertTrue(writer.toString().contains("public class QLocale extends EntityPathBase {")); + CompileUtils.assertCompiles("QLocale", writer.toString()); + } + + @Test + public void primitive_array() throws IOException { + SimpleType type = new SimpleType(TypeCategory.ENTITY, "Entity", "", "Entity",false,false); + EntityType entityType = new EntityType(type); + entityType.addProperty(new Property(entityType, "bytes", new ClassType(byte[].class))); + typeMappings.register(entityType, queryTypeFactory.create(entityType)); + serializer.serialize(entityType, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); + assertTrue(writer.toString().contains("public final SimplePath bytes")); + CompileUtils.assertCompiles("QEntity", writer.toString()); + } + + @Test + public void include() throws IOException { + SimpleType type = new SimpleType(TypeCategory.ENTITY, "Entity", "", "Entity",false,false); + EntityType entityType = new EntityType(type); + entityType.addProperty(new Property(entityType, "b", new ClassType(TypeCategory.BOOLEAN, Boolean.class))); + entityType.addProperty(new Property(entityType, "c", new ClassType(TypeCategory.COMPARABLE, String.class))); + //entityType.addProperty(new Property(entityType, "cu", new ClassType(TypeCategory.CUSTOM, PropertyType.class))); + entityType.addProperty(new Property(entityType, "d", new ClassType(TypeCategory.DATE, Date.class))); + entityType.addProperty(new Property(entityType, "e", new ClassType(TypeCategory.ENUM, PropertyType.class))); + entityType.addProperty(new Property(entityType, "dt", new ClassType(TypeCategory.DATETIME, Date.class))); + entityType.addProperty(new Property(entityType, "i", new ClassType(TypeCategory.NUMERIC, Integer.class))); + entityType.addProperty(new Property(entityType, "s", new ClassType(TypeCategory.STRING, String.class))); + entityType.addProperty(new Property(entityType, "t", new ClassType(TypeCategory.TIME, Time.class))); + + EntityType subType = new EntityType(new SimpleType(TypeCategory.ENTITY, "Entity2", "", "Entity2",false,false)); + subType.include(new Supertype(type, entityType)); + typeMappings.register(subType, queryTypeFactory.create(subType)); + + serializer.serialize(subType, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); + CompileUtils.assertCompiles("QEntity2", writer.toString()); + } + + @Test + public void properties() throws IOException { + SimpleType type = new SimpleType(TypeCategory.ENTITY, "Entity", "", "Entity",false,false); + EntityType entityType = new EntityType(type); + entityType.addProperty(new Property(entityType, "b", new ClassType(TypeCategory.BOOLEAN, Boolean.class))); + entityType.addProperty(new Property(entityType, "c", new ClassType(TypeCategory.COMPARABLE, String.class))); + //entityType.addProperty(new Property(entityType, "cu", new ClassType(TypeCategory.CUSTOM, PropertyType.class))); + entityType.addProperty(new Property(entityType, "d", new ClassType(TypeCategory.DATE, Date.class))); + entityType.addProperty(new Property(entityType, "e", new ClassType(TypeCategory.ENUM, PropertyType.class))); + entityType.addProperty(new Property(entityType, "dt", new ClassType(TypeCategory.DATETIME, Date.class))); + entityType.addProperty(new Property(entityType, "i", new ClassType(TypeCategory.NUMERIC, Integer.class))); + entityType.addProperty(new Property(entityType, "s", new ClassType(TypeCategory.STRING, String.class))); + entityType.addProperty(new Property(entityType, "t", new ClassType(TypeCategory.TIME, Time.class))); + typeMappings.register(entityType, queryTypeFactory.create(entityType)); + + serializer.serialize(entityType, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); + CompileUtils.assertCompiles("QEntity", writer.toString()); + } + + @Test + public void superType() throws IOException { + EntityType superType = new EntityType(new SimpleType(TypeCategory.ENTITY, "Entity2", "", "Entity2",false,false)); + SimpleType type = new SimpleType(TypeCategory.ENTITY, "Entity", "", "Entity",false,false); + EntityType entityType = new EntityType(type, Collections.singleton(new Supertype(superType, superType))); + typeMappings.register(superType, queryTypeFactory.create(superType)); + typeMappings.register(entityType, queryTypeFactory.create(entityType)); + + serializer.serialize(entityType, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); + assertTrue(writer.toString().contains("public final QEntity2 _super = new QEntity2(this);")); + //CompileUtils.assertCompiles("QEntity", writer.toString()); + } + + @Test + public void delegates() throws IOException { + SimpleType type = new SimpleType(TypeCategory.ENTITY, "Entity", "", "Entity",false,false); + EntityType entityType = new EntityType(type); + Delegate delegate = new Delegate(type, type, "test", Collections.emptyList(), Types.STRING); + entityType.addDelegate(delegate); + typeMappings.register(entityType, queryTypeFactory.create(entityType)); + + serializer.serialize(entityType, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); + assertTrue(writer.toString().contains("return Entity.test(this);")); + CompileUtils.assertCompiles("QEntity", writer.toString()); + } + + @Test + public void defaultGeneratedAnnotation() throws IOException { + EntityType entityType = new EntityType(new ClassType(Entity.class)); + typeMappings.register(entityType, queryTypeFactory.create(entityType)); + + serializer.serialize(entityType, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); + String generatedSourceCode = writer.toString(); + assertTrue(generatedSourceCode.contains(String.format("import %s;", GeneratedAnnotationResolver.resolveDefault().getName()))); + assertTrue(generatedSourceCode.contains("@Generated(\"com.querydsl.codegen.DefaultEntitySerializer\")\npublic class")); + CompileUtils.assertCompiles("QEntitySerializerTest_Entity", generatedSourceCode); + } + + @Test + public void customGeneratedAnnotation() throws IOException { + EntityType entityType = new EntityType(new ClassType(Entity.class)); + typeMappings.register(entityType, queryTypeFactory.create(entityType)); + + new DefaultEntitySerializer(typeMappings, Collections.emptySet(), com.querydsl.core.annotations.Generated.class).serialize(entityType, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); + String generatedSourceCode = writer.toString(); + assertTrue(generatedSourceCode.contains("import " + com.querydsl.core.annotations.Generated.class.getName() + ";")); + assertTrue(generatedSourceCode.contains("@" + com.querydsl.core.annotations.Generated.class.getSimpleName() + "(\"com.querydsl.codegen.DefaultEntitySerializer\")\npublic class")); + CompileUtils.assertCompiles("QEntitySerializerTest_Entity", generatedSourceCode); + } + +} diff --git a/querydsl-codegen/src/test/java/com/querydsl/codegen/EntityTypeTest.java b/querydsl-codegen/src/test/java/com/querydsl/codegen/EntityTypeTest.java new file mode 100644 index 0000000000..ed5de491b8 --- /dev/null +++ b/querydsl-codegen/src/test/java/com/querydsl/codegen/EntityTypeTest.java @@ -0,0 +1,55 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.codegen; + +import static org.junit.Assert.assertEquals; + +import java.util.Collections; + +import org.junit.Test; + +import com.querydsl.codegen.utils.model.ClassType; +import com.querydsl.codegen.utils.model.TypeCategory; + +public class EntityTypeTest { + + @Test + public void uncapSimpleName_escaped() { + ClassType typeModel = new ClassType(TypeCategory.ENTITY, Object.class); + EntityType entityModel = new EntityType(typeModel); + assertEquals("object", entityModel.getModifiedSimpleName()); + + entityModel.addProperty(new Property(entityModel, "object", typeModel)); + assertEquals("object1", entityModel.getModifiedSimpleName()); + } + + @Test + public void uncapSimpleName_escaped2() { + ClassType typeModel = new ClassType(TypeCategory.ENTITY, Object.class); + EntityType entityModel = new EntityType(typeModel); + assertEquals("object", entityModel.getModifiedSimpleName()); + + entityModel.addProperty(new Property(entityModel, "OBJECT", "object", typeModel, + Collections. emptyList(), false)); + assertEquals("object1", entityModel.getModifiedSimpleName()); + } + + @Test + public void uncapSimpleName_escaped3() { + ClassType typeModel = new ClassType(TypeCategory.ENTITY, Void.class); + EntityType entityModel = new EntityType(typeModel); + assertEquals("void$", entityModel.getModifiedSimpleName()); + } + +} diff --git a/querydsl-codegen/src/test/java/com/mysema/query/codegen/ExampleEmbeddable.java b/querydsl-codegen/src/test/java/com/querydsl/codegen/ExampleEmbeddable.java similarity index 83% rename from querydsl-codegen/src/test/java/com/mysema/query/codegen/ExampleEmbeddable.java rename to querydsl-codegen/src/test/java/com/querydsl/codegen/ExampleEmbeddable.java index 45022514b2..5593515f9b 100644 --- a/querydsl-codegen/src/test/java/com/mysema/query/codegen/ExampleEmbeddable.java +++ b/querydsl-codegen/src/test/java/com/querydsl/codegen/ExampleEmbeddable.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,9 +11,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.codegen; +package com.querydsl.codegen; -import com.mysema.query.annotations.QueryEmbeddable; +import com.querydsl.core.annotations.QueryEmbeddable; @QueryEmbeddable public class ExampleEmbeddable { diff --git a/querydsl-codegen/src/test/java/com/mysema/query/codegen/ExampleEmbedded.java b/querydsl-codegen/src/test/java/com/querydsl/codegen/ExampleEmbedded.java similarity index 88% rename from querydsl-codegen/src/test/java/com/mysema/query/codegen/ExampleEmbedded.java rename to querydsl-codegen/src/test/java/com/querydsl/codegen/ExampleEmbedded.java index e379a02675..c85b5a7618 100644 --- a/querydsl-codegen/src/test/java/com/mysema/query/codegen/ExampleEmbedded.java +++ b/querydsl-codegen/src/test/java/com/querydsl/codegen/ExampleEmbedded.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.codegen; +package com.querydsl.codegen; public class ExampleEmbedded { diff --git a/querydsl-codegen/src/test/java/com/querydsl/codegen/ExampleEntity.java b/querydsl-codegen/src/test/java/com/querydsl/codegen/ExampleEntity.java new file mode 100644 index 0000000000..cb4c983e3d --- /dev/null +++ b/querydsl-codegen/src/test/java/com/querydsl/codegen/ExampleEntity.java @@ -0,0 +1,88 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.codegen; + +import java.util.List; +import java.util.Map; + +import com.querydsl.core.annotations.QueryEmbedded; +import com.querydsl.core.annotations.QueryEntity; + +@QueryEntity +public class ExampleEntity extends ExampleSupertype { + + private String name; + + private ExampleEntity mate; + + private List mates; + + private Map matesByName; + + private ExampleEmbeddable embeddable; + + @QueryEmbedded + private ExampleEmbedded embedded; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public ExampleEntity getMate() { + return mate; + } + + public void setMate(ExampleEntity mate) { + this.mate = mate; + } + + public ExampleEmbeddable getEmbeddable() { + return embeddable; + } + + public void setEmbeddable(ExampleEmbeddable embeddable) { + this.embeddable = embeddable; + } + + public List getMates() { + return mates; + } + + public void setMates(List mates) { + this.mates = mates; + } + + public Map getMatesByName() { + return matesByName; + } + + public void setMatesByName(Map matesByName) { + this.matesByName = matesByName; + } + + public ExampleEmbedded getEmbedded() { + return embedded; + } + + public void setEmbedded(ExampleEmbedded embedded) { + this.embedded = embedded; + } + + + +} diff --git a/querydsl-codegen/src/test/java/com/mysema/query/codegen/ExampleEntityInterface.java b/querydsl-codegen/src/test/java/com/querydsl/codegen/ExampleEntityInterface.java similarity index 80% rename from querydsl-codegen/src/test/java/com/mysema/query/codegen/ExampleEntityInterface.java rename to querydsl-codegen/src/test/java/com/querydsl/codegen/ExampleEntityInterface.java index 6cfeaa97da..377b4cab5c 100644 --- a/querydsl-codegen/src/test/java/com/mysema/query/codegen/ExampleEntityInterface.java +++ b/querydsl-codegen/src/test/java/com/querydsl/codegen/ExampleEntityInterface.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,9 +11,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.codegen; +package com.querydsl.codegen; -import com.mysema.query.annotations.QueryEntity; +import com.querydsl.core.annotations.QueryEntity; @QueryEntity public interface ExampleEntityInterface { diff --git a/querydsl-codegen/src/test/java/com/mysema/query/codegen/ExampleSupertype.java b/querydsl-codegen/src/test/java/com/querydsl/codegen/ExampleSupertype.java similarity index 82% rename from querydsl-codegen/src/test/java/com/mysema/query/codegen/ExampleSupertype.java rename to querydsl-codegen/src/test/java/com/querydsl/codegen/ExampleSupertype.java index e05eb12a27..665902421a 100644 --- a/querydsl-codegen/src/test/java/com/mysema/query/codegen/ExampleSupertype.java +++ b/querydsl-codegen/src/test/java/com/querydsl/codegen/ExampleSupertype.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,9 +11,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.codegen; +package com.querydsl.codegen; -import com.mysema.query.annotations.QuerySupertype; +import com.querydsl.core.annotations.QuerySupertype; @QuerySupertype public class ExampleSupertype { diff --git a/querydsl-codegen/src/test/java/com/querydsl/codegen/Examples.java b/querydsl-codegen/src/test/java/com/querydsl/codegen/Examples.java new file mode 100644 index 0000000000..2dde5cee96 --- /dev/null +++ b/querydsl-codegen/src/test/java/com/querydsl/codegen/Examples.java @@ -0,0 +1,115 @@ +package com.querydsl.codegen; + +import java.util.*; + +import com.querydsl.core.DefaultQueryMetadata; +import com.querydsl.core.annotations.QueryEmbedded; +import com.querydsl.core.annotations.QueryEntity; +import com.querydsl.core.types.OrderSpecifier; + + +public class Examples { + + public static class Supertype { + + public String supertypeProperty; + } + + @QueryEntity + public static class SimpleEntity extends Supertype { + + } + + @QueryEntity + public abstract static class AbstractEntity { + + public Id id; + + public String first; + + } + + @QueryEntity + public static class SubEntity extends AbstractEntity { + + public String second; + + } + + + @QueryEntity + public static class ComplexCollections { + + @QueryEmbedded + public List> list; + + @QueryEmbedded + public Map> map; + + @QueryEmbedded + public Map> map2; + + @QueryEmbedded + public Map> map3; + + + } + + + public static class Complex> implements Comparable> { + + public T a; + + @Override + public int compareTo(Complex arg0) { + return 0; + } + + public boolean equals(Object o) { + return o == this; + } + } + + @QueryEntity + public static class Reference { + + } + + @QueryEntity + public static class GenericRelations { + public Collection> col1; + public Collection> col2; + public Collection> col3; + public Collection> col4; + + public Set> set1; + public Set> set2; + public Set> set3; + public Set> set4; + + public Map> map1; + public Map,String> map2; + public Map> map3; + public Map,String> map4; + } + + @QueryEntity + public static class Subtype extends DefaultQueryMetadata { + + private static final long serialVersionUID = -218949941713252847L; + + } + + @QueryEntity + public static class OrderBys { + + List> orderBy = new ArrayList>(); + + } + + @QueryEntity + public static class SimpleTypes { + + List> classList5; + } +} diff --git a/querydsl-codegen/src/test/java/com/querydsl/codegen/ExternalEmbeddableTest.java b/querydsl-codegen/src/test/java/com/querydsl/codegen/ExternalEmbeddableTest.java new file mode 100644 index 0000000000..d0c608e502 --- /dev/null +++ b/querydsl-codegen/src/test/java/com/querydsl/codegen/ExternalEmbeddableTest.java @@ -0,0 +1,20 @@ +package com.querydsl.codegen; + +import org.junit.Ignore; + +import com.querydsl.core.annotations.QueryEmbedded; +import com.querydsl.core.annotations.QueryEntity; +import com.querydsl.core.domain.EmbeddableWithoutQType; + +@Ignore +public class ExternalEmbeddableTest { + + @QueryEntity + public static class EntityWithExternalEmbeddable { + + @QueryEmbedded + EmbeddableWithoutQType embeddable; + + } + +} diff --git a/querydsl-codegen/src/test/java/com/querydsl/codegen/GeneratedAnnotationResolverTest.java b/querydsl-codegen/src/test/java/com/querydsl/codegen/GeneratedAnnotationResolverTest.java new file mode 100644 index 0000000000..849fbf4f65 --- /dev/null +++ b/querydsl-codegen/src/test/java/com/querydsl/codegen/GeneratedAnnotationResolverTest.java @@ -0,0 +1,32 @@ +package com.querydsl.codegen; + +import org.junit.Test; + +import javax.annotation.Generated; +import java.lang.annotation.Annotation; + +import static org.junit.Assert.assertNotNull; + +public class GeneratedAnnotationResolverTest { + + private static final String defaultGenerated = Generated.class.getName(); + + @Test + public void resolveCustom() { + String customClass = "some.random.Class"; + Class resolvedAnnotationClass = GeneratedAnnotationResolver.resolve(customClass); + assertNotNull(resolvedAnnotationClass); + } + + @Test + public void resolveNull() { + Class resolvedAnnotationClass = GeneratedAnnotationResolver.resolve(null); + assertNotNull(resolvedAnnotationClass); + } + + @Test + public void resolveDefault() { + Class resolvedAnnotationClass = GeneratedAnnotationResolver.resolveDefault(); + assertNotNull(resolvedAnnotationClass); + } +} diff --git a/querydsl-codegen/src/test/java/com/querydsl/codegen/Generic2Test.java b/querydsl-codegen/src/test/java/com/querydsl/codegen/Generic2Test.java new file mode 100644 index 0000000000..0e0bfc38af --- /dev/null +++ b/querydsl-codegen/src/test/java/com/querydsl/codegen/Generic2Test.java @@ -0,0 +1,63 @@ +package com.querydsl.codegen; + +import static org.junit.Assert.assertEquals; + +import java.io.File; +import java.lang.annotation.Annotation; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import org.junit.Test; + +import com.querydsl.codegen.utils.model.Type; +import com.querydsl.core.annotations.QueryEntity; + +public class Generic2Test { + + @QueryEntity + public static class AbstractCollectionAttribute> { + + T value; + + } + + @QueryEntity + public static class ListAttribute extends AbstractCollectionAttribute> { + + String name; + + } + + @QueryEntity + public static class Product { + + ListAttribute integerAttributes; + ListAttribute stringAttributes; + + } + + @Test + public void resolve() { + TypeFactory factory = new TypeFactory(Collections.>emptyList()); + Type type = factory.get(AbstractCollectionAttribute.class); + assertEquals("com.querydsl.codegen.Generic2Test.AbstractCollectionAttribute", type.getGenericName(false)); + assertEquals("com.querydsl.codegen.Generic2Test.AbstractCollectionAttribute", type.getGenericName(true)); + } + + @Test + public void resolve2() { + TypeFactory factory = new TypeFactory(Collections.>emptyList()); + Type type = factory.getEntityType(AbstractCollectionAttribute.class); + assertEquals("com.querydsl.codegen.Generic2Test.AbstractCollectionAttribute>", type.getGenericName(false)); + assertEquals("com.querydsl.codegen.Generic2Test.AbstractCollectionAttribute>", type.getGenericName(true)); + } + + + @Test + public void export() { + GenericExporter exporter = new GenericExporter(); + exporter.setTargetFolder(new File("target/Generic2Test")); + exporter.export(Generic2Test.class.getClasses()); + } +} diff --git a/querydsl-codegen/src/test/java/com/querydsl/codegen/GenericExporterTest.java b/querydsl-codegen/src/test/java/com/querydsl/codegen/GenericExporterTest.java new file mode 100644 index 0000000000..c886a0f52f --- /dev/null +++ b/querydsl-codegen/src/test/java/com/querydsl/codegen/GenericExporterTest.java @@ -0,0 +1,167 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.codegen; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; + +import com.querydsl.core.domain.Cat; + +public class GenericExporterTest { + + @Rule + public TemporaryFolder folder = new TemporaryFolder(); + + private GenericExporter exporter; + + @Before + public void setUp() { + exporter = new GenericExporter(); + } + + @Test + public void export() { + exporter.setTargetFolder(folder.getRoot()); + exporter.export(getClass().getPackage()); + assertTrue(new File(folder.getRoot(), "com/querydsl/codegen/QExampleEmbeddable.java").exists()); + assertTrue(new File(folder.getRoot(), "com/querydsl/codegen/QExampleEmbedded.java").exists()); + assertTrue(new File(folder.getRoot(), "com/querydsl/codegen/QExampleEntity.java").exists()); + assertTrue(new File(folder.getRoot(), "com/querydsl/codegen/QExampleEntityInterface.java").exists()); + assertTrue(new File(folder.getRoot(), "com/querydsl/codegen/QExampleSupertype.java").exists()); + assertTrue(new File(folder.getRoot(), "com/querydsl/codegen/sub/QExampleEntity2.java").exists()); + } + + @Test + public void export_with_keywords() throws IOException { + exporter.setKeywords(Keywords.JPA); + exporter.setTargetFolder(folder.getRoot()); + exporter.export(getClass().getPackage()); + String str = new String(Files.readAllBytes(new File(folder.getRoot(), "com/querydsl/codegen/QGroup.java").toPath()), StandardCharsets.UTF_8); + assertTrue(str.contains("QGroup group = new QGroup(\"group1\");")); + } + + @Test + public void export_with_stopClass() { + exporter.setTargetFolder(folder.getRoot()); + exporter.addStopClass(Examples.Supertype.class); + exporter.export(getClass().getPackage()); + assertFalse(new File(folder.getRoot(), "com/querydsl/codegen/QExamples_Supertype.java").exists()); + } + + @Test + public void override_serializer() { + exporter.setTargetFolder(folder.getRoot()); + exporter.setSerializerClass(DefaultEntitySerializer.class); + exporter.export(getClass().getPackage()); + assertTrue(new File(folder.getRoot(), "com/querydsl/codegen/QExampleEmbeddable.java").exists()); + assertTrue(new File(folder.getRoot(), "com/querydsl/codegen/QExampleEmbedded.java").exists()); + assertTrue(new File(folder.getRoot(), "com/querydsl/codegen/QExampleEntity.java").exists()); + assertTrue(new File(folder.getRoot(), "com/querydsl/codegen/QExampleEntityInterface.java").exists()); + assertTrue(new File(folder.getRoot(), "com/querydsl/codegen/QExampleSupertype.java").exists()); + assertTrue(new File(folder.getRoot(), "com/querydsl/codegen/sub/QExampleEntity2.java").exists()); + } + + @Test + public void export_package_as_string() { + exporter.setTargetFolder(folder.getRoot()); + exporter.export(getClass().getPackage().getName()); + assertTrue(new File(folder.getRoot(), "com/querydsl/codegen/QExampleEmbeddable.java").exists()); + assertTrue(new File(folder.getRoot(), "com/querydsl/codegen/QExampleEmbedded.java").exists()); + assertTrue(new File(folder.getRoot(), "com/querydsl/codegen/QExampleEntity.java").exists()); + assertTrue(new File(folder.getRoot(), "com/querydsl/codegen/QExampleEntityInterface.java").exists()); + assertTrue(new File(folder.getRoot(), "com/querydsl/codegen/QExampleSupertype.java").exists()); + assertTrue(new File(folder.getRoot(), "com/querydsl/codegen/sub/QExampleEntity2.java").exists()); + } + + @Test + public void export_with_package_suffix() { + exporter.setTargetFolder(folder.getRoot()); + exporter.setPackageSuffix("types"); + exporter.export(getClass().getPackage()); + assertTrue(new File(folder.getRoot(), "com/querydsl/codegentypes/QExampleEmbeddable.java").exists()); + assertTrue(new File(folder.getRoot(), "com/querydsl/codegentypes/QExampleEmbedded.java").exists()); + assertTrue(new File(folder.getRoot(), "com/querydsl/codegentypes/QExampleEntity.java").exists()); + assertTrue(new File(folder.getRoot(), "com/querydsl/codegentypes/QExampleEntityInterface.java").exists()); + assertTrue(new File(folder.getRoot(), "com/querydsl/codegentypes/QExampleSupertype.java").exists()); + assertTrue(new File(folder.getRoot(), "com/querydsl/codegen/subtypes/QExampleEntity2.java").exists()); + } + + @Test + public void export_handle_no_methods_nor_fields() { + exporter.setTargetFolder(folder.getRoot()); + exporter.setHandleFields(false); + exporter.setHandleMethods(false); + exporter.export(getClass().getPackage()); + assertTrue(new File(folder.getRoot(), "com/querydsl/codegen/QExampleEmbeddable.java").exists()); + } + + @Test + public void export_domain_package() { + exporter.setTargetFolder(folder.getRoot()); + exporter.export(Cat.class.getPackage()); + } + + @Test + public void export_serializerConfig() { + exporter.setTargetFolder(folder.getRoot()); + exporter.setSerializerConfig(new SimpleSerializerConfig(true, true, true, true, "")); + exporter.export(getClass().getPackage()); + assertTrue(new File(folder.getRoot(), "com/querydsl/codegen/QExampleEmbeddable.java").exists()); + assertTrue(new File(folder.getRoot(), "com/querydsl/codegen/QExampleEmbedded.java").exists()); + assertTrue(new File(folder.getRoot(), "com/querydsl/codegen/QExampleEntity.java").exists()); + assertTrue(new File(folder.getRoot(), "com/querydsl/codegen/QExampleEntityInterface.java").exists()); + assertTrue(new File(folder.getRoot(), "com/querydsl/codegen/QExampleSupertype.java").exists()); + assertTrue(new File(folder.getRoot(), "com/querydsl/codegen/sub/QExampleEntity2.java").exists()); + } + + @Test + public void export_useFieldTypes() { + exporter.setTargetFolder(folder.getRoot()); + exporter.setUseFieldTypes(true); + exporter.export(getClass().getPackage()); + assertTrue(new File(folder.getRoot(), "com/querydsl/codegen/QExampleEmbeddable.java").exists()); + assertTrue(new File(folder.getRoot(), "com/querydsl/codegen/QExampleEmbedded.java").exists()); + assertTrue(new File(folder.getRoot(), "com/querydsl/codegen/QExampleEntity.java").exists()); + assertTrue(new File(folder.getRoot(), "com/querydsl/codegen/QExampleEntityInterface.java").exists()); + assertTrue(new File(folder.getRoot(), "com/querydsl/codegen/QExampleSupertype.java").exists()); + assertTrue(new File(folder.getRoot(), "com/querydsl/codegen/sub/QExampleEntity2.java").exists()); + } + + @Test + public void export_propertyHandling() throws IOException { + for (PropertyHandling ph : PropertyHandling.values()) { + File f = folder.newFolder(); + GenericExporter e = new GenericExporter(); + e.setTargetFolder(f); + e.setPropertyHandling(ph); + e.export(getClass().getPackage()); + assertTrue(new File(f, "com/querydsl/codegen/QExampleEmbeddable.java").exists()); + assertTrue(new File(f, "com/querydsl/codegen/QExampleEntity.java").exists()); + assertTrue(new File(f, "com/querydsl/codegen/QExampleEntityInterface.java").exists()); + assertTrue(new File(f, "com/querydsl/codegen/QExampleSupertype.java").exists()); + assertTrue(new File(f, "com/querydsl/codegen/sub/QExampleEntity2.java").exists()); + } + } + +} diff --git a/querydsl-codegen/src/test/java/com/querydsl/codegen/GenericTest.java b/querydsl-codegen/src/test/java/com/querydsl/codegen/GenericTest.java new file mode 100644 index 0000000000..6391c25ead --- /dev/null +++ b/querydsl-codegen/src/test/java/com/querydsl/codegen/GenericTest.java @@ -0,0 +1,36 @@ +package com.querydsl.codegen; + +import org.junit.Test; + +import com.querydsl.codegen.utils.model.Type; + + +public class GenericTest { + + public abstract static class CapiBCKeyedByGrundstueck { + + } + + public abstract static class HidaBez, G extends HidaBezGruppe> extends CapiBCKeyedByGrundstueck { + + } + + public abstract static class HidaBezGruppe, B extends HidaBez> extends + CapiBCKeyedByGrundstueck { + } + + private TypeFactory typeFactory = new TypeFactory(); + + @Test + public void hidaBez() { + Type type = typeFactory.getEntityType(HidaBez.class); + //System.out.println(type.getGenericName(true)); + } + + @Test + public void hidaBezGruppe() { + Type type = typeFactory.getEntityType(HidaBezGruppe.class); + //System.out.println(type.getGenericName(true)); + } + +} diff --git a/querydsl-codegen/src/test/java/com/mysema/query/codegen/GroovyBeanSerializerTest.java b/querydsl-codegen/src/test/java/com/querydsl/codegen/GroovyBeanSerializerTest.java similarity index 84% rename from querydsl-codegen/src/test/java/com/mysema/query/codegen/GroovyBeanSerializerTest.java rename to querydsl-codegen/src/test/java/com/querydsl/codegen/GroovyBeanSerializerTest.java index bedcc28d48..7b3e14fb96 100644 --- a/querydsl-codegen/src/test/java/com/mysema/query/codegen/GroovyBeanSerializerTest.java +++ b/querydsl-codegen/src/test/java/com/querydsl/codegen/GroovyBeanSerializerTest.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,7 +11,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.codegen; +package com.querydsl.codegen; + +import static org.junit.Assert.assertTrue; import java.io.IOException; import java.io.StringWriter; @@ -19,29 +21,29 @@ import java.util.Arrays; import java.util.Date; -import com.mysema.codegen.JavaWriter; -import com.mysema.codegen.StringUtils; -import com.mysema.codegen.model.*; import org.junit.Before; import org.junit.Test; -import static org.junit.Assert.assertTrue; + +import com.querydsl.codegen.utils.JavaWriter; +import com.querydsl.codegen.utils.StringUtils; +import com.querydsl.codegen.utils.model.*; public class GroovyBeanSerializerTest { - + private Type typeModel; - + private EntityType type; private final Writer writer = new StringWriter(); @Before public void setUp() { - typeModel = new SimpleType(TypeCategory.ENTITY, "com.mysema.query.DomainClass", "com.mysema.query", "DomainClass", false,false); - type = new EntityType(typeModel); + typeModel = new SimpleType(TypeCategory.ENTITY, "com.querydsl.DomainClass", "com.querydsl", "DomainClass", false,false); + type = new EntityType(typeModel); } - + @Test - public void Properties() throws IOException{ + public void properties() throws IOException { // property type.addProperty(new Property(type, "entityField", type)); type.addProperty(new Property(type, "collection", new SimpleType(Types.COLLECTION, typeModel))); @@ -50,7 +52,7 @@ public void Properties() throws IOException{ type.addProperty(new Property(type, "arrayField", new ClassType(TypeCategory.ARRAY, String[].class))); type.addProperty(new Property(type, "mapField", new SimpleType(Types.MAP, typeModel, typeModel))); - for (Class cl : Arrays.>asList(Boolean.class, Comparable.class, Integer.class, + for (Class cl : Arrays.>asList(Boolean.class, Comparable.class, Integer.class, Date.class, java.sql.Date.class, java.sql.Time.class)) { Type classType = new ClassType(TypeCategory.get(cl.getName()), cl); type.addProperty(new Property(type, StringUtils.uncapitalize(cl.getSimpleName()), classType)); @@ -75,5 +77,5 @@ public void Properties() throws IOException{ assertTrue(prop + " was not contained", str.contains(prop)); } } - + } diff --git a/querydsl-codegen/src/test/java/com/querydsl/codegen/Group.java b/querydsl-codegen/src/test/java/com/querydsl/codegen/Group.java new file mode 100644 index 0000000000..f654be2b02 --- /dev/null +++ b/querydsl-codegen/src/test/java/com/querydsl/codegen/Group.java @@ -0,0 +1,8 @@ +package com.querydsl.codegen; + +import com.querydsl.core.annotations.QueryEntity; + +@QueryEntity +public class Group { + +} diff --git a/querydsl-codegen/src/test/java/com/querydsl/codegen/Inheritance2Test.java b/querydsl-codegen/src/test/java/com/querydsl/codegen/Inheritance2Test.java new file mode 100644 index 0000000000..dc6d24c7a3 --- /dev/null +++ b/querydsl-codegen/src/test/java/com/querydsl/codegen/Inheritance2Test.java @@ -0,0 +1,73 @@ +package com.querydsl.codegen; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import java.io.File; +import java.lang.reflect.Field; + +import org.junit.Test; + +import com.querydsl.codegen.utils.model.Type; +import com.querydsl.codegen.utils.model.TypeExtends; +import com.querydsl.core.annotations.QueryEntity; + +public class Inheritance2Test { + + @QueryEntity + public abstract class Base> { + @SuppressWarnings("unchecked") + Base2 base; + Base2 base2; + } + + @QueryEntity + public abstract class Base2,U extends IFace> { + + } + + @QueryEntity + public abstract class BaseSub extends Base { + + } + + @QueryEntity + public abstract class BaseSub2> extends Base { + + } + + @QueryEntity + public abstract class Base2Sub extends Base2,T> { + + } + + public interface IFace { + + } + + @Test + public void base_base() throws SecurityException, NoSuchFieldException { + TypeFactory typeFactory = new TypeFactory(); + Field field = Base.class.getDeclaredField("base"); + Type type = typeFactory.get(field.getType(), field.getGenericType()); + assertEquals(0, type.getParameters().size()); + } + + @Test + public void base_base2() throws SecurityException, NoSuchFieldException { + TypeFactory typeFactory = new TypeFactory(); + Field field = Base.class.getDeclaredField("base2"); + Type type = typeFactory.get(field.getType(), field.getGenericType()); + assertEquals(2, type.getParameters().size()); + assertNull(((TypeExtends) type.getParameters().get(0)).getVarName()); + assertNull(((TypeExtends) type.getParameters().get(1)).getVarName()); + } + + @Test + public void test() { + GenericExporter exporter = new GenericExporter(); + exporter.setTargetFolder(new File("target/" + getClass().getSimpleName())); + exporter.export(getClass().getClasses()); + } + +} \ No newline at end of file diff --git a/querydsl-codegen/src/test/java/com/querydsl/codegen/PackageSuffixTest.java b/querydsl-codegen/src/test/java/com/querydsl/codegen/PackageSuffixTest.java new file mode 100644 index 0000000000..153b2b8f79 --- /dev/null +++ b/querydsl-codegen/src/test/java/com/querydsl/codegen/PackageSuffixTest.java @@ -0,0 +1,49 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.codegen; + +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.io.StringWriter; +import java.util.Collections; + +import org.junit.Test; + +import com.querydsl.codegen.utils.JavaWriter; +import com.querydsl.codegen.utils.model.SimpleType; +import com.querydsl.codegen.utils.model.TypeCategory; + +public class PackageSuffixTest { + + private final QueryTypeFactory queryTypeFactory = new QueryTypeFactoryImpl("Q", "", ".query"); + + private final TypeMappings typeMappings = new JavaTypeMappings(); + + private final EntitySerializer serializer = new DefaultEntitySerializer(typeMappings, Collections.emptySet()); + + private final StringWriter writer = new StringWriter(); + + @Test + public void correct_imports() throws IOException { + SimpleType type = new SimpleType(TypeCategory.ENTITY, "test.Entity", "test", "Entity",false,false); + EntityType entityType = new EntityType(type); + typeMappings.register(entityType, queryTypeFactory.create(entityType)); + + serializer.serialize(entityType, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); + assertTrue(writer.toString().contains("import test.Entity;")); + assertTrue(writer.toString().contains("public class QEntity extends EntityPathBase {")); + } + +} diff --git a/querydsl-codegen/src/test/java/com/querydsl/codegen/Point.java b/querydsl-codegen/src/test/java/com/querydsl/codegen/Point.java new file mode 100644 index 0000000000..282e5da357 --- /dev/null +++ b/querydsl-codegen/src/test/java/com/querydsl/codegen/Point.java @@ -0,0 +1,37 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.codegen; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.ArrayPath; + + +public class Point extends ArrayPath { + + private static final long serialVersionUID = 1776628530121566388L; + + public Point(String variable) { + super(Double[].class, variable); + } + + public Point(Path parent, String property) { + super(Double[].class, parent, property); + } + + public Point(PathMetadata metadata) { + super(Double[].class, metadata); + } + +} diff --git a/querydsl-codegen/src/test/java/com/querydsl/codegen/ProjectionSerializerTest.java b/querydsl-codegen/src/test/java/com/querydsl/codegen/ProjectionSerializerTest.java new file mode 100644 index 0000000000..69f86c8cf3 --- /dev/null +++ b/querydsl-codegen/src/test/java/com/querydsl/codegen/ProjectionSerializerTest.java @@ -0,0 +1,82 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.codegen; + +import com.querydsl.codegen.utils.JavaWriter; +import com.querydsl.codegen.utils.model.Constructor; +import com.querydsl.codegen.utils.model.Parameter; +import com.querydsl.codegen.utils.model.SimpleType; +import com.querydsl.codegen.utils.model.Type; +import com.querydsl.codegen.utils.model.TypeCategory; +import com.querydsl.codegen.utils.model.Types; +import com.querydsl.core.annotations.Generated; +import org.junit.Test; + +import java.io.IOException; +import java.io.StringWriter; +import java.io.Writer; +import java.util.Arrays; + +import static org.hamcrest.Matchers.containsString; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; + +public class ProjectionSerializerTest { + + @Test + public void constructors() throws IOException { + Type typeModel = new SimpleType(TypeCategory.ENTITY, "com.querydsl.DomainClass", "com.querydsl", "DomainClass", false,false); + EntityType type = new EntityType(typeModel); + + // constructor + Parameter firstName = new Parameter("firstName", Types.STRING); + Parameter lastName = new Parameter("lastName", Types.STRING); + Parameter age = new Parameter("age", Types.INTEGER); + type.addConstructor(new Constructor(Arrays.asList(firstName, lastName, age))); + + Writer writer = new StringWriter(); + ProjectionSerializer serializer = new DefaultProjectionSerializer(new JavaTypeMappings()); + serializer.serialize(type, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); + assertTrue(writer.toString().contains("Expression firstName")); + assertTrue(writer.toString().contains("Expression lastName")); + assertTrue(writer.toString().contains("Expression age")); + } + + @Test + public void defaultGeneratedAnnotation() throws IOException { + Type typeModel = new SimpleType(TypeCategory.ENTITY, "com.querydsl.DomainClass", "com.querydsl", "DomainClass", false,false); + EntityType type = new EntityType(typeModel); + + Writer writer = new StringWriter(); + ProjectionSerializer serializer = new DefaultProjectionSerializer(new JavaTypeMappings()); + serializer.serialize(type, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); + String generatedSource = writer.toString(); + assertThat(generatedSource, containsString(String.format("import %s;", GeneratedAnnotationResolver.resolveDefault().getName()))); + assertThat(generatedSource, containsString("@Generated(\"com.querydsl.codegen.DefaultProjectionSerializer\")\npublic class")); + } + + @Test + public void customGeneratedAnnotation() throws IOException { + Type typeModel = new SimpleType(TypeCategory.ENTITY, "com.querydsl.DomainClass", "com.querydsl", "DomainClass", false,false); + EntityType type = new EntityType(typeModel); + + Writer writer = new StringWriter(); + ProjectionSerializer serializer = new DefaultProjectionSerializer(new JavaTypeMappings(), Generated.class); + serializer.serialize(type, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); + String generatedSource = writer.toString(); + assertThat(generatedSource, containsString("import com.querydsl.core.annotations.Generated")); + assertThat(generatedSource, containsString("@Generated(\"com.querydsl.codegen.DefaultProjectionSerializer\")\npublic class")); + } + +} diff --git a/querydsl-codegen/src/test/java/com/mysema/query/codegen/PropertyTest.java b/querydsl-codegen/src/test/java/com/querydsl/codegen/PropertyTest.java similarity index 75% rename from querydsl-codegen/src/test/java/com/mysema/query/codegen/PropertyTest.java rename to querydsl-codegen/src/test/java/com/querydsl/codegen/PropertyTest.java index f6fc9bfd5d..5ec735a80e 100644 --- a/querydsl-codegen/src/test/java/com/mysema/query/codegen/PropertyTest.java +++ b/querydsl-codegen/src/test/java/com/querydsl/codegen/PropertyTest.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.codegen; +package com.querydsl.codegen; import static org.junit.Assert.assertEquals; @@ -19,15 +19,15 @@ import org.junit.Test; -import com.mysema.codegen.model.SimpleType; -import com.mysema.codegen.model.Type; -import com.mysema.codegen.model.TypeCategory; +import com.querydsl.codegen.utils.model.SimpleType; +import com.querydsl.codegen.utils.model.Type; +import com.querydsl.codegen.utils.model.TypeCategory; public class PropertyTest { @Test - public void Equals_And_HashCode() { - Type typeModel = new SimpleType(TypeCategory.ENTITY, "com.mysema.query.DomainClass", "com.mysema.query", "DomainClass", false,false); + public void equals_and_hashCode() { + Type typeModel = new SimpleType(TypeCategory.ENTITY, "com.querydsl.DomainClass", "com.querydsl", "DomainClass", false,false); EntityType type = new EntityType(typeModel); Property p1 = new Property(type, "property", type, Collections.emptyList()); Property p2 = new Property(type, "property", type, Collections.emptyList()); @@ -37,11 +37,11 @@ public void Equals_And_HashCode() { } @Test - public void EscapedName() { - Type typeModel = new SimpleType(TypeCategory.ENTITY, "com.mysema.query.DomainClass", "com.mysema.query", "DomainClass", false,false); + public void escapedName() { + Type typeModel = new SimpleType(TypeCategory.ENTITY, "com.querydsl.DomainClass", "com.querydsl", "DomainClass", false,false); EntityType type = new EntityType(typeModel); Property property = new Property(type, "boolean", type, Collections.emptyList()); assertEquals("boolean$", property.getEscapedName()); } - + } diff --git a/querydsl-codegen/src/test/java/com/querydsl/codegen/QueryEmbeddable2Test.java b/querydsl-codegen/src/test/java/com/querydsl/codegen/QueryEmbeddable2Test.java new file mode 100644 index 0000000000..bbe35c3973 --- /dev/null +++ b/querydsl-codegen/src/test/java/com/querydsl/codegen/QueryEmbeddable2Test.java @@ -0,0 +1,31 @@ +package com.querydsl.codegen; + +import com.querydsl.core.annotations.QueryEmbeddable; +import com.querydsl.core.annotations.QueryEntity; + +public class QueryEmbeddable2Test extends AbstractExporterTest { + + @QueryEntity + public static class User { + + Complex complex; + + } + + @QueryEmbeddable + public static class Complex> implements Comparable> { + + T a; + + @Override + public int compareTo(Complex arg0) { + return 0; + } + + public boolean equals(Object o) { + return o == this; + } + + } + +} \ No newline at end of file diff --git a/querydsl-codegen/src/test/java/com/mysema/query/codegen/QueryEntityImpl.java b/querydsl-codegen/src/test/java/com/querydsl/codegen/QueryEntityImpl.java similarity index 78% rename from querydsl-codegen/src/test/java/com/mysema/query/codegen/QueryEntityImpl.java rename to querydsl-codegen/src/test/java/com/querydsl/codegen/QueryEntityImpl.java index a06b2f789a..21801ad322 100644 --- a/querydsl-codegen/src/test/java/com/mysema/query/codegen/QueryEntityImpl.java +++ b/querydsl-codegen/src/test/java/com/querydsl/codegen/QueryEntityImpl.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,14 +11,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.codegen; +package com.querydsl.codegen; import java.lang.annotation.Annotation; -import com.mysema.query.annotations.QueryEntity; +import com.querydsl.core.annotations.QueryEntity; @SuppressWarnings("all") -public class QueryEntityImpl implements QueryEntity{ +public class QueryEntityImpl implements QueryEntity { @Override public Class annotationType() { diff --git a/querydsl-codegen/src/test/java/com/querydsl/codegen/QueryTypeFactoryTest.java b/querydsl-codegen/src/test/java/com/querydsl/codegen/QueryTypeFactoryTest.java new file mode 100644 index 0000000000..ae5e165426 --- /dev/null +++ b/querydsl-codegen/src/test/java/com/querydsl/codegen/QueryTypeFactoryTest.java @@ -0,0 +1,51 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.codegen; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import com.querydsl.codegen.utils.model.ClassType; +import com.querydsl.codegen.utils.model.Type; + +public class QueryTypeFactoryTest { + + private Type type = new ClassType(Point.class); + + @Test + public void prefix_only() { + QueryTypeFactory factory = new QueryTypeFactoryImpl("Q", "", ""); + assertEquals("com.querydsl.codegen.QPoint", factory.create(type).getFullName()); + } + + @Test + public void prefix_and_suffix() { + QueryTypeFactory factory = new QueryTypeFactoryImpl("Q", "Type", ""); + assertEquals("com.querydsl.codegen.QPointType", factory.create(type).getFullName()); + } + + @Test + public void suffix_only() { + QueryTypeFactory factory = new QueryTypeFactoryImpl("", "Type", ""); + assertEquals("com.querydsl.codegen.PointType", factory.create(type).getFullName()); + } + + @Test + public void prefix_and_package_suffix() { + QueryTypeFactory factory = new QueryTypeFactoryImpl("Q", "", ".query"); + assertEquals("com.querydsl.codegen.query.QPoint", factory.create(type).getFullName()); + } + +} diff --git a/querydsl-codegen/src/test/java/com/mysema/query/codegen/ScalaTypeDump.java b/querydsl-codegen/src/test/java/com/querydsl/codegen/ScalaTypeDump.java similarity index 75% rename from querydsl-codegen/src/test/java/com/mysema/query/codegen/ScalaTypeDump.java rename to querydsl-codegen/src/test/java/com/querydsl/codegen/ScalaTypeDump.java index 66cbb7bf04..002b4716ca 100644 --- a/querydsl-codegen/src/test/java/com/mysema/query/codegen/ScalaTypeDump.java +++ b/querydsl-codegen/src/test/java/com/querydsl/codegen/ScalaTypeDump.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.codegen; +package com.querydsl.codegen; import java.io.IOException; import java.io.StringWriter; @@ -22,18 +22,18 @@ import org.junit.Ignore; import org.junit.Test; -import com.mysema.codegen.ScalaWriter; -import com.mysema.codegen.model.ClassType; -import com.mysema.codegen.model.Parameter; -import com.mysema.codegen.model.Type; -import com.mysema.query.types.Expression; -import com.mysema.query.types.expr.*; +import com.querydsl.codegen.utils.ScalaWriter; +import com.querydsl.codegen.utils.model.ClassType; +import com.querydsl.codegen.utils.model.Parameter; +import com.querydsl.codegen.utils.model.Type; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.dsl.*; public class ScalaTypeDump { - + @Test @Ignore - public void test() throws IOException{ + public void test() throws IOException { List> classes = new ArrayList>(); classes.add(SimpleExpression.class); classes.add(ComparableExpression.class); @@ -45,10 +45,10 @@ public void test() throws IOException{ classes.add(DateExpression.class); classes.add(EnumExpression.class); classes.add(NumberExpression.class); - + StringWriter w = new StringWriter(); ScalaWriter writer = new ScalaWriter(w); - writer.packageDecl("com.mysema.query.scala"); + writer.packageDecl("com.querydsl.scala"); writer.imports(Expression.class.getPackage()); for (Class cl : classes) { Type type = new ClassType(cl); @@ -57,15 +57,15 @@ public void test() throws IOException{ for (Method m : cl.getDeclaredMethods()) { List params = new ArrayList(); for (Class paramType : m.getParameterTypes()) { - params.add(new Parameter("arg"+params.size(), new ClassType(paramType))); + params.add(new Parameter("arg" + params.size(), new ClassType(paramType))); } Type returnType = new ClassType(m.getReturnType()); - writer.beginPublicMethod(returnType, ":"+m.getName(), params.toArray(new Parameter[params.size()])); + writer.beginPublicMethod(returnType, ":" + m.getName(), params.toArray(new Parameter[0])); writer.end(); } writer.end(); } - + System.out.println(w); } diff --git a/querydsl-codegen/src/test/java/com/querydsl/codegen/SerializerTest.java b/querydsl-codegen/src/test/java/com/querydsl/codegen/SerializerTest.java new file mode 100644 index 0000000000..ff3d484904 --- /dev/null +++ b/querydsl-codegen/src/test/java/com/querydsl/codegen/SerializerTest.java @@ -0,0 +1,93 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.codegen; + +import java.io.IOException; +import java.io.StringWriter; +import java.io.Writer; +import java.util.*; + +import org.junit.Before; +import org.junit.Test; + +import com.querydsl.codegen.utils.JavaWriter; +import com.querydsl.codegen.utils.StringUtils; +import com.querydsl.codegen.utils.model.*; + +public class SerializerTest { + + private EntityType type; + + private Writer writer = new StringWriter(); + + private TypeMappings typeMappings = new JavaTypeMappings(); + + @SuppressWarnings("unchecked") + @Before + public void setUp() { + // type + Type typeModel = new SimpleType(TypeCategory.ENTITY, "com.querydsl.DomainClass", "com.querydsl", "DomainClass", false, false); + type = new EntityType(typeModel); + + // property + type.addProperty(new Property(type, "entityField", type)); + type.addProperty(new Property(type, "collection", new ClassType(TypeCategory.COLLECTION, Collection.class, typeModel))); + type.addProperty(new Property(type, "listField", new ClassType(TypeCategory.LIST, List.class, typeModel))); + type.addProperty(new Property(type, "setField", new ClassType(TypeCategory.SET, Set.class, typeModel))); + type.addProperty(new Property(type, "arrayField", new ClassType(TypeCategory.ARRAY, String[].class, typeModel))); + type.addProperty(new Property(type, "mapField", new ClassType(TypeCategory.MAP, List.class, typeModel, typeModel))); + type.addProperty(new Property(type, "superTypeField", new TypeExtends(new ClassType(TypeCategory.MAP, List.class, typeModel, typeModel)))); + type.addProperty(new Property(type, "extendsTypeField", new TypeSuper(new ClassType(TypeCategory.MAP, List.class, typeModel, typeModel)))); + + for (Class cl : Arrays.asList(Boolean.class, Comparable.class, Integer.class, Date.class, java.sql.Date.class, java.sql.Time.class)) { + Type classType = new ClassType(TypeCategory.get(cl.getName()), cl); + type.addProperty(new Property(type, StringUtils.uncapitalize(cl.getSimpleName()), classType)); + } + + // constructor + Parameter firstName = new Parameter("firstName", new ClassType(TypeCategory.STRING, String.class)); + Parameter lastName = new Parameter("lastName", new ClassType(TypeCategory.STRING, String.class)); + type.addConstructor(new Constructor(Arrays.asList(firstName, lastName))); + } + + @Test + public void entitySerializer() throws Exception { + new DefaultEntitySerializer(typeMappings, Collections.emptyList()) + .serialize(type, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); + } + + @Test + public void entitySerializer2() throws Exception { + new DefaultEntitySerializer(typeMappings,Collections.emptyList()) + .serialize(type, new SimpleSerializerConfig(true,true,true,true,""), new JavaWriter(writer)); + } + + @Test + public void embeddableSerializer() throws Exception { + new DefaultEmbeddableSerializer(typeMappings,Collections.emptyList()) + .serialize(type, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); + } + + @Test + public void supertypeSerializer() throws IOException { + new DefaultSupertypeSerializer(typeMappings,Collections.emptyList()) + .serialize(type, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); + } + + @Test + public void projectionSerializer() throws IOException { + new DefaultProjectionSerializer(typeMappings) + .serialize(type, SimpleSerializerConfig.DEFAULT, new JavaWriter(writer)); + } +} diff --git a/querydsl-codegen/src/test/java/com/querydsl/codegen/SomeOtherClass.java b/querydsl-codegen/src/test/java/com/querydsl/codegen/SomeOtherClass.java new file mode 100644 index 0000000000..25ec9e12ad --- /dev/null +++ b/querydsl-codegen/src/test/java/com/querydsl/codegen/SomeOtherClass.java @@ -0,0 +1,10 @@ +package com.querydsl.codegen; + +public class SomeOtherClass { + + static { + SomeOtherClass2.property = "XXX"; + } + + public String someProperty; +} diff --git a/querydsl-codegen/src/test/java/com/querydsl/codegen/SomeOtherClass2.java b/querydsl-codegen/src/test/java/com/querydsl/codegen/SomeOtherClass2.java new file mode 100644 index 0000000000..853b493910 --- /dev/null +++ b/querydsl-codegen/src/test/java/com/querydsl/codegen/SomeOtherClass2.java @@ -0,0 +1,9 @@ +package com.querydsl.codegen; + +public final class SomeOtherClass2 { + + private SomeOtherClass2() { } + + public static String property; + +} diff --git a/querydsl-codegen/src/test/java/com/mysema/query/codegen/TypeFactoryTest.java b/querydsl-codegen/src/test/java/com/querydsl/codegen/TypeFactoryTest.java similarity index 78% rename from querydsl-codegen/src/test/java/com/mysema/query/codegen/TypeFactoryTest.java rename to querydsl-codegen/src/test/java/com/querydsl/codegen/TypeFactoryTest.java index f93a8e5b89..f530c88b81 100644 --- a/querydsl-codegen/src/test/java/com/mysema/query/codegen/TypeFactoryTest.java +++ b/querydsl-codegen/src/test/java/com/querydsl/codegen/TypeFactoryTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2011, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,11 +11,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.codegen; +package com.querydsl.codegen; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.*; import java.io.Serializable; import java.lang.reflect.Field; @@ -27,13 +25,9 @@ import org.junit.Test; -import com.mysema.codegen.model.ClassType; -import com.mysema.codegen.model.Type; -import com.mysema.codegen.model.TypeCategory; -import com.mysema.codegen.model.TypeExtends; -import com.mysema.codegen.model.Types; -import com.mysema.query.DefaultQueryMetadata; -import com.mysema.query.types.Expression; +import com.querydsl.codegen.utils.model.*; +import com.querydsl.core.DefaultQueryMetadata; +import com.querydsl.core.types.Expression; public class TypeFactoryTest { @@ -45,7 +39,7 @@ public class TypeFactoryTest { List> field4; - enum EnumExample { FIRST, SECOND} + enum EnumExample { FIRST, SECOND } static class Entity { @@ -62,23 +56,22 @@ static class ComparableEntity> implements Serial private TypeFactory factory = new TypeFactory(); @Test - public void InnerClass_Field() throws SecurityException, NoSuchFieldException{ + public void innerClass_field() throws SecurityException, NoSuchFieldException { Field field = Entity.class.getDeclaredField("field"); Type type = factory.get(field.getType(), field.getGenericType()); assertEquals(1, type.getParameters().size()); - System.out.println(type.getParameters().get(0)); assertEquals(Types.OBJECT, type.getParameters().get(0)); } @Test - public void Parameters() { + public void parameters() { EntityType type = factory.getEntityType(Examples.Complex.class); assertEquals(1, type.getParameters().size()); assertEquals(TypeExtends.class, type.getParameters().get(0).getClass()); } @Test - public void Map_Field_Parameters() throws SecurityException, NoSuchFieldException { + public void map_field_parameters() throws SecurityException, NoSuchFieldException { Field field = Examples.ComplexCollections.class.getDeclaredField("map2"); Type type = factory.get(field.getType(), field.getGenericType()); assertEquals(2, type.getParameters().size()); @@ -88,28 +81,28 @@ public void Map_Field_Parameters() throws SecurityException, NoSuchFieldExceptio } @Test - public void OrderBys() throws SecurityException, NoSuchFieldException { + public void orderBys() throws SecurityException, NoSuchFieldException { Field field = Examples.OrderBys.class.getDeclaredField("orderBy"); Type type = factory.get(field.getType(), field.getGenericType()); assertEquals(1, type.getParameters().size()); } @Test - public void SubEntity() { + public void subEntity() { Type type = factory.get(Examples.SubEntity.class); assertEquals(0, type.getParameters().size()); } @Test - public void AbstractEntity_Code() throws SecurityException, NoSuchFieldException { + public void abstractEntity_code() throws SecurityException, NoSuchFieldException { Field field = EmbeddedTest.AbstractEntity.class.getDeclaredField("code"); Type type = factory.get(field.getType(), field.getGenericType()); assertTrue(type instanceof TypeExtends); - assertEquals("C", ((TypeExtends)type).getVarName()); + assertEquals("C", ((TypeExtends) type).getVarName()); } @Test - public void SimpleTypes_classList5() throws SecurityException, NoSuchFieldException { + public void simpleTypes_classList5() throws SecurityException, NoSuchFieldException { Field field = Examples.SimpleTypes.class.getDeclaredField("classList5"); Type type = factory.get(field.getType(), field.getGenericType()); assertEquals(TypeCategory.LIST, type.getCategory()); @@ -119,7 +112,7 @@ public void SimpleTypes_classList5() throws SecurityException, NoSuchFieldExcept } @Test - public void Collection_Of_Collection() throws SecurityException, NoSuchFieldException { + public void collection_of_collection() throws SecurityException, NoSuchFieldException { Field field = Examples.GenericRelations.class.getDeclaredField("col3"); Type type = factory.get(field.getType(), field.getGenericType()); assertEquals(1, type.getParameters().size()); @@ -128,7 +121,7 @@ public void Collection_Of_Collection() throws SecurityException, NoSuchFieldExce } @Test - public void Generics_WildCard() throws SecurityException, NoSuchFieldException{ + public void generics_wildCard() throws SecurityException, NoSuchFieldException { Field field = getClass().getDeclaredField("field"); Type type = factory.get(field.getType(), field.getGenericType()); assertEquals(1, type.getParameters().size()); @@ -137,7 +130,7 @@ public void Generics_WildCard() throws SecurityException, NoSuchFieldException{ } @Test - public void Generics_Object() throws SecurityException, NoSuchFieldException{ + public void generics_object() throws SecurityException, NoSuchFieldException { Field field = getClass().getDeclaredField("field2"); Type type = factory.get(field.getType(), field.getGenericType()); assertEquals(1, type.getParameters().size()); @@ -145,7 +138,7 @@ public void Generics_Object() throws SecurityException, NoSuchFieldException{ } @Test - public void Generics_TypeVariable() { + public void generics_typeVariable() { Type type = factory.getEntityType(Generic2Test.AbstractCollectionAttribute.class); assertEquals(TypeExtends.class, type.getParameters().get(0).getClass()); TypeExtends t = (TypeExtends) type.getParameters().get(0); @@ -153,7 +146,7 @@ public void Generics_TypeVariable() { } @Test - public void Generics_Wildcard() throws SecurityException, NoSuchFieldException { + public void generics_wildcard() throws SecurityException, NoSuchFieldException { Field field = DefaultQueryMetadata.class.getDeclaredField("exprInJoins"); Type type = factory.get(field.getType(), field.getGenericType()); assertEquals(TypeCategory.SET, type.getCategory()); @@ -161,21 +154,21 @@ public void Generics_Wildcard() throws SecurityException, NoSuchFieldException { assertEquals(Expression.class, parameter.getJavaClass()); parameter = parameter.getParameters().get(0); assertEquals(TypeExtends.class, parameter.getClass()); - assertNull(((TypeExtends)parameter).getVarName()); + assertNull(((TypeExtends) parameter).getVarName()); } @Test - public void ComparableEntity() { + public void comparableEntity() { Type type = factory.getEntityType(ComparableEntity.class); //ComparableEntity> implements Serializable assertEquals(1, type.getParameters().size()); - TypeExtends t = (TypeExtends)type.getParameters().get(0); + TypeExtends t = (TypeExtends) type.getParameters().get(0); assertEquals("T", t.getVarName()); assertEquals(1, t.getParameters().size()); } @Test - public void RawField() throws SecurityException, NoSuchFieldException{ + public void rawField() throws SecurityException, NoSuchFieldException { Field field = getClass().getDeclaredField("field3"); Type type = factory.get(field.getType(), field.getGenericType()); assertEquals(1, type.getParameters().size()); @@ -183,7 +176,7 @@ public void RawField() throws SecurityException, NoSuchFieldException{ } @Test - public void Extends() throws SecurityException, NoSuchFieldException{ + public void extends_() throws SecurityException, NoSuchFieldException { Field field = getClass().getDeclaredField("field4"); Type type = factory.get(field.getType(), field.getGenericType()); assertEquals(1, type.getParameters().size()); @@ -191,13 +184,13 @@ public void Extends() throws SecurityException, NoSuchFieldException{ } @Test - public void ClassName() { + public void className() { Type type = factory.get(EnumExample.class); - assertEquals("com.mysema.query.codegen.TypeFactoryTest.EnumExample", type.getFullName()); + assertEquals("com.querydsl.codegen.TypeFactoryTest.EnumExample", type.getFullName()); } @Test - public void Blob() { + public void blob() { Type blob = factory.get(Blob.class); assertEquals("Blob", blob.getSimpleName()); assertEquals("java.sql.Blob", blob.getFullName()); @@ -205,7 +198,7 @@ public void Blob() { } @Test - public void Boolean() { + public void boolean_() { Type bo = factory.get(boolean.class); assertEquals(TypeCategory.BOOLEAN, bo.getCategory()); assertEquals("Boolean", bo.getSimpleName()); @@ -214,26 +207,26 @@ public void Boolean() { } @Test - public void SimpleType() { + public void simpleType() { for (Class cl : Arrays.>asList(Blob.class, Clob.class, Locale.class, Class.class, Serializable.class)) { assertEquals("wrong type for " + cl.getName(), TypeCategory.SIMPLE, factory.get(cl).getCategory()); } } @Test - public void NumberType() { + public void numberType() { for (Class cl : Arrays.>asList(Byte.class, Integer.class)) { assertEquals("wrong type for " + cl.getName(), TypeCategory.NUMERIC, factory.get(cl).getCategory()); } } @Test - public void EnumType() { + public void enumType() { assertEquals(TypeCategory.ENUM, factory.get(EnumExample.class).getCategory()); } @Test - public void UnknownAsEntity() { + public void unknownAsEntity() { assertEquals(TypeCategory.SIMPLE, factory.get(TypeFactoryTest.class).getCategory()); factory = new TypeFactory(); @@ -242,7 +235,7 @@ public void UnknownAsEntity() { } @Test - public void ArrayType() { + public void arrayType() { assertEquals(Types.BYTE.asArrayType(), factory.get(Byte[].class)); assertEquals(Types.BYTE_P.asArrayType(), factory.get(byte[].class)); } diff --git a/querydsl-codegen/src/test/java/com/querydsl/codegen/TypeMappingsTest.java b/querydsl-codegen/src/test/java/com/querydsl/codegen/TypeMappingsTest.java new file mode 100644 index 0000000000..a73d6db8cc --- /dev/null +++ b/querydsl-codegen/src/test/java/com/querydsl/codegen/TypeMappingsTest.java @@ -0,0 +1,67 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.codegen; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import com.querydsl.codegen.utils.model.SimpleType; +import org.junit.Test; + +import com.querydsl.codegen.utils.model.ClassType; +import com.querydsl.codegen.utils.model.Type; + +import java.util.Collections; +import java.util.List; + +public class TypeMappingsTest { + + static class Entity { } + + @Test + public void getPathType_of_innerClass() { + TypeMappings typeMappings = new JavaTypeMappings(); + EntityType model = new EntityType(new ClassType(TypeMappingsTest.class)); + EntityType type = new EntityType(new ClassType(Entity.class)); + typeMappings.register(type, new QueryTypeFactoryImpl("Q","","").create(type)); + + Type pathType = typeMappings.getPathType(type, model, false); + assertEquals("QTypeMappingsTest_Entity", pathType.getSimpleName()); + } + + @Test + public void isRegistered() { + TypeMappings typeMappings = new JavaTypeMappings(); + typeMappings.register(new ClassType(Double[].class), new ClassType(Point.class)); + assertTrue(typeMappings.isRegistered(new ClassType(Double[].class))); + } + + @Test + public void testGenericTypeRegistration() { + SimpleType rawListType = new SimpleType(List.class.getName()); + SimpleType integerListType = new SimpleType(rawListType, Collections. singletonList(new SimpleType(Integer.class.getName()))); + SimpleType longListType = new SimpleType(rawListType, Collections. singletonList(new SimpleType(Long.class.getName()))); + + SimpleType integerListTypeExpression = new SimpleType("integerListTypeExpression"); + SimpleType longListTypeExpression = new SimpleType("longListTypeExpression"); + + TypeMappings typeMappings = new JavaTypeMappings(); + typeMappings.register(integerListType, integerListTypeExpression); + typeMappings.register(longListType, longListTypeExpression); + + assertEquals(integerListTypeExpression, typeMappings.getExprType(integerListType, null, false)); + assertEquals(longListTypeExpression, typeMappings.getExprType(longListType, null, false)); + } + +} diff --git a/querydsl-codegen/src/test/java/com/querydsl/codegen/TypeResolverTest.java b/querydsl-codegen/src/test/java/com/querydsl/codegen/TypeResolverTest.java new file mode 100644 index 0000000000..4f03ecc203 --- /dev/null +++ b/querydsl-codegen/src/test/java/com/querydsl/codegen/TypeResolverTest.java @@ -0,0 +1,7 @@ +package com.querydsl.codegen; + +public class TypeResolverTest { + + // generic parameter + +} diff --git a/querydsl-codegen/src/test/java/com/querydsl/codegen/sub/ExampleEntity2.java b/querydsl-codegen/src/test/java/com/querydsl/codegen/sub/ExampleEntity2.java new file mode 100644 index 0000000000..a9d66276f3 --- /dev/null +++ b/querydsl-codegen/src/test/java/com/querydsl/codegen/sub/ExampleEntity2.java @@ -0,0 +1,31 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.codegen.sub; + +import com.querydsl.core.annotations.QueryEntity; + +@QueryEntity +public class ExampleEntity2 { + + private int id; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + +} diff --git a/querydsl-codegen/src/test/java/com/suntanning/ShouldBeLoaded.java b/querydsl-codegen/src/test/java/com/suntanning/ShouldBeLoaded.java new file mode 100644 index 0000000000..91114f6b82 --- /dev/null +++ b/querydsl-codegen/src/test/java/com/suntanning/ShouldBeLoaded.java @@ -0,0 +1,4 @@ +package com.suntanning; + +public class ShouldBeLoaded { +} diff --git a/querydsl-codegen/template.mf b/querydsl-codegen/template.mf deleted file mode 100644 index 2aec995362..0000000000 --- a/querydsl-codegen/template.mf +++ /dev/null @@ -1,13 +0,0 @@ -Bundle-SymbolicName: com.mysema.querydsl.codegen -Bundle-Name: Querydsl Codegen -Bundle-Vendor: Mysema -Bundle-ManifestVersion: 2 -Import-Template: - com.mysema.codegen.*;version="${codegen.version}";resolution:=optional, - com.mysema.commons.lang.*;version="${mysema.lang.version}", - com.mysema.query.*;version="${project.version}", - com.mysema.util.*;version="${project.version}", - javax.annotation.*;version="0", - javax.inject.*;version="0", - net.sf.cglib.proxy.*;version="${cglib.version}", - com.google.common.*;version="${guava.version}" \ No newline at end of file diff --git a/querydsl-collections/README.md b/querydsl-collections/README.md index f12e0192e2..6a757e759d 100644 --- a/querydsl-collections/README.md +++ b/querydsl-collections/README.md @@ -6,55 +6,63 @@ The Collections module provides integration with Java Collections and Beans. Add the following dependencies to your Maven project : - - com.mysema.querydsl - querydsl-apt - ${querydsl.version} - provided - - - - com.mysema.querydsl - querydsl-collections - ${querydsl.version} - - - - org.slf4j - slf4j-log4j12 - 1.6.1 - - -If you are not using JPA or JDO you can generate Querydsl query types for your domain types by annotating them with the com.mysema.query.annotations.QueryEntity annotation and adding the following plugin configuration into your Maven configuration (pom.xml) : - - - com.mysema.maven - apt-maven-plugin - 1.0.6 - - - - process - - - target/generated-sources/java - com.mysema.query.apt.QuerydslAnnotationProcessor - - - - - +```XML + + com.querydsl + querydsl-apt + ${querydsl.version} + provided + + + com.querydsl + querydsl-collections + ${querydsl.version} + +``` + +If you are not using JPA or JDO you can generate Querydsl query types for your domain types by annotating them with the com.querydsl.core.annotations.QueryEntity annotation and adding the following plugin configuration into your Maven configuration (pom.xml) : + +```XML + + + + ... + + com.mysema.maven + apt-maven-plugin + 1.1.3 + + + + process + + + target/generated-sources/java + com.querydsl.apt.QuerydslAnnotationProcessor + + + + + ... + + + +``` + **Querying** Querying with Querydsl Collections is as simple as this : - import static com.mysema.query.collections.CollQueryFactory.*; - - QCat cat = new QCat("cat"); - for (String name : from(cat,cats) - .where(cat.kittens.size().gt(0)) - .list(cat.name)){ - System.out.println(name); - } +```JAVA +import static com.querydsl.collections.CollQueryFactory.*; + +QCat cat = new QCat("cat"); +for (String name : from(cat,cats) + .select(cat.name) + .where(cat.kittens.size().gt(0)) + .fetch()){ + System.out.println(name); +} +``` -For more information on the Querydsl Collections module visit the reference documentation http://www.querydsl.com/static/querydsl/latest/reference/html/ch02s07.html \ No newline at end of file +For more information on the Querydsl Collections module visit the reference documentation http://www.querydsl.com/static/querydsl/latest/reference/html/ch02s08.html diff --git a/querydsl-collections/doc/perf-20090313.txt b/querydsl-collections/doc/perf-20090313.txt deleted file mode 100644 index 4721d154a0..0000000000 --- a/querydsl-collections/doc/perf-20090313.txt +++ /dev/null @@ -1,50 +0,0 @@ - #1 order preserved cat.ne(otherCat), - #2 order preserved cat.eq(otherCat), - #3 order preserved cat.name.eq(otherCat.name), - #4 inverted cat.name.ne(otherCat.name).and(otherCat.name.eq("Kate5")), - #5 inverted cat.name.ne(otherCat.name).or(otherCat.name.eq("Kate5")), - #6 order preserved cat.bodyWeight.eq(0).and(otherCat.name.eq("Kate5")), - #7 order preserved cat.bodyWeight.eq(0).or(otherCat.name.eq("Kate5")), - #8 inverted cat.name.ne(otherCat.name).and(otherCat.name.like("Kate5%")), - #9 inverted cat.name.ne(otherCat.name).or(otherCat.name.like("Kate5%")), -#10 order preserved cat.name.like("Bob5%").and(otherCat.name.like("Kate5%")), -#11 order preserved cat.name.like("Bob5%").or(otherCat.name.like("Kate5%")) - -100 * 100 items - #1 19 ms 17 ms 20 ms 17 ms - #2 8 ms 3 ms 2 ms 3 ms - #3 9 ms 3 ms 3 ms 4 ms - #4 8 ms 9 ms 5 ms 8 ms - #5 14 ms 19 ms 21 ms 18 ms - #6 10 ms 8 ms 9 ms 8 ms - #7 12 ms 18 ms 19 ms 20 ms - #8 11 ms 10 ms 8 ms 6 ms - #9 12 ms 20 ms 19 ms 21 ms -#10 10 ms 6 ms 4 ms 6 ms -#11 10 ms 18 ms 17 ms 19 ms - -500 * 500 items - #1 225 ms 282 ms 281 ms 284 ms - #2 157 ms 2 ms 2 ms 4 ms - #3 161 ms 4 ms 2 ms 4 ms - #4 169 ms 84 ms 5 ms 8 ms - #5 241 ms 311 ms 305 ms 305 ms - #6 166 ms 82 ms 81 ms 84 ms - #7 238 ms 309 ms 312 ms 314 ms - #8 173 ms 94 ms 15 ms 16 ms - #9 235 ms 308 ms 306 ms 302 ms -#10 163 ms 10 ms 5 ms 10 ms -#11 185 ms 258 ms 259 ms 262 ms - -1000 * 1000 items - #1 882 ms 1108 ms 1109 ms 1107 ms - #2 623 ms 3 ms 2 ms 3 ms - #3 619 ms 3 ms 4 ms 5 ms - #4 658 ms 307 ms 9 ms 5 ms - #5 946 ms 1238 ms 1233 ms 1218 ms - #6 664 ms 301 ms 302 ms 302 ms - #7 921 ms 1196 ms 1206 ms 1194 ms - #8 688 ms 423 ms 145 ms 152 ms - #9 926 ms 1195 ms 1186 ms 1196 ms -#10 658 ms 55 ms 53 ms 55 ms -#11 768 ms 1047 ms 1050 ms 1052 ms diff --git a/querydsl-collections/doc/perf-20090315.txt b/querydsl-collections/doc/perf-20090315.txt deleted file mode 100644 index 8e273b8a9a..0000000000 --- a/querydsl-collections/doc/perf-20090315.txt +++ /dev/null @@ -1,58 +0,0 @@ -#1 order preserved !cat.equals(otherCat) -#2 order preserved cat.equals(otherCat) -#3 order preserved cat.getName().equals(otherCat.getName()) -#4 inverted cat.getName().equals(otherCat.getName()) && otherCat.getName().equals(a1) -#5 inverted !cat.getName().equals(otherCat.getName()) && otherCat.getName().equals(a1) -#6 inverted !cat.getName().equals(otherCat.getName()) || otherCat.getName().equals(a1) -#7 order preserved cat.getBodyWeight() == a1 && otherCat.getName().equals(a2) -#8 order preserved cat.getBodyWeight() == a1 || otherCat.getName().equals(a2) -#9 inverted !cat.getName().equals(otherCat.getName()) && otherCat.getName().startsWith(a1, 0) -#10 inverted !cat.getName().equals(otherCat.getName()) || otherCat.getName().endsWith(a1) -#11 order preserved cat.getName().startsWith(a1, 0) && otherCat.getName().startsWith(a2, 0) -#12 order preserved cat.getName().startsWith(a1, 0) || otherCat.getName().endsWith(a2) - - - filtered filtered filtered - sorted sorted - indexed -100 * 100 items - #1 20 ms 23 ms 21 ms 21 ms - #2 9 ms 5 ms 9 ms 4 ms - #3 11 ms 10 ms 10 ms 8 ms - #4 12 ms 9 ms 8 ms 8 ms - #5 12 ms 11 ms 7 ms 6 ms - #6 15 ms 20 ms 26 ms 24 ms - #7 12 ms 11 ms 11 ms 11 ms - #8 15 ms 22 ms 24 ms 24 ms - #9 12 ms 10 ms 6 ms 5 ms - #10 16 ms 23 ms 24 ms 21 ms - #11 13 ms 5 ms 5 ms 4 ms - #12 12 ms 19 ms 22 ms 20 ms - -500 * 500 items - #1 250 ms 325 ms 328 ms 325 ms - #2 170 ms 81 ms 81 ms 5 ms - #3 172 ms 86 ms 88 ms 8 ms - #4 179 ms 100 ms 5 ms 7 ms - #5 186 ms 103 ms 7 ms 6 ms - #6 260 ms 351 ms 349 ms 347 ms - #7 181 ms 97 ms 98 ms 99 ms - #8 257 ms 350 ms 351 ms 348 ms - #9 192 ms 113 ms 17 ms 15 ms - #10 258 ms 352 ms 350 ms 348 ms - #11 182 ms 6 ms 10 ms 9 ms - #12 190 ms 285 ms 284 ms 282 ms - -1000 * 1000 items - #1 965 ms 1273 ms 1276 ms 1275 ms - #2 663 ms 306 ms 306 ms 4 ms - #3 657 ms 332 ms 328 ms 13 ms - #4 696 ms 370 ms 5 ms 11 ms TODO : add constant based index - #5 720 ms 388 ms 9 ms 8 ms TODO : add constant based index - #6 1014 ms 1391 ms 1358 ms 1361 ms - #7 699 ms 367 ms 366 ms 365 ms TODO : add constant based index - #8 1031 ms 1396 ms 1412 ms 1407 ms - #9 729 ms 416 ms 25 ms 27 ms TODO : tree based index - #10 1014 ms 1392 ms 1358 ms 1356 ms - #11 698 ms 12 ms 12 ms 14 ms TODO : tree based index - #12 739 ms 1091 ms 1094 ms 1098 ms \ No newline at end of file diff --git a/querydsl-collections/doc/perf-20090316.txt b/querydsl-collections/doc/perf-20090316.txt deleted file mode 100644 index 7970de2ff0..0000000000 --- a/querydsl-collections/doc/perf-20090316.txt +++ /dev/null @@ -1,82 +0,0 @@ -#1 order preserved !cat.equals(otherCat) -#2 order preserved cat.equals(otherCat) -#3 order preserved cat.getName().equals(otherCat.getName()) -#4 inverted cat.getName().equals(otherCat.getName()) && otherCat.getName().equals(a1) -#5 inverted !(cat.getName().equals(otherCat.getName())) && otherCat.getName().equals(a1) -#6 inverted cat.getName().equals(otherCat.getName()) && !(otherCat.getName().equals(a1)) -#7 inverted !cat.getName().equals(otherCat.getName()) && otherCat.getName().equals(a1) -#8 inverted !cat.getName().equals(otherCat.getName()) && otherCat.getName().startsWith(a1, 0) -#9 order preserved cat.getBodyWeight() == a1 && otherCat.getName().equals(a2) -#10 order preserved cat.getName().startsWith(a1, 0) && otherCat.getName().startsWith(a2, 0) -#11 inverted cat.getName().equals(otherCat.getName()) || otherCat.getName().equals(a1) -#12 inverted cat.getName().equals(otherCat.getName()) || !(otherCat.getName().equals(a1)) -#13 inverted !cat.getName().equals(otherCat.getName()) || otherCat.getName().equals(a1) -#14 inverted !cat.getName().equals(otherCat.getName()) || otherCat.getName().endsWith(a1) -#15 order preserved cat.getBodyWeight() == a1 || otherCat.getName().equals(a2) -#16 order preserved !(cat.getBodyWeight() == a1) || otherCat.getName().equals(a2) -#17 order preserved cat.getBodyWeight() == a1 || !(otherCat.getName().equals(a2)) -#18 order preserved cat.getName().startsWith(a1, 0) || otherCat.getName().endsWith(a2) - - filtered filtered filtered - sorted sorted - indexed -100 * 100 items - #1 18 ms 19 ms 18 ms 19 ms - #2 7 ms 8 ms 4 ms 4 ms - #3 11 ms 8 ms 9 ms 5 ms - #4 10 ms 9 ms 4 ms 8 ms - #5 10 ms 9 ms 6 ms 7 ms - #6 10 ms 9 ms 9 ms 9 ms - #7 9 ms 13 ms 2 ms 7 ms - #8 14 ms 5 ms 10 ms 2 ms - #9 10 ms 9 ms 9 ms 9 ms - #10 10 ms 5 ms 3 ms 5 ms - #11 10 ms 9 ms 18 ms 18 ms - #12 13 ms 22 ms 20 ms 21 ms - #13 15 ms 19 ms 18 ms 21 ms - #14 12 ms 19 ms 22 ms 20 ms - #15 11 ms 20 ms 20 ms 21 ms - #16 10 ms 18 ms 16 ms 16 ms - #17 12 ms 22 ms 22 ms 20 ms - #18 11 ms 17 ms 17 ms 16 ms - -500 * 500 items - #1 226 ms 296 ms 298 ms 297 ms - #2 155 ms 76 ms 75 ms 4 ms - #3 161 ms 82 ms 83 ms 7 ms - #4 162 ms 92 ms 3 ms 10 ms - #5 172 ms 98 ms 5 ms 7 ms - #6 164 ms 92 ms 81 ms 10 ms - #7 167 ms 93 ms 6 ms 7 ms - #8 171 ms 103 ms 14 ms 16 ms - #9 162 ms 93 ms 91 ms 9 ms - #10 165 ms 8 ms 8 ms 8 ms - #11 169 ms 96 ms 252 ms 252 ms - #12 239 ms 332 ms 321 ms 320 ms - #13 234 ms 322 ms 317 ms 315 ms - #14 238 ms 332 ms 326 ms 321 ms - #15 237 ms 324 ms 323 ms 324 ms - #16 165 ms 245 ms 250 ms 246 ms - #17 235 ms 316 ms 315 ms 316 ms - #18 171 ms 256 ms 256 ms 257 ms - -1000 * 1000 items - #1 874 ms 1162 ms 1155 ms 1161 ms - #2 615 ms 285 ms 286 ms 3 ms - #3 607 ms 308 ms 308 ms 10 ms - #4 646 ms 338 ms 7 ms 7 ms - #5 648 ms 352 ms 9 ms 6 ms - #6 632 ms 339 ms 303 ms 14 ms - #7 645 ms 353 ms 6 ms 9 ms - #8 665 ms 379 ms 21 ms 25 ms - #9 646 ms 335 ms 333 ms 11 ms - #10 643 ms 11 ms 12 ms 10 ms - #11 661 ms 358 ms 977 ms 972 ms UNION used - #12 952 ms 1318 ms 1268 ms 1277 ms UNION used - #13 939 ms 1290 ms 1268 ms 1265 ms UNION used - #14 939 ms 1302 ms 1269 ms 1269 ms UNION used - #15 925 ms 1245 ms 1248 ms 1245 ms UNION used - #16 637 ms 964 ms 963 ms 970 ms UNION used - #17 917 ms 1242 ms 1240 ms 1246 ms UNION used - #18 665 ms 1001 ms 999 ms 1000 ms UNION used - \ No newline at end of file diff --git a/querydsl-collections/doc/perf-20090317-2.txt b/querydsl-collections/doc/perf-20090317-2.txt deleted file mode 100644 index 9d0ad78cf6..0000000000 --- a/querydsl-collections/doc/perf-20090317-2.txt +++ /dev/null @@ -1,87 +0,0 @@ -#1 order preserved !cat.equals(otherCat) -#2 order preserved cat.equals(otherCat) -#3 order preserved cat.getName().equals(otherCat.getName()) - -#4 inverted cat.getName().equals(otherCat.getName()) && otherCat.getName().equals(a1) -#5 inverted !(cat.getName().equals(otherCat.getName())) && otherCat.getName().equals(a1) -#6 inverted cat.getName().equals(otherCat.getName()) && !(otherCat.getName().equals(a1)) -#7 inverted !cat.getName().equals(otherCat.getName()) && otherCat.getName().equals(a1) -#8 inverted !cat.getName().equals(otherCat.getName()) && otherCat.getName().startsWith(a1, 0) -#9 order preserved cat.getBodyWeight() == a1 && otherCat.getName().equals(a2) -#10 order preserved cat.getName().startsWith(a1, 0) && otherCat.getName().startsWith(a2, 0) - -#11 inverted cat.getName().equals(otherCat.getName()) || otherCat.getName().equals(a1) -#12 inverted cat.getName().equals(otherCat.getName()) || !(otherCat.getName().equals(a1)) -#13 inverted !cat.getName().equals(otherCat.getName()) || otherCat.getName().equals(a1) -#14 inverted !cat.getName().equals(otherCat.getName()) || otherCat.getName().endsWith(a1) -#15 order preserved cat.getBodyWeight() == a1 || otherCat.getName().equals(a2) -#16 order preserved !(cat.getBodyWeight() == a1) || otherCat.getName().equals(a2) -#17 order preserved cat.getBodyWeight() == a1 || !(otherCat.getName().equals(a2)) -#18 order preserved cat.getName().startsWith(a1, 0) || otherCat.getName().endsWith(a2) - - filtered filtered filtered filtered - sorted sorted sorted - indexed indexed - serial union - - #1 18 ms 17 ms 17 ms 19 ms 17 ms - #2 8 ms 7 ms 5 ms 4 ms 4 ms - #3 9 ms 9 ms 8 ms 6 ms 5 ms - #4 11 ms 8 ms 5 ms 7 ms 7 ms - #5 10 ms 11 ms 5 ms 5 ms 6 ms - #6 11 ms 9 ms 13 ms 6 ms 8 ms - #7 10 ms 10 ms 5 ms 6 ms 6 ms - #8 11 ms 9 ms 5 ms 5 ms 5 ms - #9 11 ms 11 ms 7 ms 10 ms 5 ms - #10 10 ms 5 ms 3 ms 5 ms 3 ms - #11 12 ms 8 ms 19 ms 17 ms 10 ms - #12 12 ms 23 ms 21 ms 21 ms 28 ms - #13 16 ms 23 ms 24 ms 26 ms 32 ms - #14 15 ms 21 ms 24 ms 24 ms 25 ms - #15 15 ms 21 ms 21 ms 21 ms 22 ms - #16 10 ms 20 ms 17 ms 18 ms 12 ms - #17 14 ms 22 ms 20 ms 23 ms 22 ms - #18 11 ms 19 ms 19 ms 18 ms 14 ms - -500 * 500 items - #1 246 ms 320 ms 322 ms 322 ms 321 ms - #2 164 ms 81 ms 81 ms 4 ms 4 ms - #3 166 ms 89 ms 91 ms 6 ms 8 ms - #4 178 ms 101 ms 6 ms 6 ms 8 ms - #5 180 ms 106 ms 6 ms 9 ms 8 ms - #6 177 ms 101 ms 91 ms 11 ms 10 ms - #7 182 ms 102 ms 6 ms 9 ms 7 ms - #8 185 ms 111 ms 16 ms 16 ms 15 ms - #9 179 ms 97 ms 98 ms 9 ms 12 ms - #10 180 ms 8 ms 9 ms 8 ms 10 ms - #11 178 ms 103 ms 271 ms 266 ms 16 ms - #12 264 ms 363 ms 350 ms 354 ms 385 ms - #13 259 ms 352 ms 345 ms 346 ms 366 ms - #14 262 ms 354 ms 340 ms 343 ms 358 ms - #15 241 ms 326 ms 325 ms 330 ms 264 ms - #16 167 ms 252 ms 252 ms 254 ms 12 ms - #17 237 ms 322 ms 322 ms 327 ms 262 ms - #18 173 ms 258 ms 258 ms 262 ms 97 ms - -1000 * 1000 items - #1 915 ms 1191 ms 1209 ms 1192 ms 1182 ms - #2 601 ms 287 ms 299 ms 4 ms 4 ms - #3 606 ms 310 ms 322 ms 9 ms 10 ms - - #4 641 ms 348 ms 4 ms 12 ms 8 ms - #5 647 ms 360 ms 8 ms 8 ms 10 ms - #6 639 ms 345 ms 321 ms 11 ms 14 ms - #7 644 ms 354 ms 8 ms 9 ms 11 ms - #8 651 ms 385 ms 21 ms 26 ms 24 ms - #9 651 ms 342 ms 354 ms 11 ms 12 ms - #10 659 ms 10 ms 14 ms 13 ms 10 ms - - #11 650 ms 354 ms 972 ms 948 ms 20 ms - #12 963 ms 1306 ms 1283 ms 1263 ms 1366 ms PENALTY! - #13 958 ms 1296 ms 1285 ms 1262 ms 1322 ms PENALTY! - #14 960 ms 1295 ms 1290 ms 1265 ms 1324 ms PENALTY! - #15 986 ms 1334 ms 1350 ms 1338 ms 1073 ms - #16 694 ms 1039 ms 1058 ms 1037 ms 17 ms - #17 1020 ms 1365 ms 1391 ms 1370 ms 1091 ms - #18 734 ms 1074 ms 1101 ms 1081 ms 380 ms - diff --git a/querydsl-collections/doc/perf-20090317.txt b/querydsl-collections/doc/perf-20090317.txt deleted file mode 100644 index 8f267b341a..0000000000 --- a/querydsl-collections/doc/perf-20090317.txt +++ /dev/null @@ -1,85 +0,0 @@ -#1 order preserved !cat.equals(otherCat) -#2 order preserved cat.equals(otherCat) -#3 order preserved cat.getName().equals(otherCat.getName()) - -#4 inverted cat.getName().equals(otherCat.getName()) && otherCat.getName().equals(a1) -#5 inverted !(cat.getName().equals(otherCat.getName())) && otherCat.getName().equals(a1) -#6 inverted cat.getName().equals(otherCat.getName()) && !(otherCat.getName().equals(a1)) -#7 inverted !cat.getName().equals(otherCat.getName()) && otherCat.getName().equals(a1) -#8 inverted !cat.getName().equals(otherCat.getName()) && otherCat.getName().startsWith(a1, 0) -#9 order preserved cat.getBodyWeight() == a1 && otherCat.getName().equals(a2) -#10 order preserved cat.getName().startsWith(a1, 0) && otherCat.getName().startsWith(a2, 0) - -#11 inverted cat.getName().equals(otherCat.getName()) || otherCat.getName().equals(a1) -#12 inverted cat.getName().equals(otherCat.getName()) || !(otherCat.getName().equals(a1)) -#13 inverted !cat.getName().equals(otherCat.getName()) || otherCat.getName().equals(a1) -#14 inverted !cat.getName().equals(otherCat.getName()) || otherCat.getName().endsWith(a1) -#15 order preserved cat.getBodyWeight() == a1 || otherCat.getName().equals(a2) -#16 order preserved !(cat.getBodyWeight() == a1) || otherCat.getName().equals(a2) -#17 order preserved cat.getBodyWeight() == a1 || !(otherCat.getName().equals(a2)) -#18 order preserved cat.getName().startsWith(a1, 0) || otherCat.getName().endsWith(a2) - - filtered filtered filtered filtered - sorted sorted sorted - indexed indexed - union optimized - - #1 19 ms 17 ms 16 ms 17 ms 18 ms - #2 7 ms 6 ms 5 ms 4 ms 3 ms - #3 8 ms 9 ms 6 ms 8 ms 4 ms - #4 9 ms 10 ms 4 ms 7 ms 7 ms - #5 10 ms 10 ms 6 ms 5 ms 6 ms - #6 10 ms 9 ms 10 ms 7 ms 7 ms - #7 9 ms 10 ms 5 ms 5 ms 6 ms - #8 11 ms 9 ms 5 ms 5 ms 5 ms - #9 9 ms 10 ms 10 ms 7 ms 7 ms - #10 8 ms 6 ms 5 ms 4 ms 5 ms - #11 10 ms 8 ms 17 ms 19 ms 20 ms - #12 13 ms 23 ms 22 ms 21 ms 36 ms - #13 13 ms 19 ms 21 ms 19 ms 33 ms - #14 13 ms 20 ms 20 ms 21 ms 31 ms - #15 12 ms 20 ms 21 ms 19 ms 32 ms - #16 11 ms 17 ms 18 ms 17 ms 16 ms - #17 12 ms 21 ms 20 ms 21 ms 33 ms - #18 11 ms 18 ms 17 ms 17 ms 19 ms - -500 * 500 items - #1 224 ms 295 ms 298 ms 297 ms 296 ms - #2 151 ms 75 ms 73 ms 4 ms 3 ms - #3 151 ms 84 ms 80 ms 6 ms 8 ms - #4 164 ms 94 ms 4 ms 8 ms 9 ms - #5 172 ms 98 ms 7 ms 7 ms 6 ms - #6 164 ms 93 ms 84 ms 9 ms 9 ms - #7 167 ms 100 ms 3 ms 7 ms 7 ms - #8 169 ms 106 ms 14 ms 15 ms 14 ms - #9 164 ms 93 ms 92 ms 8 ms 10 ms - #10 164 ms 7 ms 9 ms 9 ms 8 ms - #11 172 ms 98 ms 249 ms 247 ms 21 ms - #12 238 ms 335 ms 318 ms 319 ms 365 ms - #13 237 ms 325 ms 318 ms 316 ms 368 ms - #14 238 ms 328 ms 328 ms 320 ms 362 ms - #15 239 ms 324 ms 324 ms 322 ms 371 ms - #16 172 ms 258 ms 257 ms 256 ms 17 ms - #17 235 ms 317 ms 320 ms 318 ms 365 ms - #18 170 ms 253 ms 258 ms 254 ms 113 ms - -1000 * 1000 items - #1 897 ms 1173 ms 1190 ms 1165 ms 1169 ms - #2 586 ms 282 ms 291 ms 6 ms 3 ms - #3 591 ms 304 ms 315 ms 9 ms 10 ms - #4 629 ms 342 ms 3 ms 9 ms 9 ms - #5 639 ms 354 ms 7 ms 8 ms 10 ms - #6 630 ms 345 ms 319 ms 14 ms 10 ms - #7 640 ms 350 ms 9 ms 9 ms 11 ms - #8 648 ms 388 ms 21 ms 24 ms 21 ms - #9 639 ms 337 ms 349 ms 12 ms 11 ms - #10 637 ms 11 ms 12 ms 12 ms 12 ms - #11 642 ms 356 ms 961 ms 942 ms 26 ms - #12 937 ms 1302 ms 1264 ms 1252 ms 1382 ms - #13 935 ms 1273 ms 1263 ms 1234 ms 1373 ms - #14 946 ms 1283 ms 1274 ms 1256 ms 1392 ms - #15 942 ms 1249 ms 1279 ms 1250 ms 1391 ms - #16 646 ms 964 ms 978 ms 964 ms 18 ms - #17 954 ms 1263 ms 1299 ms 1270 ms 1416 ms - #18 681 ms 1010 ms 1033 ms 1012 ms 383 ms - \ No newline at end of file diff --git a/querydsl-collections/doc/perf-20090319.txt b/querydsl-collections/doc/perf-20090319.txt deleted file mode 100644 index 30f41899da..0000000000 --- a/querydsl-collections/doc/perf-20090319.txt +++ /dev/null @@ -1,99 +0,0 @@ -#1 order preserved !cat.equals(otherCat) -#2 order preserved cat.equals(otherCat) -#3 order preserved cat.getName().equals(otherCat.getName()) -#4 inverted cat.getName().equals(otherCat.getName()) && otherCat.getName().equals(a1) -#5 inverted !(cat.getName().equals(otherCat.getName())) && otherCat.getName().equals(a1) -#6 inverted cat.getName().equals(otherCat.getName()) && !(otherCat.getName().equals(a1)) -#7 inverted !cat.getName().equals(otherCat.getName()) && otherCat.getName().equals(a1) -#8 inverted !cat.getName().equals(otherCat.getName()) && otherCat.getName().startsWith(a1, 0) -#9 order preserved cat.getBodyWeight() == a1 && otherCat.getName().equals(a2) -#10 order preserved cat.getName().startsWith(a1, 0) && otherCat.getName().startsWith(a2, 0) -#11 inverted cat.getName().equals(otherCat.getName()) || otherCat.getName().equals(a1) -#12 inverted cat.getName().equals(otherCat.getName()) || !(otherCat.getName().equals(a1)) -#13 inverted !cat.getName().equals(otherCat.getName()) || otherCat.getName().equals(a1) -#14 inverted !cat.getName().equals(otherCat.getName()) || otherCat.getName().endsWith(a1) -#15 order preserved cat.getBodyWeight() == a1 || otherCat.getName().equals(a2) -#16 order preserved cat.getBodyWeight() == a1 || cat.getName().equals(a2) -#17 order preserved cat.getBodyWeight() > a1 && otherCat.getName().equals(a2) || cat.getName().equals(a3) -#18 order preserved cat.getBodyWeight() > a1 && otherCat.getName().equals(cat.getName()) || cat.getName().equals(a2) -#19 order preserved cat.getBodyWeight() > a1 || otherCat.getName().equals(cat.getName()) -#20 order preserved !(cat.getBodyWeight() == a1) || otherCat.getName().equals(a2) -#21 order preserved cat.getBodyWeight() == a1 || !(otherCat.getName().equals(a2)) -#22 order preserved cat.getName().startsWith(a1, 0) || otherCat.getName().endsWith(a2) - - filtered filtered filtered filtered - sorted sorted sorted - indexed indexed - serial union - -100 * 100 items - #1 21 ms 17 ms 19 ms 17 ms 17 ms - #2 9 ms 6 ms 7 ms 5 ms 4 ms - #3 10 ms 9 ms 7 ms 6 ms 6 ms - #4 11 ms 9 ms 5 ms 7 ms 6 ms - #5 10 ms 11 ms 5 ms 7 ms 5 ms - #6 13 ms 6 ms 12 ms 9 ms 7 ms - #7 11 ms 9 ms 5 ms 6 ms 6 ms - #8 11 ms 11 ms 6 ms 6 ms 5 ms - #9 10 ms 10 ms 11 ms 6 ms 8 ms - #10 11 ms 4 ms 5 ms 5 ms 4 ms - #11 9 ms 9 ms 17 ms 19 ms 12 ms - #12 13 ms 21 ms 22 ms 22 ms 26 ms - #13 13 ms 20 ms 20 ms 19 ms 29 ms - #14 14 ms 19 ms 20 ms 24 ms 22 ms - #15 14 ms 20 ms 20 ms 19 ms 23 ms - #16 13 ms 15 ms 16 ms 16 ms 21 ms - #17 10 ms 6 ms 6 ms 5 ms 12 ms - #18 11 ms 5 ms 5 ms 5 ms 13 ms - #19 10 ms 16 ms 16 ms 16 ms 9 ms - #20 10 ms 17 ms 16 ms 18 ms 9 ms - #21 12 ms 19 ms 21 ms 20 ms 19 ms - #22 9 ms 17 ms 18 ms 19 ms 13 ms - -500 * 500 items - #1 235 ms 306 ms 300 ms 300 ms 301 ms - #2 155 ms 76 ms 78 ms 3 ms 4 ms - #3 154 ms 86 ms 83 ms 5 ms 9 ms - #4 167 ms 93 ms 3 ms 9 ms 7 ms - #5 166 ms 99 ms 5 ms 7 ms 8 ms - #6 162 ms 93 ms 83 ms 9 ms 10 ms - #7 162 ms 97 ms 6 ms 9 ms 7 ms - #8 167 ms 104 ms 14 ms 14 ms 15 ms - #9 161 ms 94 ms 90 ms 6 ms 12 ms - #10 166 ms 7 ms 8 ms 9 ms 8 ms - #11 163 ms 96 ms 245 ms 245 ms 12 ms - #12 244 ms 334 ms 324 ms 325 ms 346 ms - #13 242 ms 326 ms 325 ms 320 ms 332 ms - #14 240 ms 327 ms 322 ms 323 ms 329 ms - #15 239 ms 320 ms 320 ms 319 ms 268 ms - #16 238 ms 240 ms 239 ms 240 ms 258 ms - #17 166 ms 6 ms 6 ms 7 ms 14 ms - #18 168 ms 5 ms 7 ms 6 ms 15 ms - #19 166 ms 239 ms 236 ms 240 ms 12 ms - #20 166 ms 247 ms 249 ms 248 ms 13 ms - #21 238 ms 324 ms 318 ms 319 ms 259 ms - #22 171 ms 254 ms 256 ms 264 ms 98 ms - -1000 * 1000 items - #1 918 ms 1180 ms 1179 ms 1178 ms 1180 ms - #2 598 ms 288 ms 289 ms 4 ms 5 ms - #3 607 ms 317 ms 315 ms 13 ms 8 ms - #4 641 ms 345 ms 8 ms 10 ms 10 ms - #5 650 ms 364 ms 7 ms 10 ms 9 ms - #6 642 ms 352 ms 319 ms 16 ms 9 ms - #7 650 ms 364 ms 6 ms 11 ms 10 ms - #8 664 ms 398 ms 25 ms 25 ms 23 ms - #9 643 ms 342 ms 349 ms 10 ms 13 ms - #10 640 ms 10 ms 14 ms 11 ms 12 ms - #11 652 ms 363 ms 965 ms 969 ms 21 ms - #12 960 ms 1318 ms 1273 ms 1275 ms 1344 ms - #13 975 ms 1311 ms 1298 ms 1294 ms 1334 ms - #14 953 ms 1290 ms 1265 ms 1267 ms 1288 ms - #15 955 ms 1266 ms 1267 ms 1274 ms 1020 ms - #16 951 ms 956 ms 954 ms 952 ms 1018 ms - #17 654 ms 8 ms 9 ms 7 ms 19 ms - #18 651 ms 6 ms 10 ms 6 ms 19 ms - #19 646 ms 939 ms 936 ms 935 ms 14 ms - #20 644 ms 970 ms 974 ms 968 ms 15 ms - #21 965 ms 1276 ms 1283 ms 1278 ms 1027 ms - #22 712 ms 1049 ms 1047 ms 1052 ms 375 ms \ No newline at end of file diff --git a/querydsl-collections/pom.xml b/querydsl-collections/pom.xml index 30d54c410d..4bde6aec1c 100644 --- a/querydsl-collections/pom.xml +++ b/querydsl-collections/pom.xml @@ -1,15 +1,15 @@ - + 4.0.0 - com.mysema.querydsl + com.querydsl querydsl-root - 3.4.1.BUILD-SNAPSHOT - ../querydsl-root/pom.xml + 5.1.0 + ../pom.xml - com.mysema.querydsl + com.querydsl querydsl-collections Querydsl - Collections support Collections support for Querydsl @@ -24,56 +24,98 @@ - com.mysema.querydsl + com.querydsl querydsl-codegen ${project.version} - com.mysema.querydsl - querydsl-apt - ${project.version} + org.jetbrains + annotations + provided - - org.slf4j - slf4j-api + com.querydsl + querydsl-apt + ${project.version} - - org.slf4j - slf4j-log4j12 - + org.hamcrest - hamcrest-core - 1.3 + hamcrest + compile true - com.mysema.querydsl + com.querydsl querydsl-core ${project.version} test test-jar + + + io.github.classgraph + classgraph + test + + + + com.querydsl + querydsl-guava + ${project.version} + test + + + + cglib + cglib + ${cglib.version} + test + + + + org.openjdk.jmh + jmh-core + ${jmh.version} + test + + + + org.openjdk.jmh + jmh-generator-annprocess + ${jmh.version} + test + joda-time joda-time - 1.6 + ${jodatime.version} test - + - com.springsource.bundlor - com.springsource.bundlor.maven + org.apache.maven.plugins + maven-jar-plugin + + + + com.querydsl.collections + + + + + + org.apache.felix + maven-bundle-plugin com.mysema.maven @@ -86,13 +128,59 @@ target/generated-test-sources/java - com.mysema.query.apt.QuerydslAnnotationProcessor + com.querydsl.apt.QuerydslAnnotationProcessor true - + + + org.apache.maven.plugins + maven-compiler-plugin + + -proc:none + + - + + + java-21 + + [21,) + + + + cglib + cglib + ${cglib.version} + test + + + org.ow2.asm + asm + + + org.ow2.asm + asm-commons + + + + + org.ow2.asm + asm + ${asm.version} + test + + + org.ow2.asm + asm-commons + ${asm.version} + test + + + + + + diff --git a/querydsl-collections/src/main/java/com/mysema/query/collections/AbstractCollQuery.java b/querydsl-collections/src/main/java/com/mysema/query/collections/AbstractCollQuery.java deleted file mode 100644 index d7d9492efa..0000000000 --- a/querydsl-collections/src/main/java/com/mysema/query/collections/AbstractCollQuery.java +++ /dev/null @@ -1,246 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.collections; - -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import com.mysema.commons.lang.CloseableIterator; -import com.mysema.commons.lang.IteratorAdapter; -import com.mysema.query.JoinType; -import com.mysema.query.QueryException; -import com.mysema.query.QueryMetadata; -import com.mysema.query.SearchResults; -import com.mysema.query.SimpleQuery; -import com.mysema.query.Tuple; -import com.mysema.query.support.ProjectableQuery; -import com.mysema.query.types.Expression; -import com.mysema.query.types.MapExpression; -import com.mysema.query.types.OperationImpl; -import com.mysema.query.types.Ops; -import com.mysema.query.types.Path; - -/** - * AbstractCollQuery provides a base class for Collection query implementations. - * Extend it like this - * - *
- * public class MyType extends AbstractColQuery<MyType>{
- *   ...
- * }
- * 
- * - * @see CollQuery - * - * @author tiwe - */ -public abstract class AbstractCollQuery> extends ProjectableQuery implements SimpleQuery { - - private final Map, Iterable> iterables = new HashMap, Iterable>(); - - private final QueryEngine queryEngine; - - @SuppressWarnings("unchecked") - public AbstractCollQuery(QueryMetadata metadata, QueryEngine queryEngine) { - super(new CollQueryMixin(metadata)); - this.queryMixin.setSelf((Q) this); - this.queryEngine = queryEngine; - } - - @Override - public long count() { - try { - return queryEngine.count(getMetadata(), iterables); - } catch (Exception e) { - throw new QueryException(e.getMessage(), e); - } finally { - reset(); - } - } - - @Override - public boolean exists() { - try { - return queryEngine.exists(getMetadata(), iterables); - } catch (Exception e) { - throw new QueryException(e.getMessage(), e); - } finally { - reset(); - } - } - - private Expression createAlias(Path> target, Path alias) { - return OperationImpl.create(alias.getType(), Ops.ALIAS, target, alias); - } - - private Expression createAlias(MapExpression target, Path alias) { - return OperationImpl.create(alias.getType(), Ops.ALIAS, target, alias); - } - - /** - * Add a query source - * - * @param
- * @param entity Path for the source - * @param col content of the source - * @return - */ - public Q from(Path entity, Iterable col) { - iterables.put(entity, col); - getMetadata().addJoin(JoinType.DEFAULT, entity); - return (Q)this; - } - - /** - * Bind the given collection to an already existing query source - * - * @param - * @param entity Path for the source - * @param col content of the source - * @return - */ - public Q bind(Path entity, Iterable col) { - iterables.put(entity, col); - return (Q)this; - } - - public abstract QueryMetadata getMetadata(); - - protected QueryEngine getQueryEngine() { - return queryEngine; - } - - /** - * Define an inner join from the Collection typed path to the alias - * - * @param

- * @param collectionPath - * @param alias - * @return - */ - public

Q innerJoin(Path> target, Path

alias) { - getMetadata().addJoin(JoinType.INNERJOIN, createAlias(target, alias)); - return (Q)this; - } - - /** - * Define an inner join from the Map typed path to the alias - * - * @param

- * @param mapPath - * @param alias - * @return - */ - public

Q innerJoin(MapExpression target, Path

alias) { - getMetadata().addJoin(JoinType.INNERJOIN, createAlias(target, alias)); - return (Q)this; - } - - /** - * Define a left join from the Collection typed path to the alias - * - * @param

- * @param collectionPath - * @param alias - * @return - */ - public

Q leftJoin(Path> target, Path

alias) { - getMetadata().addJoin(JoinType.LEFTJOIN, createAlias(target, alias)); - return (Q)this; - } - - /** - * Define a left join from the Map typed path to the alias - * - * @param

- * @param mapPath - * @param alias - * @return - */ - public

Q leftJoin(MapExpression target, Path

alias) { - getMetadata().addJoin(JoinType.LEFTJOIN, createAlias(target, alias)); - return (Q)this; - } - - @Override - public CloseableIterator iterate(Expression... args) { - return iterate(queryMixin.createProjection(args)); - } - - @Override - public CloseableIterator iterate(Expression projection) { - try { - projection = queryMixin.addProjection(projection); - return new IteratorAdapter(queryEngine.list(getMetadata(), iterables, projection).iterator()); - } finally { - reset(); - } - } - - @Override - public List list(Expression... args) { - return list(queryMixin.createProjection(args)); - } - - @Override - public List list(Expression projection) { - try { - projection = queryMixin.addProjection(projection); - return queryEngine.list(getMetadata(), iterables, projection); - } finally { - reset(); - } - } - - @Override - public SearchResults listResults(Expression... args) { - return listResults(queryMixin.createProjection(args)); - } - - @Override - public SearchResults listResults(Expression projection) { - projection = queryMixin.addProjection(projection); - long count = queryEngine.count(getMetadata(), iterables); - if (count > 0l) { - List list = queryEngine.list(getMetadata(), iterables, projection); - reset(); - return new SearchResults(list, getMetadata().getModifiers(), count); - } else { - reset(); - return SearchResults.emptyResults(); - } - - } - - @Override - public Tuple uniqueResult(Expression... args) { - return uniqueResult(queryMixin.createProjection(args)); - } - - @Override - public RT uniqueResult(Expression expr) { - queryMixin.setUnique(true); - if (queryMixin.getMetadata().getModifiers().getLimit() == null) { - limit(2l); - } - return uniqueResult(iterate(expr)); - } - - private void reset() { - getMetadata().reset(); - } - -} diff --git a/querydsl-collections/src/main/java/com/mysema/query/collections/CollDeleteClause.java b/querydsl-collections/src/main/java/com/mysema/query/collections/CollDeleteClause.java deleted file mode 100644 index 181c8a00ab..0000000000 --- a/querydsl-collections/src/main/java/com/mysema/query/collections/CollDeleteClause.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.collections; - -import java.util.Collection; - -import com.mysema.query.dml.DeleteClause; -import com.mysema.query.types.Path; -import com.mysema.query.types.Predicate; - -/** - * CollDeleteClause is an implementation of the {@link DeleteClause} interface for the Querydsl - * Collections module - * - * @author tiwe - * - * @param - */ -public class CollDeleteClause implements DeleteClause> { - - private final Collection col; - - private final Path expr; - - private final CollQuery query; - - public CollDeleteClause(QueryEngine qe, Path expr, Collection col) { - this.query = new CollQuery(qe).from(expr, col); - this.expr = expr; - this.col = col; - } - - public CollDeleteClause(Path expr, Collection col) { - this(DefaultQueryEngine.getDefault(), expr, col); - } - - @Override - public long execute() { - int rv = 0; - for (T match : query.list(expr)) { - col.remove(match); - rv++; - } - return rv; - } - - @Override - public CollDeleteClause where(Predicate... o) { - query.where(o); - return this; - } - - @Override - public String toString() { - return "delete " + query.toString(); - } -} diff --git a/querydsl-collections/src/main/java/com/mysema/query/collections/CollQuery.java b/querydsl-collections/src/main/java/com/mysema/query/collections/CollQuery.java deleted file mode 100644 index fd88810a2c..0000000000 --- a/querydsl-collections/src/main/java/com/mysema/query/collections/CollQuery.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.collections; - -import com.mysema.query.DefaultQueryMetadata; -import com.mysema.query.QueryMetadata; -import com.mysema.query.SimpleQuery; - -/** - * CollQuery is the default implementation of the {@link SimpleQuery} interface for collections - * - * @author tiwe - * - */ -public final class CollQuery extends AbstractCollQuery implements Cloneable { - - /** - * Create a new CollQuery instance - */ - public CollQuery() { - super(new DefaultQueryMetadata(), DefaultQueryEngine.getDefault()); - } - - /** - * Creates a new CollQuery instance - * - * @param templates - */ - public CollQuery(CollQueryTemplates templates) { - this(new DefaultQueryEngine(new DefaultEvaluatorFactory(templates))); - } - - /** - * Create a new CollQuery instance - * - * @param evaluatorFactory - */ - public CollQuery(QueryEngine queryEngine) { - super(new DefaultQueryMetadata(), queryEngine); - } - - - /** - * Create a new CollQuery instance - * - * @param metadata - * @param evaluatorFactory - */ - public CollQuery(QueryMetadata metadata) { - super(metadata, DefaultQueryEngine.getDefault()); - } - - /** - * Create a new CollQuery instance - * - * @param metadata - * @param evaluatorFactory - */ - public CollQuery(QueryMetadata metadata, QueryEngine queryEngine) { - super(metadata, queryEngine); - } - - /** - * Clone the state of this query to a new CollQuery instance - */ - @Override - public CollQuery clone() { - return new CollQuery(queryMixin.getMetadata().clone(), getQueryEngine()); - } - - /** - * @return - */ - @Override - public QueryMetadata getMetadata() { - return queryMixin.getMetadata(); - } - -} diff --git a/querydsl-collections/src/main/java/com/mysema/query/collections/CollQueryFactory.java b/querydsl-collections/src/main/java/com/mysema/query/collections/CollQueryFactory.java deleted file mode 100644 index e8e87bdd24..0000000000 --- a/querydsl-collections/src/main/java/com/mysema/query/collections/CollQueryFactory.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.collections; - -import java.util.Collection; - -import com.google.common.collect.ImmutableList; -import com.mysema.query.alias.Alias; -import com.mysema.query.types.Path; - -/** - * CollQueryFactory provides static convenience methods for query construction - * - * @author tiwe - */ -public final class CollQueryFactory { - - /** - * Create a new delete clause - * - * @param path source expression - * @param col source collection - * @return - */ - public static CollDeleteClause delete(Path path, Collection col) { - return new CollDeleteClause(path, col); - } - - /** - * Create a new query - * - * @param alias source alias - * @param col source collection - * @return - */ - public static CollQuery from(A alias, Iterable col) { - return new CollQuery().from(Alias.$(alias), col); - } - - /** - * Create a new query - * - * @param path source expression - * @param arr source array - * @return - */ - public static CollQuery from(Path path, A... arr) { - return new CollQuery().from(path, ImmutableList.copyOf(arr)); - } - - /** - * Create a new query - * - * @param path source expression - * @param col source collection - * @return - */ - public static CollQuery from(Path path, Iterable col) { - return new CollQuery().from(path, col); - } - - /** - * Create a new update clause - * - * @param path source expression - * @param col source collection - * @return - */ - public static CollUpdateClause update(Path path, Iterable col) { - return new CollUpdateClause(path, col); - } - - private CollQueryFactory() {} - -} diff --git a/querydsl-collections/src/main/java/com/mysema/query/collections/CollQueryFunctions.java b/querydsl-collections/src/main/java/com/mysema/query/collections/CollQueryFunctions.java deleted file mode 100644 index a90db23d54..0000000000 --- a/querydsl-collections/src/main/java/com/mysema/query/collections/CollQueryFunctions.java +++ /dev/null @@ -1,272 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.collections; - -import javax.annotation.Nullable; -import java.lang.reflect.Field; -import java.math.BigDecimal; -import java.util.*; - -import com.google.common.base.Objects; -import com.mysema.query.types.Expression; -import com.mysema.query.types.Operator; -import com.mysema.query.types.Ops; -import com.mysema.util.MathUtils; -import com.mysema.util.ReflectionUtils; - -/** - * CollQueryFunctions defines function implementation for use in ColQueryTemplates - * - * @author tiwe - * - */ -public final class CollQueryFunctions { - - private interface BinaryFunction { - - Number apply(Number num1, Number num2); - } - - private static final BinaryFunction SUM = new BinaryFunction() { - @Override - public Number apply(Number num1, Number num2) { - return MathUtils.sum(num1, num2); - } - }; - - private static final BinaryFunction MAX = new BinaryFunction() { - @Override - public Number apply(Number num1, Number num2) { - if (num1.getClass().equals(num2.getClass()) && num1 instanceof Comparable) { - return ((Comparable)num1).compareTo((Comparable)num2) < 0 ? num2 : num1; - } else { - BigDecimal n1 = new BigDecimal(num1.toString()); - BigDecimal n2 = new BigDecimal(num2.toString()); - return n1.compareTo(n2) < 0 ? num2 : num1; - } - } - }; - - private static final BinaryFunction MIN = new BinaryFunction() { - @Override - public Number apply(Number num1, Number num2) { - if (num1.getClass().equals(num2.getClass()) && num1 instanceof Comparable) { - return ((Comparable)num1).compareTo((Comparable)num2) < 0 ? num1 : num2; - } else { - BigDecimal n1 = new BigDecimal(num1.toString()); - BigDecimal n2 = new BigDecimal(num2.toString()); - return n1.compareTo(n2) < 0 ? num1 : num2; - } - } - }; - - private static final List nullList = Arrays.asList((Object) null); - - public static boolean equals(Object o1, Object o2) { - return Objects.equal(o1, o2); - } - - public static > int compareTo(T c1, T c2) { - if (c1 == null) { - return c2 == null ? 0 : -1; - } else if (c2 == null) { - return 1; - } else { - return c1.compareTo(c2); - } - } - - public static > boolean between(A a, A b, A c) { - return compareTo(a, b) >= 0 && compareTo(a, c) <= 0; - } - - public static double cot(double x) { - return Math.cos(x) / Math.sin(x); - } - - public static double coth(double x) { - return Math.cosh(x) / Math.sinh(x); - } - - public static double degrees(double x) { - return x * 180.0 / Math.PI; - } - - public static double radians(double x) { - return x * Math.PI / 180.0; - } - - public static double log(double x, int y) { - return Math.log(x) / Math.log(y); - } - - @Nullable - public static T coalesce(T... args) { - for (T arg : args) { - if (arg != null) { - return arg; - } - } - return null; - } - - public static T nullif(T first, T second) { - if (first.equals(second)) { - return null; - } else { - return first; - } - } - - public static int getYearMonth(Date date) { - Calendar cal = Calendar.getInstance(); - cal.setTime(date); - return cal.get(Calendar.YEAR) * 100 + cal.get(Calendar.MONTH) + 1; - } - - public static int getDayOfMonth(Date date) { - return getField(date, Calendar.DAY_OF_MONTH); - } - - public static int getDayOfWeek(Date date) { - return getField(date, Calendar.DAY_OF_WEEK); - } - - public static int getDayOfYear(Date date) { - return getField(date, Calendar.DAY_OF_YEAR); - } - - private static int getField(Date date, int field) { - Calendar cal = Calendar.getInstance(); - cal.setTime(date); - return cal.get(field); - } - - public static int getHour(Date date) { - return getField(date, Calendar.HOUR_OF_DAY); - } - - public static int getMilliSecond(Date date) { - return getField(date, Calendar.MILLISECOND); - } - - public static int getMinute(Date date) { - return getField(date, Calendar.MINUTE); - } - - public static int getMonth(Date date) { - return getField(date, Calendar.MONTH) + 1; - } - - public static int getSecond(Date date) { - return getField(date, Calendar.SECOND); - } - - public static int getWeek(Date date) { - return getField(date, Calendar.WEEK_OF_YEAR); - } - - public static int getYear(Date date) { - return getField(date, Calendar.YEAR); - } - - public static int getYearWeek(Date date) { - Calendar cal = Calendar.getInstance(); - cal.setTime(date); - return cal.get(Calendar.YEAR) * 100 + cal.get(Calendar.WEEK_OF_YEAR); - } - - public static Collection leftJoin(Collection coll) { - if (coll.isEmpty()) { - return (List) nullList; - } else { - return coll; - } - } - - private static Number reduce(Iterable source, BinaryFunction f) { - Iterator it = source.iterator(); - Number result = it.next(); - while (it.hasNext()) { - result = f.apply(result, it.next()); - } - return result; - } - - public static Number aggregate(Collection source, Expression expr, Operator aggregator) { - if (aggregator == Ops.AggOps.AVG_AGG) { - Number sum = reduce(source, SUM); - return sum.doubleValue() / source.size(); - } else if (aggregator == Ops.AggOps.COUNT_AGG) { - return Long.valueOf(source.size()); - } else if (aggregator == Ops.AggOps.COUNT_DISTINCT_AGG) { - if (!Set.class.isInstance(source)) { - source = new HashSet(source); - } - return Long.valueOf(source.size()); - } else if (aggregator == Ops.AggOps.MAX_AGG) { - return MathUtils.cast(reduce(source, MAX), (Class) expr.getType()); - } else if (aggregator == Ops.AggOps.MIN_AGG) { - return MathUtils.cast(reduce(source, MIN), (Class)expr.getType()); - } else if (aggregator == Ops.AggOps.SUM_AGG) { - return MathUtils.cast(reduce(source, SUM), (Class)expr.getType()); - } else { - throw new IllegalArgumentException("Unknown operator " + aggregator); - } - } - - public static boolean like(final String str, String like) { - final StringBuilder pattern = new StringBuilder(like.length() + 4); - for (int i = 0; i < like.length(); i++) { - final char ch = like.charAt(i); - if (ch == '%') { - pattern.append(".*"); - continue; - } else if (ch == '_') { - pattern.append('.'); - continue; - } else if (ch == '.' || ch == '$' || ch == '^') { - pattern.append('\\'); - } - pattern.append(ch); - } - if (pattern.toString().equals(like)) { - return str.equals(like); - } else { - return str.matches(pattern.toString()); - } - } - - public static boolean like(String str, String like, char escape) { - return like(str, like); - } - - public static T get(Object parent, String f) { - try { - Field field = ReflectionUtils.getFieldOrNull(parent.getClass(), f); - if (field != null) { - field.setAccessible(true); - return (T)field.get(parent); - } else { - throw new IllegalArgumentException("No field " + f + " for " + parent.getClass()); - } - } catch (IllegalAccessException e) { - throw new IllegalStateException(e); - } - } - - private CollQueryFunctions() {} - - -} diff --git a/querydsl-collections/src/main/java/com/mysema/query/collections/CollQueryMixin.java b/querydsl-collections/src/main/java/com/mysema/query/collections/CollQueryMixin.java deleted file mode 100644 index f52026f0e5..0000000000 --- a/querydsl-collections/src/main/java/com/mysema/query/collections/CollQueryMixin.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.collections; - -import com.mysema.query.QueryMetadata; -import com.mysema.query.support.CollectionAnyVisitor; -import com.mysema.query.support.Context; -import com.mysema.query.support.QueryMixin; -import com.mysema.query.types.ExpressionUtils; -import com.mysema.query.types.Path; -import com.mysema.query.types.Predicate; -import com.mysema.query.types.template.BooleanTemplate; - -/** - * CollQueryMixin extends {@link QueryMixin} to provide normalization logic specific to this module - * - * @author tiwe - * - * @param - */ -public class CollQueryMixin extends QueryMixin { - - private static final Predicate ANY = BooleanTemplate.create("any"); - - public CollQueryMixin() {} - - public CollQueryMixin(QueryMetadata metadata) { - super(metadata); - } - - public CollQueryMixin(T self, QueryMetadata metadata) { - super(self, metadata); - } - - @Override - protected Predicate normalize(Predicate predicate, boolean where) { - predicate = (Predicate)ExpressionUtils.extract(predicate); - if (predicate != null) { - Context context = new Context(); - Predicate transformed = (Predicate) predicate.accept(CollectionAnyVisitor.DEFAULT, context); - for (int i = 0; i < context.paths.size(); i++) { - leftJoin( - (Path)context.paths.get(i).getMetadata().getParent(), - (Path)context.replacements.get(i)); - on(ANY); - } - return transformed; - } else { - return predicate; - } - } -} diff --git a/querydsl-collections/src/main/java/com/mysema/query/collections/CollQuerySerializer.java b/querydsl-collections/src/main/java/com/mysema/query/collections/CollQuerySerializer.java deleted file mode 100644 index f24ab2626d..0000000000 --- a/querydsl-collections/src/main/java/com/mysema/query/collections/CollQuerySerializer.java +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.collections; - -import java.beans.BeanInfo; -import java.beans.IntrospectionException; -import java.beans.Introspector; -import java.beans.PropertyDescriptor; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Maps; -import com.google.common.primitives.Primitives; -import com.mysema.query.QueryException; -import com.mysema.query.codegen.Serializer; -import com.mysema.query.support.SerializerBase; -import com.mysema.query.types.Constant; -import com.mysema.query.types.Expression; -import com.mysema.query.types.FactoryExpression; -import com.mysema.query.types.Operator; -import com.mysema.query.types.Ops; -import com.mysema.query.types.Path; -import com.mysema.query.types.PathType; -import com.mysema.query.types.SubQueryExpression; -import com.mysema.query.types.Template; - -/** - * CollQuerySerializer is a {@link Serializer} implementation for the Java language - * - * @author tiwe - */ -public final class CollQuerySerializer extends SerializerBase { - - private static final Set> WRAPPER_TYPES = ImmutableSet.copyOf(Primitives.allWrapperTypes()); - - private static final Map, String> OPERATOR_SYMBOLS = Maps.newIdentityHashMap(); - - private static final Map, String> CAST_SUFFIXES = Maps.newHashMap(); - - static { - OPERATOR_SYMBOLS.put(Ops.EQ, " == "); - OPERATOR_SYMBOLS.put(Ops.NE, " != "); - OPERATOR_SYMBOLS.put(Ops.GT, " > "); - OPERATOR_SYMBOLS.put(Ops.LT, " < "); - OPERATOR_SYMBOLS.put(Ops.GOE, " >= "); - OPERATOR_SYMBOLS.put(Ops.LOE, " <= "); - - OPERATOR_SYMBOLS.put(Ops.ADD, " + "); - OPERATOR_SYMBOLS.put(Ops.SUB, " - "); - OPERATOR_SYMBOLS.put(Ops.MULT, " * "); - OPERATOR_SYMBOLS.put(Ops.DIV, " / "); - - CAST_SUFFIXES.put(Boolean.class, ".booleanValue()"); - CAST_SUFFIXES.put(Byte.class, ".byteValue()"); - CAST_SUFFIXES.put(Character.class, ".charValue()"); - CAST_SUFFIXES.put(Double.class, ".doubleValue()"); - CAST_SUFFIXES.put(Float.class, ".floatValue()"); - CAST_SUFFIXES.put(Integer.class, ".intValue()"); - CAST_SUFFIXES.put(Long.class, ".longValue()"); - CAST_SUFFIXES.put(Short.class, ".shortValue()"); - CAST_SUFFIXES.put(String.class, ".toString()"); - } - - public CollQuerySerializer(CollQueryTemplates templates) { - super(templates); - } - - @Override - public Void visit(Path path, Void context) { - final PathType pathType = path.getMetadata().getPathType(); - if (pathType == PathType.PROPERTY) { - final Path parent = path.getMetadata().getParent(); - final String property = path.getMetadata().getName(); - final Class parentType = parent.getType(); - try { - // getter - Method m = getAccessor(parentType, property); - if (m != null && Modifier.isPublic(m.getModifiers())) { - handle(parent); - append(".").append(m.getName()).append("()"); - } else { - // field - Field f = getField(parentType, property); - if (f != null && Modifier.isPublic(f.getModifiers())) { - handle(parent); - append(".").append(property); - } else { - // field access by reflection - append(CollQueryFunctions.class.getName() + ".<"); - append(((Class)path.getType()).getName()).append(">get("); - handle(parent); - append(", \""+property+"\")"); - } - } - } catch (Exception e) { - throw new QueryException(e); - } - - } else if (pathType == PathType.DELEGATE) { - append("("); - append("(").append(path.getType().getName()).append(")"); - path.getMetadata().getParent().accept(this, context); - append(")"); - - } else { - List args = new ArrayList(2); - if (path.getMetadata().getParent() != null) { - args.add((Expression)path.getMetadata().getParent()); - } - args.add(path.getMetadata().getElement()); - final Template template = getTemplate(pathType); - for (Template.Element element : template.getElements()) { - Object rv = element.convert(args); - if (rv instanceof Expression) { - ((Expression)rv).accept(this, context); - } else if (element.isString()) { - append(rv.toString()); - } else { - visitConstant(rv); - } - } - } - return null; - - } - - private Method getAccessor(Class owner, String property) { - try { - BeanInfo beanInfo = Introspector.getBeanInfo(owner); - PropertyDescriptor[] descriptors = beanInfo.getPropertyDescriptors(); - for(PropertyDescriptor pd : descriptors) { - if(pd.getName().equals(property)) { - return pd.getReadMethod(); - } - } - return null; - } catch (IntrospectionException e) { - return null; - } - } - - private Field getField(Class owner, String field) { - try { - return owner.getField(field); - } catch (NoSuchFieldException e) { - return null; - } - } - - @Override - public Void visit(SubQueryExpression expr, Void context) { - throw new IllegalArgumentException("Not supported"); - } - - private void visitCast(Operator operator, Expression source, Class targetType) { - if (Number.class.isAssignableFrom(source.getType()) && !Constant.class.isInstance(source)) { - append("new ").append(source.getType().getSimpleName()).append("("); - handle(source); - append(")"); - } else { - handle(source); - } - - if (CAST_SUFFIXES.containsKey(targetType)) { - append(CAST_SUFFIXES.get(targetType)); - } else { - throw new IllegalArgumentException("Unsupported cast type " + targetType.getName()); - } - } - - @Override - protected void visitOperation(Class type, Operator operator, List> args) { - if (args.size() == 2 && OPERATOR_SYMBOLS.containsKey(operator) - && isPrimitive(args.get(0).getType()) && isPrimitive(args.get(1).getType())) { - handle(args.get(0)); - append(OPERATOR_SYMBOLS.get(operator)); - handle(args.get(1)); - if (args.get(1) instanceof Constant) { - append(CAST_SUFFIXES.get(args.get(1).getType())); - } - return; - } - - if (operator == Ops.STRING_CAST) { - visitCast(operator, args.get(0), String.class); - } else if (operator == Ops.NUMCAST) { - visitCast(operator, args.get(0), (Class) ((Constant) args.get(1)).getConstant()); - } else { - super.visitOperation(type, operator, args); - } - } - - private static boolean isPrimitive(Class type) { - return type.isPrimitive() || WRAPPER_TYPES.contains(type); - } - - @Override - public Void visit(FactoryExpression expr, Void context) { - visitConstant(expr); - append(".newInstance("); - handle(", ", expr.getArgs()); - append(")"); - return null; - } - -} diff --git a/querydsl-collections/src/main/java/com/mysema/query/collections/DefaultEvaluatorFactory.java b/querydsl-collections/src/main/java/com/mysema/query/collections/DefaultEvaluatorFactory.java deleted file mode 100644 index b00a96682b..0000000000 --- a/querydsl-collections/src/main/java/com/mysema/query/collections/DefaultEvaluatorFactory.java +++ /dev/null @@ -1,293 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.collections; - -import java.net.URLClassLoader; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.annotation.Nullable; -import javax.tools.JavaCompiler; - -import com.google.common.primitives.Primitives; -import com.mysema.codegen.ECJEvaluatorFactory; -import com.mysema.codegen.Evaluator; -import com.mysema.codegen.EvaluatorFactory; -import com.mysema.codegen.JDKEvaluatorFactory; -import com.mysema.codegen.model.ClassType; -import com.mysema.codegen.model.SimpleType; -import com.mysema.codegen.model.Type; -import com.mysema.codegen.model.TypeCategory; -import com.mysema.codegen.model.Types; -import com.mysema.codegen.support.ClassUtils; -import com.mysema.query.JoinExpression; -import com.mysema.query.JoinType; -import com.mysema.query.QueryMetadata; -import com.mysema.query.support.CollectionAnyVisitor; -import com.mysema.query.support.Context; -import com.mysema.query.types.Expression; -import com.mysema.query.types.FactoryExpression; -import com.mysema.query.types.Operation; -import com.mysema.query.types.ParamExpression; -import com.mysema.query.types.ParamNotSetException; -import com.mysema.query.types.Predicate; - -/** - * DefaultEvaluatorFactory provides Java source templates for evaluation of ColQuery queries - * - * @author tiwe - * - */ -public class DefaultEvaluatorFactory { - - private final EvaluatorFactory factory; - - private final CollQueryTemplates templates; - - public DefaultEvaluatorFactory(CollQueryTemplates templates) { - this(templates, - Thread.currentThread().getContextClassLoader()); - } - - public DefaultEvaluatorFactory(CollQueryTemplates templates, EvaluatorFactory factory) { - this.templates = templates; - this.factory = factory; - } - - protected DefaultEvaluatorFactory(CollQueryTemplates templates, - URLClassLoader classLoader, JavaCompiler compiler) { - this.templates = templates; - this.factory = new JDKEvaluatorFactory(classLoader, compiler); - } - - protected DefaultEvaluatorFactory(CollQueryTemplates templates, ClassLoader classLoader) { - this.templates = templates; - if (classLoader instanceof URLClassLoader) { - this.factory = new JDKEvaluatorFactory((URLClassLoader) classLoader); - } else { - // for OSGi compatibility - this.factory = new ECJEvaluatorFactory(classLoader); - } - } - - /** - * Create an Evaluator for the given query sources and projection - * - * @param - * @param sources - * @param projection - * @return - */ - public Evaluator create(QueryMetadata metadata, List> sources, - Expression projection) { - final CollQuerySerializer serializer = new CollQuerySerializer(templates); - serializer.append("return "); - if (projection instanceof FactoryExpression) { - serializer.append("("); - serializer.append(ClassUtils.getName(projection.getType())); - serializer.append(")("); - serializer.handle(projection); - serializer.append(")"); - } else { - serializer.handle(projection); - } - serializer.append(";"); - - Map constantToLabel = serializer.getConstantToLabel(); - Map constants = getConstants(metadata, constantToLabel); - Class[] types = new Class[sources.size()]; - String[] names = new String[sources.size()]; - for (int i = 0; i < sources.size(); i++) { - types[i] = sources.get(i).getType(); - names[i] = sources.get(i).toString(); - } - - // normalize types - for (int i = 0; i < types.length; i++) { - if (Primitives.isWrapperType(types[i])) { - types[i] = Primitives.unwrap(types[i]); - } - } - - return factory.createEvaluator(serializer.toString(), projection.getType(), names, - types, constants); - } - - /** - * Create an Evaluator for the given source and filter - * - * @param - * @param source - * @param filter - * @return - */ - public Evaluator> createEvaluator(QueryMetadata metadata, - Expression source, Predicate filter) { - String typeName = ClassUtils.getName(source.getType()); - CollQuerySerializer ser = new CollQuerySerializer(templates); - ser.append("java.util.List<"+typeName+"> rv = new java.util.ArrayList<"+typeName+">();\n"); - ser.append("for (" + typeName + " "+ source + " : " + source + "_) {\n"); - ser.append(" try {\n"); - ser.append(" if (").handle(filter).append(") {\n"); - ser.append(" rv.add("+source+");\n"); - ser.append(" }\n"); - ser.append(" } catch (NullPointerException npe) { }\n"); - ser.append("}\n"); - ser.append("return rv;"); - - Map constantToLabel = ser.getConstantToLabel(); - Map constants = getConstants(metadata, constantToLabel); - - Type sourceType = new ClassType(TypeCategory.SIMPLE, source.getType()); - ClassType sourceListType = new ClassType(TypeCategory.SIMPLE, Iterable.class, sourceType); - - return factory.createEvaluator( - ser.toString(), - sourceListType, - new String[]{source+"_"}, - new Type[]{sourceListType}, - new Class[]{Iterable.class}, - constants); - } - - /** - * Create an Evaluator for the given sources and the given optional filter - * - * @param joins - * @param filter - * @return - */ - public Evaluator> createEvaluator(QueryMetadata metadata, - List joins, @Nullable Predicate filter) { - List sourceNames = new ArrayList(); - List sourceTypes = new ArrayList(); - List> sourceClasses = new ArrayList>(); - StringBuilder vars = new StringBuilder(); - CollQuerySerializer ser = new CollQuerySerializer(templates); - ser.append("java.util.List rv = new java.util.ArrayList();\n"); - - List anyJoinMatchers = new ArrayList(); - - // creating context - for (JoinExpression join : joins) { - Expression target = join.getTarget(); - String typeName = com.mysema.codegen.support.ClassUtils.getName(target.getType()); - if (vars.length() > 0) { - vars.append(","); - } - switch (join.getType()) { - case DEFAULT: - ser.append("for (" + typeName + " "+ target + " : " + target + "_) {\n"); - vars.append(target); - sourceNames.add(target+"_"); - sourceTypes.add(new SimpleType(Types.ITERABLE, new ClassType(TypeCategory.SIMPLE,target.getType()))); - sourceClasses.add(Iterable.class); - break; - - case INNERJOIN: - case LEFTJOIN: - Operation alias = (Operation)join.getTarget(); - boolean colAnyJoin = join.getCondition() != null && join.getCondition().toString().equals("any"); - boolean leftJoin = join.getType() == JoinType.LEFTJOIN; - String matcher = null; - if (colAnyJoin) { - matcher = alias.getArg(1).toString() + "_matched"; - ser.append("boolean " + matcher + " = false;\n"); - anyJoinMatchers.add(matcher); - } - ser.append("for (" + typeName + " " + alias.getArg(1) + " : "); - if (leftJoin) { - ser.append(CollQueryFunctions.class.getName()+".leftJoin("); - } - if (colAnyJoin) { - Context context = new Context(); - Expression replacement = alias.getArg(0) - .accept(CollectionAnyVisitor.DEFAULT, context); - ser.handle(replacement); - } else { - ser.handle(alias.getArg(0)); - } - if (alias.getArg(0).getType().equals(Map.class)) { - ser.append(".values()"); - } - if (leftJoin) { - ser.append(")"); - } - ser.append(") {\n"); - if (matcher != null) { - ser.append("if (!" + matcher + ") {\n"); - } - vars.append(alias.getArg(1)); - break; - - default: - throw new IllegalArgumentException("Illegal join expression " + join); - } - } - - // filter - if (filter != null) { - ser.append("try {\n"); - ser.append("if ("); - ser.handle(filter).append(") {\n"); - for (String matcher : anyJoinMatchers) { - ser.append(" "+ matcher + " = true;\n"); - } - ser.append(" rv.add(new Object[]{"+vars+"});\n"); - ser.append("}\n"); - ser.append("} catch (NullPointerException npe) { }\n"); - } else { - ser.append("rv.add(new Object[]{"+vars+"});\n"); - } - - // closing context - int amount = joins.size() + anyJoinMatchers.size(); - for (int i = 0; i < amount; i++) { - ser.append("}\n"); - } - ser.append("return rv;"); - - Map constantToLabel = ser.getConstantToLabel(); - Map constants = getConstants(metadata, constantToLabel); - - ClassType projectionType = new ClassType(TypeCategory.LIST, List.class, Types.OBJECTS); - return factory.createEvaluator( - ser.toString(), - projectionType, - sourceNames.toArray(new String[sourceNames.size()]), - sourceTypes.toArray(new Type[sourceTypes.size()]), - sourceClasses.toArray(new Class[sourceClasses.size()]), - constants); - } - - private Map getConstants(QueryMetadata metadata, - Map constantToLabel) { - Map constants = new HashMap(); - for (Map.Entry entry : constantToLabel.entrySet()) { - if (entry.getKey() instanceof ParamExpression) { - Object value = metadata.getParams().get(entry.getKey()); - if (value == null) { - throw new ParamNotSetException((ParamExpression) entry.getKey()); - } - constants.put(entry.getValue(), value); - } else { - constants.put(entry.getValue(), entry.getKey()); - } - } - return constants; - } - -} diff --git a/querydsl-collections/src/main/java/com/mysema/query/collections/GuavaHelpers.java b/querydsl-collections/src/main/java/com/mysema/query/collections/GuavaHelpers.java deleted file mode 100644 index 3f04a75ca8..0000000000 --- a/querydsl-collections/src/main/java/com/mysema/query/collections/GuavaHelpers.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 2012, Mysema Ltd - * - * 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. - */ -package com.mysema.query.collections; - -import java.util.Collections; - -import com.google.common.base.Function; -import com.mysema.codegen.Evaluator; -import com.mysema.query.EmptyMetadata; -import com.mysema.query.types.Expression; -import com.mysema.query.types.Path; -import com.mysema.query.types.PathExtractor; -import com.mysema.query.types.Predicate; - -/** - * GuavaHelpers provides functionality to wrap Querydsl {@link Predicate} instances to Guava predicates - * and Querydsl {@link Expression} instances to Guava functions - * - * @author tiwe - * - */ -public final class GuavaHelpers { - - private static final DefaultEvaluatorFactory evaluatorFactory = - new DefaultEvaluatorFactory(CollQueryTemplates.DEFAULT); - - /** - * Wrap a Querydsl predicate into a Guava predicate - * - * @param predicate - * @return - */ - public static com.google.common.base.Predicate wrap(Predicate predicate) { - Path path = (Path)predicate.accept(PathExtractor.DEFAULT, null); - if (path != null) { - final Evaluator ev = createEvaluator(path.getRoot(), predicate); - return new com.google.common.base.Predicate() { - @Override - public boolean apply(T input) { - return ev.evaluate(input); - } - }; - } else { - throw new IllegalArgumentException("No path in " + predicate); - } - } - - /** - * Wrap a Querydsl expression into a Guava function - * - * @param projection - * @return - */ - public static Function wrap(Expression projection) { - Path path = (Path)projection.accept(PathExtractor.DEFAULT, null); - if (path != null) { - final Evaluator ev = createEvaluator(path.getRoot(), projection); - return new Function() { - @Override - public T apply(F input) { - return ev.evaluate(input); - } - }; - } else { - throw new IllegalArgumentException("No path in " + projection); - } - } - - private static Evaluator createEvaluator(Path path, Expression projection) { - return evaluatorFactory.create(EmptyMetadata.DEFAULT, - Collections.singletonList(path), projection); - } - - private GuavaHelpers() { } - -} diff --git a/querydsl-collections/src/main/java/com/mysema/query/collections/MultiComparator.java b/querydsl-collections/src/main/java/com/mysema/query/collections/MultiComparator.java deleted file mode 100644 index c5662cee87..0000000000 --- a/querydsl-collections/src/main/java/com/mysema/query/collections/MultiComparator.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.collections; - -import java.io.Serializable; -import java.util.Comparator; - -import com.mysema.codegen.Evaluator; -import com.mysema.query.util.NullSafeComparableComparator; - -/** - * MultiComparator compares arrays - * - * @author tiwe - */ - -public class MultiComparator implements Comparator, Serializable { - - @SuppressWarnings("unchecked") - private static final Comparator naturalOrder = new NullSafeComparableComparator(); - - private static final long serialVersionUID = 1121416260773566299L; - - private final boolean[] asc; - - private final transient Evaluator ev; - - public MultiComparator(Evaluator ev, boolean[] directions) { - this.ev = ev; - this.asc = directions.clone(); - } - - @Override - public int compare(T o1, T o2) { - if (o1.getClass().isArray()) { - return innerCompare(ev.evaluate((Object[])o1), ev.evaluate((Object[])o2)); - } else { - return innerCompare(ev.evaluate(o1), ev.evaluate(o2)); - } - } - - private int innerCompare(Object[] o1, Object[] o2) { - for (int i = 0; i < o1.length; i++) { - int res; - if (o1[i] == null) { - res = o2[i] == null ? 0 : -1; - } else if (o2[i] == null) { - res = 1; - } else { - res = naturalOrder.compare(o1[i], o2[i]); - } - if (res != 0) { - return asc[i] ? res : -res; - } - } - return 0; - } - -} diff --git a/querydsl-collections/src/main/java/com/mysema/query/collections/QueryEngine.java b/querydsl-collections/src/main/java/com/mysema/query/collections/QueryEngine.java deleted file mode 100644 index 2402c7c46e..0000000000 --- a/querydsl-collections/src/main/java/com/mysema/query/collections/QueryEngine.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.collections; - -import java.util.List; -import java.util.Map; - -import com.mysema.query.QueryMetadata; -import com.mysema.query.types.Expression; - -/** - * QueryEngine defines an interface for the evaluation of ColQuery queries - * - * @author tiwe - * - */ -public interface QueryEngine { - - /** - * Evaluate the given query and return the count of matched rows - * - * @param metadata - * @param iterables - * @return - */ - long count(QueryMetadata metadata, Map, Iterable> iterables); - - /** - * Evaluate the given query and return the projection as a list - * - * @param metadata - * @param iterables - * @return - */ - List list(QueryMetadata metadata, Map, Iterable> iterables, - Expression projection); - - /** - * @param metadata - * @param iterables - * @return - */ - boolean exists(QueryMetadata metadata, Map, Iterable> iterables); - -} diff --git a/querydsl-collections/src/main/java/com/mysema/query/collections/package-info.java b/querydsl-collections/src/main/java/com/mysema/query/collections/package-info.java deleted file mode 100644 index 281a4a0d43..0000000000 --- a/querydsl-collections/src/main/java/com/mysema/query/collections/package-info.java +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ - -/** - * Implementations of Querydsl query interfaces for JavaBean collections - */ -package com.mysema.query.collections; diff --git a/querydsl-collections/src/main/java/com/querydsl/collections/AbstractCollQuery.java b/querydsl-collections/src/main/java/com/querydsl/collections/AbstractCollQuery.java new file mode 100644 index 0000000000..80eb51f911 --- /dev/null +++ b/querydsl-collections/src/main/java/com/querydsl/collections/AbstractCollQuery.java @@ -0,0 +1,214 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.collections; + +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Stream; + +import com.mysema.commons.lang.CloseableIterator; +import com.mysema.commons.lang.IteratorAdapter; +import com.querydsl.core.*; +import com.querydsl.core.support.FetchableQueryBase; +import com.querydsl.core.types.*; + +/** + * {@code AbstractCollQuery} provides a base class for {@code Collection} query implementations. + * + * @param result type + * @param concrete subtype + * + * @see CollQuery + * @author tiwe + */ +public abstract class AbstractCollQuery> extends FetchableQueryBase + implements FetchableQuery { + + private final Map, Iterable> iterables = new HashMap, Iterable>(); + + private final QueryEngine queryEngine; + + public AbstractCollQuery(QueryMetadata metadata, QueryEngine queryEngine) { + super(new CollQueryMixin(metadata)); + @SuppressWarnings("unchecked") // Q is this + subtype + Q self = (Q) this; + this.queryMixin.setSelf(self); + this.queryEngine = queryEngine; + } + + @Override + public long fetchCount() { + return queryEngine.count(queryMixin.getMetadata(), iterables); + } + + protected QueryMetadata getMetadata() { + return queryMixin.getMetadata(); + } + + private Expression createAlias(Path> target, Path alias) { + return ExpressionUtils.operation(alias.getType(), Ops.ALIAS, target, alias); + } + + private Expression createAlias(MapExpression target, Path alias) { + return ExpressionUtils.operation(alias.getType(), Ops.ALIAS, target, alias); + } + + /** + * Add a query source + * + * @param type of expression + * @param entity Path for the source + * @param col content of the source + * @return current object + */ + public Q from(Path entity, Iterable col) { + iterables.put(entity, col); + getMetadata().addJoin(JoinType.DEFAULT, entity); + return queryMixin.getSelf(); + } + + /** + * Bind the given collection to an already existing query source + * + * @param type of expression + * @param entity Path for the source + * @param col content of the source + * @return current object + */ + public Q bind(Path entity, Iterable col) { + iterables.put(entity, col); + return queryMixin.getSelf(); + } + + @Override + public Q groupBy(Expression e) { + throw new UnsupportedOperationException(); + } + + @Override + public Q groupBy(Expression... o) { + throw new UnsupportedOperationException(); + } + + @Override + public Q having(Predicate e) { + throw new UnsupportedOperationException(); + } + + @Override + public Q having(Predicate... e) { + throw new UnsupportedOperationException(); + } + + protected QueryEngine getQueryEngine() { + return queryEngine; + } + + /** + * Define an inner join from the Collection typed path to the alias + * + * @param

type of expression + * @param target target of the join + * @param alias alias for the join target + * @return current object + */ + public

Q innerJoin(Path> target, Path

alias) { + getMetadata().addJoin(JoinType.INNERJOIN, createAlias(target, alias)); + return queryMixin.getSelf(); + } + + /** + * Define an inner join from the Map typed path to the alias + * + * @param

type of expression + * @param target target of the join + * @param alias alias for the join target + * @return current object + */ + public

Q innerJoin(MapExpression target, Path

alias) { + getMetadata().addJoin(JoinType.INNERJOIN, createAlias(target, alias)); + return queryMixin.getSelf(); + } + + /** + * Define a left join from the Collection typed path to the alias + * + * @param

type of expression + * @param target target of the join + * @param alias alias for the join target + * @return current object + */ + public

Q leftJoin(Path> target, Path

alias) { + getMetadata().addJoin(JoinType.LEFTJOIN, createAlias(target, alias)); + return queryMixin.getSelf(); + } + + /** + * Define a left join from the Map typed path to the alias + * + * @param

type of expression + * @param target target of the join + * @param alias alias for the joint target + * @return current object + */ + public

Q leftJoin(MapExpression target, Path

alias) { + getMetadata().addJoin(JoinType.LEFTJOIN, createAlias(target, alias)); + return queryMixin.getSelf(); + } + + @Override + public CloseableIterator iterate() { + @SuppressWarnings("unchecked") // This is the built type + Expression projection = (Expression) queryMixin.getMetadata().getProjection(); + return new IteratorAdapter(fetch().iterator()); + } + + @Override + public Stream stream() { + return fetch().stream(); + } + + @Override + public List fetch() { + @SuppressWarnings("unchecked") // This is the built type + Expression projection = (Expression) queryMixin.getMetadata().getProjection(); + return queryEngine.list(getMetadata(), iterables, projection); + } + + @Override + public QueryResults fetchResults() { + @SuppressWarnings("unchecked") // This is the built type + Expression projection = (Expression) queryMixin.getMetadata().getProjection(); + long count = queryEngine.count(getMetadata(), iterables); + if (count > 0L) { + List list = queryEngine.list(getMetadata(), iterables, projection); + return new QueryResults(list, getMetadata().getModifiers(), count); + } else { + return QueryResults.emptyResults(); + } + } + + @Override + public T fetchOne() throws NonUniqueResultException { + queryMixin.setUnique(true); + if (queryMixin.getMetadata().getModifiers().getLimit() == null) { + limit(2L); + } + return uniqueResult(iterate()); + } + + +} diff --git a/querydsl-collections/src/main/java/com/querydsl/collections/CollDeleteClause.java b/querydsl-collections/src/main/java/com/querydsl/collections/CollDeleteClause.java new file mode 100644 index 0000000000..a7f1bad3f1 --- /dev/null +++ b/querydsl-collections/src/main/java/com/querydsl/collections/CollDeleteClause.java @@ -0,0 +1,65 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.collections; + +import java.util.Collection; + +import com.querydsl.core.dml.DeleteClause; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.Predicate; + +/** + * {@code CollDeleteClause} is an implementation of the {@link DeleteClause} interface for the Querydsl + * Collections module + * + * @author tiwe + * + * @param + */ +public class CollDeleteClause implements DeleteClause> { + + private final Collection col; + + private final CollQuery query; + + public CollDeleteClause(QueryEngine qe, Path expr, Collection col) { + this.query = new CollQuery(qe).from(expr, col).select(expr); + this.col = col; + } + + public CollDeleteClause(Path expr, Collection col) { + this(DefaultQueryEngine.getDefault(), expr, col); + } + + @Override + public long execute() { + int rv = 0; + for (T match : query.fetch()) { + col.remove(match); + rv++; + } + return rv; + } + + @Override + public CollDeleteClause where(Predicate... o) { + query.where(o); + return this; + } + + @Override + public String toString() { + return "delete " + query.toString(); + } +} diff --git a/querydsl-collections/src/main/java/com/querydsl/collections/CollQuery.java b/querydsl-collections/src/main/java/com/querydsl/collections/CollQuery.java new file mode 100644 index 0000000000..016fdaeeca --- /dev/null +++ b/querydsl-collections/src/main/java/com/querydsl/collections/CollQuery.java @@ -0,0 +1,99 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.collections; + +import com.querydsl.core.DefaultQueryMetadata; +import com.querydsl.core.FetchableQuery; +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.Tuple; +import com.querydsl.core.types.Expression; + +/** + * {@code CollQuery} is the default implementation of the {@link FetchableQuery} interface for collections + * + * @param result type + * + * @author tiwe + */ +public class CollQuery extends AbstractCollQuery> implements Cloneable { + + /** + * Create a new CollQuery instance + */ + public CollQuery() { + super(new DefaultQueryMetadata(), DefaultQueryEngine.getDefault()); + } + + /** + * Creates a new CollQuery instance + * + * @param templates serialization templates + */ + public CollQuery(CollQueryTemplates templates) { + this(new DefaultQueryEngine(new DefaultEvaluatorFactory(templates))); + } + + /** + * Create a new CollQuery instance + * + * @param queryEngine query engine for query execution + */ + public CollQuery(QueryEngine queryEngine) { + super(new DefaultQueryMetadata(), queryEngine); + } + + + /** + * Create a new CollQuery instance + * + * @param metadata query metadata + */ + public CollQuery(QueryMetadata metadata) { + super(metadata, DefaultQueryEngine.getDefault()); + } + + /** + * Create a new CollQuery instance + * + * @param metadata query metadata + * @param queryEngine query engine for query execution + */ + public CollQuery(QueryMetadata metadata, QueryEngine queryEngine) { + super(metadata, queryEngine); + } + + /** + * Clone the state of this query to a new CollQuery instance + */ + @Override + public CollQuery clone() { + return new CollQuery(queryMixin.getMetadata().clone(), getQueryEngine()); + } + + @Override + public CollQuery select(Expression expr) { + queryMixin.setProjection(expr); + @SuppressWarnings("unchecked") // This is the new projection's type + CollQuery newType = (CollQuery) queryMixin.getSelf(); + return newType; + } + + @Override + public CollQuery select(Expression... exprs) { + queryMixin.setProjection(exprs); + @SuppressWarnings("unchecked") // This is the new projection's type + CollQuery newType = (CollQuery) queryMixin.getSelf(); + return newType; + } +} diff --git a/querydsl-collections/src/main/java/com/querydsl/collections/CollQueryFactory.java b/querydsl-collections/src/main/java/com/querydsl/collections/CollQueryFactory.java new file mode 100644 index 0000000000..b43aa21463 --- /dev/null +++ b/querydsl-collections/src/main/java/com/querydsl/collections/CollQueryFactory.java @@ -0,0 +1,88 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.collections; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; + +import com.querydsl.core.alias.Alias; +import com.querydsl.core.types.Path; + +/** + * {@code CollQueryFactory} provides static convenience methods for query construction + * + * @author tiwe + */ +public final class CollQueryFactory { + + /** + * Create a new delete clause + * + * @param path source expression + * @param col source collection + * @return delete clause + */ + public static CollDeleteClause delete(Path path, Collection col) { + return new CollDeleteClause(path, col); + } + + /** + * Create a new query + * + * @param alias source alias + * @param col source collection + * @return query + */ + public static CollQuery from(A alias, Iterable col) { + Path expr = Alias.$(alias); + return new CollQuery().from(expr, col).select(expr); + } + + /** + * Create a new query + * + * @param path source expression + * @param arr source array + * @return query + */ + public static CollQuery from(Path path, A... arr) { + return new CollQuery().from(path, Collections.unmodifiableList(Arrays.asList(arr))).select(path); + } + + /** + * Create a new query + * + * @param path source expression + * @param col source collection + * @return query + */ + public static CollQuery from(Path path, Iterable col) { + return new CollQuery().from(path, col).select(path); + } + + /** + * Create a new update clause + * + * @param path source expression + * @param col source collection + * @return query + */ + public static CollUpdateClause update(Path path, Iterable col) { + return new CollUpdateClause(path, col); + } + + private CollQueryFactory() { } + +} diff --git a/querydsl-collections/src/main/java/com/querydsl/collections/CollQueryFunctions.java b/querydsl-collections/src/main/java/com/querydsl/collections/CollQueryFunctions.java new file mode 100644 index 0000000000..4477a38293 --- /dev/null +++ b/querydsl-collections/src/main/java/com/querydsl/collections/CollQueryFunctions.java @@ -0,0 +1,311 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.collections; + +import java.lang.reflect.Field; +import java.math.BigDecimal; +import java.util.*; +import java.util.regex.Pattern; + +import org.jetbrains.annotations.Nullable; + +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.Operator; +import com.querydsl.core.types.Ops; +import com.querydsl.core.util.MathUtils; +import com.querydsl.core.util.ReflectionUtils; + +/** + * {@code CollQueryFunctions} defines function implementation for use in ColQueryTemplates + * + * @author tiwe + * + */ +public final class CollQueryFunctions { + + private interface BinaryFunction { + + Number apply(Number num1, Number num2); + } + + private static final BinaryFunction SUM = new BinaryFunction() { + @Override + public Number apply(Number num1, Number num2) { + return MathUtils.sum(num1, num2); + } + }; + + private static final BinaryFunction MAX = new BinaryFunction() { + @Override + public Number apply(Number num1, Number num2) { + if (num1.getClass().equals(num2.getClass()) && num1 instanceof Comparable) { + @SuppressWarnings("unchecked") // The types are interchangeable, guarded by previous check + Comparable left = (Comparable) num1; + return left.compareTo(num2) < 0 ? num2 : num1; + } else { + BigDecimal n1 = new BigDecimal(num1.toString()); + BigDecimal n2 = new BigDecimal(num2.toString()); + return n1.compareTo(n2) < 0 ? num2 : num1; + } + } + }; + + private static final BinaryFunction MIN = new BinaryFunction() { + @Override + public Number apply(Number num1, Number num2) { + if (num1.getClass().equals(num2.getClass()) && num1 instanceof Comparable) { + @SuppressWarnings("unchecked") // The types are interchangeable, guarded by previous check + Comparable left = (Comparable) num1; + return left.compareTo(num2) < 0 ? num1 : num2; + } else { + BigDecimal n1 = new BigDecimal(num1.toString()); + BigDecimal n2 = new BigDecimal(num2.toString()); + return n1.compareTo(n2) < 0 ? num1 : num2; + } + } + }; + + private static final List nullList = Collections.singletonList((Object) null); + + @SuppressWarnings("unused") + public static boolean equals(Object o1, Object o2) { + return Objects.equals(o1, o2); + } + + public static > int compareTo(T c1, T c2) { + if (c1 == null) { + return c2 == null ? 0 : -1; + } else if (c2 == null) { + return 1; + } else { + return c1.compareTo(c2); + } + } + + public static > boolean between(A a, A b, A c) { + return compareTo(a, b) >= 0 && compareTo(a, c) <= 0; + } + + public static double cot(double x) { + return Math.cos(x) / Math.sin(x); + } + + public static double coth(double x) { + return Math.cosh(x) / Math.sinh(x); + } + + public static double degrees(double x) { + return x * 180.0 / Math.PI; + } + + public static double radians(double x) { + return x * Math.PI / 180.0; + } + + public static double log(double x, int y) { + return Math.log(x) / Math.log(y); + } + + @Nullable + public static T coalesce(T... args) { + for (T arg : args) { + if (arg != null) { + return arg; + } + } + return null; + } + + public static T nullif(T first, T second) { + if (first.equals(second)) { + return null; + } else { + return first; + } + } + + public static int getYearMonth(Date date) { + Calendar cal = Calendar.getInstance(); + cal.setTime(date); + return cal.get(Calendar.YEAR) * 100 + cal.get(Calendar.MONTH) + 1; + } + + public static int getDayOfMonth(Date date) { + return getField(date, Calendar.DAY_OF_MONTH); + } + + public static int getDayOfWeek(Date date) { + return getField(date, Calendar.DAY_OF_WEEK); + } + + public static int getDayOfYear(Date date) { + return getField(date, Calendar.DAY_OF_YEAR); + } + + private static int getField(Date date, int field) { + Calendar cal = Calendar.getInstance(); + cal.setTime(date); + return cal.get(field); + } + + public static int getHour(Date date) { + return getField(date, Calendar.HOUR_OF_DAY); + } + + public static int getMilliSecond(Date date) { + return getField(date, Calendar.MILLISECOND); + } + + public static int getMinute(Date date) { + return getField(date, Calendar.MINUTE); + } + + public static int getMonth(Date date) { + return getField(date, Calendar.MONTH) + 1; + } + + public static int getSecond(Date date) { + return getField(date, Calendar.SECOND); + } + + public static int getWeek(Date date) { + return getField(date, Calendar.WEEK_OF_YEAR); + } + + public static int getYear(Date date) { + return getField(date, Calendar.YEAR); + } + + public static int getYearWeek(Date date) { + Calendar cal = Calendar.getInstance(); + cal.setTime(date); + return cal.get(Calendar.YEAR) * 100 + cal.get(Calendar.WEEK_OF_YEAR); + } + + public static Collection leftJoin(Collection coll) { + if (coll == null || coll.isEmpty()) { + @SuppressWarnings("unchecked") // List only contains null + Collection rv = (Collection) nullList; + return rv; + } else { + return coll; + } + } + + private static Number reduce(Iterable source, BinaryFunction f) { + Iterator it = source.iterator(); + Number result = it.next(); + while (it.hasNext()) { + result = f.apply(result, it.next()); + } + return result; + } + + public static Number aggregate(Collection source, Expression expr, Operator aggregator) { + @SuppressWarnings("unchecked") // This is a number expression + Class numberType = (Class) expr.getType(); + if (aggregator == Ops.AggOps.AVG_AGG) { + Number sum = reduce(source, SUM); + return sum.doubleValue() / source.size(); + } else if (aggregator == Ops.AggOps.COUNT_AGG) { + return (long) source.size(); + } else if (aggregator == Ops.AggOps.COUNT_DISTINCT_AGG) { + if (!Set.class.isInstance(source)) { + source = new HashSet<>(source); + } + return (long) source.size(); + } else if (aggregator == Ops.AggOps.MAX_AGG) { + return MathUtils.cast(reduce(source, MAX), numberType); + } else if (aggregator == Ops.AggOps.MIN_AGG) { + return MathUtils.cast(reduce(source, MIN), numberType); + } else if (aggregator == Ops.AggOps.SUM_AGG) { + return MathUtils.cast(reduce(source, SUM), numberType); + } else { + throw new IllegalArgumentException("Unknown operator " + aggregator); + } + } + + public static boolean like(final String str, String like) { + final StringBuilder pattern = new StringBuilder(like.length() + 4); + for (int i = 0; i < like.length(); i++) { + final char ch = like.charAt(i); + if (ch == '%') { + pattern.append(".*"); + continue; + } else if (ch == '_') { + pattern.append('.'); + continue; + } else if (ch == '.' || ch == '$' || ch == '^') { + pattern.append('\\'); + } + pattern.append(ch); + } + if (pattern.toString().equals(like)) { + return str.equals(like); + } else { + return str.matches(pattern.toString()); + } + } + + public static boolean like(String str, String like, char escape) { + return like(str, like); + } + + public static boolean likeIgnoreCase(String str, String like) { + final StringBuilder pattern = new StringBuilder(like.length() + 4); + for (int i = 0; i < like.length(); i++) { + final char ch = like.charAt(i); + if (ch == '%') { + pattern.append(".*"); + continue; + } else if (ch == '_') { + pattern.append('.'); + continue; + } else if (ch == '.' || ch == '$' || ch == '^') { + pattern.append('\\'); + } + pattern.append(ch); + } + if (pattern.toString().equals(like)) { + return str.equalsIgnoreCase(like); + } else { + return Pattern.compile(pattern.toString(), Pattern.CASE_INSENSITIVE) + .matcher(str).matches(); + } + } + + public static boolean likeIgnoreCase(String str, String like, char escape) { + return likeIgnoreCase(str, like); + } + + public static T get(Object parent, String f) { + try { + Field field = ReflectionUtils.getFieldOrNull(parent.getClass(), f); + if (field != null) { + field.setAccessible(true); + @SuppressWarnings("unchecked") + T rv = (T) field.get(parent); + return rv; + } else { + throw new IllegalArgumentException("No field " + f + " for " + parent.getClass()); + } + } catch (IllegalAccessException e) { + throw new IllegalStateException(e); + } + } + + private CollQueryFunctions() { } + + +} diff --git a/querydsl-collections/src/main/java/com/querydsl/collections/CollQueryMixin.java b/querydsl-collections/src/main/java/com/querydsl/collections/CollQueryMixin.java new file mode 100644 index 0000000000..2b98f2fbb0 --- /dev/null +++ b/querydsl-collections/src/main/java/com/querydsl/collections/CollQueryMixin.java @@ -0,0 +1,62 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.collections; + +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.support.Context; +import com.querydsl.core.support.QueryMixin; +import com.querydsl.core.types.ExpressionUtils; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.Predicate; +import com.querydsl.core.types.dsl.Expressions; + +/** + * {@code CollQueryMixin} extends {@link QueryMixin} to provide normalization logic specific to this module + * + * @author tiwe + * + * @param + */ +public class CollQueryMixin extends QueryMixin { + + private static final Predicate ANY = Expressions.booleanTemplate("any"); + + public CollQueryMixin() { } + + public CollQueryMixin(QueryMetadata metadata) { + super(metadata); + } + + public CollQueryMixin(T self, QueryMetadata metadata) { + super(self, metadata); + } + + @Override + protected Predicate convert(Predicate predicate, Role role) { + predicate = (Predicate) ExpressionUtils.extract(predicate); + if (predicate != null) { + Context context = new Context(); + Predicate transformed = (Predicate) predicate.accept(collectionAnyVisitor, context); + for (int i = 0; i < context.paths.size(); i++) { + leftJoin( + (Path) context.paths.get(i).getMetadata().getParent(), + (Path) context.replacements.get(i)); + on(ANY); + } + return transformed; + } else { + return predicate; + } + } +} diff --git a/querydsl-collections/src/main/java/com/querydsl/collections/CollQuerySerializer.java b/querydsl-collections/src/main/java/com/querydsl/collections/CollQuerySerializer.java new file mode 100644 index 0000000000..3a30b0d088 --- /dev/null +++ b/querydsl-collections/src/main/java/com/querydsl/collections/CollQuerySerializer.java @@ -0,0 +1,219 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.collections; + +import java.beans.BeanInfo; +import java.beans.IntrospectionException; +import java.beans.Introspector; +import java.beans.PropertyDescriptor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.IdentityHashMap; +import java.util.List; +import java.util.Map; + +import com.querydsl.codegen.Serializer; +import com.querydsl.core.QueryException; +import com.querydsl.core.support.SerializerBase; +import com.querydsl.core.types.*; +import com.querydsl.core.util.PrimitiveUtils; + +/** + * {@code CollQuerySerializer} is a {@link Serializer} implementation for the Java language + * + * @author tiwe + */ +public final class CollQuerySerializer extends SerializerBase { + + private static final Map OPERATOR_SYMBOLS = new IdentityHashMap<>(); + + private static final Map, String> CAST_SUFFIXES = new HashMap<>(); + + static { + OPERATOR_SYMBOLS.put(Ops.EQ, " == "); + OPERATOR_SYMBOLS.put(Ops.NE, " != "); + OPERATOR_SYMBOLS.put(Ops.GT, " > "); + OPERATOR_SYMBOLS.put(Ops.LT, " < "); + OPERATOR_SYMBOLS.put(Ops.GOE, " >= "); + OPERATOR_SYMBOLS.put(Ops.LOE, " <= "); + + OPERATOR_SYMBOLS.put(Ops.ADD, " + "); + OPERATOR_SYMBOLS.put(Ops.SUB, " - "); + OPERATOR_SYMBOLS.put(Ops.MULT, " * "); + OPERATOR_SYMBOLS.put(Ops.DIV, " / "); + + CAST_SUFFIXES.put(Boolean.class, ".booleanValue()"); + CAST_SUFFIXES.put(Byte.class, ".byteValue()"); + CAST_SUFFIXES.put(Character.class, ".charValue()"); + CAST_SUFFIXES.put(Double.class, ".doubleValue()"); + CAST_SUFFIXES.put(Float.class, ".floatValue()"); + CAST_SUFFIXES.put(Integer.class, ".intValue()"); + CAST_SUFFIXES.put(Long.class, ".longValue()"); + CAST_SUFFIXES.put(Short.class, ".shortValue()"); + CAST_SUFFIXES.put(String.class, ".toString()"); + } + + public CollQuerySerializer(CollQueryTemplates templates) { + super(templates); + } + + @Override + public Void visit(Path path, Void context) { + final PathType pathType = path.getMetadata().getPathType(); + if (pathType == PathType.PROPERTY) { + final Path parent = path.getMetadata().getParent(); + final String property = path.getMetadata().getName(); + final Class parentType = parent.getType(); + try { + // getter + Method m = getAccessor(parentType, property); + if (m != null && Modifier.isPublic(m.getModifiers())) { + handle(parent); + append(".").append(m.getName()).append("()"); + } else { + // field + Field f = getField(parentType, property); + if (f != null && Modifier.isPublic(f.getModifiers())) { + handle(parent); + append(".").append(property); + } else { + // field access by reflection + append(CollQueryFunctions.class.getName() + ".<"); + append((path.getType()).getName()).append(">get("); + handle(parent); + append(", \"" + property + "\")"); + } + } + } catch (Exception e) { + throw new QueryException(e); + } + + } else if (pathType == PathType.DELEGATE) { + append("("); + append("(").append(path.getType().getName()).append(")"); + path.getMetadata().getParent().accept(this, context); + append(")"); + + } else { + List args = new ArrayList(2); + if (path.getMetadata().getParent() != null) { + args.add(path.getMetadata().getParent()); + } + args.add(path.getMetadata().getElement()); + final Template template = getTemplate(pathType); + for (Template.Element element : template.getElements()) { + Object rv = element.convert(args); + if (rv instanceof Expression) { + ((Expression) rv).accept(this, context); + } else if (element.isString()) { + append(rv.toString()); + } else { + visitConstant(rv); + } + } + } + return null; + + } + + private Method getAccessor(Class owner, String property) { + try { + BeanInfo beanInfo = Introspector.getBeanInfo(owner); + PropertyDescriptor[] descriptors = beanInfo.getPropertyDescriptors(); + for (PropertyDescriptor pd : descriptors) { + if (pd.getName().equals(property)) { + return pd.getReadMethod(); + } + } + return null; + } catch (IntrospectionException e) { + return null; + } + } + + private Field getField(Class owner, String field) { + try { + return owner.getField(field); + } catch (NoSuchFieldException e) { + return null; + } + } + + @Override + public Void visit(SubQueryExpression expr, Void context) { + throw new IllegalArgumentException("Not supported"); + } + + private void visitCast(Operator operator, Expression source, Class targetType) { + if (Number.class.isAssignableFrom(source.getType()) && !Constant.class.isInstance(source)) { + append("new ").append(source.getType().getSimpleName()).append("("); + handle(source); + append(")"); + } else { + handle(source); + } + + if (CAST_SUFFIXES.containsKey(targetType)) { + append(CAST_SUFFIXES.get(targetType)); + } else { + throw new IllegalArgumentException("Unsupported cast type " + targetType.getName()); + } + } + + @Override + protected void visitOperation(Class type, Operator operator, List> args) { + if (Ops.aggOps.contains(operator)) { + throw new UnsupportedOperationException("Aggregation operators are only supported as single expressions"); + } + if (args.size() == 2 && OPERATOR_SYMBOLS.containsKey(operator) + && isPrimitiveOrWrapperType(args.get(0).getType()) && isPrimitiveOrWrapperType(args.get(1).getType())) { + handle(args.get(0)); + append(OPERATOR_SYMBOLS.get(operator)); + handle(args.get(1)); + if (args.get(1) instanceof Constant) { + append(CAST_SUFFIXES.get(args.get(1).getType())); + } + return; + } + + if (operator == Ops.STRING_CAST) { + visitCast(operator, args.get(0), String.class); + } else if (operator == Ops.NUMCAST) { + @SuppressWarnings("unchecked") //this is the second argument's type + Constant> rightArg = (Constant>) args.get(1); + + visitCast(operator, args.get(0), rightArg.getConstant()); + } else { + super.visitOperation(type, operator, args); + } + } + + private static boolean isPrimitiveOrWrapperType(Class type) { + return type.isPrimitive() || PrimitiveUtils.isWrapperType(type); + } + + @Override + public Void visit(FactoryExpression expr, Void context) { + visitConstant(expr); + append(".newInstance("); + append("new Object[] {"); + handle(", ", expr.getArgs()); + append("})"); + return null; + } + +} diff --git a/querydsl-collections/src/main/java/com/mysema/query/collections/CollQueryTemplates.java b/querydsl-collections/src/main/java/com/querydsl/collections/CollQueryTemplates.java similarity index 87% rename from querydsl-collections/src/main/java/com/mysema/query/collections/CollQueryTemplates.java rename to querydsl-collections/src/main/java/com/querydsl/collections/CollQueryTemplates.java index c3315761ba..8fa66af6de 100644 --- a/querydsl-collections/src/main/java/com/mysema/query/collections/CollQueryTemplates.java +++ b/querydsl-collections/src/main/java/com/querydsl/collections/CollQueryTemplates.java @@ -1,5 +1,5 @@ /* - * Copyright 2011, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,20 +11,21 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.collections; +package com.querydsl.collections; -import com.mysema.query.types.JavaTemplates; -import com.mysema.query.types.Ops; -import com.mysema.query.types.PathType; +import com.querydsl.core.types.JavaTemplates; +import com.querydsl.core.types.Ops; +import com.querydsl.core.types.PathType; /** - * CollQueryTemplates extends {@link JavaTemplates} to add module specific operation + * {@code CollQueryTemplates} extends {@link JavaTemplates} to add module specific operation * templates. * * @author tiwe */ public class CollQueryTemplates extends JavaTemplates { + @SuppressWarnings("FieldNameHidesFieldInSuperclass") //intentional public static final CollQueryTemplates DEFAULT = new CollQueryTemplates(); protected CollQueryTemplates() { @@ -72,7 +73,9 @@ protected CollQueryTemplates() { // String add(Ops.LIKE, functions + ".like({0},{1})"); + add(Ops.LIKE_IC, functions + ".likeIgnoreCase({0},{1})"); add(Ops.LIKE_ESCAPE, functions + ".like({0},{1},{2})"); + add(Ops.LIKE_ESCAPE_IC, functions + ".likeIgnoreCase({0},{1},{2})"); // Path types for (PathType type : new PathType[] { diff --git a/querydsl-collections/src/main/java/com/mysema/query/collections/CollUpdateClause.java b/querydsl-collections/src/main/java/com/querydsl/collections/CollUpdateClause.java similarity index 81% rename from querydsl-collections/src/main/java/com/mysema/query/collections/CollUpdateClause.java rename to querydsl-collections/src/main/java/com/querydsl/collections/CollUpdateClause.java index be42b79b01..55ebb9e36c 100644 --- a/querydsl-collections/src/main/java/com/mysema/query/collections/CollUpdateClause.java +++ b/querydsl-collections/src/main/java/com/querydsl/collections/CollUpdateClause.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,20 +11,20 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.collections; +package com.querydsl.collections; import java.util.HashMap; import java.util.List; import java.util.Map; -import com.mysema.query.dml.UpdateClause; -import com.mysema.query.types.Expression; -import com.mysema.query.types.Path; -import com.mysema.query.types.Predicate; -import com.mysema.util.BeanMap; +import com.querydsl.core.dml.UpdateClause; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.Predicate; +import com.querydsl.core.util.BeanMap; /** - * CollUpdateClause is an implementation of the UpdateClause interface for Querydsl Collections + * {@code CollUpdateClause} is an implementation of the {@link UpdateClause} interface for Querydsl Collections * * @author tiwe * @@ -32,15 +32,12 @@ */ public class CollUpdateClause implements UpdateClause> { - private final Path expr; - private final Map, Object> paths = new HashMap, Object>(); - private final CollQuery query; + private final CollQuery query; public CollUpdateClause(QueryEngine qe, Path expr, Iterable col) { - this.query = new CollQuery(qe).from(expr, col); - this.expr = expr; + this.query = new CollQuery(qe).from(expr, col).select(expr); } public CollUpdateClause(Path expr, Iterable col) { @@ -50,7 +47,7 @@ public CollUpdateClause(Path expr, Iterable col) { @Override public long execute() { int rv = 0; - for (T match : query.list(expr)) { + for (T match : query.fetch()) { BeanMap beanMap = new BeanMap(match); for (Map.Entry,Object> entry : paths.entrySet()) { // TODO : support deep updates as well @@ -67,14 +64,14 @@ public CollUpdateClause set(Path path, U value) { paths.put(path, value); return this; } - + @Override public CollUpdateClause set(Path path, Expression expression) { // TODO : implement throw new UnsupportedOperationException(); } - + @Override public CollUpdateClause setNull(Path path) { paths.put(path, null); @@ -94,7 +91,7 @@ public CollUpdateClause where(Predicate... o) { query.where(o); return this; } - + @Override public String toString() { return "update " + query; diff --git a/querydsl-collections/src/main/java/com/querydsl/collections/DefaultEvaluatorFactory.java b/querydsl-collections/src/main/java/com/querydsl/collections/DefaultEvaluatorFactory.java new file mode 100644 index 0000000000..5e460c3ed1 --- /dev/null +++ b/querydsl-collections/src/main/java/com/querydsl/collections/DefaultEvaluatorFactory.java @@ -0,0 +1,298 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.collections; + +import com.querydsl.codegen.utils.ECJEvaluatorFactory; +import com.querydsl.codegen.utils.Evaluator; +import com.querydsl.codegen.utils.EvaluatorFactory; +import com.querydsl.codegen.utils.JDKEvaluatorFactory; +import com.querydsl.codegen.utils.model.ClassType; +import com.querydsl.codegen.utils.model.SimpleType; +import com.querydsl.codegen.utils.model.Type; +import com.querydsl.codegen.utils.model.TypeCategory; +import com.querydsl.codegen.utils.model.Types; +import com.querydsl.codegen.utils.support.ClassUtils; +import com.querydsl.core.JoinExpression; +import com.querydsl.core.JoinType; +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.support.CollectionAnyVisitor; +import com.querydsl.core.support.Context; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.FactoryExpression; +import com.querydsl.core.types.Operation; +import com.querydsl.core.types.ParamExpression; +import com.querydsl.core.types.ParamNotSetException; +import com.querydsl.core.types.Predicate; +import com.querydsl.core.util.PrimitiveUtils; +import org.jetbrains.annotations.Nullable; + +import javax.tools.JavaCompiler; +import javax.tools.ToolProvider; +import java.net.URLClassLoader; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * {@code DefaultEvaluatorFactory} provides Java source templates for evaluation of {@link CollQuery} queries + * + * @author tiwe + * + */ +public class DefaultEvaluatorFactory { + + private final EvaluatorFactory factory; + + private final CollQueryTemplates templates; + + private final CollectionAnyVisitor collectionAnyVisitor = new CollectionAnyVisitor(); + + public DefaultEvaluatorFactory(CollQueryTemplates templates) { + this(templates, + Thread.currentThread().getContextClassLoader() != null ? Thread.currentThread().getContextClassLoader() : DefaultEvaluatorFactory.class.getClassLoader()); + } + + public DefaultEvaluatorFactory(CollQueryTemplates templates, EvaluatorFactory factory) { + this.templates = templates; + this.factory = factory; + } + + protected DefaultEvaluatorFactory(CollQueryTemplates templates, + URLClassLoader classLoader, JavaCompiler compiler) { + this.templates = templates; + this.factory = new JDKEvaluatorFactory(classLoader, compiler); + } + + protected DefaultEvaluatorFactory(CollQueryTemplates templates, ClassLoader classLoader) { + this.templates = templates; + final JavaCompiler systemJavaCompiler = ToolProvider.getSystemJavaCompiler(); + if (classLoader instanceof URLClassLoader && systemJavaCompiler != null) { + this.factory = new JDKEvaluatorFactory((URLClassLoader) classLoader, systemJavaCompiler); + } else { + // for OSGi and JRE compatibility + this.factory = new ECJEvaluatorFactory(classLoader); + } + } + + /** + * Create an Evaluator for the given query sources and projection + * + * @param + * @param metadata query metadata + * @param sources sources of the query + * @param projection projection of the query + * @return evaluator + */ + public Evaluator create(QueryMetadata metadata, List> sources, + Expression projection) { + final CollQuerySerializer serializer = new CollQuerySerializer(templates); + serializer.append("return "); + if (projection instanceof FactoryExpression) { + serializer.append("("); + serializer.append(ClassUtils.getName(projection.getType())); + serializer.append(")("); + serializer.handle(projection); + serializer.append(")"); + } else { + serializer.handle(projection); + } + serializer.append(";"); + + Map constantToLabel = serializer.getConstantToLabel(); + Map constants = getConstants(metadata, constantToLabel); + Class[] types = new Class[sources.size()]; + String[] names = new String[sources.size()]; + for (int i = 0; i < sources.size(); i++) { + types[i] = sources.get(i).getType(); + names[i] = sources.get(i).toString(); + } + + // normalize types + for (int i = 0; i < types.length; i++) { + if (PrimitiveUtils.isWrapperType(types[i])) { + types[i] = PrimitiveUtils.unwrap(types[i]); + } + } + + return factory.createEvaluator(serializer.toString(), projection.getType(), names, + types, constants); + } + + /** + * Create an Evaluator for the given source and filter + * + * @param + * @param source source of the query + * @param filter filter of the query + * @return evaluator + */ + public Evaluator> createEvaluator(QueryMetadata metadata, + Expression source, Predicate filter) { + String typeName = ClassUtils.getName(source.getType()); + CollQuerySerializer ser = new CollQuerySerializer(templates); + ser.append("java.util.List<" + typeName + "> rv = new java.util.ArrayList<" + typeName + ">();\n"); + ser.append("for (" + typeName + " " + source + " : " + source + "_) {\n"); + ser.append(" try {\n"); + ser.append(" if (").handle(filter).append(") {\n"); + ser.append(" rv.add(" + source + ");\n"); + ser.append(" }\n"); + ser.append(" } catch (NullPointerException npe) { }\n"); + ser.append("}\n"); + ser.append("return rv;"); + + Map constantToLabel = ser.getConstantToLabel(); + Map constants = getConstants(metadata, constantToLabel); + + Type sourceType = new ClassType(TypeCategory.SIMPLE, source.getType()); + ClassType sourceListType = new ClassType(TypeCategory.SIMPLE, Iterable.class, sourceType); + + return factory.createEvaluator( + ser.toString(), + sourceListType, + new String[]{source + "_"}, + new Type[]{sourceListType}, + new Class[]{Iterable.class}, + constants); + } + + /** + * Create an Evaluator for the given sources and the given optional filter + * + * @param metadata query metadata + * @param joins joins + * @param filter where condition + * @return evaluator + */ + public Evaluator> createEvaluator(QueryMetadata metadata, + List joins, @Nullable Predicate filter) { + List sourceNames = new ArrayList(); + List sourceTypes = new ArrayList(); + List> sourceClasses = new ArrayList>(); + StringBuilder vars = new StringBuilder(); + CollQuerySerializer ser = new CollQuerySerializer(templates); + ser.append("java.util.List rv = new java.util.ArrayList();\n"); + + List anyJoinMatchers = new ArrayList(); + + // creating context + for (JoinExpression join : joins) { + Expression target = join.getTarget(); + String typeName = com.querydsl.codegen.utils.support.ClassUtils.getName(target.getType()); + if (vars.length() > 0) { + vars.append(","); + } + switch (join.getType()) { + case DEFAULT: + ser.append("for (" + typeName + " " + target + " : " + target + "_) {\n"); + vars.append(target); + sourceNames.add(target + "_"); + sourceTypes.add(new SimpleType(Types.ITERABLE, new ClassType(TypeCategory.SIMPLE,target.getType()))); + sourceClasses.add(Iterable.class); + break; + + case INNERJOIN: + case LEFTJOIN: + Operation alias = (Operation) join.getTarget(); + boolean colAnyJoin = join.getCondition() != null && join.getCondition().toString().equals("any"); + boolean leftJoin = join.getType() == JoinType.LEFTJOIN; + String matcher = null; + if (colAnyJoin) { + matcher = alias.getArg(1).toString() + "_matched"; + ser.append("boolean " + matcher + " = false;\n"); + anyJoinMatchers.add(matcher); + } + ser.append("for (" + typeName + " " + alias.getArg(1) + " : "); + if (leftJoin) { + ser.append(CollQueryFunctions.class.getName() + ".leftJoin("); + } + if (colAnyJoin) { + Context context = new Context(); + Expression replacement = alias.getArg(0) + .accept(collectionAnyVisitor, context); + ser.handle(replacement); + } else { + ser.handle(alias.getArg(0)); + } + if (alias.getArg(0).getType().equals(Map.class)) { + ser.append(".values()"); + } + if (leftJoin) { + ser.append(")"); + } + ser.append(") {\n"); + if (matcher != null) { + ser.append("if (!" + matcher + ") {\n"); + } + vars.append(alias.getArg(1)); + break; + + default: + throw new IllegalArgumentException("Illegal join expression " + join); + } + } + + // filter + if (filter != null) { + ser.append("try {\n"); + ser.append("if ("); + ser.handle(filter).append(") {\n"); + for (String matcher : anyJoinMatchers) { + ser.append(" " + matcher + " = true;\n"); + } + ser.append(" rv.add(new Object[]{" + vars + "});\n"); + ser.append("}\n"); + ser.append("} catch (NullPointerException npe) { }\n"); + } else { + ser.append("rv.add(new Object[]{" + vars + "});\n"); + } + + // closing context + int amount = joins.size() + anyJoinMatchers.size(); + for (int i = 0; i < amount; i++) { + ser.append("}\n"); + } + ser.append("return rv;"); + + Map constantToLabel = ser.getConstantToLabel(); + Map constants = getConstants(metadata, constantToLabel); + + ClassType projectionType = new ClassType(TypeCategory.LIST, List.class, Types.OBJECTS); + return factory.createEvaluator( + ser.toString(), + projectionType, + sourceNames.toArray(new String[0]), + sourceTypes.toArray(new Type[0]), + sourceClasses.toArray(new Class[0]), + constants); + } + + private Map getConstants(QueryMetadata metadata, + Map constantToLabel) { + Map constants = new HashMap(); + for (Map.Entry entry : constantToLabel.entrySet()) { + if (entry.getKey() instanceof ParamExpression) { + Object value = metadata.getParams().get(entry.getKey()); + if (value == null) { + throw new ParamNotSetException((ParamExpression) entry.getKey()); + } + constants.put(entry.getValue(), value); + } else { + constants.put(entry.getValue(), entry.getKey()); + } + } + return constants; + } + +} diff --git a/querydsl-collections/src/main/java/com/mysema/query/collections/DefaultQueryEngine.java b/querydsl-collections/src/main/java/com/querydsl/collections/DefaultQueryEngine.java similarity index 78% rename from querydsl-collections/src/main/java/com/mysema/query/collections/DefaultQueryEngine.java rename to querydsl-collections/src/main/java/com/querydsl/collections/DefaultQueryEngine.java index 0934755431..e09247cdf1 100644 --- a/querydsl-collections/src/main/java/com/mysema/query/collections/DefaultQueryEngine.java +++ b/querydsl-collections/src/main/java/com/querydsl/collections/DefaultQueryEngine.java @@ -1,5 +1,5 @@ /* - * Copyright 2011, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,30 +11,30 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.collections; +package com.querydsl.collections; + +import com.querydsl.codegen.utils.Evaluator; +import com.mysema.commons.lang.IteratorAdapter; +import com.querydsl.core.JoinExpression; +import com.querydsl.core.JoinType; +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.QueryModifiers; +import com.querydsl.core.types.ArrayConstructorExpression; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.Operation; +import com.querydsl.core.types.Operator; +import com.querydsl.core.types.Ops; +import com.querydsl.core.types.Order; +import com.querydsl.core.types.OrderSpecifier; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Iterators; -import com.mysema.codegen.Evaluator; -import com.mysema.commons.lang.IteratorAdapter; -import com.mysema.query.JoinExpression; -import com.mysema.query.JoinType; -import com.mysema.query.QueryMetadata; -import com.mysema.query.QueryModifiers; -import com.mysema.query.types.ArrayConstructorExpression; -import com.mysema.query.types.Expression; -import com.mysema.query.types.Operation; -import com.mysema.query.types.Operator; -import com.mysema.query.types.Ops; -import com.mysema.query.types.Order; -import com.mysema.query.types.OrderSpecifier; +import java.util.stream.Collectors; /** * Default implementation of the {@link QueryEngine} interface @@ -45,13 +45,13 @@ @SuppressWarnings("unchecked") public class DefaultQueryEngine implements QueryEngine { - private static volatile QueryEngine DEFAULT; + private static transient volatile QueryEngine defaultQueryEngine; public static QueryEngine getDefault() { - if (DEFAULT == null) { - DEFAULT = new DefaultQueryEngine(new DefaultEvaluatorFactory(CollQueryTemplates.DEFAULT)); + if (defaultQueryEngine == null) { + defaultQueryEngine = new DefaultQueryEngine(new DefaultEvaluatorFactory(CollQueryTemplates.DEFAULT)); } - return DEFAULT; + return defaultQueryEngine; } private final DefaultEvaluatorFactory evaluatorFactory; @@ -72,7 +72,7 @@ public long count(QueryMetadata metadata, Map, Iterable> iterab @Override public boolean exists(QueryMetadata metadata, Map, Iterable> iterables) { QueryModifiers modifiers = metadata.getModifiers(); - metadata.setLimit(1l); + metadata.setLimit(1L); try { if (metadata.getJoins().size() == 1) { return !evaluateSingleSource(metadata, iterables, true).isEmpty(); @@ -99,7 +99,7 @@ private List distinct(List list) { if (!list.isEmpty() && list.get(0) != null && list.get(0).getClass().isArray()) { Set set = new HashSet(list.size()); for (T o : list) { - if (set.add(ImmutableList.copyOf((Object[])o))) { + if (set.add(Collections.unmodifiableList(Arrays.asList((Object[]) o)))) { rv.add(o); } } @@ -166,14 +166,14 @@ private List evaluateSingleSource(QueryMetadata metadata, Map, final Iterable iterable = iterables.values().iterator().next(); List list; if (iterable instanceof List) { - list = (List)iterable; + list = (List) iterable; } else { list = IteratorAdapter.asList(iterable.iterator()); } // from & where if (metadata.getWhere() != null) { - Evaluator> evaluator = (Evaluator)evaluatorFactory + Evaluator> evaluator = (Evaluator) evaluatorFactory .createEvaluator(metadata, source, metadata.getWhere()); list = evaluator.evaluate(list); } @@ -188,7 +188,7 @@ private List evaluateSingleSource(QueryMetadata metadata, Map, order(metadata, sources, list); } // projection - if (metadata.getProjection().size() > 1 || !metadata.getProjection().get(0).equals(source)) { + if (metadata.getProjection() != null && !metadata.getProjection().equals(source)) { list = project(metadata, sources, list); } // limit + offset @@ -214,29 +214,30 @@ private void order(QueryMetadata metadata, List> sources, List List> orderBy = metadata.getOrderBy(); Expression[] orderByExpr = new Expression[orderBy.size()]; boolean[] directions = new boolean[orderBy.size()]; + boolean[] nullsLast = new boolean[orderBy.size()]; for (int i = 0; i < orderBy.size(); i++) { orderByExpr[i] = (Expression) orderBy.get(i).getTarget(); directions[i] = orderBy.get(i).getOrder() == Order.ASC; + nullsLast[i] = orderBy.get(i).getNullHandling() == OrderSpecifier.NullHandling.NullsLast; } Expression expr = new ArrayConstructorExpression(Object[].class, orderByExpr); Evaluator orderEvaluator = evaluatorFactory.create(metadata, sources, expr); - Collections.sort(list, new MultiComparator(orderEvaluator, directions)); + list.sort(new MultiComparator(orderEvaluator, directions, nullsLast)); } private List project(QueryMetadata metadata, List> sources, List list) { - Expression projection = metadata.getProjection().get(0); - Operator aggregator = null; - if (projection instanceof Operation && Ops.aggOps.contains(((Operation)projection).getOperator())) { - Operation aggregation = (Operation)projection; + Expression projection = metadata.getProjection(); + Operator aggregator = null; + if (projection instanceof Operation && Ops.aggOps.contains(((Operation) projection).getOperator())) { + Operation aggregation = (Operation) projection; aggregator = aggregation.getOperator(); projection = aggregation.getArg(0); } Evaluator projectionEvaluator = evaluatorFactory.create(metadata, sources, projection); - EvaluatorFunction transformer = new EvaluatorFunction(projectionEvaluator); - List target = new ArrayList(); - Iterators.addAll(target, Iterators.transform(list.iterator(), transformer)); + EvaluatorFunction transformer = new EvaluatorFunction(projectionEvaluator); + List target = list.stream().map(transformer).collect(Collectors.toList()); if (aggregator != null) { - return ImmutableList.of(CollQueryFunctions.aggregate(target, projection, aggregator)); + return Collections.singletonList(CollQueryFunctions.aggregate(target, projection, aggregator)); } else { return target; } diff --git a/querydsl-collections/src/main/java/com/mysema/query/collections/EvaluatorFunction.java b/querydsl-collections/src/main/java/com/querydsl/collections/EvaluatorFunction.java similarity index 77% rename from querydsl-collections/src/main/java/com/mysema/query/collections/EvaluatorFunction.java rename to querydsl-collections/src/main/java/com/querydsl/collections/EvaluatorFunction.java index fb4493239c..eab6b0cb03 100644 --- a/querydsl-collections/src/main/java/com/mysema/query/collections/EvaluatorFunction.java +++ b/querydsl-collections/src/main/java/com/querydsl/collections/EvaluatorFunction.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,14 +11,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.collections; +package com.querydsl.collections; -import com.google.common.base.Function; -import com.mysema.codegen.Evaluator; +import com.querydsl.codegen.utils.Evaluator; + +import java.util.function.Function; /** * Function implementation which uses an {@link Evaluator} for transformation - * + * + * @param source type + * @param target type + * * @author tiwe */ public class EvaluatorFunction implements Function { @@ -34,7 +38,7 @@ public T apply(S input) { if (input.getClass().isArray()) { return ev.evaluate((Object[]) input); } else { - return ev.evaluate(new Object[]{input}); + return ev.evaluate(input); } } } diff --git a/querydsl-collections/src/main/java/com/querydsl/collections/FunctionalHelpers.java b/querydsl-collections/src/main/java/com/querydsl/collections/FunctionalHelpers.java new file mode 100644 index 0000000000..3176f7e5f7 --- /dev/null +++ b/querydsl-collections/src/main/java/com/querydsl/collections/FunctionalHelpers.java @@ -0,0 +1,77 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.collections; + +import com.querydsl.codegen.utils.Evaluator; +import com.querydsl.core.EmptyMetadata; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathExtractor; +import com.querydsl.core.types.Predicate; + +import java.util.Collections; +import java.util.function.Function; + +/** + * {@code GuavaHelpers} provides functionality to wrap Querydsl {@link Predicate} instances to Guava predicates + * and Querydsl {@link Expression} instances to Guava functions + * + * @author tiwe + * + */ +public final class FunctionalHelpers { + + private static final DefaultEvaluatorFactory evaluatorFactory = + new DefaultEvaluatorFactory(CollQueryTemplates.DEFAULT); + + /** + * Wrap a Querydsl predicate into a Guava predicate + * + * @param predicate predicate to wrapped + * @return Guava predicate + */ + public static java.util.function.Predicate wrap(Predicate predicate) { + Path path = predicate.accept(PathExtractor.DEFAULT, null); + if (path != null) { + final Evaluator ev = createEvaluator(path.getRoot(), predicate); + return ev::evaluate; + } else { + throw new IllegalArgumentException("No path in " + predicate); + } + } + + /** + * Wrap a Querydsl expression into a Guava function + * + * @param projection projection to wrap + * @return Guava function + */ + public static Function wrap(Expression projection) { + Path path = projection.accept(PathExtractor.DEFAULT, null); + if (path != null) { + final Evaluator ev = createEvaluator(path.getRoot(), projection); + return ev::evaluate; + } else { + throw new IllegalArgumentException("No path in " + projection); + } + } + + private static Evaluator createEvaluator(Path path, Expression projection) { + return evaluatorFactory.create(EmptyMetadata.DEFAULT, + Collections.singletonList(path), projection); + } + + private FunctionalHelpers() { } + +} diff --git a/querydsl-collections/src/main/java/com/mysema/query/collections/JodaTimeTemplates.java b/querydsl-collections/src/main/java/com/querydsl/collections/JodaTimeTemplates.java similarity index 85% rename from querydsl-collections/src/main/java/com/mysema/query/collections/JodaTimeTemplates.java rename to querydsl-collections/src/main/java/com/querydsl/collections/JodaTimeTemplates.java index 4ca3617860..ea53433384 100644 --- a/querydsl-collections/src/main/java/com/mysema/query/collections/JodaTimeTemplates.java +++ b/querydsl-collections/src/main/java/com/querydsl/collections/JodaTimeTemplates.java @@ -1,5 +1,5 @@ /* - * Copyright 2012, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,9 +11,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.collections; +package com.querydsl.collections; -import com.mysema.query.types.Ops; +import com.querydsl.core.types.Ops; /** @@ -24,7 +24,8 @@ */ public class JodaTimeTemplates extends CollQueryTemplates { - public static final CollQueryTemplates DEFAULT = new JodaTimeTemplates(); + @SuppressWarnings("FieldNameHidesFieldInSuperclass") //Intentional + public static final JodaTimeTemplates DEFAULT = new JodaTimeTemplates(); protected JodaTimeTemplates() { add(Ops.DateTimeOps.YEAR, "{0}.getYear()"); diff --git a/querydsl-collections/src/main/java/com/querydsl/collections/MultiComparator.java b/querydsl-collections/src/main/java/com/querydsl/collections/MultiComparator.java new file mode 100644 index 0000000000..a68e3740bf --- /dev/null +++ b/querydsl-collections/src/main/java/com/querydsl/collections/MultiComparator.java @@ -0,0 +1,73 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.collections; + +import java.io.Serializable; +import java.util.Comparator; + +import com.querydsl.codegen.utils.Evaluator; +import com.querydsl.core.util.NullSafeComparableComparator; + +/** + * {@code MultiComparator} compares arrays + * + * @param element type + * @author tiwe + */ +public class MultiComparator implements Comparator, Serializable { + + @SuppressWarnings("unchecked") + private static final Comparator naturalOrder = new NullSafeComparableComparator(); + + private static final long serialVersionUID = 1121416260773566299L; + + private final boolean[] asc; + + private final boolean[] nullsLast; + + private final transient Evaluator ev; + + public MultiComparator(Evaluator ev, boolean[] directions, boolean[] nullsLast) { + this.ev = ev; + this.asc = directions.clone(); + this.nullsLast = nullsLast.clone(); + } + + @Override + public int compare(T o1, T o2) { + if (o1 instanceof Object[]) { + return innerCompare(ev.evaluate((Object[]) o1), ev.evaluate((Object[]) o2)); + } else { + return innerCompare(ev.evaluate(o1), ev.evaluate(o2)); + } + } + + private int innerCompare(Object[] o1, Object[] o2) { + for (int i = 0; i < o1.length; i++) { + if (o1[i] == null) { + return o2[i] == null ? 0 : nullsLast[i] ? 1 : -1; + } else if (o2[i] == null) { + return nullsLast[i] ? -1 : 1; + } else { + int res; + res = naturalOrder.compare(o1[i], o2[i]); + if (res != 0) { + return asc[i] ? res : -res; + } + } + } + return 0; + } + +} diff --git a/querydsl-collections/src/main/java/com/mysema/query/collections/PathComparator.java b/querydsl-collections/src/main/java/com/querydsl/collections/PathComparator.java similarity index 85% rename from querydsl-collections/src/main/java/com/mysema/query/collections/PathComparator.java rename to querydsl-collections/src/main/java/com/querydsl/collections/PathComparator.java index 13486f993c..4e1139ecd5 100644 --- a/querydsl-collections/src/main/java/com/mysema/query/collections/PathComparator.java +++ b/querydsl-collections/src/main/java/com/querydsl/collections/PathComparator.java @@ -1,6 +1,6 @@ /* - * Copyright 2012, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,12 +11,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.collections; +package com.querydsl.collections; -import java.util.Comparator; +import com.querydsl.core.types.Path; -import com.google.common.base.Function; -import com.mysema.query.types.Path; +import java.util.Comparator; +import java.util.function.Function; /** * Compares two beans based on the values at a specific path. @@ -28,25 +28,25 @@ * @param type of value being matched */ public class PathComparator> implements Comparator { - + private final Function accessor; - + public PathComparator(Path comparingPath) { - this(comparingPath, GuavaHelpers.wrap(comparingPath)); + this(comparingPath, FunctionalHelpers.wrap(comparingPath)); } - + public PathComparator(Path comparingPath, Function accessor) { this.accessor = accessor; } - + public static > PathComparator pathComparator(Path comparingPath) { return new PathComparator(comparingPath); } @Override public int compare(T leftBean, T rightBean) { - if(leftBean == rightBean) { - return 0; // Reference to the seme object should always result in '0' + if (leftBean == rightBean) { + return 0; // Reference to the same object should always result in '0' } else if (leftBean == null) { return -1; // Whenever the reference varies and left is null, right is not null } else if (rightBean == null) { @@ -56,7 +56,7 @@ public int compare(T leftBean, T rightBean) { } return comparePathValues(leftBean, rightBean); } - + private int comparePathValues(T leftBean, T rightBean) { V left = accessor.apply(leftBean); V right = accessor.apply(rightBean); diff --git a/querydsl-collections/src/main/java/com/mysema/query/collections/PathMatcher.java b/querydsl-collections/src/main/java/com/querydsl/collections/PathMatcher.java similarity index 87% rename from querydsl-collections/src/main/java/com/mysema/query/collections/PathMatcher.java rename to querydsl-collections/src/main/java/com/querydsl/collections/PathMatcher.java index b89d00fbde..03432cbb20 100644 --- a/querydsl-collections/src/main/java/com/mysema/query/collections/PathMatcher.java +++ b/querydsl-collections/src/main/java/com/querydsl/collections/PathMatcher.java @@ -1,6 +1,6 @@ /* - * Copyright 2012, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,55 +11,52 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.collections; - -import static org.hamcrest.core.IsNull.notNullValue; +package com.querydsl.collections; +import com.querydsl.core.types.Path; import org.hamcrest.Description; -import org.hamcrest.Factory; import org.hamcrest.Matcher; import org.hamcrest.TypeSafeDiagnosingMatcher; -import com.google.common.base.Function; -import com.mysema.query.types.Path; +import java.util.function.Function; + +import static org.hamcrest.core.IsNull.notNullValue; /** * Matches based on the current value of a path. - * + * * @author Jeroen van Schagen * @author tiwe * * @param type of the path root * @param type of value being matched */ -public class PathMatcher extends TypeSafeDiagnosingMatcher { - +public class PathMatcher extends TypeSafeDiagnosingMatcher { + private final Function accessor; - + private final Matcher matcher; - + private final Path path; - + public PathMatcher(Path path, Matcher matcher) { - this(path, matcher, GuavaHelpers.wrap(path)); + this(path, matcher, FunctionalHelpers.wrap(path)); } - + public PathMatcher(Path path, Matcher matcher, Function accessor) { this.path = path; this.matcher = matcher; this.accessor = accessor; } - - @Factory + public static Matcher hasValue(Path

path) { return new PathMatcher(path, notNullValue()); } - - @Factory + public static Matcher hasValue(Path

path, Matcher matcher) { return new PathMatcher(path, matcher); } - + @Override protected boolean matchesSafely(T bean, Description mismatchDescription) { V value = accessor.apply(bean); @@ -79,5 +76,5 @@ public void describeTo(Description description) { description.appendDescriptionOf(matcher); description.appendText(")"); } - + } diff --git a/querydsl-collections/src/main/java/com/querydsl/collections/QueryEngine.java b/querydsl-collections/src/main/java/com/querydsl/collections/QueryEngine.java new file mode 100644 index 0000000000..bb61210872 --- /dev/null +++ b/querydsl-collections/src/main/java/com/querydsl/collections/QueryEngine.java @@ -0,0 +1,58 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.collections; + +import java.util.List; +import java.util.Map; + +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.types.Expression; + +/** + * {@code QueryEngine} defines an interface for the evaluation of ColQuery queries + * + * @author tiwe + * + */ +public interface QueryEngine { + + /** + * Evaluate the given query and return the count of matched rows + * + * @param metadata query metadata + * @param iterables source contents + * @return matching row count + */ + long count(QueryMetadata metadata, Map, Iterable> iterables); + + /** + * Evaluate the given query and return the projection as a list + * + * @param metadata query metadata + * @param iterables source contents + * @return matching rows + */ + List list(QueryMetadata metadata, Map, Iterable> iterables, + Expression projection); + + /** + * Evaluate the given query return whether rows where matched + * + * @param metadata query metadata + * @param iterables source contents + * @return true, if at least one row was matched + */ + boolean exists(QueryMetadata metadata, Map, Iterable> iterables); + +} diff --git a/querydsl-collections/src/main/java/com/querydsl/collections/package-info.java b/querydsl-collections/src/main/java/com/querydsl/collections/package-info.java new file mode 100644 index 0000000000..9bde598cf1 --- /dev/null +++ b/querydsl-collections/src/main/java/com/querydsl/collections/package-info.java @@ -0,0 +1,18 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ + +/** + * Java Bean collections support + */ +package com.querydsl.collections; diff --git a/querydsl-collections/src/test/java/InnerClassTest.java b/querydsl-collections/src/test/java/InnerClassTest.java deleted file mode 100644 index 4e528913db..0000000000 --- a/querydsl-collections/src/test/java/InnerClassTest.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ - -import static com.mysema.query.alias.Alias.$; -import static com.mysema.query.alias.Alias.alias; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import java.util.Arrays; - -import org.junit.Test; - -import com.mysema.query.collections.CollQueryFactory; - -public class InnerClassTest { - - public static class Example { - - public String getId() { - return null; - } - } - - @Test - public void Query() { - Example example = alias(Example.class); - assertFalse(CollQueryFactory.from($(example), Arrays.asList(new Example())) - .where($(example.getId()).isNull()) - .list($(example)).isEmpty()); - assertTrue(CollQueryFactory.from($(example), Arrays.asList(new Example())) - .where($(example.getId()).isNotNull()) - .list($(example)).isEmpty()); - } - -} diff --git a/querydsl-collections/src/test/java/com/mysema/query/CollQueryStandardTest.java b/querydsl-collections/src/test/java/com/mysema/query/CollQueryStandardTest.java deleted file mode 100644 index 272ec1edff..0000000000 --- a/querydsl-collections/src/test/java/com/mysema/query/CollQueryStandardTest.java +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; - -import java.util.Arrays; -import java.util.Date; -import java.util.List; - -import org.junit.Test; - -import com.mysema.commons.lang.Pair; -import com.mysema.query.collections.Cat; -import com.mysema.query.collections.CollQueryFactory; -import com.mysema.query.collections.QCat; -import com.mysema.query.types.ArrayConstructorExpression; -import com.mysema.query.types.Concatenation; -import com.mysema.query.types.ConstructorExpression; -import com.mysema.query.types.Expression; -import com.mysema.query.types.ParamNotSetException; -import com.mysema.query.types.Predicate; -import com.mysema.query.types.QTuple; -import com.mysema.query.types.expr.Param; - -public class CollQueryStandardTest { - - private final Date birthDate = new Date(); - - private final java.sql.Date date = new java.sql.Date(birthDate.getTime()); - - private final java.sql.Time time = new java.sql.Time(birthDate.getTime()); - - private final QCat cat = new QCat("cat"); - - private final QCat otherCat = new QCat("otherCat"); - - private final List data = Arrays.asList( - new Cat("Bob", 1, birthDate), - new Cat("Ruth", 2, birthDate), - new Cat("Felix", 3, birthDate), - new Cat("Allen", 4, birthDate), - new Cat("Mary", 5, birthDate) - ); - - private static final Expression[] NO_EXPRESSIONS = new Expression[0]; - - private QueryExecution standardTest = new QueryExecution(Module.COLLECTIONS, Target.MEM) { - @Override - protected Pair[]> createQuery() { - return Pair.of( - (Projectable)CollQueryFactory.from(cat, data).from(otherCat, data), - NO_EXPRESSIONS); - } - @Override - protected Pair[]> createQuery(Predicate filter) { - return Pair.of( - (Projectable)CollQueryFactory.from(cat, data).from(otherCat, data).where(filter), - new Expression[]{cat.name}); - } - }; - - @Test - public void test() { - Cat kitten = data.get(0).getKittens().get(0); - standardTest.runArrayTests(cat.kittenArray, otherCat.kittenArray, kitten, new Cat()); - standardTest.runBooleanTests(cat.name.isNull(), otherCat.kittens.isEmpty()); - standardTest.runCollectionTests(cat.kittens, otherCat.kittens, kitten, new Cat()); - standardTest.runDateTests(cat.dateField, otherCat.dateField, date); - standardTest.runDateTimeTests(cat.birthdate, otherCat.birthdate, birthDate); - standardTest.runListTests(cat.kittens, otherCat.kittens, kitten, new Cat()); - standardTest.runMapTests(cat.kittensByName, otherCat.kittensByName, "Kitty", kitten, "NoName", new Cat()); - - // int - standardTest.runNumericCasts(cat.id, otherCat.id, 1); - standardTest.runNumericTests(cat.id, otherCat.id, 1); - - standardTest.runStringTests(cat.name, otherCat.name, "Bob"); - standardTest.runTimeTests(cat.timeField, otherCat.timeField, time); - standardTest.report(); - } - - @Test - public void TupleProjection() { - List tuples = CollQueryFactory.from(cat, data) - .list(new QTuple(cat.name, cat.birthdate)); - for (Tuple tuple : tuples) { - assertNotNull(tuple.get(cat.name)); - assertNotNull(tuple.get(cat.birthdate)); - } - } - - @Test - public void Nested_TupleProjection() { - Concatenation concat = new Concatenation(cat.name, cat.name); - List tuples = CollQueryFactory.from(cat, data) - .list(new QTuple(concat, cat.name, cat.birthdate)); - for (Tuple tuple : tuples) { - assertNotNull(tuple.get(cat.name)); - assertNotNull(tuple.get(cat.birthdate)); - assertEquals(tuple.get(cat.name) + tuple.get(cat.name), tuple.get(concat)); - } - } - - @SuppressWarnings("unchecked") - @Test - public void ArrayProjection() { - List results = CollQueryFactory.from(cat, data) - .list(new ArrayConstructorExpression(String[].class, cat.name)); - assertFalse(results.isEmpty()); - for (String[] result : results) { - assertNotNull(result[0]); - } - } - - @Test - public void ConstructorProjection() { - List projections = CollQueryFactory.from(cat, data) - .list(ConstructorExpression.create(Projection.class, cat.name, cat)); - assertFalse(projections.isEmpty()); - for (Projection projection : projections) { - assertNotNull(projection); - } - } - - @Test - public void Params() { - Param name = new Param(String.class,"name"); - assertEquals("Bob", CollQueryFactory.from(cat, data).where(cat.name.eq(name)).set(name,"Bob").uniqueResult(cat.name)); - } - - @Test - public void Params_anon() { - Param name = new Param(String.class); - assertEquals("Bob", CollQueryFactory.from(cat, data).where(cat.name.eq(name)).set(name,"Bob").uniqueResult(cat.name)); - } - - @Test(expected=ParamNotSetException.class) - public void Params_not_set() { - Param name = new Param(String.class,"name"); - assertEquals("Bob", CollQueryFactory.from(cat, data).where(cat.name.eq(name)).uniqueResult(cat.name)); - } - - @Test - public void Limit() { - CollQueryFactory.from(cat, data).limit(Long.MAX_VALUE).list(cat); - } - -} diff --git a/querydsl-collections/src/test/java/com/mysema/query/Projection.java b/querydsl-collections/src/test/java/com/mysema/query/Projection.java deleted file mode 100644 index 32a6b1e784..0000000000 --- a/querydsl-collections/src/test/java/com/mysema/query/Projection.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.mysema.query; - -import com.mysema.query.collections.Cat; - -public class Projection { - - public Projection(String str, Cat cat) { - } - -} \ No newline at end of file diff --git a/querydsl-collections/src/test/java/com/mysema/query/QueryPerformanceTest.java b/querydsl-collections/src/test/java/com/mysema/query/QueryPerformanceTest.java deleted file mode 100644 index a03a2dea53..0000000000 --- a/querydsl-collections/src/test/java/com/mysema/query/QueryPerformanceTest.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.mysema.query; - -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.List; - -import org.junit.BeforeClass; -import org.junit.Ignore; -import org.junit.Test; -import org.junit.experimental.categories.Category; - -import com.mysema.query.collections.Cat; -import com.mysema.query.collections.CollQueryFactory; -import com.mysema.query.collections.QCat; -import com.mysema.testutil.Benchmark; -import com.mysema.testutil.Performance; -import com.mysema.testutil.Runner; - -@Ignore -@Category(Performance.class) -public class QueryPerformanceTest { - - private static final int size = 1000; - - private static List cats = new ArrayList(size); - - @BeforeClass - public static void setUpClass() throws SQLException, ClassNotFoundException { - for (int i = 0; i < size; i++) { - cats.add(new Cat(String.valueOf(i), i)); - } - } - - @Test - public void ById() throws Exception { - // 15857 - Runner.run("by id", new Benchmark() { - @Override - public void run(int times) throws Exception { - for (int i = 0; i < times; i++) { - QCat cat = QCat.cat; - CollQueryFactory.from(cat, cats).where(cat.id.eq(i % size)).list(cat); - } - } - }); - } - - -} diff --git a/querydsl-collections/src/test/java/com/mysema/query/collections/AbstractQueryTest.java b/querydsl-collections/src/test/java/com/mysema/query/collections/AbstractQueryTest.java deleted file mode 100644 index db399d3c30..0000000000 --- a/querydsl-collections/src/test/java/com/mysema/query/collections/AbstractQueryTest.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.collections; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import org.junit.Before; - -import com.mysema.query.DefaultQueryMetadata; -import com.mysema.query.QueryMetadata; -import com.mysema.query.alias.Alias; -import com.mysema.query.types.Expression; - -public abstract class AbstractQueryTest { - - protected final Cat c1 = new Cat("Kitty"); - - protected final Cat c2 = new Cat("Bob"); - - protected final Cat c3 = new Cat("Alex"); - - protected final Cat c4 = new Cat("Francis"); - - protected final QCat cat = new QCat("cat"); - - protected final QCat kitten = new QCat("kitten"); - - protected final QCat offspr = new QCat("offspr"); - - protected final QCat otherCat = new QCat("otherCat"); - - protected final QCat mate = new QCat("mate"); - - protected List cats = Arrays.asList(c1, c2, c3, c4); - - protected List ints = new ArrayList(); - - protected List myInts = new ArrayList(); - - protected TestQuery last; - - - @Before - public void setUp() { - myInts.addAll(Arrays.asList(1, 2, 3, 4)); - Alias.resetAlias(); - } - - protected List cats(int size) { - List cats = new ArrayList(size); - for (int i = 0; i < size / 2; i++) { - cats.add(new Cat("Kate" + (i + 1))); - cats.add(new Cat("Bob" + (i + 1))); - } - return cats; - } - - protected TestQuery query() { - last = new TestQuery(); - return last; - } - - static class TestQuery extends AbstractCollQuery { - - List res = new ArrayList(); - - public TestQuery() { - super(new DefaultQueryMetadata(), DefaultQueryEngine.getDefault()); - } - - @Override - public QueryMetadata getMetadata() { - return queryMixin.getMetadata(); - } - - @Override - public List list(Expression projection) { - boolean array = projection.getType().isArray(); - List rv = super.list(projection); - for (Object o : rv) { - //System.out.println(array ? Arrays.toString((Object[])o) : o); - res.add(o); - } - //System.out.println(); - return rv; - } - - } -} diff --git a/querydsl-collections/src/test/java/com/mysema/query/collections/AggregationTest.java b/querydsl-collections/src/test/java/com/mysema/query/collections/AggregationTest.java deleted file mode 100644 index 6b92ab8695..0000000000 --- a/querydsl-collections/src/test/java/com/mysema/query/collections/AggregationTest.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.mysema.query.collections; - -import static org.junit.Assert.assertEquals; - -import java.util.Arrays; - -import org.junit.Before; -import org.junit.Test; - -public class AggregationTest extends AbstractQueryTest { - - private static final QCat cat = QCat.cat; - - private CollQuery query; - - @Override - @Before - public void setUp() { - Cat cat1 = new Cat(); - cat1.setWeight(2); - Cat cat2 = new Cat(); - cat2.setWeight(3); - Cat cat3 = new Cat(); - cat3.setWeight(4); - Cat cat4 = new Cat(); - cat4.setWeight(5); - query = CollQueryFactory.from(cat, Arrays.asList(cat1, cat2, cat3, cat4)); - } - - @Test - public void Avg() { - assertEquals(Double.valueOf(3.5), query.uniqueResult(cat.weight.avg())); - } - - @Test - public void Count() { - assertEquals(Long.valueOf(4l), query.uniqueResult(cat.count())); - } - - @Test - public void CountDistinct() { - assertEquals(Long.valueOf(4l), query.uniqueResult(cat.countDistinct())); - } - - @Test - public void Max() { - assertEquals(Integer.valueOf(5), query.uniqueResult(cat.weight.max())); - } - - @Test - public void Min() { - assertEquals(Integer.valueOf(2), query.uniqueResult(cat.weight.min())); - } - - @Test - public void Sum() { - assertEquals(Integer.valueOf(14), query.uniqueResult(cat.weight.sum())); - } - -} diff --git a/querydsl-collections/src/test/java/com/mysema/query/collections/AliasTest.java b/querydsl-collections/src/test/java/com/mysema/query/collections/AliasTest.java deleted file mode 100644 index f78970fd6e..0000000000 --- a/querydsl-collections/src/test/java/com/mysema/query/collections/AliasTest.java +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.collections; - -import static com.mysema.query.alias.Alias.$; -import static com.mysema.query.alias.Alias.alias; -import static com.mysema.query.alias.Alias.var; -import static com.mysema.query.collections.CollQueryFactory.from; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import java.util.Date; - -import org.junit.Before; -import org.junit.Test; - -import com.mysema.query.alias.Alias; -import com.mysema.query.types.path.NumberPath; -import com.mysema.query.types.path.StringPath; - -public class AliasTest extends AbstractQueryTest { - - @Before - public void setUp() { - myInts.add(1); - myInts.add(2); - myInts.add(3); - myInts.add(4); - - Alias.resetAlias(); - } - - @Test - public void AliasVariations1() { - // 1st - QCat cat = new QCat("cat"); - for (String name : from(cat, cats).where(cat.kittens.size().gt(0)).list(cat.name)) { - assertNotNull(name); - System.out.println(name); - } - - // 2nd - Cat c = alias(Cat.class, "cat"); - for (String name : from(c, cats).where($(c.getKittens()).size().gt(0)).list($(c.getName()))) { - assertNotNull(name); - System.out.println(name); - } - - // 2nd - variation 1 -// for (String name : from(c, cats).where($(c.getKittens().size()).gt(0)) -// .list(c.getName())) { -// System.out.println(name); -// } - - } - - @Test - public void AliasVariations2() { - // 1st - QCat cat = new QCat("cat"); - for (String name : from(cat, cats).where(cat.name.matches("fri.*")).list(cat.name)) { - assertNotNull(name); - System.out.println(name); - } - - // 2nd - Cat c = alias(Cat.class, "cat"); - for (String name : from(c, cats).where($(c.getName()).matches("fri.*")).list($(c.getName()))) { - assertNotNull(name); - System.out.println(name); - } - } - - @Test - public void Alias3() { - QCat cat = new QCat("cat"); - Cat other = new Cat(); - Cat c = alias(Cat.class, "cat"); - - // 1 - from(c, cats).where($(c.getBirthdate()).gt(new Date())).list($(c)).iterator(); - - // 2 - try { - from(c, cats).where($(c.getMate().getName().toUpperCase()).eq("MOE")); - fail("expected NPE"); - } catch (NullPointerException ne) { - // expected - } - - // 3 - assertEquals(cat.name, $(c.getName())); - - // 4 - from(c,cats) - .where($(c.getKittens().get(0).getBodyWeight()).gt(12)) - .list($(c.getName())).iterator(); - - // 5 - from(c, cats).where($(c).eq(other)).list($(c)).iterator(); - - // 6 - from(c, cats).where($(c.getKittens()).contains(other)).list($(c)) - .iterator(); - - // 7 - from(c, cats).where($(c.getKittens().isEmpty())).list($(c)).iterator(); - - // 8 - from(c, cats).where($(c.getName()).startsWith("B")).list($(c)).iterator(); - - // 9 - from(c, cats).where($(c.getName()).upper().eq("MOE")).list($(c)).iterator(); - - // 10 - assertNotNull($(c.getKittensByName())); - assertNotNull($(c.getKittensByName().get("Kitty"))); - from(c, cats).where($(c.getKittensByName().get("Kitty")).isNotNull()).list(cat); - - // 11 -// try { -// from(cat, cats).where(cat.mate.alive).list(cat); -// fail("expected RuntimeException"); -// } catch (RuntimeException e) { -// System.out.println(e.getMessage()); -// assertEquals("null in cat.mate.alive", e.getMessage()); -// } - - // 12 - // TestQuery query = query().from(cat, c1, c2).from(cat, c1, c2); - // assertEquals(1, query.getMetadata().getJoins().size()); - - } - - @Test - public void Various1() { - StringPath str = new StringPath("str"); - for (String s : from(str, "a", "ab", "cd", "de").where(str.startsWith("a")).list(str)) { - assertTrue(s.equals("a") || s.equals("ab")); - System.out.println(s); - } - } - - @Test - public void Various2() { - for (Object o : from(var(), 1, 2, "abc", 5, 3).where(var().ne("abc")).list(var())) { - int i = (Integer) o; - assertTrue(i > 0 && i < 6); - System.out.println(o); - } - } - - @Test - public void Various3() { - NumberPath num = new NumberPath(Integer.class, "num"); - for (Integer i : from(num, 1, 2, 3, 4).where(num.lt(4)).list(num)) { - System.out.println(i); - } - } - -} diff --git a/querydsl-collections/src/test/java/com/mysema/query/collections/Animal.java b/querydsl-collections/src/test/java/com/mysema/query/collections/Animal.java deleted file mode 100644 index eab37fc798..0000000000 --- a/querydsl-collections/src/test/java/com/mysema/query/collections/Animal.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.collections; - -import java.util.Date; - -import com.mysema.query.annotations.PropertyType; -import com.mysema.query.annotations.QueryEntity; -import com.mysema.query.annotations.QueryType; - -@QueryEntity -public class Animal { - - protected boolean alive; - - protected java.util.Date birthdate = new java.util.Date(); - - @QueryType(PropertyType.SIMPLE) - private Date dateAsSimple; - - protected int bodyWeight, weight, toes; - - protected Color color; - - protected int id; - - protected String name; - - public java.util.Date getBirthdate() { - return birthdate; - } - - public int getBodyWeight() { - return bodyWeight; - } - - public Color getColor() { - return color; - } - - public int getId() { - return id; - } - - public String getName() { - return name; - } - - public int getToes() { - return toes; - } - - public int getWeight() { - return weight; - } - - public boolean isAlive() { - return alive; - } - - public void setAlive(boolean alive) { - this.alive = alive; - } - - public void setBirthdate(java.util.Date birthdate) { - this.birthdate = new Date(birthdate.getTime()); - } - - public void setBodyWeight(int bodyWeight) { - this.bodyWeight = bodyWeight; - } - - public void setWeight(int weight) { - this.weight = weight; - } - - public void setToes(int toes) { - this.toes = toes; - } - - public void setColor(Color color) { - this.color = color; - } - - public void setId(int id) { - this.id = id; - } - - public void setName(String name) { - this.name = name; - } - - public Date getDateAsSimple() { - return dateAsSimple; - } - - public void setDateAsSimple(Date dateAsSimple) { - this.dateAsSimple = new Date(dateAsSimple.getTime()); - } - -} diff --git a/querydsl-collections/src/test/java/com/mysema/query/collections/AnimalTest.java b/querydsl-collections/src/test/java/com/mysema/query/collections/AnimalTest.java deleted file mode 100644 index bf77148310..0000000000 --- a/querydsl-collections/src/test/java/com/mysema/query/collections/AnimalTest.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.collections; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import org.junit.Test; - -import com.mysema.query.types.path.SimplePath; - -public class AnimalTest { - - @Test - public void Cast() { - QCat cat = QAnimal.animal.as(QCat.class); - assertEquals(QAnimal.animal, cat.getMetadata().getElement()); - assertEquals("animal", cat.toString()); - } - - @Test - public void Date_As_Simple() { - assertTrue(QAnimal.animal.dateAsSimple.getClass().equals(SimplePath.class)); - } - -} diff --git a/querydsl-collections/src/test/java/com/mysema/query/collections/BigDecimalTest.java b/querydsl-collections/src/test/java/com/mysema/query/collections/BigDecimalTest.java deleted file mode 100644 index 426d783a91..0000000000 --- a/querydsl-collections/src/test/java/com/mysema/query/collections/BigDecimalTest.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.mysema.query.collections; - -import java.math.BigDecimal; -import java.util.Arrays; - -import org.junit.Test; - -import com.mysema.query.types.path.NumberPath; - -public class BigDecimalTest { - - @Test - public void Arithmetic() { - NumberPath num = new NumberPath(BigDecimal.class, "num"); - CollQuery query = CollQueryFactory.from(num, Arrays.asList(BigDecimal.ONE, BigDecimal.ONE)); - query.list(num.add(BigDecimal.ONE)); - query.list(num.subtract(BigDecimal.ONE)); - query.list(num.multiply(BigDecimal.ONE)); - query.list(num.divide(BigDecimal.ONE)); - } - -} diff --git a/querydsl-collections/src/test/java/com/mysema/query/collections/BooleanTest.java b/querydsl-collections/src/test/java/com/mysema/query/collections/BooleanTest.java deleted file mode 100644 index 6e9b891707..0000000000 --- a/querydsl-collections/src/test/java/com/mysema/query/collections/BooleanTest.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.mysema.query.collections; - -import java.util.Collections; - -import org.junit.Test; - -import com.mysema.query.alias.Alias; -import static com.mysema.query.alias.Alias.*; - -public class BooleanTest { - - public static class Entity { - - private boolean boolean1 = true; - - private Boolean boolean2 = Boolean.TRUE; - - public boolean isBoolean1() { - return boolean1; - } - - public Boolean getBoolean2() { - return boolean2; - } - - } - - @Test - public void Primitive_Boolean() { - Entity entity = Alias.alias(Entity.class); - CollQueryFactory.from(entity, Collections.singleton(new Entity())) - .where($(entity.isBoolean1()).eq(Boolean.TRUE)) - .count(); - } - - @Test - public void Object_Boolean() { - Entity entity = Alias.alias(Entity.class); - CollQueryFactory.from(entity, Collections.singleton(new Entity())) - .where($(entity.getBoolean2()).eq(Boolean.TRUE)) - .count(); - - } - -} diff --git a/querydsl-collections/src/test/java/com/mysema/query/collections/CastTest.java b/querydsl-collections/src/test/java/com/mysema/query/collections/CastTest.java deleted file mode 100644 index 44b4a1c1ca..0000000000 --- a/querydsl-collections/src/test/java/com/mysema/query/collections/CastTest.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.mysema.query.collections; - -import static org.junit.Assert.*; - -import org.junit.Test; - -public class CastTest extends AbstractQueryTest { - - @Test - public void Parents() { - QCat cat = QAnimal.animal.as(QCat.class); - assertEquals(QAnimal.animal, cat.getMetadata().getParent()); - } - - @Test - public void Cast() { - query().from(QAnimal.animal, cats) - .where(QAnimal.animal.as(QCat.class).breed.eq(0)) - .list(QAnimal.animal); - } - - @Test - public void PropertyDereference() { - Cat cat = new Cat(); - cat.setEyecolor(Color.TABBY); - assertEquals(Color.TABBY, - CollQueryFactory.from(QAnimal.animal, cat) - .where(QAnimal.animal.instanceOf(Cat.class)) - .singleResult(QAnimal.animal.as(QCat.class).eyecolor)); - } - -} diff --git a/querydsl-collections/src/test/java/com/mysema/query/collections/Cat.java b/querydsl-collections/src/test/java/com/mysema/query/collections/Cat.java deleted file mode 100644 index 7be1a81f19..0000000000 --- a/querydsl-collections/src/test/java/com/mysema/query/collections/Cat.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.collections; - -import java.util.Arrays; -import java.util.Collections; -import java.util.Date; -import java.util.List; -import java.util.Map; - -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.mysema.query.annotations.PropertyType; -import com.mysema.query.annotations.QueryEntity; -import com.mysema.query.annotations.QueryProjection; -import com.mysema.query.annotations.QueryType; - -@QueryEntity -public class Cat extends Animal { - - private int breed; - - private java.sql.Date dateField; - - private Color eyecolor; - - private List kittens = Lists.newArrayList(); - - private Cat[] kittenArray; - - private Map kittensByName = Maps.newHashMap(); - - private Cat mate; - - @QueryType(PropertyType.NONE) - private String skippedField; - - @QueryType(PropertyType.SIMPLE) - private String stringAsSimple; - - private java.sql.Time timeField; - - public Cat() { - this.kittensByName = Collections.emptyMap(); - } - - public Cat(String name) { - Cat kitten = new Cat(); - this.kittens = Arrays.asList(kitten); - this.kittenArray = new Cat[]{kitten}; - this.kittensByName = Collections.singletonMap("Kitty", kitten); - this.name = name; - } - - public Cat(String name, String kittenName) { - this(name); - kittens.get(0).setName(kittenName); - } - - @QueryProjection - public Cat(String name, int id) { - this(name); - this.id = id; - } - - public Cat(String name, int id, Date birthdate) { - this(name, id); - this.birthdate = new Date(birthdate.getTime()); - this.dateField = new java.sql.Date(birthdate.getTime()); - this.timeField = new java.sql.Time(birthdate.getTime()); - } - - public int getBreed() { - return breed; - } - - public java.sql.Date getDateField() { - return dateField; - } - - public Color getEyecolor() { - return eyecolor; - } - - public List getKittens() { - return kittens; - } - - public Map getKittensByName() { - return kittensByName; - } - - public Cat getMate() { - return mate; - } - - public String getSkippedField() { - return skippedField; - } - - public String getStringAsSimple() { - return stringAsSimple; - } - - public java.sql.Time getTimeField() { - return timeField; - } - - public void setBreed(int breed) { - this.breed = breed; - } - - public void setDateField(java.sql.Date dateField) { - this.dateField = new java.sql.Date(dateField.getTime()); - } - - public void setEyecolor(Color eyecolor) { - this.eyecolor = eyecolor; - } - - public void setKittens(List kittens) { - this.kittens = kittens; - } - - public void setKittensByName(Map kittensByName) { - this.kittensByName = kittensByName; - } - - public void setMate(Cat mate) { - this.mate = mate; - } - - public void setSkippedField(String skippedField) { - this.skippedField = skippedField; - } - - public void setStringAsSimple(String stringAsSimple) { - this.stringAsSimple = stringAsSimple; - } - - public void setTimeField(java.sql.Time timeField) { - this.timeField = timeField; - } - - public Cat[] getKittenArray() { - return kittenArray; - } - - public void setKittenArray(Cat[] kittenArray) { - this.kittenArray = kittenArray.clone(); - } - - @Override - public String toString() { - return name; - } - -} diff --git a/querydsl-collections/src/test/java/com/mysema/query/collections/CatTest.java b/querydsl-collections/src/test/java/com/mysema/query/collections/CatTest.java deleted file mode 100644 index f49b04fed0..0000000000 --- a/querydsl-collections/src/test/java/com/mysema/query/collections/CatTest.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.collections; - -import static org.junit.Assert.assertTrue; - -import org.junit.Test; - -import com.mysema.query.types.path.SimplePath; - -public class CatTest { - - @Test(expected=NoSuchFieldException.class) - public void SkippedField() throws SecurityException, NoSuchFieldException{ - QCat.class.getField("skippedField"); - } - - @Test - public void StringAsSimple() throws SecurityException, NoSuchFieldException { - assertTrue(QCat.cat.stringAsSimple.getClass().equals(SimplePath.class)); - } - - @Test - public void DateAsSimple() { - assertTrue(QCat.cat.dateAsSimple.getClass().equals(SimplePath.class)); - } -} diff --git a/querydsl-collections/src/test/java/com/mysema/query/collections/CollQueryTest.java b/querydsl-collections/src/test/java/com/mysema/query/collections/CollQueryTest.java deleted file mode 100644 index fabedd4b1c..0000000000 --- a/querydsl-collections/src/test/java/com/mysema/query/collections/CollQueryTest.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.collections; - -import static com.mysema.query.collections.CollQueryFactory.from; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import java.math.BigDecimal; -import java.util.Arrays; -import java.util.Collections; -import java.util.Date; -import java.util.List; - -import org.junit.Test; - -import com.mysema.query.Tuple; -import com.mysema.query.types.Expression; -import com.mysema.query.types.Ops; -import com.mysema.query.types.expr.NumberExpression; -import com.mysema.query.types.path.NumberPath; -import com.mysema.query.types.path.StringPath; - -public class CollQueryTest extends AbstractQueryTest { - - @Test - public void CustomTemplates() { - CollQueryTemplates templates = new CollQueryTemplates() {{ - add(Ops.DateTimeOps.MONTH, "{0}.getMonthOfYear()"); - add(Ops.DateTimeOps.YEAR, "{0}.getYear()"); - }}; - new CollQuery(templates); - } - - @Test - public void InstanceOf() { - assertEquals( - Arrays.asList(c1, c2), - query().from(cat, Arrays.asList(c1, c2)).where(cat.instanceOf(Cat.class)).list(cat)); - } - - @Test - public void After_And_Before() { - query().from(cat, Arrays.asList(c1, c2)) - .where( - cat.birthdate.lt(new Date()), - cat.birthdate.loe(new Date()), - cat.birthdate.gt(new Date()), - cat.birthdate.goe(new Date())) - .list(cat); - } - - @Test - public void ArrayProjection() { - // select pairs of cats with different names - query().from(cat, cats).from(otherCat, cats).where(cat.name.ne(otherCat.name)).list(cat.name, otherCat.name); - assertEquals(4*3, last.res.size()); - } - - @Test - public void Cast() { - NumberExpression num = cat.id; - Expression[] expr = new Expression[] { num.byteValue(), num.doubleValue(), - num.floatValue(), num.intValue(), num.longValue(), - num.shortValue(), num.stringValue() }; - - for (Expression e : expr) { - query().from(cat, Arrays.asList(c1, c2)).list(e); - } - - } - - @Test - public void Clone() { - CollQuery query = new CollQuery().from(cat, Collections.emptyList()).where(cat.isNotNull()).clone(); - assertEquals("cat is not null", query.getMetadata().getWhere().toString()); - } - - @Test - public void Primitives() { - // select cats with kittens - query().from(cat, cats).where(cat.kittens.size().ne(0)).list(cat.name); - assertTrue(last.res.size() == 4); - - // select cats without kittens - query().from(cat, cats).where(cat.kittens.size().eq(0)).list(cat.name); - assertTrue(last.res.size() == 0); - } - - @Test - public void SimpleCases() { - // select all cat names - query().from(cat, cats).list(cat.name); - assertTrue(last.res.size() == 4); - - // select all kittens - query().from(cat, cats).list(cat.kittens); - assertTrue(last.res.size() == 4); - - // select cats with kittens - query().from(cat, cats).where(cat.kittens.size().gt(0)).list(cat.name); - assertTrue(last.res.size() == 4); - - // select cats named Kitty - query().from(cat, cats).where(cat.name.eq("Kitty")).list(cat.name); - assertTrue(last.res.size() == 1); - - // select cats named Kitt% - query().from(cat, cats).where(cat.name.matches("Kitt.*")).list(cat.name); - assertTrue(last.res.size() == 1); - - query().from(cat, cats).list(cat.bodyWeight.add(cat.weight)); - } - - @Test - public void Various() { - StringPath a = new StringPath("a"); - StringPath b = new StringPath("b"); - for (Tuple strs : from(a, "aa", "bb", "cc") - .from(b, Arrays.asList("a","b")) - .where(a.startsWith(b)).list(a, b)) { - System.out.println(strs); - } - - query().from(cat, cats).list(cat.mate); - - query().from(cat, cats).list(cat.kittens); - - query().from(cat, cats).where(cat.kittens.isEmpty()).list(cat); - - query().from(cat, cats).where(cat.kittens.isNotEmpty()).list(cat); - - query().from(cat, cats).where(cat.name.matches("fri.*")).list(cat.name); - - } - - @Test - public void BigDecimals() { - NumberPath a = new NumberPath(BigDecimal.class, "cost"); - List nums = from(a, new BigDecimal("2.1"), new BigDecimal("20.21"), - new BigDecimal("44.4")).where(a.lt(new BigDecimal("35.1"))).list(a); - - for (BigDecimal num : nums) { - System.out.println(num); - } - assertEquals(2, nums.size()); - for (BigDecimal num : nums) { - assertEquals(-1, num.compareTo(new BigDecimal("35"))); - } - } - -} diff --git a/querydsl-collections/src/test/java/com/mysema/query/collections/CollectionAnyTest.java b/querydsl-collections/src/test/java/com/mysema/query/collections/CollectionAnyTest.java deleted file mode 100644 index ba4e10c1e6..0000000000 --- a/querydsl-collections/src/test/java/com/mysema/query/collections/CollectionAnyTest.java +++ /dev/null @@ -1,91 +0,0 @@ -package com.mysema.query.collections; - -import static org.junit.Assert.assertEquals; - -import java.util.Arrays; -import java.util.List; - -import org.junit.Test; - -public class CollectionAnyTest extends AbstractQueryTest { - - @Test - public void Any_In_Projection() { - Cat a = new Cat("a"); - Cat aa = new Cat("aa"); - Cat ab = new Cat("ab"); - Cat ac = new Cat("ac"); - a.setKittens(Arrays.asList(aa,ab,ac)); - - Cat b = new Cat("b"); - Cat ba = new Cat("ba"); - Cat bb = new Cat("bb"); - b.setKittens(Arrays.asList(ba, bb)); - - QCat cat = QCat.cat; - List kittens = CollQueryFactory.from(cat, Arrays.asList(a,b)).list(cat.kittens.any()); - assertEquals(Arrays.asList(aa,ab,ac,ba,bb), kittens); - } - - @Test - public void Any_In_Projection2() { - Cat a = new Cat("a"); - Cat aa = new Cat("aa"); - Cat ab = new Cat("ab"); - Cat ac = new Cat("ac"); - a.setKittens(Arrays.asList(aa,ab,ac)); - - Cat b = new Cat("b"); - Cat ba = new Cat("ba"); - Cat bb = new Cat("bb"); - b.setKittens(Arrays.asList(ba, bb)); - - QCat cat = QCat.cat; - List kittens = CollQueryFactory.from(cat, Arrays.asList(a,b)) - .list(cat.kittens.any().name); - assertEquals(Arrays.asList("aa","ab","ac","ba","bb"), kittens); - } - - @Test - public void Any_In_Where_And_Projection() { - Cat a = new Cat("a"); - Cat aa = new Cat("aa"); - Cat ab = new Cat("ab"); - Cat ac = new Cat("ac"); - a.setKittens(Arrays.asList(aa,ab,ac)); - - Cat b = new Cat("b"); - Cat ba = new Cat("ba"); - Cat bb = new Cat("bb"); - b.setKittens(Arrays.asList(ba, bb)); - - QCat cat = QCat.cat; - List kittens = CollQueryFactory.from(cat, Arrays.asList(a,b)) - .where(cat.kittens.any().name.startsWith("a")) - .list(cat.kittens.any()); - - assertEquals(Arrays.asList(aa,ab,ac), kittens); - } - - @Test - public void Any_In_Where_And_Projection2() { - Cat a = new Cat("a"); - Cat aa = new Cat("aa"); - Cat ab = new Cat("ab"); - Cat ac = new Cat("ac"); - a.setKittens(Arrays.asList(aa,ab,ac)); - - Cat b = new Cat("b"); - Cat ba = new Cat("ba"); - Cat bb = new Cat("bb"); - b.setKittens(Arrays.asList(ba, bb)); - - QCat cat = QCat.cat; - List kittens = CollQueryFactory.from(cat, Arrays.asList(a,b)) - .where(cat.kittens.any().name.startsWith("a")) - .list(cat.kittens.any().name); - - assertEquals(Arrays.asList("aa","ab","ac"), kittens); - } - -} diff --git a/querydsl-collections/src/test/java/com/mysema/query/collections/CollectionTest.java b/querydsl-collections/src/test/java/com/mysema/query/collections/CollectionTest.java deleted file mode 100644 index b8d35b41a4..0000000000 --- a/querydsl-collections/src/test/java/com/mysema/query/collections/CollectionTest.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.collections; - -import static org.junit.Assert.assertEquals; - -import java.util.Arrays; -import java.util.List; - -import org.junit.Before; -import org.junit.Test; - -public class CollectionTest { - - private final QCat cat = new QCat("cat"); - - private final QCat other = new QCat("other"); - - private List cats; - - @Before - public void setUp() { - Cat cat1 = new Cat("1"); - cat1.setKittens(Arrays.asList(cat1)); - Cat cat2 = new Cat("2"); - cat2.setKittens(Arrays.asList(cat1, cat2)); - Cat cat3 = new Cat("3"); - cat3.setKittens(Arrays.asList(cat1, cat2, cat3)); - Cat cat4 = new Cat("4"); - cat4.setKittens(Arrays.asList(cat1, cat2, cat3, cat4)); - - cats = Arrays.asList(cat1, cat2, cat3, cat4); - } - - @Test - public void Join() { - assertEquals("4", CollQueryFactory.from(cat, cats) - .innerJoin(cat.kittens, other) - .where(other.name.eq("4")).uniqueResult(cat.name)); - } - - @Test - public void Join_From_Two_Sources() { - QCat cat_kittens = new QCat("cat_kittens"); - QCat other_kittens = new QCat("other_kittens"); - assertEquals(30, CollQueryFactory - .from(cat, cats).from(other, cats) - .innerJoin(cat.kittens, cat_kittens) - .innerJoin(other.kittens, other_kittens) - .where(cat_kittens.eq(other_kittens)).count()); - } - - @Test - public void Any_UniqueResult() { - assertEquals("4", CollQueryFactory.from(cat, cats) - .where(cat.kittens.any().name.eq("4")).uniqueResult(cat.name)); - } - - @Test - public void Any_Count() { - assertEquals(4, CollQueryFactory.from(cat, cats) - .where(cat.kittens.any().name.isNotNull()).count()); - } - - @Test - public void Any_Two_Levels() { - assertEquals(4, CollQueryFactory.from(cat, cats).where( - cat.kittens.any().kittens.any().isNotNull()).count()); - } - - @Test - public void Any_Two_Levels2() { - assertEquals(4, CollQueryFactory.from(cat, cats).where( - cat.kittens.any().name.isNotNull(), - cat.kittens.any().kittens.any().isNotNull()).count()); - } - - @Test - public void Any_From_Two_Sources() { - assertEquals(16, CollQueryFactory.from(cat, cats).from(other, cats).where( - cat.kittens.any().name.eq(other.kittens.any().name)).count()); - } - - @Test - public void List_Size() { - assertEquals(4, CollQueryFactory.from(cat, cats).where(cat.kittens.size().gt(0)).count()); - assertEquals(2, CollQueryFactory.from(cat, cats).where(cat.kittens.size().gt(2)).count()); - } - - @Test - public void List_Is_Empty() { - assertEquals(0, CollQueryFactory.from(cat, cats).where(cat.kittens.isEmpty()).count()); - } - -} diff --git a/querydsl-collections/src/test/java/com/mysema/query/collections/Color.java b/querydsl-collections/src/test/java/com/mysema/query/collections/Color.java deleted file mode 100644 index 045972fcc7..0000000000 --- a/querydsl-collections/src/test/java/com/mysema/query/collections/Color.java +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.collections; - -public enum Color { - BLACK, TABBY -} diff --git a/querydsl-collections/src/test/java/com/mysema/query/collections/Comment.java b/querydsl-collections/src/test/java/com/mysema/query/collections/Comment.java deleted file mode 100644 index 6d27596a48..0000000000 --- a/querydsl-collections/src/test/java/com/mysema/query/collections/Comment.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.collections; - -import com.mysema.query.annotations.QueryEntity; -import com.mysema.query.annotations.QueryProjection; - -@QueryEntity -public class Comment { - - private int id; - - private String text; - - private User user; - - private Post post; - - public Comment() {} - - @QueryProjection - public Comment(int id, String text) { - this.id = id; - this.text = text; - } - - @QueryProjection - public Comment(int id, String text, User user, Post post) { - this.id = id; - this.text = text; - this.user = user; - this.post = post; - } - - public int getId() { - return id; - } - - public void setId(int id) { - this.id = id; - } - - public String getText() { - return text; - } - - public void setText(String text) { - this.text = text; - } - - public User getUser() { - return user; - } - - public void setUser(User user) { - this.user = user; - } - - public Post getPost() { - return post; - } - - public void setPost(Post post) { - this.post = post; - } - - -} \ No newline at end of file diff --git a/querydsl-collections/src/test/java/com/mysema/query/collections/DistinctTest.java b/querydsl-collections/src/test/java/com/mysema/query/collections/DistinctTest.java deleted file mode 100644 index 823c486734..0000000000 --- a/querydsl-collections/src/test/java/com/mysema/query/collections/DistinctTest.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.collections; - -import static org.junit.Assert.assertEquals; - -import java.util.Arrays; -import java.util.List; - -import org.junit.Test; - -import com.mysema.query.types.path.NumberPath; - -public class DistinctTest extends AbstractQueryTest { - - private NumberPath intVar1 = new NumberPath(Integer.class, "var1"); - private NumberPath intVar2 = new NumberPath(Integer.class, "var2"); - private List list1 = Arrays.asList(1, 2, 2, 3, 3, 3, 4, 4, 4, 4); - private List list2 = Arrays.asList(2, 2, 3, 3, 3, 4, 4, 4, 4, 4); - - @Test - public void SingleSource() { - assertEquals(list1, CollQueryFactory.from(intVar1, list1).list(intVar1)); - assertEquals(Arrays.asList(1, 2, 3, 4), CollQueryFactory.from(intVar1, list1).distinct().list(intVar1)); - assertEquals(Arrays.asList(2, 3, 4), CollQueryFactory.from(intVar2, list2).distinct().list(intVar2)); - - assertEquals(Arrays.asList(2, 3, 4), CollQueryFactory.from(intVar2, list2).distinct().list(intVar2)); - } - - @Test - public void BothSources() { - assertEquals(100, CollQueryFactory.from(intVar1, list1).from(intVar2, list2).list(intVar1, intVar2).size()); - assertEquals(12, CollQueryFactory.from(intVar1, list1).from(intVar2, list2).distinct().list(intVar1, intVar2).size()); - - assertEquals(12, CollQueryFactory.from(intVar1, list1).from(intVar2, list2).distinct().list(intVar1, intVar2).size()); - } - - @Test - public void CountDistinct() { - assertEquals(10, CollQueryFactory.from(intVar1, list1).count()); - assertEquals(4, CollQueryFactory.from(intVar1, list1).distinct().count()); - assertEquals(3, CollQueryFactory.from(intVar2, list2).distinct().count()); - - assertEquals(3, CollQueryFactory.from(intVar2, list2).distinct().count()); - } - - @Test - public void Null() { - CollQueryFactory.from(intVar1, Arrays.asList(null, 1)).distinct().list(intVar1); - } - -} diff --git a/querydsl-collections/src/test/java/com/mysema/query/collections/Document.java b/querydsl-collections/src/test/java/com/mysema/query/collections/Document.java deleted file mode 100644 index fc92b8dd9b..0000000000 --- a/querydsl-collections/src/test/java/com/mysema/query/collections/Document.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.mysema.query.collections; - -import java.util.ArrayList; -import java.util.List; - -import com.mysema.query.annotations.QueryEntity; - -@QueryEntity -public class Document { - - private Long id; - - private List meshThesaurusTerms = new ArrayList(); - - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public List getMeshThesaurusTerms() { - return meshThesaurusTerms; - } - - public void setMeshThesaurusTerms(List meshThesaurusTerms) { - this.meshThesaurusTerms = meshThesaurusTerms; - } - -} \ No newline at end of file diff --git a/querydsl-collections/src/test/java/com/mysema/query/collections/ECJEvaluatorFactoryTest.java b/querydsl-collections/src/test/java/com/mysema/query/collections/ECJEvaluatorFactoryTest.java deleted file mode 100644 index 0c0dc90439..0000000000 --- a/querydsl-collections/src/test/java/com/mysema/query/collections/ECJEvaluatorFactoryTest.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.mysema.query.collections; - -import com.mysema.codegen.ECJEvaluatorFactory; -import org.junit.Test; - -public class ECJEvaluatorFactoryTest extends AbstractQueryTest { - - @Test - public void Evaluator_Factory() { - DefaultEvaluatorFactory evaluatorFactory = new DefaultEvaluatorFactory( - CollQueryTemplates.DEFAULT, - new ECJEvaluatorFactory(getClass().getClassLoader())); - QueryEngine queryEngine = new DefaultQueryEngine(evaluatorFactory); - CollQuery query = new CollQuery(queryEngine); - query.from(cat, cats).list(cat.name); - } - -} diff --git a/querydsl-collections/src/test/java/com/mysema/query/collections/EntityWithLongId.java b/querydsl-collections/src/test/java/com/mysema/query/collections/EntityWithLongId.java deleted file mode 100644 index 89021d4e9a..0000000000 --- a/querydsl-collections/src/test/java/com/mysema/query/collections/EntityWithLongId.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.mysema.query.collections; - -import com.mysema.query.annotations.QueryEntity; -import com.mysema.query.annotations.QueryProjection; - -@QueryEntity -public class EntityWithLongId { - - private Long id; - - @QueryProjection - public EntityWithLongId(Long id) { - this.id = id; - } - - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } -} diff --git a/querydsl-collections/src/test/java/com/mysema/query/collections/EntityWithLongIdTest.java b/querydsl-collections/src/test/java/com/mysema/query/collections/EntityWithLongIdTest.java deleted file mode 100644 index 35a87d52ca..0000000000 --- a/querydsl-collections/src/test/java/com/mysema/query/collections/EntityWithLongIdTest.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.mysema.query.collections; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -import java.util.Arrays; -import java.util.List; - -import org.junit.Test; - -public class EntityWithLongIdTest { - - private List entities = Arrays.asList( - new EntityWithLongId(999L), - new EntityWithLongId(1000L), - new EntityWithLongId(1001L), - new EntityWithLongId(1003L) - ); - - @Test - public void SimpleEquals() { - QEntityWithLongId root = QEntityWithLongId.entityWithLongId; - CollQuery query = new CollQuery().from(root, entities); - query.where(root.id.eq(1000L)); - - Long found = query.singleResult(root.id); - assertNotNull(found); - assertEquals(found.longValue(), 1000); - } - - @Test - public void CartesianEquals() { - QEntityWithLongId root = new QEntityWithLongId("root1"); - QEntityWithLongId root2 = new QEntityWithLongId("root2"); - assertEquals(entities.size(), new CollQuery() - .from(root, entities).from(root2, entities) - .where(root2.id.eq(root.id)) - .count()); - } - - @Test - public void CartesianPlus1() { - QEntityWithLongId root = new QEntityWithLongId("root1"); - QEntityWithLongId root2 = new QEntityWithLongId("root2"); - assertEquals(2, new CollQuery() - .from(root, entities).from(root2, entities) - .where(root2.id.eq(root.id.add(1))) - .count()); - } - -} diff --git a/querydsl-collections/src/test/java/com/mysema/query/collections/ExistsTest.java b/querydsl-collections/src/test/java/com/mysema/query/collections/ExistsTest.java deleted file mode 100644 index 6da5ce4c85..0000000000 --- a/querydsl-collections/src/test/java/com/mysema/query/collections/ExistsTest.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.collections; - -import static org.junit.Assert.assertTrue; - -import org.junit.Test; - -public class ExistsTest extends AbstractQueryTest{ - - @Test - public void Exists() { - assertTrue(query().from(cat, cats).where(cat.name.eq("Bob")).exists()); - } - - @Test - public void NotExists() { - assertTrue(query().from(cat, cats).where(cat.name.eq("Bobby")).notExists()); - } - - -} diff --git a/querydsl-collections/src/test/java/com/mysema/query/collections/GroupBy2Test.java b/querydsl-collections/src/test/java/com/mysema/query/collections/GroupBy2Test.java deleted file mode 100644 index 703c02b430..0000000000 --- a/querydsl-collections/src/test/java/com/mysema/query/collections/GroupBy2Test.java +++ /dev/null @@ -1,157 +0,0 @@ -package com.mysema.query.collections; - -import static com.mysema.query.group.GroupBy.*; -import static org.junit.Assert.assertEquals; - -import java.util.List; -import java.util.Map; - -import org.junit.Before; -import org.junit.Test; - -import com.google.common.collect.Lists; -import com.mysema.query.annotations.QueryEntity; -import com.mysema.query.annotations.QueryProjection; -import com.mysema.query.group.GroupBy; - -public class GroupBy2Test { - -// select u1.id,u1.name,r1.id,r1.name,s1.name from users u1 -// join roles r1 on u1.role = r1.id -// join security_groups s1 on r1.secgroup = s1.id - - @QueryEntity - public static class User { - public Long id; - public String name; - public List roles; - } - - @QueryEntity - public static class Role { - public Long id; - public String name; - public List groups; - } - - @QueryEntity - public static class SecurityGroup { - public Long id; - public String name; - - public SecurityGroup(Long id, String name) { - this.id = id; - this.name = name; - } - } - - public static class UserDto { - public Long id; - public String name; - public List roleIds; - public List roleNames; - public List secIds; - - @QueryProjection - public UserDto(Long id, String name, List roleIds, List roleNames, List secIds) { - this.id = id; - this.name = name; - this.roleIds = roleIds; - this.roleNames = roleNames; - this.secIds = secIds; - } - - @QueryProjection - public UserDto(Long id, String name, Map roles, Map groups) { - this.id = id; - this.name = name; - this.roleIds = Lists.newArrayList(roles.keySet()); - this.roleNames = Lists.newArrayList(roles.values()); - this.secIds = Lists.newArrayList(groups.keySet()); - } - } - - private List users; - - @Before - public void setUp() { - Role r1 = new Role(); - r1.id = 1l; - r1.name = "User"; - r1.groups = Lists.newArrayList(new SecurityGroup(1l, "User 1")); - - Role r2 = new Role(); - r2.id = 2l; - r2.name = null; // NOTE this is null on purpose - r2.groups = Lists.newArrayList(new SecurityGroup(2l, "Admin 1"), - new SecurityGroup(3l, "Admin 2")); - - User u1 = new User(); - u1.id = 3l; - u1.name = "Bob"; - u1.roles = Lists.newArrayList(r1); - - User u2 = new User(); - u2.id = 32l; - u2.name = "Ann"; - u2.roles = Lists.newArrayList(r1, r2); - - users = Lists.newArrayList(u1, u2); - } - - @Test - public void test() { - QGroupBy2Test_User user = QGroupBy2Test_User.user; - QGroupBy2Test_Role role = QGroupBy2Test_Role.role; - QGroupBy2Test_SecurityGroup group = QGroupBy2Test_SecurityGroup.securityGroup; - - Map userDtos = CollQueryFactory.from(user, users) - .innerJoin(user.roles, role) - .innerJoin(role.groups, group) - .transform(GroupBy.groupBy(user.id) - .as(new QGroupBy2Test_UserDto( - user.id, - user.name, - list(role.id), - list(role.name), - list(group.id)))); - - UserDto dto1 = userDtos.get(3l); - assertEquals(1, dto1.roleIds.size()); - assertEquals(1, dto1.roleNames.size()); - assertEquals(1, dto1.secIds.size()); - - UserDto dto2 = userDtos.get(32l); - assertEquals(3, dto2.roleIds.size()); - assertEquals(1, dto2.roleNames.size()); - assertEquals(3, dto2.secIds.size()); - } - - @Test - public void test2() { - QGroupBy2Test_User user = QGroupBy2Test_User.user; - QGroupBy2Test_Role role = QGroupBy2Test_Role.role; - QGroupBy2Test_SecurityGroup group = QGroupBy2Test_SecurityGroup.securityGroup; - - Map userDtos = CollQueryFactory.from(user, users) - .innerJoin(user.roles, role) - .innerJoin(role.groups, group) - .transform(GroupBy.groupBy(user.id) - .as(new QGroupBy2Test_UserDto( - user.id, - user.name, - map(role.id, role.name), - map(group.id, group.name)))); - - UserDto dto1 = userDtos.get(3l); - assertEquals(1, dto1.roleIds.size()); - assertEquals(1, dto1.roleNames.size()); - assertEquals(1, dto1.secIds.size()); - - UserDto dto2 = userDtos.get(32l); - assertEquals(2, dto2.roleIds.size()); - assertEquals(2, dto2.roleNames.size()); - assertEquals(3, dto2.secIds.size()); - } - -} diff --git a/querydsl-collections/src/test/java/com/mysema/query/collections/GroupBy3Test.java b/querydsl-collections/src/test/java/com/mysema/query/collections/GroupBy3Test.java deleted file mode 100644 index 7edba0905d..0000000000 --- a/querydsl-collections/src/test/java/com/mysema/query/collections/GroupBy3Test.java +++ /dev/null @@ -1,97 +0,0 @@ -package com.mysema.query.collections; - -import static com.mysema.query.group.GroupBy.groupBy; -import static com.mysema.query.group.GroupBy.set; -import static org.easymock.EasyMock.createMock; -import static org.easymock.EasyMock.expect; -import static org.easymock.EasyMock.replay; -import static org.easymock.EasyMock.verify; - -import java.util.Map; -import java.util.Set; - -import org.junit.Test; - -import com.mysema.commons.lang.EmptyCloseableIterator; -import com.mysema.query.Projectable; -import com.mysema.query.ResultTransformer; -import com.mysema.query.annotations.QueryEntity; -import com.mysema.query.group.Group; -import com.mysema.query.types.Projections; -import com.mysema.query.types.QTuple; - -public class GroupBy3Test { - - @QueryEntity - public static class RiskAnalysis { - public String id; - public Set assetThreats; - } - - @QueryEntity - public static class AssetThreat { - public String id; - public Set threats; - } - - @QueryEntity - public static class Threat { - public String id; - } - - @Test - public void Nested_Expressions() { - QGroupBy3Test_RiskAnalysis riskAnalysis = QGroupBy3Test_RiskAnalysis.riskAnalysis; - QGroupBy3Test_AssetThreat assetThreat = QGroupBy3Test_AssetThreat.assetThreat; - QGroupBy3Test_Threat threat = QGroupBy3Test_Threat.threat; - - ResultTransformer> transformer = - groupBy(riskAnalysis.id) - .as(Projections.bean(RiskAnalysis.class, - riskAnalysis.id, - set(Projections.bean(AssetThreat.class, - assetThreat.id, - set(Projections.bean(Threat.class, threat.id)).as("threats"))) - .as("assetThreats"))); - - Projectable projectable = createMock(Projectable.class); - expect(projectable.iterate(new QTuple( - riskAnalysis.id, - riskAnalysis.id, - assetThreat.id, - Projections.bean(Threat.class, threat.id)))) - .andReturn(new EmptyCloseableIterator()); - replay(projectable); - - transformer.transform(projectable); - verify(projectable); - } - - @Test - public void Alias_Usage() { - QGroupBy3Test_RiskAnalysis riskAnalysis = QGroupBy3Test_RiskAnalysis.riskAnalysis; - QGroupBy3Test_AssetThreat assetThreat = QGroupBy3Test_AssetThreat.assetThreat; - QGroupBy3Test_Threat threat = QGroupBy3Test_Threat.threat; - - ResultTransformer> transformer = - groupBy(riskAnalysis.id) - .as(riskAnalysis.id, - set(Projections.bean(AssetThreat.class, - assetThreat.id, - set(Projections.bean(Threat.class, threat.id)).as("threats")) - .as("assetThreats"))); - - Projectable projectable = createMock(Projectable.class); - expect(projectable.iterate(new QTuple( - riskAnalysis.id, - riskAnalysis.id, - assetThreat.id, - Projections.bean(Threat.class, threat.id)))) - .andReturn(new EmptyCloseableIterator()); - replay(projectable); - - transformer.transform(projectable); - verify(projectable); - } - -} diff --git a/querydsl-collections/src/test/java/com/mysema/query/collections/GroupBy4Test.java b/querydsl-collections/src/test/java/com/mysema/query/collections/GroupBy4Test.java deleted file mode 100644 index 2b7cb9861b..0000000000 --- a/querydsl-collections/src/test/java/com/mysema/query/collections/GroupBy4Test.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.mysema.query.collections; - -import static com.mysema.query.group.GroupBy.groupBy; -import static com.mysema.query.group.GroupBy.map; -import static org.junit.Assert.assertEquals; - -import java.util.List; -import java.util.Map; - -import org.junit.Test; - -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Lists; -import com.mysema.query.annotations.QueryEntity; - - -public class GroupBy4Test { - - @QueryEntity - public static class Table { - String col1, col2, col3; - - public Table(String c1, String c2, String c3) { - col1 = c1; - col2 = c2; - col3 = c3; - } - } - - @Test - public void test() { - List data = Lists.newArrayList(); - data.add(new Table("1", "abc", "111")); - data.add(new Table("1", "pqr", "222")); - data.add(new Table("2", "abc", "333")); - data.add(new Table("2", "pqr", "444")); - data.add(new Table("3", "abc", "555")); - data.add(new Table("3", "pqr", "666")); - - QGroupBy4Test_Table table = QGroupBy4Test_Table.table; - Map> grouped = CollQueryFactory - .from(table, data) - .transform(groupBy(table.col1).as(map(table.col2, table.col3))); - - assertEquals(3, grouped.size()); - assertEquals(2, grouped.get("1").size()); - assertEquals(ImmutableSet.of("abc", "pqr"), grouped.get("1").keySet()); - - } - -} diff --git a/querydsl-collections/src/test/java/com/mysema/query/collections/GroupByTest.java b/querydsl-collections/src/test/java/com/mysema/query/collections/GroupByTest.java deleted file mode 100644 index 337de69143..0000000000 --- a/querydsl-collections/src/test/java/com/mysema/query/collections/GroupByTest.java +++ /dev/null @@ -1,289 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.collections; - - -import static com.mysema.query.group.GroupBy.avg; -import static com.mysema.query.group.GroupBy.groupBy; -import static com.mysema.query.group.GroupBy.list; -import static com.mysema.query.group.GroupBy.map; -import static com.mysema.query.group.GroupBy.max; -import static com.mysema.query.group.GroupBy.min; -import static com.mysema.query.group.GroupBy.set; -import static com.mysema.query.group.GroupBy.sum; -import static junit.framework.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; - -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.junit.Ignore; -import org.junit.Test; - -import com.mysema.query.group.Group; -import com.mysema.query.types.ConstructorExpression; -import com.mysema.query.types.Projections; - -public class GroupByTest { - - private static final List users = Arrays.asList(new User("Bob"), new User("Jane"), new User("Jack")); - - private static final List posts = Arrays.asList( - new Post(1, "Post 1", users.get(0)), - new Post(2, "Post 2", users.get(0)), - new Post(3, "Post 3", users.get(1))); - - private static final List comments = Arrays.asList( - new Comment(1, "Comment 1", users.get(0), posts.get(0)), - new Comment(2, "Comment 2", users.get(1), posts.get(1)), - new Comment(3, "Comment 3", users.get(2), posts.get(1)), - new Comment(4, "Comment 4", users.get(0), posts.get(2)), - new Comment(5, "Comment 5", users.get(1), posts.get(2)), - new Comment(6, "Comment 6", users.get(2), posts.get(2))); - - private static final QUser user = QUser.user; - - private static final QComment comment = QComment.comment; - - private static final QPost post = QPost.post; - - private static final ConstructorExpression qComment = QComment.create(comment.id, comment.text); - - @Test - public void Group_Min() { - Map results = CollQueryFactory.from(post, posts).from(comment, comments) - .where(comment.post.id.eq(post.id)) - .transform(groupBy(post.id).as(min(comment.text))); - - assertEquals("Comment 1", results.get(1)); - assertEquals("Comment 2", results.get(2)); - assertEquals("Comment 4", results.get(3)); - } - - public void Comments_By_Post() { - Map> results = CollQueryFactory.from(post, posts).from(comment, comments) - .where(comment.post.id.eq(post.id)) - .transform(groupBy(post.id).as(list(comment))); - - assertEquals(1, results.get(1).size()); - assertEquals(2, results.get(2).size()); - assertEquals(3, results.get(3).size()); - } - - @Test - public void Group_Max() { - Map results = CollQueryFactory.from(post, posts).from(comment, comments) - .where(comment.post.id.eq(post.id)) - .transform(groupBy(post.id).as(max(comment.text))); - - assertEquals("Comment 1", results.get(1)); - assertEquals("Comment 3", results.get(2)); - assertEquals("Comment 6", results.get(3)); - } - - @Test - public void Group_Sum() { - Map results = CollQueryFactory.from(post, posts).from(comment, comments) - .where(comment.post.id.eq(post.id)) - .transform(groupBy(post.id).as(sum(comment.id))); - - assertEquals(1, results.get(1).intValue()); - assertEquals(5, results.get(2).intValue()); - assertEquals(15, results.get(3).intValue()); - } - - @Test - public void Group_Avg() { - Map results = CollQueryFactory.from(post, posts).from(comment, comments) - .where(comment.post.id.eq(post.id)) - .transform(groupBy(post.id).as(avg(comment.id))); - - assertEquals(1, results.get(1).intValue()); - assertEquals(2, results.get(2).intValue()); - assertEquals(5, results.get(3).intValue()); - } - - @Test - public void Group_Order() { - Map results = CollQueryFactory.from(post, posts).from(comment, comments) - .where(comment.post.id.eq(post.id)) - .transform(groupBy(post.id).as(post.name, set(comment.id))); - - assertEquals(3, results.size()); - } - - @Test - public void First_Set_And_List() { - Map results = CollQueryFactory.from(post, posts).from(comment, comments) - .where(comment.post.id.eq(post.id)) - .transform(groupBy(post.id).as(post.name, set(comment.id), list(comment.text))); - - Group group = results.get(1); - assertEquals(toInt(1), group.getOne(post.id)); - assertEquals("Post 1", group.getOne(post.name)); - assertEquals(toSet(1), group.getSet(comment.id)); - assertEquals(Arrays.asList("Comment 1"), group.getList(comment.text)); - } - - @Test - @Ignore - public void Group_By_Null() { - Map results = CollQueryFactory.from(post, posts).from(comment, comments) - .where(comment.post.id.eq(post.id)) - .transform(groupBy(post.id).as(post.name, set(comment.id), list(comment.text))); - - Group group = results.get(null); - assertNull(group.getOne(post.id)); - assertEquals("null post", group.getOne(post.name)); - assertEquals(toSet(7, 8), group.getSet(comment.id)); - assertEquals(Arrays.asList("comment 7", "comment 8"), group.getList(comment.text)); - - } - -// @Test(expected=NoSuchElementException.class) -// public void NoSuchElementException() { -// Map results = BASIC_RESULTS.transform( -// groupBy(postId, postName, set(commentId), list(commentText))); -// -// Group group = results.get(1); -// group.getSet(qComment); -// } - - @Test(expected=ClassCastException.class) - public void ClassCastException() { - Map results = CollQueryFactory.from(post, posts).from(comment, comments) - .where(comment.post.id.eq(post.id)) - .transform(groupBy(post.id).as(post.name, set(comment.id), list(comment.text))); - - Group group = results.get(1); - group.getList(comment.id); - } - - @Test - @Ignore - public void Map() { - Map results = CollQueryFactory.from(post, posts).from(comment, comments) - .where(comment.post.id.eq(post.id)) - .transform(groupBy(post.id).as(post.name, map(comment.id, comment.text))); - - Group group = results.get(1); - Map comments = group.getMap(comment.id, comment.text); - assertEquals(1, comments.size()); -// assertEquals("comment 2", comments.get(2)); - } - - @Test - public void Array_Access() { - Map results = CollQueryFactory.from(post, posts).from(comment, comments) - .where(comment.post.id.eq(post.id)) - .transform(groupBy(post.id).as(post.name, set(comment.id), list(comment.text))); - - Group group = results.get(1); - Object[] array = group.toArray(); - assertEquals(toInt(1), array[0]); - assertEquals("Post 1", array[1]); - assertEquals(toSet(1), array[2]); - assertEquals(Arrays.asList("Comment 1"), array[3]); - } - - @Test - public void Transform_Results() { - Map results = CollQueryFactory.from(post, posts).from(comment, comments) - .where(comment.post.id.eq(post.id)) - .transform(groupBy(post.id).as(QPost.create(post.id, post.name, set(qComment)))); - - Post post = results.get(1); - assertNotNull(post); - assertEquals(1, post.getId()); - assertEquals("Post 1", post.getName()); - assertEquals(1, post.getComments().size()); - } - - @Test - public void Transform_As_Bean() { - Map results = CollQueryFactory.from(post, posts).from(comment, comments) - .where(comment.post.id.eq(post.id)) - .transform(groupBy(post.id).as(Projections.bean(Post.class, post.id, post.name, set(qComment).as("comments")))); - - Post post = results.get(1); - assertNotNull(post); - assertEquals(1, post.getId()); - assertEquals("Post 1", post.getName()); - assertEquals(1, post.getComments().size()); - } - - - @Test - public void OneToOneToMany_Projection() { - Map results = CollQueryFactory.from(user, users).from(post, posts).from(comment, comments) - .where(user.name.eq(post.user.name), post.id.eq(comment.post.id)) - .transform(groupBy(user.name).as(Projections.constructor(User.class, user.name, - QPost.create(post.id, post.name, set(qComment))))); - - assertEquals(2, results.size()); - - User user = results.get("Jane"); - Post post = user.getLatestPost(); - assertEquals(3, post.getId()); - assertEquals("Post 3", post.getName()); - assertEquals(3, post.getComments().size()); - } - - - @Test - public void OneToOneToMany_Projection_As_Bean() { - Map results = CollQueryFactory.from(user, users).from(post, posts).from(comment, comments) - .where(user.name.eq(post.user.name), post.id.eq(comment.post.id)) - .transform(groupBy(user.name).as(Projections.bean(User.class, user.name, - Projections.bean(Post.class, post.id, post.name, set(qComment).as("comments")).as("latestPost")))); - - assertEquals(2, results.size()); - - User user = results.get("Jane"); - Post post = user.getLatestPost(); - assertEquals(3, post.getId()); - assertEquals("Post 3", post.getName()); - assertEquals(3, post.getComments().size()); - } - - @Test - public void OneToOneToMany_Projection_As_Bean_And_Constructor() { - Map results = CollQueryFactory.from(user, users).from(post, posts).from(comment, comments) - .where(user.name.eq(post.user.name), post.id.eq(comment.post.id)) - .transform(groupBy(user.name).as(Projections.bean(User.class, user.name, - QPost.create(post.id, post.name, set(qComment)).as("latestPost")))); - - assertEquals(2, results.size()); - - User user = results.get("Jane"); - Post post = user.getLatestPost(); - assertEquals(3, post.getId()); - assertEquals("Post 3", post.getName()); - assertEquals(3, post.getComments().size()); - } - - private Integer toInt(int i) { - return Integer.valueOf(i); - } - - private Set toSet(T... s) { - return new HashSet(Arrays.asList(s)); - } - - -} diff --git a/querydsl-collections/src/test/java/com/mysema/query/collections/GuavaHelpersTest.java b/querydsl-collections/src/test/java/com/mysema/query/collections/GuavaHelpersTest.java deleted file mode 100644 index 9cd08794f4..0000000000 --- a/querydsl-collections/src/test/java/com/mysema/query/collections/GuavaHelpersTest.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.mysema.query.collections; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import org.junit.Test; - -import com.google.common.base.Function; -import com.google.common.base.Predicate; - -public class GuavaHelpersTest { - - @Test - public void Predicate() { - Predicate predicate = GuavaHelpers.wrap(QCat.cat.name.startsWith("Ann")); - assertTrue(predicate.apply(new Cat("Ann"))); - assertFalse(predicate.apply(new Cat("Bob"))); - } - - @Test - public void Function() { - Function function = GuavaHelpers.wrap(QCat.cat.name); - assertEquals("Ann", function.apply(new Cat("Ann"))); - assertEquals("Bob", function.apply(new Cat("Bob"))); - } - -} diff --git a/querydsl-collections/src/test/java/com/mysema/query/collections/InnerClassTest.java b/querydsl-collections/src/test/java/com/mysema/query/collections/InnerClassTest.java deleted file mode 100644 index e57975ce23..0000000000 --- a/querydsl-collections/src/test/java/com/mysema/query/collections/InnerClassTest.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.collections; - -import static com.mysema.query.alias.Alias.$; -import static com.mysema.query.alias.Alias.alias; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import java.util.Arrays; - -import org.junit.Test; - -public class InnerClassTest { - - public static class Example { - - public String getId() { - return null; - } - } - - @Test - public void Query() { - Example example = alias(Example.class); - assertFalse(CollQueryFactory.from($(example), Arrays.asList(new Example())) - .where($(example.getId()).isNull()) - .list($(example)).isEmpty()); - assertTrue(CollQueryFactory.from($(example), Arrays.asList(new Example())) - .where($(example.getId()).isNotNull()) - .list($(example)).isEmpty()); - } - -} diff --git a/querydsl-collections/src/test/java/com/mysema/query/collections/IterationTest.java b/querydsl-collections/src/test/java/com/mysema/query/collections/IterationTest.java deleted file mode 100644 index 5c7843c85e..0000000000 --- a/querydsl-collections/src/test/java/com/mysema/query/collections/IterationTest.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.collections; - -import static com.mysema.query.alias.Alias.$; -import static com.mysema.query.alias.Alias.alias; -import static org.junit.Assert.assertEquals; - -import java.util.Arrays; -import java.util.List; - -import org.junit.Test; - -public class IterationTest { - - public static class Data { - - private String data = "data"; - - public String getData() { - return data; - } - - } - - private List allData = Arrays.asList(new Data(), new Data()); - - private Data lt = alias(Data.class,"Data"); - - private List expected = Arrays.asList("data","data"); - - @Test - public void test() { - assertEquals(expected, CollQueryFactory.from ($(lt), allData).list($(lt.getData()))); - } - - @Test - public void test2() { - assertEquals(expected, CollQueryFactory.from ($(lt), Arrays.asList(allData.toArray())).list($(lt.getData()))); - } - - @Test - public void test3() { - assertEquals(expected, CollQueryFactory.from (lt, allData).list($(lt.getData()))); - } - - @Test - public void test4() { - assertEquals(expected, CollQueryFactory.from (lt, Arrays.asList(allData.toArray())).list($(lt.getData()))); - } -} diff --git a/querydsl-collections/src/test/java/com/mysema/query/collections/JodaTimeTemplatesTest.java b/querydsl-collections/src/test/java/com/mysema/query/collections/JodaTimeTemplatesTest.java deleted file mode 100644 index d92c09a2c8..0000000000 --- a/querydsl-collections/src/test/java/com/mysema/query/collections/JodaTimeTemplatesTest.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.mysema.query.collections; - -import java.util.Arrays; - -import org.joda.time.DateTime; -import org.joda.time.LocalDate; -import org.joda.time.LocalTime; -import org.junit.Test; - -import com.mysema.query.types.path.DatePath; -import com.mysema.query.types.path.DateTimePath; -import com.mysema.query.types.path.TimePath; - -public class JodaTimeTemplatesTest { - - private CollQuery query = new CollQuery(JodaTimeTemplates.DEFAULT); - - @Test - public void DateTime() { - DateTimePath entity = new DateTimePath(DateTime.class, "entity"); - query.from(entity, Arrays.asList(new DateTime(), new DateTime(0l))) - .list(entity.year(), entity.yearMonth(), entity.month(), entity.week(), - entity.dayOfMonth(), entity.dayOfWeek(), entity.dayOfYear(), - entity.hour(), entity.minute(), entity.second(), entity.milliSecond()); - } - - @Test - public void LocalDate() { - DatePath entity = new DatePath(LocalDate.class, "entity"); - query.from(entity, Arrays.asList(new LocalDate(), new LocalDate(0l))) - .list(entity.year(), entity.yearMonth(), entity.month(), entity.week(), - entity.dayOfMonth(), entity.dayOfWeek(), entity.dayOfYear()); - } - - @Test - public void LocalTime() { - TimePath entity = new TimePath(LocalTime.class, "entity"); - query.from(entity, Arrays.asList(new LocalTime(), new LocalTime(0l))) - .list(entity.hour(), entity.minute(), entity.second(), entity.milliSecond()); - } - -} diff --git a/querydsl-collections/src/test/java/com/mysema/query/collections/MappingProjectionTest.java b/querydsl-collections/src/test/java/com/mysema/query/collections/MappingProjectionTest.java deleted file mode 100644 index 831615e053..0000000000 --- a/querydsl-collections/src/test/java/com/mysema/query/collections/MappingProjectionTest.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.mysema.query.collections; - -import static org.junit.Assert.*; - -import java.util.List; - -import org.junit.Test; - -import com.mysema.query.Tuple; -import com.mysema.query.types.MappingProjection; - -@SuppressWarnings("serial") -public class MappingProjectionTest extends AbstractQueryTest { - - public class ResultPart { - - } - - public class ResultObject { - - } - - @Test - public void test() { - final MappingProjection key = new MappingProjection(ResultPart.class, - cat.name) { - - @Override - protected ResultPart map(Tuple row) { - return new ResultPart(); - } - - }; - - List list = query().from(cat, cats).list( - new MappingProjection(ResultObject.class, key) { - - @Override - protected ResultObject map(Tuple row) { - ResultPart consolidationKey = row.get(key); - return new ResultObject(); - } - }); - - assertEquals(cats.size(), list.size()); - } - -} diff --git a/querydsl-collections/src/test/java/com/mysema/query/collections/MathTest.java b/querydsl-collections/src/test/java/com/mysema/query/collections/MathTest.java deleted file mode 100644 index f9e64dda28..0000000000 --- a/querydsl-collections/src/test/java/com/mysema/query/collections/MathTest.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.mysema.query.collections; - -import static org.junit.Assert.assertEquals; - -import java.util.Arrays; - -import org.junit.Test; - -import com.mysema.query.types.Expression; -import com.mysema.query.types.expr.MathExpressions; -import com.mysema.query.types.path.NumberPath; - -public class MathTest { - - private NumberPath num = new NumberPath(Double.class, "num"); - - @Test - public void Math() { - Expression expr = num; - - assertEquals(Math.acos(0.5), unique(MathExpressions.acos(expr)), 0.001); - assertEquals(Math.asin(0.5), unique(MathExpressions.asin(expr)), 0.001); - assertEquals(Math.atan(0.5), unique(MathExpressions.atan(expr)), 0.001); - assertEquals(Math.cos(0.5), unique(MathExpressions.cos(expr)), 0.001); - assertEquals(Math.cosh(0.5), unique(MathExpressions.cosh(expr)), 0.001); - assertEquals(cot(0.5), unique(MathExpressions.cot(expr)), 0.001); - assertEquals(coth(0.5), unique(MathExpressions.coth(expr)), 0.001); - assertEquals(degrees(0.5), unique(MathExpressions.degrees(expr)), 0.001); - assertEquals(Math.exp(0.5), unique(MathExpressions.exp(expr)), 0.001); - assertEquals(Math.log(0.5), unique(MathExpressions.ln(expr)), 0.001); - assertEquals(log(0.5, 10), unique(MathExpressions.log(expr, 10)), 0.001); - assertEquals(0.25, unique(MathExpressions.power(expr, 2)), 0.001); - assertEquals(radians(0.5), unique(MathExpressions.radians(expr)), 0.001); - assertEquals(Integer.valueOf(1), - unique(MathExpressions.sign(expr))); - assertEquals(Math.sin(0.5), unique(MathExpressions.sin(expr)), 0.001); - assertEquals(Math.sinh(0.5), unique(MathExpressions.sinh(expr)), 0.001); - assertEquals(Math.tan(0.5), unique(MathExpressions.tan(expr)), 0.001); - assertEquals(Math.tanh(0.5), unique(MathExpressions.tanh(expr)), 0.001); - - } - - private double cot(double x) { - return Math.cos(x) / Math.sin(x); - } - - private double coth(double x) { - return Math.cosh(x) / Math.sinh(x); - } - - private double degrees(double x) { - return x * 180.0 / Math.PI; - } - - private double radians(double x) { - return x * Math.PI / 180.0; - } - - private double log(double x, int y) { - return Math.log(x) / Math.log(y); - } - - private T unique(Expression expr) { - //return query().uniqueResult(expr); - return CollQueryFactory.from(num, Arrays.asList(0.5)).uniqueResult(expr); - } - -} diff --git a/querydsl-collections/src/test/java/com/mysema/query/collections/MockTest.java b/querydsl-collections/src/test/java/com/mysema/query/collections/MockTest.java deleted file mode 100644 index c1e02856cd..0000000000 --- a/querydsl-collections/src/test/java/com/mysema/query/collections/MockTest.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.mysema.query.collections; - -import static org.junit.Assert.*; - -import java.util.List; - -import org.easymock.EasyMock; -import org.junit.Test; - -import com.google.common.collect.Lists; -import com.mysema.query.types.path.SimplePath; - -public class MockTest { - - @Test - public void test() { - List tests = Lists.newArrayList(new MockTest(), new MockTest(), new MockTest()); - SimplePath path = new SimplePath(MockTest.class, "obj"); - MockTest mock = EasyMock.createMock(MockTest.class); - assertTrue(CollQueryFactory.from(path, tests).where(path.eq(mock)).list(path).isEmpty()); - } - -} diff --git a/querydsl-collections/src/test/java/com/mysema/query/collections/NullSafetyTest.java b/querydsl-collections/src/test/java/com/mysema/query/collections/NullSafetyTest.java deleted file mode 100644 index 3b7f174bbe..0000000000 --- a/querydsl-collections/src/test/java/com/mysema/query/collections/NullSafetyTest.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.mysema.query.collections; - -import static org.junit.Assert.assertEquals; - -import java.util.Arrays; - -import org.junit.Test; - -public class NullSafetyTest extends AbstractQueryTest { - - @Test - public void Filters() { - QCat cat = QCat.cat; - CollQuery query = CollQueryFactory.from(cat, Arrays.asList(new Cat(), new Cat("Bob"))); - assertEquals(1l, query.where(cat.name.eq("Bob")).count()); - } - - @Test - public void Joins() { - Cat kitten1 = new Cat(); - Cat kitten2 = new Cat("Bob"); - Cat cat1 = new Cat(); - cat1.setKittens(Arrays.asList(kitten1, kitten2)); - Cat cat2 = new Cat(); - - QCat cat = QCat.cat; - QCat kitten = new QCat("kitten"); - CollQuery query = CollQueryFactory.from(cat, Arrays.asList(cat1, cat2)).innerJoin(cat.kittens, kitten); - assertEquals(1, query.where(kitten.name.eq("Bob")).count()); - } - -} diff --git a/querydsl-collections/src/test/java/com/mysema/query/collections/NumberTest.java b/querydsl-collections/src/test/java/com/mysema/query/collections/NumberTest.java deleted file mode 100644 index bc189077b4..0000000000 --- a/querydsl-collections/src/test/java/com/mysema/query/collections/NumberTest.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.mysema.query.collections; - -import java.math.BigDecimal; -import java.util.Arrays; - -import com.mysema.query.types.path.NumberPath; -import org.junit.Test; -import static org.junit.Assert.*; - -public class NumberTest { - - @Test - public void sum() throws Exception { - final NumberPath num = new NumberPath(BigDecimal.class, "num"); - final CollQuery query = CollQueryFactory.from(num, Arrays.asList(new BigDecimal("1.6"), new BigDecimal("1.3"))); - - assertEquals(new BigDecimal("2.9"), query.uniqueResult(num.sum())); - } -} diff --git a/querydsl-collections/src/test/java/com/mysema/query/collections/OrderTest.java b/querydsl-collections/src/test/java/com/mysema/query/collections/OrderTest.java deleted file mode 100644 index fd79326737..0000000000 --- a/querydsl-collections/src/test/java/com/mysema/query/collections/OrderTest.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.collections; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import java.util.Arrays; -import java.util.List; - -import org.junit.Test; - -public class OrderTest extends AbstractQueryTest { - - @Test - public void test() { - query().from(cat, cats).orderBy(cat.name.asc()).list(cat.name); - assertArrayEquals(new Object[] { "Alex", "Bob", "Francis", "Kitty" }, last.res.toArray()); - - query().from(cat, cats).orderBy(cat.name.desc()).list(cat.name); - assertArrayEquals(new Object[] { "Kitty", "Francis", "Bob", "Alex" }, last.res.toArray()); - - query().from(cat, cats).orderBy(cat.name.substring(1).asc()).list(cat.name); - assertArrayEquals(new Object[] { "Kitty", "Alex", "Bob", "Francis" }, last.res.toArray()); - - query().from(cat, cats).from(otherCat, cats).orderBy(cat.name.asc(), otherCat.name.desc()).list(cat.name, otherCat.name); - - // TODO : more tests - } - - @Test - public void test2() { - List orderedNames = Arrays.asList("Alex","Bob","Francis","Kitty"); - assertEquals(orderedNames, query().from(cat,cats).orderBy(cat.name.asc()).list(cat.name)); - assertEquals(orderedNames, query().from(cat,cats).orderBy(cat.name.asc()).distinct().list(cat.name)); - } - - @Test - public void With_count() { - CollQuery q = new CollQuery(); - q.from(cat, cats); - long size = q.distinct().count(); - assertTrue(size > 0); - q.offset(0).limit(10); - q.orderBy(cat.name.asc()); - assertEquals(Arrays.asList("Alex","Bob","Francis","Kitty"), q.distinct().list(cat.name)); - } - - @Test - public void With_null() { - List cats = Arrays.asList(new Cat(), new Cat("Bob")); - assertEquals(cats, query().from(cat, cats).orderBy(cat.name.asc()).list(cat)); - assertEquals(Arrays.asList(cats.get(1), cats.get(0)), query().from(cat, cats).orderBy(cat.name.desc()).list(cat)); - - } -} diff --git a/querydsl-collections/src/test/java/com/mysema/query/collections/PagingTest.java b/querydsl-collections/src/test/java/com/mysema/query/collections/PagingTest.java deleted file mode 100644 index 26a10d5340..0000000000 --- a/querydsl-collections/src/test/java/com/mysema/query/collections/PagingTest.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.collections; - -import static org.junit.Assert.assertEquals; - -import java.util.Arrays; -import java.util.List; - -import org.junit.Test; - -import com.mysema.commons.lang.IteratorAdapter; -import com.mysema.query.QueryModifiers; -import com.mysema.query.SearchResults; -import com.mysema.query.types.path.NumberPath; - -public class PagingTest extends AbstractQueryTest { - - private List ints = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9); - - private NumberPath var = new NumberPath(Integer.class, "var"); - - @Test - public void test() { - assertResultSize(9, 9, QueryModifiers.EMPTY); - assertResultSize(9, 2, new QueryModifiers(2l, null)); - assertResultSize(9, 2, new QueryModifiers(2l, 0l)); - assertResultSize(9, 2, new QueryModifiers(2l, 3l)); - assertResultSize(9, 9, new QueryModifiers(20l, null)); - assertResultSize(9, 9, new QueryModifiers(20l, 0l)); - assertResultSize(9, 5, new QueryModifiers(20l, 4l)); - assertResultSize(9, 0, new QueryModifiers(10l, 9l)); - } - - private void assertResultSize(int total, int size, QueryModifiers modifiers) { - // via list - assertEquals(size, createQuery(modifiers).list(var).size()); - - // via results - SearchResults results = createQuery(modifiers).listResults(var); - assertEquals(total, results.getTotal()); - assertEquals(size, results.getResults().size()); - - // via count (ignore limit and offset) - assertEquals(total, createQuery(modifiers).count()); - - // via iterator - assertEquals(size, IteratorAdapter.asList(createQuery(modifiers).iterate(var)).size()); - } - - private CollQuery createQuery(QueryModifiers modifiers) { - CollQuery query = new CollQuery().from(var, ints); - if (modifiers != null) { - query.restrict(modifiers); - } - return query; - } -} diff --git a/querydsl-collections/src/test/java/com/mysema/query/collections/Person.java b/querydsl-collections/src/test/java/com/mysema/query/collections/Person.java deleted file mode 100644 index 57b151f00a..0000000000 --- a/querydsl-collections/src/test/java/com/mysema/query/collections/Person.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.mysema.query.collections; - -public class Person { - private String name; - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } -} diff --git a/querydsl-collections/src/test/java/com/mysema/query/collections/Post.java b/querydsl-collections/src/test/java/com/mysema/query/collections/Post.java deleted file mode 100644 index d7800bc3a9..0000000000 --- a/querydsl-collections/src/test/java/com/mysema/query/collections/Post.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.collections; - -import java.util.Set; - -import com.mysema.query.annotations.QueryEntity; -import com.mysema.query.annotations.QueryProjection; - -@QueryEntity -public class Post { - - private int id; - - private String name; - - private User user; - - private Set comments; - - public Post() {} - - @QueryProjection - public Post(int id, String name, User user) { - this.id = id; - this.name = name; - this.user = user; - } - - @QueryProjection - public Post(int id, String name, Set comments) { - this.id = id; - this.name = name; - this.comments = comments; - } - - public int getId() { - return id; - } - - public void setId(int id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public User getUser() { - return user; - } - - public void setUser(User user) { - this.user = user; - } - - public Set getComments() { - return comments; - } - - public void setComments(Set comments) { - this.comments = comments; - } - - - -} \ No newline at end of file diff --git a/querydsl-collections/src/test/java/com/mysema/query/collections/PropertiesTest.java b/querydsl-collections/src/test/java/com/mysema/query/collections/PropertiesTest.java deleted file mode 100644 index ba4ba9f21b..0000000000 --- a/querydsl-collections/src/test/java/com/mysema/query/collections/PropertiesTest.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.mysema.query.collections; - -import static org.junit.Assert.*; - -import java.util.Collections; -import java.util.List; - -import org.junit.Test; - -public class PropertiesTest { - - @Test - public void Hidden() { - QStateHistory history = QStateHistory.stateHistory; - List histories = Collections.singletonList(new StateHistory()); - assertEquals(1, CollQueryFactory.from(history, histories) - .where(history.changedAt.isNull()).list(history).size()); - } - - @Test - public void Hidden2() { - QStateHistoryOwner historyOwner = QStateHistoryOwner.stateHistoryOwner; - List historyOwners = Collections.singletonList(new StateHistoryOwner()); - assertEquals(1, CollQueryFactory.from(historyOwner, historyOwners) - .where(historyOwner.stateHistory.isNull()).list(historyOwner).size()); - } - -} diff --git a/querydsl-collections/src/test/java/com/mysema/query/collections/QCar.java b/querydsl-collections/src/test/java/com/mysema/query/collections/QCar.java deleted file mode 100644 index 30abe4d47e..0000000000 --- a/querydsl-collections/src/test/java/com/mysema/query/collections/QCar.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.mysema.query.collections; - -import com.mysema.query.types.PathMetadata; -import com.mysema.query.types.path.BeanPath; -import com.mysema.query.types.path.NumberPath; -import com.mysema.query.types.path.StringPath; - -public class QCar extends BeanPath { - - public final StringPath model = createString("model"); - - public final NumberPath horsePower = createNumber("horsePower", Integer.class); - - public final QPerson owner = new QPerson(new BeanPath(Person.class, this, "owner")); - - public static QCar car = new QCar(new BeanPath(Car.class, "car")); - - public QCar(BeanPath entity) { - super(entity.getType(), entity.getMetadata()); - } - - public QCar(PathMetadata metadata) { - super(Car.class, metadata); - } - -} diff --git a/querydsl-collections/src/test/java/com/mysema/query/collections/QPerson.java b/querydsl-collections/src/test/java/com/mysema/query/collections/QPerson.java deleted file mode 100644 index 603d2d368b..0000000000 --- a/querydsl-collections/src/test/java/com/mysema/query/collections/QPerson.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.mysema.query.collections; - -import com.mysema.query.types.PathMetadata; -import com.mysema.query.types.path.BeanPath; -import com.mysema.query.types.path.StringPath; - -public class QPerson extends BeanPath { - - public final StringPath name = createString("name"); - - public static QPerson car = new QPerson(new BeanPath(Person.class, "person")); - - public QPerson(BeanPath entity) { - super(entity.getType(), entity.getMetadata()); - } - - public QPerson(PathMetadata metadata) { - super(Person.class, metadata); - } - -} diff --git a/querydsl-collections/src/test/java/com/mysema/query/collections/QueryMetadataTest.java b/querydsl-collections/src/test/java/com/mysema/query/collections/QueryMetadataTest.java deleted file mode 100644 index f3d915661f..0000000000 --- a/querydsl-collections/src/test/java/com/mysema/query/collections/QueryMetadataTest.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.collections; - -import static org.junit.Assert.assertEquals; - -import java.util.Arrays; - -import org.junit.Test; - -import com.mysema.query.DefaultQueryMetadata; -import com.mysema.query.JoinType; -import com.mysema.query.QueryMetadata; - -public class QueryMetadataTest extends AbstractQueryTest { - - @Test - public void Reusage() { - QueryMetadata metadata = new DefaultQueryMetadata(); - metadata.addJoin(JoinType.DEFAULT, cat); - metadata.addWhere(cat.name.startsWith("A")); - - CollQuery query = new CollQuery(metadata); - query.bind(cat, cats); - assertEquals(Arrays.asList(c3), query.list(cat)); - } - -} diff --git a/querydsl-collections/src/test/java/com/mysema/query/collections/QueryMutabilityTest.java b/querydsl-collections/src/test/java/com/mysema/query/collections/QueryMutabilityTest.java deleted file mode 100644 index f5da10f275..0000000000 --- a/querydsl-collections/src/test/java/com/mysema/query/collections/QueryMutabilityTest.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.collections; - -import java.io.IOException; -import java.lang.reflect.InvocationTargetException; -import java.util.Collections; - -import org.junit.Test; - -import com.mysema.query.QueryMutability; - -public class QueryMutabilityTest { - - @Test - public void test() throws SecurityException, IllegalArgumentException, - NoSuchMethodException, IllegalAccessException, - InvocationTargetException, IOException { - QCat cat = QCat.cat; - CollQuery query = new CollQuery(); - query.from(cat, Collections. emptyList()); - new QueryMutability(query).test(cat.id, cat.name); - - } - -} diff --git a/querydsl-collections/src/test/java/com/mysema/query/collections/SerializationTest.java b/querydsl-collections/src/test/java/com/mysema/query/collections/SerializationTest.java deleted file mode 100644 index cb334d98a4..0000000000 --- a/querydsl-collections/src/test/java/com/mysema/query/collections/SerializationTest.java +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.collections; - -import java.util.ArrayList; -import java.util.List; - -import org.junit.Ignore; -import org.junit.Test; - -import com.mysema.query.Tuple; -import com.mysema.query.types.QTuple; - -public class SerializationTest extends AbstractQueryTest{ - - // TODO : order - - // TODO : subqueries - - private QTuple tuple = new QTuple(cat, otherCat); - - @Test - public void OneSource_list() { - query().from(cat, cats).list(cat); - } - - public List oneSource_list(List cat_) { - return cat_; - } - - @Test - public void TwoSources_list() { - query().from(cat,cats).from(otherCat, cats).list(cat); - } - - public List twoSources_list(List cat_, List otherCat_) { - return cat_; - } - - @Test - public void OneSource_filteredList() { - query().from(cat, cats).where(cat.name.eq("Kitty")).list(cat); - } - - public List oneSource_filteredList(List cat_) { - List rv = new ArrayList(); - for (Cat cat : cats) { // from - if (cat.getName().equals("Kitty")) { // where - rv.add(cat); // list - } - } - return rv; - } - - @Test - public void OneSource_projectedList() { - query().from(cat, cats).list(cat.name); - } - - public List oneSource_projectedList(List cat_) { - List rv = new ArrayList(); - for (Cat cat : cat_) { // from - rv.add(cat.getName()); // list - } - return rv; - } - - @Test - public void OneSource_filtered_projectedList() { - query().from(cat, cats).where(cat.name.eq("Kitty")).list(cat.name); - } - - public List oneSource_filtered_projectedList(List cat_) { - List rv = new ArrayList(); - for (Cat cat : cat_) { // from - if (cat.getName().equals("Kitty")) { // where - rv.add(cat.getName()); // list - } - } - return rv; - } - - @Test - public void OneSource_filtered_projectedUnique() { - query().from(cat, cats).where(cat.name.eq("Kitty")).uniqueResult(cat.name); - } - - public String oneSource_filtered_projectedUnique(List cat_) { - for (Cat cat : cat_) { // from - if (cat.getName().equals("Kitty")) { // where - return cat.getName(); // unique - } - } - throw new IllegalArgumentException(); - } - - @Test - @Ignore - public void Join_list() { - query().from(cat, cats).innerJoin(cat.kittens, kitten).where(kitten.name.eq("Kitty")).list(cat); - } - - public List join_list(List cat_) { - List rv = new ArrayList(); - for (Cat cat : cat_) { // from - for (Cat kitten : cat.getKittens()) { // inner join - if (kitten.getName().equals("Kitty")) { // where - rv.add(cat); // list - } - } - } - return rv; - } - - public List pairs(List cat_, List otherCat_) { - query().from(cat, cats).from(otherCat, cats).where(cat.name.eq(otherCat.name)).list(cat, otherCat); - - List rv = new ArrayList(); - for (Cat cat : cat_) { // from - for (Cat otherCat : otherCat_) { // from - if (cat.getName().equals(otherCat.getName())) { // where - rv.add(new Object[]{cat,otherCat}); // list - } - } - } - return rv; - } - - public List pairsAsTuple(List cat_, List otherCat_) { - query().from(cat, cats).from(otherCat, cats).where(cat.name.eq(otherCat.name)).list(new QTuple(cat, otherCat)); - - List rv = new ArrayList(); - for (Cat cat : cat_) { // from - for (Cat otherCat : otherCat_) { // from - if (cat.getName().equals(otherCat.getName())) { // where - rv.add(tuple.newInstance(cat, otherCat)); // list - } - } - } - return rv; - } - -} diff --git a/querydsl-collections/src/test/java/com/mysema/query/collections/SingleResultContractTest.java b/querydsl-collections/src/test/java/com/mysema/query/collections/SingleResultContractTest.java deleted file mode 100644 index 9ceae68891..0000000000 --- a/querydsl-collections/src/test/java/com/mysema/query/collections/SingleResultContractTest.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.collections; - -import static org.junit.Assert.assertNotNull; - -import org.junit.Test; - -public class SingleResultContractTest extends AbstractQueryTest{ - - @Test - public void SingleResult() { - assertNotNull(CollQueryFactory.from(cat, cats).where(cat.name.isNotNull()).singleResult(cat)); - } - -} diff --git a/querydsl-collections/src/test/java/com/mysema/query/collections/StateHistory.java b/querydsl-collections/src/test/java/com/mysema/query/collections/StateHistory.java deleted file mode 100644 index 9e9fa7a5b3..0000000000 --- a/querydsl-collections/src/test/java/com/mysema/query/collections/StateHistory.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.mysema.query.collections; - -import java.util.Date; - -import com.mysema.query.annotations.QueryEntity; - -@QueryEntity -public class StateHistory { - - private Date changedAt; - - protected final Date getChangedAtTime() { - return changedAt; - } - -} \ No newline at end of file diff --git a/querydsl-collections/src/test/java/com/mysema/query/collections/StateHistoryOwner.java b/querydsl-collections/src/test/java/com/mysema/query/collections/StateHistoryOwner.java deleted file mode 100644 index 8e4e06938b..0000000000 --- a/querydsl-collections/src/test/java/com/mysema/query/collections/StateHistoryOwner.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.mysema.query.collections; - -import com.mysema.query.annotations.QueryEntity; - -@QueryEntity -public class StateHistoryOwner { - - private StateHistory stateHistory; - - protected final StateHistory getStateHistory() { - return stateHistory; - } - -} diff --git a/querydsl-collections/src/test/java/com/mysema/query/collections/StringHandlingTest.java b/querydsl-collections/src/test/java/com/mysema/query/collections/StringHandlingTest.java deleted file mode 100644 index 9f16fb2371..0000000000 --- a/querydsl-collections/src/test/java/com/mysema/query/collections/StringHandlingTest.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.collections; - -import static org.junit.Assert.assertEquals; - -import java.util.Arrays; -import java.util.Iterator; -import java.util.List; - -import org.junit.Test; - -import com.mysema.query.Tuple; -import com.mysema.query.types.path.StringPath; - -public class StringHandlingTest extends AbstractQueryTest { - - private List data1 = Arrays.asList("petER", "THomas", "joHAN"); - - private List data2 = Arrays.asList("PETer", "thOMAS", "JOhan"); - - private List data = Arrays.asList("abc", "aBC", "def"); - - private final StringPath a = new StringPath("a"); - - private final StringPath b = new StringPath("b"); - - @Test - public void EqualsIgnoreCase() { - Iterator res = Arrays.asList("petER - PETer", - "THomas - thOMAS", "joHAN - JOhan").iterator(); - for (Tuple arr : query() - .from(a, data1) - .from(b, data2) - .where(a.equalsIgnoreCase(b)).list(a, b)) { - assertEquals(res.next(), arr.get(a) + " - " + arr.get(b)); - } - } - - @Test - public void StartsWithIgnoreCase() { - assertEquals(2, CollQueryFactory.from(a, data).where(a.startsWithIgnoreCase("AB")).count()); - assertEquals(2, CollQueryFactory.from(a, data).where(a.startsWithIgnoreCase("ab")).count()); - } - - @Test - public void EndsWithIgnoreCase() { - assertEquals(2, CollQueryFactory.from(a, data).where(a.endsWithIgnoreCase("BC")).count()); - assertEquals(2, CollQueryFactory.from(a, data).where(a.endsWithIgnoreCase("bc")).count()); - } - -} diff --git a/querydsl-collections/src/test/java/com/mysema/query/collections/TypeCastTest.java b/querydsl-collections/src/test/java/com/mysema/query/collections/TypeCastTest.java deleted file mode 100644 index 9af6ff7573..0000000000 --- a/querydsl-collections/src/test/java/com/mysema/query/collections/TypeCastTest.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.collections; - -import java.util.Collections; - -import org.junit.Ignore; -import org.junit.Test; - -import com.mysema.query.types.path.PathInits; - -public class TypeCastTest { - - @Test(expected=IllegalStateException.class) - @Ignore - public void Cast() { - QAnimal animal = QAnimal.animal; - QCat cat = new QCat(animal.getMetadata(), new PathInits("*")); - System.out.println(cat); - CollQueryFactory.from(animal, Collections. emptyList()).from(cat, Collections. emptyList()); - } - -} diff --git a/querydsl-collections/src/test/java/com/mysema/query/collections/UniqueResultContractTest.java b/querydsl-collections/src/test/java/com/mysema/query/collections/UniqueResultContractTest.java deleted file mode 100644 index a7f78d1a86..0000000000 --- a/querydsl-collections/src/test/java/com/mysema/query/collections/UniqueResultContractTest.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.collections; - -import org.junit.Test; - -import com.mysema.query.NonUniqueResultException; -import com.mysema.query.types.Expression; - -public class UniqueResultContractTest extends AbstractQueryTest{ - - @Test(expected=NonUniqueResultException.class) - public void Unique_Result_Throws_Exception_On_Multiple_Results() { - CollQueryFactory.from(cat, cats).where(cat.name.isNotNull()).uniqueResult(cat); - } - - @Test - public void UniqueResult_With_Array() { - CollQueryFactory.from(cat, cats).where(cat.name.isNotNull()).limit(1).uniqueResult(new Expression[]{cat}); - } - -} diff --git a/querydsl-collections/src/test/java/com/mysema/query/collections/User.java b/querydsl-collections/src/test/java/com/mysema/query/collections/User.java deleted file mode 100644 index e2deec89f8..0000000000 --- a/querydsl-collections/src/test/java/com/mysema/query/collections/User.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.collections; - -import com.mysema.query.annotations.QueryEntity; -import com.mysema.query.annotations.QueryProjection; - - -@QueryEntity -public class User { - - private String name; - - private Post latestPost; - - public User() {} - - @QueryProjection - public User(String name) { - this.name = name; - } - - @QueryProjection - public User(String name, Post latestPost) { - this.name = name; - this.latestPost = latestPost; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public Post getLatestPost() { - return latestPost; - } - - public void setLatestPost(Post latestPost) { - this.latestPost = latestPost; - } - - - -} \ No newline at end of file diff --git a/querydsl-collections/src/test/java/com/querydsl/collections/AbstractQueryTest.java b/querydsl-collections/src/test/java/com/querydsl/collections/AbstractQueryTest.java new file mode 100644 index 0000000000..ec39f83d4e --- /dev/null +++ b/querydsl-collections/src/test/java/com/querydsl/collections/AbstractQueryTest.java @@ -0,0 +1,107 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.collections; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.junit.Before; + +import com.querydsl.core.DefaultQueryMetadata; +import com.querydsl.core.Tuple; +import com.querydsl.core.alias.Alias; +import com.querydsl.core.types.Expression; + +public abstract class AbstractQueryTest { + + protected final Cat c1 = new Cat("Kitty"); + + protected final Cat c2 = new Cat("Bob"); + + protected final Cat c3 = new Cat("Alex"); + + protected final Cat c4 = new Cat("Francis"); + + protected final QCat cat = new QCat("cat"); + + protected final QCat kitten = new QCat("kitten"); + + protected final QCat offspr = new QCat("offspr"); + + protected final QCat otherCat = new QCat("otherCat"); + + protected final QCat mate = new QCat("mate"); + + protected List cats = Arrays.asList(c1, c2, c3, c4); + + protected List ints = new ArrayList(); + + protected List myInts = new ArrayList(); + + protected TestQuery last; + + + @Before + public void setUp() { + myInts.addAll(Arrays.asList(1, 2, 3, 4)); + Alias.resetAlias(); + } + + protected List cats(int size) { + List cats = new ArrayList(size); + for (int i = 0; i < size / 2; i++) { + cats.add(new Cat("Kate" + (i + 1))); + cats.add(new Cat("Bob" + (i + 1))); + } + return cats; + } + + protected TestQuery query() { + last = new TestQuery(); + return last; + } + + static class TestQuery extends AbstractCollQuery> { + + List res = new ArrayList(); + + TestQuery() { + super(new DefaultQueryMetadata(), DefaultQueryEngine.getDefault()); + } + + @Override + public List fetch() { + List rv = super.fetch(); + res.addAll(rv); + return rv; + } + + @Override + public TestQuery select(Expression expr) { + queryMixin.setProjection(expr); + @SuppressWarnings("unchecked") // This is the new projection's type + TestQuery newType = (TestQuery) queryMixin.getSelf(); + return newType; + } + + @Override + public TestQuery select(Expression... exprs) { + queryMixin.setProjection(exprs); + @SuppressWarnings("unchecked") // This is the new projection's type + TestQuery newType = (TestQuery) queryMixin.getSelf(); + return newType; + } + } +} diff --git a/querydsl-collections/src/test/java/com/querydsl/collections/AggregationTest.java b/querydsl-collections/src/test/java/com/querydsl/collections/AggregationTest.java new file mode 100644 index 0000000000..51033e1221 --- /dev/null +++ b/querydsl-collections/src/test/java/com/querydsl/collections/AggregationTest.java @@ -0,0 +1,66 @@ +package com.querydsl.collections; + +import static org.junit.Assert.assertEquals; + +import java.util.Arrays; + +import org.junit.Before; +import org.junit.Test; + +public class AggregationTest extends AbstractQueryTest { + + private static final QCat cat = QCat.cat; + + private CollQuery query; + + @Override + @Before + public void setUp() { + Cat cat1 = new Cat(); + cat1.setWeight(2); + Cat cat2 = new Cat(); + cat2.setWeight(3); + Cat cat3 = new Cat(); + cat3.setWeight(4); + Cat cat4 = new Cat(); + cat4.setWeight(5); + query = CollQueryFactory. from(cat, Arrays.asList(cat1, cat2, cat3, cat4)); + } + + @Test + public void avg() { + assertEquals(3.5, query.select(cat.weight.avg()).fetchOne(), 0.0); + } + + @Test + public void count() { + assertEquals(Long.valueOf(4L), query.select(cat.count()).fetchOne()); + } + + @Test + public void countDistinct() { + assertEquals(Long.valueOf(4L), query.select(cat.countDistinct()).fetchOne()); + } + + @Test + public void max() { + assertEquals(Integer.valueOf(5), query.select(cat.weight.max()).fetchOne()); + } + + @Test + public void min() { + assertEquals(Integer.valueOf(2), query.select(cat.weight.min()).fetchOne()); + } + + @SuppressWarnings("unchecked") + @Test(expected = UnsupportedOperationException.class) + public void min_and_max() { + query.select(cat.weight.min(), cat.weight.max()).fetchOne(); + } + + @Test + public void sum() { + assertEquals(Integer.valueOf(14), query.select(cat.weight.sum()).fetchOne()); + } + +} diff --git a/querydsl-collections/src/test/java/com/querydsl/collections/AliasTest.java b/querydsl-collections/src/test/java/com/querydsl/collections/AliasTest.java new file mode 100644 index 0000000000..ac88bc7d85 --- /dev/null +++ b/querydsl-collections/src/test/java/com/querydsl/collections/AliasTest.java @@ -0,0 +1,151 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.collections; + +import static com.querydsl.collections.CollQueryFactory.from; +import static com.querydsl.core.alias.Alias.*; +import static org.junit.Assert.*; + +import java.util.Arrays; +import java.util.Collections; +import java.util.Date; + +import org.junit.Before; +import org.junit.Test; + +import com.querydsl.core.alias.Alias; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.StringPath; + +public class AliasTest extends AbstractQueryTest { + + @Before + public void setUp() { + myInts.add(1); + myInts.add(2); + myInts.add(3); + myInts.add(4); + + Alias.resetAlias(); + } + + @Test + public void aliasVariations1() { + // 1st + QCat cat = new QCat("cat"); + assertEquals(Arrays.asList("Kitty", "Bob", "Alex", "Francis"), + from(cat, cats).where(cat.kittens.size().gt(0)).select(cat.name).fetch()); + + // 2nd + Cat c = alias(Cat.class, "cat"); + assertEquals(Arrays.asList("Kitty", "Bob", "Alex", "Francis"), + from(c, cats).where($(c.getKittens()).size().gt(0)).select($(c.getName())).fetch()); + } + + @Test + public void aliasVariations2() { + // 1st + QCat cat = new QCat("cat"); + assertEquals(Collections.emptyList(), + from(cat, cats).where(cat.name.matches("fri.*")).select(cat.name).fetch()); + + // 2nd + Cat c = alias(Cat.class, "cat"); + assertEquals(Collections.emptyList(), + from(c, cats).where($(c.getName()).matches("fri.*")).select($(c.getName())).fetch()); + } + + @Test + public void alias3() { + QCat cat = new QCat("cat"); + Cat other = new Cat(); + Cat c = alias(Cat.class, "cat"); + + // 1 + from(c, cats).where($(c.getBirthdate()).gt(new Date())).select($(c)).iterate(); + + // 2 + try { + from(c, cats).where($(c.getMate().getName().toUpperCase()).eq("MOE")); + fail("expected NPE"); + } catch (NullPointerException ne) { + // expected + } + + // 3 + assertEquals(cat.name, $(c.getName())); + + // 4 + from(c,cats) + .where($(c.getKittens().get(0).getBodyWeight()).gt(12)) + .select($(c.getName())).iterate(); + + // 5 + from(c, cats).where($(c).eq(other)).select($(c)).iterate(); + + // 6 + from(c, cats).where($(c.getKittens()).contains(other)).select($(c)) + .iterate(); + + // 7 + from(c, cats).where($(c.getKittens().isEmpty())).select($(c)).iterate(); + + // 8 + from(c, cats).where($(c.getName()).startsWith("B")).select($(c)).iterate(); + + // 9 + from(c, cats).where($(c.getName()).upper().eq("MOE")).select($(c)).iterate(); + + // 10 + assertNotNull($(c.getKittensByName())); + assertNotNull($(c.getKittensByName().get("Kitty"))); + from(c, cats).where($(c.getKittensByName().get("Kitty")).isNotNull()).select(cat).iterate(); + + // 11 +// try { +// from(cat, cats).where(cat.mate.alive).fetch(cat); +// fail("expected RuntimeException"); +// } catch (RuntimeException e) { +// System.out.println(e.getMessage()); +// assertEquals("null in cat.mate.alive", e.getMessage()); +// } + + // 12 + // TestQuery query = query().from(cat, c1, c2).from(cat, c1, c2); + // assertEquals(1, query.getMetadata().getJoins().size()); + + } + + @Test + public void various1() { + StringPath str = Expressions.stringPath("str"); + assertEquals(Arrays.asList("a", "ab"), + from(str, "a", "ab", "cd", "de").where(str.startsWith("a")).select(str).fetch()); + } + + @Test + public void various2() { + assertEquals(Arrays.asList(1, 2, 5, 3), + from(var(), 1, 2, "abc", 5, 3).where(var().ne("abc")).select(var()).fetch()); + } + + @Test + public void various3() { + NumberPath num = Expressions.numberPath(Integer.class, "num"); + assertEquals(Arrays.asList(1, 2, 3), + from(num, 1, 2, 3, 4).where(num.lt(4)).select(num).fetch()); + } + +} diff --git a/querydsl-collections/src/test/java/com/querydsl/collections/Animal.java b/querydsl-collections/src/test/java/com/querydsl/collections/Animal.java new file mode 100644 index 0000000000..646f97ff7e --- /dev/null +++ b/querydsl-collections/src/test/java/com/querydsl/collections/Animal.java @@ -0,0 +1,112 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.collections; + +import java.util.Date; + +import com.querydsl.core.annotations.PropertyType; +import com.querydsl.core.annotations.QueryEntity; +import com.querydsl.core.annotations.QueryType; + +@QueryEntity +public class Animal { + + protected boolean alive; + + protected java.util.Date birthdate = new java.util.Date(); + + @QueryType(PropertyType.SIMPLE) + private Date dateAsSimple; + + protected int bodyWeight, weight, toes; + + protected Color color; + + protected int id; + + protected String name; + + public java.util.Date getBirthdate() { + return birthdate; + } + + public int getBodyWeight() { + return bodyWeight; + } + + public Color getColor() { + return color; + } + + public int getId() { + return id; + } + + public String getName() { + return name; + } + + public int getToes() { + return toes; + } + + public int getWeight() { + return weight; + } + + public boolean isAlive() { + return alive; + } + + public void setAlive(boolean alive) { + this.alive = alive; + } + + public void setBirthdate(java.util.Date birthdate) { + this.birthdate = new Date(birthdate.getTime()); + } + + public void setBodyWeight(int bodyWeight) { + this.bodyWeight = bodyWeight; + } + + public void setWeight(int weight) { + this.weight = weight; + } + + public void setToes(int toes) { + this.toes = toes; + } + + public void setColor(Color color) { + this.color = color; + } + + public void setId(int id) { + this.id = id; + } + + public void setName(String name) { + this.name = name; + } + + public Date getDateAsSimple() { + return dateAsSimple; + } + + public void setDateAsSimple(Date dateAsSimple) { + this.dateAsSimple = new Date(dateAsSimple.getTime()); + } + +} diff --git a/querydsl-collections/src/test/java/com/querydsl/collections/AnimalTest.java b/querydsl-collections/src/test/java/com/querydsl/collections/AnimalTest.java new file mode 100644 index 0000000000..c0af354e98 --- /dev/null +++ b/querydsl-collections/src/test/java/com/querydsl/collections/AnimalTest.java @@ -0,0 +1,37 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.collections; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +import com.querydsl.core.types.dsl.SimplePath; + +public class AnimalTest { + + @Test + public void cast() { + QCat cat = QAnimal.animal.as(QCat.class); + assertEquals(QAnimal.animal, cat.getMetadata().getElement()); + assertEquals("animal", cat.toString()); + } + + @Test + public void date_as_simple() { + assertTrue(QAnimal.animal.dateAsSimple.getClass().equals(SimplePath.class)); + } + +} diff --git a/querydsl-collections/src/test/java/com/querydsl/collections/BigDecimalTest.java b/querydsl-collections/src/test/java/com/querydsl/collections/BigDecimalTest.java new file mode 100644 index 0000000000..1d492bb29f --- /dev/null +++ b/querydsl-collections/src/test/java/com/querydsl/collections/BigDecimalTest.java @@ -0,0 +1,29 @@ +package com.querydsl.collections; + +import static org.junit.Assert.assertEquals; + +import java.math.BigDecimal; +import java.util.Arrays; + +import org.junit.Test; + +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberPath; + +public class BigDecimalTest { + + @Test + public void arithmetic() { + NumberPath num = Expressions.numberPath(BigDecimal.class, "num"); + CollQuery query = CollQueryFactory. from(num, Arrays. asList(BigDecimal.ONE, BigDecimal.valueOf(2))); + assertEquals(Arrays.asList(BigDecimal.valueOf(11), BigDecimal.valueOf(12)), + query. select(num.add(BigDecimal.TEN)).fetch()); + assertEquals(Arrays.asList(BigDecimal.valueOf(-9), BigDecimal.valueOf(-8)), + query. select(num.subtract(BigDecimal.TEN)).fetch()); + assertEquals(Arrays.asList(BigDecimal.valueOf(10), BigDecimal.valueOf(20)), + query. select(num.multiply(BigDecimal.TEN)).fetch()); + assertEquals(Arrays.asList(new BigDecimal("0.1"), new BigDecimal("0.2")), + query. select(num.divide(BigDecimal.TEN)).fetch()); + } + +} diff --git a/querydsl-collections/src/test/java/com/querydsl/collections/BooleanTest.java b/querydsl-collections/src/test/java/com/querydsl/collections/BooleanTest.java new file mode 100644 index 0000000000..495e01ad16 --- /dev/null +++ b/querydsl-collections/src/test/java/com/querydsl/collections/BooleanTest.java @@ -0,0 +1,47 @@ +package com.querydsl.collections; + +import static com.querydsl.core.alias.Alias.$; +import static org.junit.Assert.assertEquals; + +import java.util.Collections; + +import org.junit.Test; + +import com.querydsl.core.alias.Alias; + +public class BooleanTest { + + public static class Entity { + + private boolean boolean1 = true; + + private Boolean boolean2 = Boolean.TRUE; + + public boolean isBoolean1() { + return boolean1; + } + + public Boolean getBoolean2() { + return boolean2; + } + + } + + @Test + public void primitive_boolean() { + Entity entity = Alias.alias(Entity.class); + assertEquals(1, CollQueryFactory.from(entity, Collections.singleton(new Entity())) + .where($(entity.isBoolean1()).eq(Boolean.TRUE)) + .fetchCount()); + } + + @Test + public void object_boolean() { + Entity entity = Alias.alias(Entity.class); + assertEquals(1, CollQueryFactory.from(entity, Collections.singleton(new Entity())) + .where($(entity.getBoolean2()).eq(Boolean.TRUE)) + .fetchCount()); + + } + +} diff --git a/querydsl-collections/src/test/java/com/mysema/query/collections/Car.java b/querydsl-collections/src/test/java/com/querydsl/collections/Car.java similarity index 93% rename from querydsl-collections/src/test/java/com/mysema/query/collections/Car.java rename to querydsl-collections/src/test/java/com/querydsl/collections/Car.java index 808f5165ee..7e38354427 100644 --- a/querydsl-collections/src/test/java/com/mysema/query/collections/Car.java +++ b/querydsl-collections/src/test/java/com/querydsl/collections/Car.java @@ -1,4 +1,4 @@ -package com.mysema.query.collections; +package com.querydsl.collections; public class Car { diff --git a/querydsl-collections/src/test/java/com/querydsl/collections/CastTest.java b/querydsl-collections/src/test/java/com/querydsl/collections/CastTest.java new file mode 100644 index 0000000000..bd91972221 --- /dev/null +++ b/querydsl-collections/src/test/java/com/querydsl/collections/CastTest.java @@ -0,0 +1,35 @@ +package com.querydsl.collections; + +import static org.junit.Assert.assertEquals; + +import java.util.Arrays; + +import org.junit.Test; + +public class CastTest extends AbstractQueryTest { + + @Test + public void parents() { + QCat cat = QAnimal.animal.as(QCat.class); + assertEquals(QAnimal.animal, cat.getMetadata().getParent()); + } + + @Test + public void cast() { + assertEquals(Arrays.asList(c1, c2, c3, c4), + query().from(QAnimal.animal, cats) + .where(QAnimal.animal.as(QCat.class).breed.eq(0)) + .select(QAnimal.animal).fetch()); + } + + @Test + public void property_dereference() { + Cat cat = new Cat(); + cat.setEyecolor(Color.TABBY); + assertEquals(Color.TABBY, + CollQueryFactory.from(QAnimal.animal, cat) + .where(QAnimal.animal.instanceOf(Cat.class)) + .select(QAnimal.animal.as(QCat.class).eyecolor).fetchFirst()); + } + +} diff --git a/querydsl-collections/src/test/java/com/querydsl/collections/Cat.java b/querydsl-collections/src/test/java/com/querydsl/collections/Cat.java new file mode 100644 index 0000000000..067f8fa219 --- /dev/null +++ b/querydsl-collections/src/test/java/com/querydsl/collections/Cat.java @@ -0,0 +1,163 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.collections; + +import java.util.*; + +import com.querydsl.core.annotations.PropertyType; +import com.querydsl.core.annotations.QueryEntity; +import com.querydsl.core.annotations.QueryProjection; +import com.querydsl.core.annotations.QueryType; + +@QueryEntity +public class Cat extends Animal { + + private int breed; + + private java.sql.Date dateField; + + private Color eyecolor; + + private List kittens = new ArrayList<>(); + + private Cat[] kittenArray; + + private Map kittensByName = new HashMap<>(); + + private Cat mate; + + @QueryType(PropertyType.NONE) + private String skippedField; + + @QueryType(PropertyType.SIMPLE) + private String stringAsSimple; + + private java.sql.Time timeField; + + public Cat() { + this.kittensByName = Collections.emptyMap(); + } + + public Cat(String name) { + Cat kitten = new Cat(); + this.kittens = Collections.singletonList(kitten); + this.kittenArray = new Cat[]{kitten}; + this.kittensByName = Collections.singletonMap("Kitty", kitten); + this.name = name; + } + + public Cat(String name, String kittenName) { + this(name); + kittens.get(0).setName(kittenName); + } + + @QueryProjection + public Cat(String name, int id) { + this(name); + this.id = id; + } + + public Cat(String name, int id, Date birthdate) { + this(name, id); + this.birthdate = new Date(birthdate.getTime()); + this.dateField = new java.sql.Date(birthdate.getTime()); + this.timeField = new java.sql.Time(birthdate.getTime()); + } + + public int getBreed() { + return breed; + } + + public java.sql.Date getDateField() { + return dateField; + } + + public Color getEyecolor() { + return eyecolor; + } + + public List getKittens() { + return kittens; + } + + public Map getKittensByName() { + return kittensByName; + } + + public Cat getMate() { + return mate; + } + + public String getSkippedField() { + return skippedField; + } + + public String getStringAsSimple() { + return stringAsSimple; + } + + public java.sql.Time getTimeField() { + return timeField; + } + + public void setBreed(int breed) { + this.breed = breed; + } + + public void setDateField(java.sql.Date dateField) { + this.dateField = new java.sql.Date(dateField.getTime()); + } + + public void setEyecolor(Color eyecolor) { + this.eyecolor = eyecolor; + } + + public void setKittens(List kittens) { + this.kittens = kittens; + } + + public void setKittensByName(Map kittensByName) { + this.kittensByName = kittensByName; + } + + public void setMate(Cat mate) { + this.mate = mate; + } + + public void setSkippedField(String skippedField) { + this.skippedField = skippedField; + } + + public void setStringAsSimple(String stringAsSimple) { + this.stringAsSimple = stringAsSimple; + } + + public void setTimeField(java.sql.Time timeField) { + this.timeField = timeField; + } + + public Cat[] getKittenArray() { + return kittenArray; + } + + public void setKittenArray(Cat[] kittenArray) { + this.kittenArray = kittenArray.clone(); + } + + @Override + public String toString() { + return name; + } + +} diff --git a/querydsl-collections/src/test/java/com/querydsl/collections/CatTest.java b/querydsl-collections/src/test/java/com/querydsl/collections/CatTest.java new file mode 100644 index 0000000000..d3dcaa3a7c --- /dev/null +++ b/querydsl-collections/src/test/java/com/querydsl/collections/CatTest.java @@ -0,0 +1,38 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.collections; + +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +import com.querydsl.core.types.dsl.SimplePath; + +public class CatTest { + + @Test(expected = NoSuchFieldException.class) + public void skippedField() throws SecurityException, NoSuchFieldException { + QCat.class.getField("skippedField"); + } + + @Test + public void stringAsSimple() throws SecurityException, NoSuchFieldException { + assertTrue(QCat.cat.stringAsSimple.getClass().equals(SimplePath.class)); + } + + @Test + public void dateAsSimple() { + assertTrue(QCat.cat.dateAsSimple.getClass().equals(SimplePath.class)); + } +} diff --git a/querydsl-collections/src/test/java/com/mysema/query/collections/CollDeleteClauseTest.java b/querydsl-collections/src/test/java/com/querydsl/collections/CollDeleteClauseTest.java similarity index 90% rename from querydsl-collections/src/test/java/com/mysema/query/collections/CollDeleteClauseTest.java rename to querydsl-collections/src/test/java/com/querydsl/collections/CollDeleteClauseTest.java index 13025bea2c..2741ccd83f 100644 --- a/querydsl-collections/src/test/java/com/mysema/query/collections/CollDeleteClauseTest.java +++ b/querydsl-collections/src/test/java/com/querydsl/collections/CollDeleteClauseTest.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.collections; +package com.querydsl.collections; import static org.junit.Assert.assertEquals; @@ -24,7 +24,7 @@ public class CollDeleteClauseTest { @Test - public void Execute() { + public void execute() { QCat cat = QCat.cat; List cats = new ArrayList(Arrays.asList(new Cat("Ann"), new Cat("Bob"), new Cat("John"), new Cat("Carl"))); diff --git a/querydsl-collections/src/test/java/com/mysema/query/collections/CollQueryFunctionsTest.java b/querydsl-collections/src/test/java/com/querydsl/collections/CollQueryFunctionsTest.java similarity index 81% rename from querydsl-collections/src/test/java/com/mysema/query/collections/CollQueryFunctionsTest.java rename to querydsl-collections/src/test/java/com/querydsl/collections/CollQueryFunctionsTest.java index 3e24707e62..5c43f8549d 100644 --- a/querydsl-collections/src/test/java/com/mysema/query/collections/CollQueryFunctionsTest.java +++ b/querydsl-collections/src/test/java/com/querydsl/collections/CollQueryFunctionsTest.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,11 +11,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.collections; +package com.querydsl.collections; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.*; import org.junit.Ignore; import org.junit.Test; @@ -23,15 +21,15 @@ public class CollQueryFunctionsTest { @Test - public void Coalesce() { + public void coalesce() { assertEquals("1", CollQueryFunctions.coalesce("1",null)); assertEquals("1", CollQueryFunctions.coalesce(null,"1","2")); assertNull(CollQueryFunctions.coalesce(null,null)); } - @Test + @Test @Ignore - public void LikeSpeed() { + public void likeSpeed() { // 3015 final int iterations = 1000000; long start = System.currentTimeMillis(); @@ -43,16 +41,16 @@ public void LikeSpeed() { long duration = System.currentTimeMillis() - start; System.err.println(duration); } - + @Test - public void Like() { + public void like() { assertTrue(CollQueryFunctions.like("abcDOG", "%DOG")); assertTrue(CollQueryFunctions.like("DOGabc", "DOG%")); - assertTrue(CollQueryFunctions.like("abcDOGabc", "%DOG%")); + assertTrue(CollQueryFunctions.like("abcDOGabc", "%DOG%")); } - + @Test - public void Like_With_Special_Chars() { + public void like_with_special_chars() { assertTrue(CollQueryFunctions.like("$DOG", "$DOG")); assertTrue(CollQueryFunctions.like("$DOGabc", "$DOG%")); } diff --git a/querydsl-collections/src/test/java/com/querydsl/collections/CollQueryStandardTest.java b/querydsl-collections/src/test/java/com/querydsl/collections/CollQueryStandardTest.java new file mode 100644 index 0000000000..8a35a7cf9e --- /dev/null +++ b/querydsl-collections/src/test/java/com/querydsl/collections/CollQueryStandardTest.java @@ -0,0 +1,181 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.collections; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +import java.util.Arrays; +import java.util.Date; +import java.util.List; + +import com.querydsl.core.Fetchable; +import com.querydsl.core.QuerydslModule; +import com.querydsl.core.QueryExecution; +import com.querydsl.core.Target; +import com.querydsl.core.Tuple; +import com.querydsl.core.types.ArrayConstructorExpression; +import com.querydsl.core.types.Concatenation; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.ParamNotSetException; +import com.querydsl.core.types.Predicate; +import com.querydsl.core.types.Projections; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.Param; +import org.junit.Test; + +public class CollQueryStandardTest { + + private final Date birthDate = new Date(); + + private final java.sql.Date date = new java.sql.Date(birthDate.getTime()); + + private final java.sql.Time time = new java.sql.Time(birthDate.getTime()); + + private final QCat cat = new QCat("cat"); + + private final QCat otherCat = new QCat("otherCat"); + + private final List data = Arrays.asList( + new Cat("Bob", 1, birthDate), + new Cat("Ruth", 2, birthDate), + new Cat("Felix", 3, birthDate), + new Cat("Allen", 4, birthDate), + new Cat("Mary", 5, birthDate) + ); + + private static final Expression[] NO_EXPRESSIONS = new Expression[0]; + + private QueryExecution standardTest = new QueryExecution(QuerydslModule.COLLECTIONS, Target.MEM) { + @Override + protected Fetchable createQuery() { + return CollQueryFactory.from(cat, data).from(otherCat, data); + } + @Override + protected Fetchable createQuery(Predicate filter) { + return CollQueryFactory.from(cat, data).from(otherCat, data) + .where(filter).select(cat.name); + } + }; + + @Test + public void test() { + Cat kitten = data.get(0).getKittens().get(0); + standardTest.runArrayTests(cat.kittenArray, otherCat.kittenArray, kitten, new Cat()); + standardTest.runBooleanTests(cat.name.isNull(), otherCat.kittens.isEmpty()); + standardTest.runCollectionTests(cat.kittens, otherCat.kittens, kitten, new Cat()); + standardTest.runDateTests(cat.dateField, otherCat.dateField, date); + standardTest.runDateTimeTests(cat.birthdate, otherCat.birthdate, birthDate); + standardTest.runListTests(cat.kittens, otherCat.kittens, kitten, new Cat()); + standardTest.runMapTests(cat.kittensByName, otherCat.kittensByName, "Kitty", kitten, "NoName", new Cat()); + + // int + standardTest.runNumericCasts(cat.id, otherCat.id, 1); + standardTest.runNumericTests(cat.id, otherCat.id, 1); + + standardTest.runStringTests(cat.name, otherCat.name, "Bob"); + standardTest.runTimeTests(cat.timeField, otherCat.timeField, time); + standardTest.report(); + } + + @Test + public void tupleMultipleFieldsProjection() { + List tuples = CollQueryFactory.from(cat, data) + .select(cat.name, cat.birthdate).fetch(); + for (Tuple tuple : tuples) { + assertNotNull(tuple.get(cat.name)); + assertNotNull(tuple.get(cat.birthdate)); + } + } + + @Test + public void tupleOneFieldProjection() { + List tuples = CollQueryFactory.from(cat, data) + .select(new Expression[] {cat.name}).fetch(); + for (Tuple tuple : tuples) { + assertEquals(1, tuple.size()); + assertNotNull(tuple.get(cat.name)); + } + } + + @Test + public void tupleOneNullFieldProjection() { + List tuples = CollQueryFactory.from(cat, data) + .select(new Expression[] {Expressions.nullExpression()}).fetch(); + for (Tuple tuple : tuples) { + assertNotNull(tuple); + assertEquals(1, tuple.size()); // THIS FAILS WITH NPE + assertNull(tuple.get(Expressions.nullExpression())); + } + } + + @Test + public void nested_tupleProjection() { + Concatenation concat = new Concatenation(cat.name, cat.name); + List tuples = CollQueryFactory.from(cat, data) + .select(concat, cat.name, cat.birthdate).fetch(); + for (Tuple tuple : tuples) { + assertNotNull(tuple.get(cat.name)); + assertNotNull(tuple.get(cat.birthdate)); + assertEquals(tuple.get(cat.name) + tuple.get(cat.name), tuple.get(concat)); + } + } + + @SuppressWarnings("unchecked") + @Test + public void arrayProjection() { + List results = CollQueryFactory.from(cat, data) + .select(new ArrayConstructorExpression(String[].class, cat.name)).fetch(); + assertFalse(results.isEmpty()); + for (String[] result : results) { + assertNotNull(result[0]); + } + } + + @Test + public void constructorProjection() { + List projections = CollQueryFactory.from(cat, data) + .select(Projections.constructor(Projection.class, cat.name, cat)).fetch(); + assertFalse(projections.isEmpty()); + for (Projection projection : projections) { + assertNotNull(projection); + } + } + + @Test + public void params() { + Param name = new Param(String.class,"name"); + assertEquals("Bob", CollQueryFactory.from(cat, data).where(cat.name.eq(name)).set(name,"Bob").select(cat.name).fetchOne()); + } + + @Test + public void params_anon() { + Param name = new Param(String.class); + assertEquals("Bob", CollQueryFactory.from(cat, data).where(cat.name.eq(name)).set(name,"Bob").select(cat.name).fetchOne()); + } + + @Test(expected = ParamNotSetException.class) + public void params_not_set() { + Param name = new Param(String.class,"name"); + assertEquals("Bob", CollQueryFactory.from(cat, data).where(cat.name.eq(name)).select(cat.name).fetchOne()); + } + + @Test + public void limit() { + assertEquals(data, CollQueryFactory.from(cat, data).limit(Long.MAX_VALUE).fetch()); + } + +} diff --git a/querydsl-collections/src/test/java/com/querydsl/collections/CollQueryTemplatesTest.java b/querydsl-collections/src/test/java/com/querydsl/collections/CollQueryTemplatesTest.java new file mode 100644 index 0000000000..981eca2af1 --- /dev/null +++ b/querydsl-collections/src/test/java/com/querydsl/collections/CollQueryTemplatesTest.java @@ -0,0 +1,28 @@ +package com.querydsl.collections; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.TemplatesTestUtils; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.StringPath; + +public class CollQueryTemplatesTest { + + @Test + public void generic_precedence() { + TemplatesTestUtils.testPrecedence(CollQueryTemplates.DEFAULT); + } + + @Test + public void concat() { + StringPath a = Expressions.stringPath("a"); + StringPath b = Expressions.stringPath("b"); + Expression expr = a.append(b).toLowerCase(); + String str = new CollQuerySerializer(CollQueryTemplates.DEFAULT).handle(expr).toString(); + assertEquals("(a + b).toLowerCase()", str); + } + +} diff --git a/querydsl-collections/src/test/java/com/querydsl/collections/CollQueryTest.java b/querydsl-collections/src/test/java/com/querydsl/collections/CollQueryTest.java new file mode 100644 index 0000000000..dfef345b29 --- /dev/null +++ b/querydsl-collections/src/test/java/com/querydsl/collections/CollQueryTest.java @@ -0,0 +1,171 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.collections; + +import static com.querydsl.collections.CollQueryFactory.from; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.math.BigDecimal; +import java.util.Arrays; +import java.util.Collections; +import java.util.Date; +import java.util.List; + +import org.junit.Test; + +import com.querydsl.core.Tuple; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.Ops; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberExpression; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.StringPath; + +public class CollQueryTest extends AbstractQueryTest { + + @Test + public void customTemplates() { + CollQueryTemplates templates = new CollQueryTemplates() { + { + add(Ops.DateTimeOps.MONTH, "{0}.getMonthOfYear()"); + add(Ops.DateTimeOps.YEAR, "{0}.getYear()"); + } + }; + new CollQuery(templates); + } + + @Test + public void instanceOf() { + assertEquals( + Arrays.asList(c1, c2), + query().from(cat, Arrays.asList(c1, c2)).where(cat.instanceOf(Cat.class)) + .select(cat).fetch()); + } + + @Test + public void after_and_before() { + query().from(cat, Arrays.asList(c1, c2)) + .where( + cat.birthdate.lt(new Date()), + cat.birthdate.loe(new Date()), + cat.birthdate.gt(new Date()), + cat.birthdate.goe(new Date())) + .select(cat).fetch(); + } + + @Test + public void arrayProjection() { + // select pairs of cats with different names + query().from(cat, cats).from(otherCat, cats).where(cat.name.ne(otherCat.name)) + .select(cat.name, otherCat.name).fetch(); + assertEquals(4 * 3, last.res.size()); + } + + @Test + public void cast() { + NumberExpression num = cat.id; + Expression[] expr = new Expression[] {num.byteValue(), num.doubleValue(), + num.floatValue(), num.intValue(), num.longValue(), + num.shortValue(), num.stringValue()}; + + for (Expression e : expr) { + query().from(cat, Arrays.asList(c1, c2)).select(e).fetch(); + } + + } + + @Test + public void clone_() { + CollQuery query = new CollQuery().from(cat, Collections.emptyList()).where(cat.isNotNull()).clone(); + assertEquals("cat is not null", query.getMetadata().getWhere().toString()); + } + + @Test + public void primitives() { + // select cats with kittens + query().from(cat, cats).where(cat.kittens.size().ne(0)).select(cat.name).fetch(); + assertTrue(last.res.size() == 4); + + // select cats without kittens + query().from(cat, cats).where(cat.kittens.size().eq(0)).select(cat.name).fetch(); + assertTrue(last.res.size() == 0); + } + + @Test + public void simpleCases() { + // select all cat names + query().from(cat, cats).select(cat.name).fetch(); + assertTrue(last.res.size() == 4); + + // select all kittens + query().from(cat, cats).select(cat.kittens).fetch(); + assertTrue(last.res.size() == 4); + + // select cats with kittens + query().from(cat, cats).where(cat.kittens.size().gt(0)).select(cat.name).fetch(); + assertTrue(last.res.size() == 4); + + // select cats named Kitty + query().from(cat, cats).where(cat.name.eq("Kitty")).select(cat.name).fetch(); + assertTrue(last.res.size() == 1); + + // select cats named Kitt% + query().from(cat, cats).where(cat.name.matches("Kitt.*")).select(cat.name).fetch(); + assertTrue(last.res.size() == 1); + + query().from(cat, cats).select(cat.bodyWeight.add(cat.weight)).fetch(); + } + + @Test + public void various() { + StringPath a = Expressions.stringPath("a"); + StringPath b = Expressions.stringPath("b"); + for (Tuple strs : from(a, "aa", "bb", "cc") + .from(b, Arrays.asList("a","b")) + .where(a.startsWith(b)).select(a, b).fetch()) { + assertEquals(strs.get(a), strs.get(b) + strs.get(b)); + } + + query().from(cat, cats).select(cat.mate).fetch(); + + query().from(cat, cats).select(cat.kittens).fetch(); + + query().from(cat, cats).where(cat.kittens.isEmpty()).select(cat).fetch(); + + query().from(cat, cats).where(cat.kittens.isNotEmpty()).select(cat).fetch(); + + query().from(cat, cats).where(cat.name.matches("fri.*")).select(cat.name).fetch(); + + } + + @Test + public void bigDecimals() { + NumberPath a = Expressions.numberPath(BigDecimal.class, "cost"); + List nums = from(a, new BigDecimal("2.1"), new BigDecimal("20.21"), + new BigDecimal("44.4")).where(a.lt(new BigDecimal("35.1"))).select(a).fetch(); + assertEquals(Arrays.asList(new BigDecimal("2.1"), new BigDecimal("20.21")), nums); + } + + @Test(expected = UnsupportedOperationException.class) + public void groupBy() { + query().from(cat, cats).groupBy(cat.name); + } + + @Test(expected = UnsupportedOperationException.class) + public void having() { + query().from(cat, cats).having(cat.name.isNull()); + } + +} diff --git a/querydsl-collections/src/test/java/com/mysema/query/collections/CollUpdateClauseTest.java b/querydsl-collections/src/test/java/com/querydsl/collections/CollUpdateClauseTest.java similarity index 89% rename from querydsl-collections/src/test/java/com/mysema/query/collections/CollUpdateClauseTest.java rename to querydsl-collections/src/test/java/com/querydsl/collections/CollUpdateClauseTest.java index a2d2a1c8d2..74f1c0c549 100644 --- a/querydsl-collections/src/test/java/com/mysema/query/collections/CollUpdateClauseTest.java +++ b/querydsl-collections/src/test/java/com/querydsl/collections/CollUpdateClauseTest.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.collections; +package com.querydsl.collections; import static org.junit.Assert.assertEquals; @@ -23,7 +23,7 @@ public class CollUpdateClauseTest { @Test - public void Execute() { + public void execute() { QCat cat = QCat.cat; List cats = Arrays.asList(new Cat("Ann"), new Cat("Bob"), new Cat("John"), new Cat("Carl")); @@ -34,5 +34,5 @@ public void Execute() { assertEquals("Bobby", cats.get(1).getName()); } - + } diff --git a/querydsl-collections/src/test/java/com/querydsl/collections/CollectionAnyTest.java b/querydsl-collections/src/test/java/com/querydsl/collections/CollectionAnyTest.java new file mode 100644 index 0000000000..94a4667e09 --- /dev/null +++ b/querydsl-collections/src/test/java/com/querydsl/collections/CollectionAnyTest.java @@ -0,0 +1,101 @@ +package com.querydsl.collections; + +import static org.junit.Assert.assertEquals; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.junit.Test; + +public class CollectionAnyTest extends AbstractQueryTest { + + @Test + public void any_null() { + Cat a = new Cat("a"); + a.setKittens(null); + + assertEquals(0, CollQueryFactory. from(cat, Collections.singletonList(a)) + .where(cat.kittens.any().name.startsWith("a")).fetchCount()); + } + + @Test + public void any_in_projection() { + Cat a = new Cat("a"); + Cat aa = new Cat("aa"); + Cat ab = new Cat("ab"); + Cat ac = new Cat("ac"); + a.setKittens(Arrays.asList(aa,ab,ac)); + + Cat b = new Cat("b"); + Cat ba = new Cat("ba"); + Cat bb = new Cat("bb"); + b.setKittens(Arrays.asList(ba, bb)); + + QCat cat = QCat.cat; + List kittens = CollQueryFactory. from(cat, Arrays. asList(a,b)). select(cat.kittens.any()).fetch(); + assertEquals(Arrays.asList(aa,ab,ac,ba,bb), kittens); + } + + @Test + public void any_in_projection2() { + Cat a = new Cat("a"); + Cat aa = new Cat("aa"); + Cat ab = new Cat("ab"); + Cat ac = new Cat("ac"); + a.setKittens(Arrays.asList(aa,ab,ac)); + + Cat b = new Cat("b"); + Cat ba = new Cat("ba"); + Cat bb = new Cat("bb"); + b.setKittens(Arrays.asList(ba, bb)); + + QCat cat = QCat.cat; + List kittens = CollQueryFactory. from(cat, Arrays. asList(a,b)) + .select(cat.kittens.any().name).fetch(); + assertEquals(Arrays.asList("aa","ab","ac","ba","bb"), kittens); + } + + @Test + public void any_in_where_and_projection() { + Cat a = new Cat("a"); + Cat aa = new Cat("aa"); + Cat ab = new Cat("ab"); + Cat ac = new Cat("ac"); + a.setKittens(Arrays.asList(aa,ab,ac)); + + Cat b = new Cat("b"); + Cat ba = new Cat("ba"); + Cat bb = new Cat("bb"); + b.setKittens(Arrays.asList(ba, bb)); + + QCat cat = QCat.cat; + List kittens = CollQueryFactory. from(cat, Arrays. asList(a,b)) + .where(cat.kittens.any().name.startsWith("a")) + .select(cat.kittens.any()).fetch(); + + assertEquals(Arrays.asList(aa,ab,ac), kittens); + } + + @Test + public void any_in_where_and_projection2() { + Cat a = new Cat("a"); + Cat aa = new Cat("aa"); + Cat ab = new Cat("ab"); + Cat ac = new Cat("ac"); + a.setKittens(Arrays.asList(aa,ab,ac)); + + Cat b = new Cat("b"); + Cat ba = new Cat("ba"); + Cat bb = new Cat("bb"); + b.setKittens(Arrays.asList(ba, bb)); + + QCat cat = QCat.cat; + List kittens = CollQueryFactory. from(cat, Arrays. asList(a,b)) + .where(cat.kittens.any().name.startsWith("a")) + .select(cat.kittens.any().name).fetch(); + + assertEquals(Arrays.asList("aa","ab","ac"), kittens); + } + +} diff --git a/querydsl-collections/src/test/java/com/querydsl/collections/CollectionTest.java b/querydsl-collections/src/test/java/com/querydsl/collections/CollectionTest.java new file mode 100644 index 0000000000..d891088a4e --- /dev/null +++ b/querydsl-collections/src/test/java/com/querydsl/collections/CollectionTest.java @@ -0,0 +1,107 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.collections; + +import static org.junit.Assert.assertEquals; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.junit.Before; +import org.junit.Test; + +public class CollectionTest { + + private final QCat cat = new QCat("cat"); + + private final QCat other = new QCat("other"); + + private List cats; + + @Before + public void setUp() { + Cat cat1 = new Cat("1"); + cat1.setKittens(Collections.singletonList(cat1)); + Cat cat2 = new Cat("2"); + cat2.setKittens(Arrays.asList(cat1, cat2)); + Cat cat3 = new Cat("3"); + cat3.setKittens(Arrays.asList(cat1, cat2, cat3)); + Cat cat4 = new Cat("4"); + cat4.setKittens(Arrays.asList(cat1, cat2, cat3, cat4)); + + cats = Arrays.asList(cat1, cat2, cat3, cat4); + } + + @Test + public void join() { + assertEquals("4", CollQueryFactory.from(cat, cats) + .innerJoin(cat.kittens, other) + .where(other.name.eq("4")).select(cat.name).fetchFirst()); + } + + @Test + public void join_from_two_sources() { + QCat catKittens = new QCat("cat_kittens"); + QCat otherKittens = new QCat("other_kittens"); + assertEquals(30, CollQueryFactory + .from(cat, cats).from(other, cats) + .innerJoin(cat.kittens, catKittens) + .innerJoin(other.kittens, otherKittens) + .where(catKittens.eq(otherKittens)).fetchCount()); + } + + @Test + public void any_uniqueResult() { + assertEquals("4", CollQueryFactory.from(cat, cats) + .where(cat.kittens.any().name.eq("4")).select(cat.name).fetchOne()); + } + + @Test + public void any_count() { + assertEquals(4, CollQueryFactory.from(cat, cats) + .where(cat.kittens.any().name.isNotNull()).fetchCount()); + } + + @Test + public void any_two_levels() { + assertEquals(4, CollQueryFactory.from(cat, cats).where( + cat.kittens.any().kittens.any().isNotNull()).fetchCount()); + } + + @Test + public void any_two_levels2() { + assertEquals(4, CollQueryFactory.from(cat, cats).where( + cat.kittens.any().name.isNotNull(), + cat.kittens.any().kittens.any().isNotNull()).fetchCount()); + } + + @Test + public void any_from_two_sources() { + assertEquals(16, CollQueryFactory.from(cat, cats).from(other, cats).where( + cat.kittens.any().name.eq(other.kittens.any().name)).fetchCount()); + } + + @Test + public void list_size() { + assertEquals(4, CollQueryFactory.from(cat, cats).where(cat.kittens.size().gt(0)).fetchCount()); + assertEquals(2, CollQueryFactory.from(cat, cats).where(cat.kittens.size().gt(2)).fetchCount()); + } + + @Test + public void list_is_empty() { + assertEquals(0, CollQueryFactory.from(cat, cats).where(cat.kittens.isEmpty()).fetchCount()); + } + +} diff --git a/querydsl-collections/src/test/java/com/querydsl/collections/Color.java b/querydsl-collections/src/test/java/com/querydsl/collections/Color.java new file mode 100644 index 0000000000..1883b51df6 --- /dev/null +++ b/querydsl-collections/src/test/java/com/querydsl/collections/Color.java @@ -0,0 +1,18 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.collections; + +public enum Color { + BLACK, TABBY +} diff --git a/querydsl-collections/src/test/java/com/querydsl/collections/Comment.java b/querydsl-collections/src/test/java/com/querydsl/collections/Comment.java new file mode 100644 index 0000000000..97a838273e --- /dev/null +++ b/querydsl-collections/src/test/java/com/querydsl/collections/Comment.java @@ -0,0 +1,79 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.collections; + +import com.querydsl.core.annotations.QueryEntity; +import com.querydsl.core.annotations.QueryProjection; + +@QueryEntity +public class Comment { + + private int id; + + private String text; + + private User user; + + private Post post; + + public Comment() { } + + @QueryProjection + public Comment(int id, String text) { + this.id = id; + this.text = text; + } + + @QueryProjection + public Comment(int id, String text, User user, Post post) { + this.id = id; + this.text = text; + this.user = user; + this.post = post; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getText() { + return text; + } + + public void setText(String text) { + this.text = text; + } + + public User getUser() { + return user; + } + + public void setUser(User user) { + this.user = user; + } + + public Post getPost() { + return post; + } + + public void setPost(Post post) { + this.post = post; + } + + +} \ No newline at end of file diff --git a/querydsl-collections/src/test/java/com/mysema/query/collections/CompilationOverheadTest.java b/querydsl-collections/src/test/java/com/querydsl/collections/CompilationOverheadTest.java similarity index 90% rename from querydsl-collections/src/test/java/com/mysema/query/collections/CompilationOverheadTest.java rename to querydsl-collections/src/test/java/com/querydsl/collections/CompilationOverheadTest.java index 5ae134e258..34648d4b08 100644 --- a/querydsl-collections/src/test/java/com/mysema/query/collections/CompilationOverheadTest.java +++ b/querydsl-collections/src/test/java/com/querydsl/collections/CompilationOverheadTest.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.collections; +package com.querydsl.collections; import java.util.Arrays; import java.util.Collections; @@ -19,7 +19,7 @@ import org.junit.Test; -import com.mysema.query.types.expr.BooleanExpression; +import com.querydsl.core.types.dsl.BooleanExpression; public class CompilationOverheadTest { @@ -40,7 +40,6 @@ public void test() { for (BooleanExpression condition : conditions) { query(condition); } - System.err.println(); // 2nd for (BooleanExpression condition : conditions) { @@ -50,7 +49,7 @@ public void test() { private void query(BooleanExpression condition) { long start = System.currentTimeMillis(); - CollQueryFactory.from(cat, Collections.emptyList()).where(condition).list(cat); + CollQueryFactory.from(cat, Collections.emptyList()).where(condition).fetch(); long duration = System.currentTimeMillis() - start; System.out.println(condition + " : " + duration + "ms"); } diff --git a/querydsl-collections/src/test/java/com/querydsl/collections/DistinctTest.java b/querydsl-collections/src/test/java/com/querydsl/collections/DistinctTest.java new file mode 100644 index 0000000000..62dd48d5c2 --- /dev/null +++ b/querydsl-collections/src/test/java/com/querydsl/collections/DistinctTest.java @@ -0,0 +1,65 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.collections; + +import static org.junit.Assert.assertEquals; + +import java.util.Arrays; +import java.util.List; + +import org.junit.Test; + +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberPath; + +public class DistinctTest extends AbstractQueryTest { + + private NumberPath intVar1 = Expressions.numberPath(Integer.class, "var1"); + private NumberPath intVar2 = Expressions.numberPath(Integer.class, "var2"); + private List list1 = Arrays.asList(1, 2, 2, 3, 3, 3, 4, 4, 4, 4); + private List list2 = Arrays.asList(2, 2, 3, 3, 3, 4, 4, 4, 4, 4); + + @Test + public void singleSource() { + assertEquals(list1, CollQueryFactory.from(intVar1, list1).fetch()); + assertEquals(Arrays.asList(1, 2, 3, 4), CollQueryFactory.from(intVar1, list1).distinct().fetch()); + assertEquals(Arrays.asList(2, 3, 4), CollQueryFactory.from(intVar2, list2).distinct().fetch()); + + assertEquals(Arrays.asList(2, 3, 4), CollQueryFactory.from(intVar2, list2).distinct().fetch()); + } + + @Test + public void bothSources() { + assertEquals(100, CollQueryFactory.from(intVar1, list1).from(intVar2, list2).select(intVar1, intVar2).fetch().size()); + assertEquals(12, CollQueryFactory.from(intVar1, list1).from(intVar2, list2).distinct().select(intVar1, intVar2).fetch().size()); + + assertEquals(12, CollQueryFactory.from(intVar1, list1).from(intVar2, list2).distinct().select(intVar1, intVar2).fetch().size()); + } + + @Test + public void countDistinct() { + assertEquals(10, CollQueryFactory.from(intVar1, list1).fetchCount()); + assertEquals(4, CollQueryFactory.from(intVar1, list1).distinct().fetchCount()); + assertEquals(3, CollQueryFactory.from(intVar2, list2).distinct().fetchCount()); + + assertEquals(3, CollQueryFactory.from(intVar2, list2).distinct().fetchCount()); + } + + @Test + public void null_() { + assertEquals(Arrays.asList(null, 1), + CollQueryFactory. from(intVar1, Arrays.asList(null, 1)).distinct().fetch()); + } + +} diff --git a/querydsl-collections/src/test/java/com/querydsl/collections/Document.java b/querydsl-collections/src/test/java/com/querydsl/collections/Document.java new file mode 100644 index 0000000000..ca00156f36 --- /dev/null +++ b/querydsl-collections/src/test/java/com/querydsl/collections/Document.java @@ -0,0 +1,31 @@ +package com.querydsl.collections; + +import java.util.ArrayList; +import java.util.List; + +import com.querydsl.core.annotations.QueryEntity; + +@QueryEntity +public class Document { + + private Long id; + + private List meshThesaurusTerms = new ArrayList(); + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public List getMeshThesaurusTerms() { + return meshThesaurusTerms; + } + + public void setMeshThesaurusTerms(List meshThesaurusTerms) { + this.meshThesaurusTerms = meshThesaurusTerms; + } + +} \ No newline at end of file diff --git a/querydsl-collections/src/test/java/com/mysema/query/collections/DocumentTest.java b/querydsl-collections/src/test/java/com/querydsl/collections/DocumentTest.java similarity index 86% rename from querydsl-collections/src/test/java/com/mysema/query/collections/DocumentTest.java rename to querydsl-collections/src/test/java/com/querydsl/collections/DocumentTest.java index cd85280c69..f04c6e9fc5 100644 --- a/querydsl-collections/src/test/java/com/mysema/query/collections/DocumentTest.java +++ b/querydsl-collections/src/test/java/com/querydsl/collections/DocumentTest.java @@ -1,4 +1,4 @@ -package com.mysema.query.collections; +package com.querydsl.collections; import static org.junit.Assert.assertTrue; @@ -7,7 +7,7 @@ import org.junit.Before; import org.junit.Test; -import com.mysema.query.types.Predicate; +import com.querydsl.core.types.Predicate; public class DocumentTest { @@ -31,21 +31,21 @@ public void setUp() { @Test public void test1() { Predicate crit = qDoc.id.eq(3L); - List expResult = CollQueryFactory.from(qDoc, doc1, doc2, doc3).where(crit).list(qDoc); + List expResult = CollQueryFactory.from(qDoc, doc1, doc2, doc3).where(crit).fetch(); assertTrue(expResult.contains(doc3)); //ok } @Test public void test2() { Predicate crit = qDoc.meshThesaurusTerms.any().eq("x"); - List expResult = CollQueryFactory.from(qDoc, doc1, doc2, doc3).where(crit).list(qDoc); + List expResult = CollQueryFactory.from(qDoc, doc1, doc2, doc3).where(crit).fetch(); assertTrue(expResult.contains(doc1)); //ok } @Test public void test3() { Predicate crit = qDoc.meshThesaurusTerms.any().eq("x").or(qDoc.id.eq(3L)); - List expResult = CollQueryFactory.from(qDoc, doc1, doc2, doc3).where(crit).list(qDoc); + List expResult = CollQueryFactory.from(qDoc, doc1, doc2, doc3).where(crit).fetch(); assertTrue(expResult.contains(doc1)); assertTrue(expResult.contains(doc3)); //fails, expResult contains only doc1, but should contain doc1 and doc3! } @@ -53,7 +53,7 @@ public void test3() { @Test public void test4() { Predicate crit = qDoc.id.eq(3L).or(qDoc.meshThesaurusTerms.any().eq("x")); - List expResult = CollQueryFactory.from(qDoc, doc1, doc2, doc3).where(crit).list(qDoc); + List expResult = CollQueryFactory.from(qDoc, doc1, doc2, doc3).where(crit).fetch(); assertTrue(expResult.contains(doc1)); assertTrue(expResult.contains(doc3)); //fails, expResult contains only doc1, but should contain doc1 and doc3! } diff --git a/querydsl-collections/src/test/java/com/querydsl/collections/ECJEvaluatorFactoryTest.java b/querydsl-collections/src/test/java/com/querydsl/collections/ECJEvaluatorFactoryTest.java new file mode 100644 index 0000000000..f4bc4eae0c --- /dev/null +++ b/querydsl-collections/src/test/java/com/querydsl/collections/ECJEvaluatorFactoryTest.java @@ -0,0 +1,19 @@ +package com.querydsl.collections; + +import org.junit.Test; + +import com.querydsl.codegen.utils.ECJEvaluatorFactory; + +public class ECJEvaluatorFactoryTest extends AbstractQueryTest { + + @Test + public void evaluator_factory() { + DefaultEvaluatorFactory evaluatorFactory = new DefaultEvaluatorFactory( + CollQueryTemplates.DEFAULT, + new ECJEvaluatorFactory(getClass().getClassLoader())); + QueryEngine queryEngine = new DefaultQueryEngine(evaluatorFactory); + CollQuery query = new CollQuery(queryEngine); + query.from(cat, cats).select(cat.name).fetch(); + } + +} diff --git a/querydsl-collections/src/test/java/com/querydsl/collections/EntityWithLongId.java b/querydsl-collections/src/test/java/com/querydsl/collections/EntityWithLongId.java new file mode 100644 index 0000000000..6c34fa792a --- /dev/null +++ b/querydsl-collections/src/test/java/com/querydsl/collections/EntityWithLongId.java @@ -0,0 +1,23 @@ +package com.querydsl.collections; + +import com.querydsl.core.annotations.QueryEntity; +import com.querydsl.core.annotations.QueryProjection; + +@QueryEntity +public class EntityWithLongId { + + private Long id; + + @QueryProjection + public EntityWithLongId(Long id) { + this.id = id; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } +} diff --git a/querydsl-collections/src/test/java/com/querydsl/collections/EntityWithLongIdTest.java b/querydsl-collections/src/test/java/com/querydsl/collections/EntityWithLongIdTest.java new file mode 100644 index 0000000000..20de545c38 --- /dev/null +++ b/querydsl-collections/src/test/java/com/querydsl/collections/EntityWithLongIdTest.java @@ -0,0 +1,51 @@ +package com.querydsl.collections; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.util.Arrays; +import java.util.List; + +import org.junit.Test; + +public class EntityWithLongIdTest { + + private List entities = Arrays.asList( + new EntityWithLongId(999L), + new EntityWithLongId(1000L), + new EntityWithLongId(1001L), + new EntityWithLongId(1003L) + ); + + @Test + public void simpleEquals() { + QEntityWithLongId root = QEntityWithLongId.entityWithLongId; + CollQuery query = new CollQuery().from(root, entities); + query.where(root.id.eq(1000L)); + + Long found = query.select(root.id).fetchFirst(); + assertNotNull(found); + assertEquals(found.longValue(), 1000); + } + + @Test + public void cartesianEquals() { + QEntityWithLongId root = new QEntityWithLongId("root1"); + QEntityWithLongId root2 = new QEntityWithLongId("root2"); + assertEquals(entities.size(), new CollQuery() + .from(root, entities).from(root2, entities) + .where(root2.id.eq(root.id)) + .fetchCount()); + } + + @Test + public void cartesianPlus1() { + QEntityWithLongId root = new QEntityWithLongId("root1"); + QEntityWithLongId root2 = new QEntityWithLongId("root2"); + assertEquals(2, new CollQuery() + .from(root, entities).from(root2, entities) + .where(root2.id.eq(root.id.add(1))) + .fetchCount()); + } + +} diff --git a/querydsl-collections/src/test/java/com/mysema/query/collections/EvaluatorTransformerTest.java b/querydsl-collections/src/test/java/com/querydsl/collections/EvaluatorTransformerTest.java similarity index 84% rename from querydsl-collections/src/test/java/com/mysema/query/collections/EvaluatorTransformerTest.java rename to querydsl-collections/src/test/java/com/querydsl/collections/EvaluatorTransformerTest.java index be59460b18..e03d10ec9a 100644 --- a/querydsl-collections/src/test/java/com/mysema/query/collections/EvaluatorTransformerTest.java +++ b/querydsl-collections/src/test/java/com/querydsl/collections/EvaluatorTransformerTest.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.collections; +package com.querydsl.collections; import static org.junit.Assert.assertEquals; @@ -19,9 +19,9 @@ import org.junit.Test; -import com.mysema.codegen.Evaluator; -import com.mysema.query.DefaultQueryMetadata; -import com.mysema.query.QueryMetadata; +import com.querydsl.codegen.utils.Evaluator; +import com.querydsl.core.DefaultQueryMetadata; +import com.querydsl.core.QueryMetadata; public class EvaluatorTransformerTest { diff --git a/querydsl-collections/src/test/java/com/querydsl/collections/FirstResultContractTest.java b/querydsl-collections/src/test/java/com/querydsl/collections/FirstResultContractTest.java new file mode 100644 index 0000000000..2ca9e8be78 --- /dev/null +++ b/querydsl-collections/src/test/java/com/querydsl/collections/FirstResultContractTest.java @@ -0,0 +1,27 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.collections; + +import static org.junit.Assert.assertNotNull; + +import org.junit.Test; + +public class FirstResultContractTest extends AbstractQueryTest { + + @Test + public void singleResult() { + assertNotNull(CollQueryFactory.from(cat, cats).where(cat.name.isNotNull()).fetchFirst()); + } + +} diff --git a/querydsl-collections/src/test/java/com/querydsl/collections/FunctionalHelpersTest.java b/querydsl-collections/src/test/java/com/querydsl/collections/FunctionalHelpersTest.java new file mode 100644 index 0000000000..d8c8d4434a --- /dev/null +++ b/querydsl-collections/src/test/java/com/querydsl/collections/FunctionalHelpersTest.java @@ -0,0 +1,28 @@ +package com.querydsl.collections; + +import org.junit.Test; + +import java.util.function.Function; +import java.util.function.Predicate; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +public class FunctionalHelpersTest { + + @Test + public void predicate() { + Predicate predicate = FunctionalHelpers.wrap(QCat.cat.name.startsWith("Ann")); + assertTrue(predicate.test(new Cat("Ann"))); + assertFalse(predicate.test(new Cat("Bob"))); + } + + @Test + public void function() { + Function function = FunctionalHelpers.wrap(QCat.cat.name); + assertEquals("Ann", function.apply(new Cat("Ann"))); + assertEquals("Bob", function.apply(new Cat("Bob"))); + } + +} diff --git a/querydsl-collections/src/test/java/com/querydsl/collections/GroupBy2Test.java b/querydsl-collections/src/test/java/com/querydsl/collections/GroupBy2Test.java new file mode 100644 index 0000000000..1f9208656c --- /dev/null +++ b/querydsl-collections/src/test/java/com/querydsl/collections/GroupBy2Test.java @@ -0,0 +1,159 @@ +package com.querydsl.collections; + +import static com.querydsl.core.group.GroupBy.list; +import static com.querydsl.core.group.GroupBy.map; +import static org.junit.Assert.assertEquals; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import org.junit.Before; +import org.junit.Test; + +import com.querydsl.core.annotations.QueryEntity; +import com.querydsl.core.annotations.QueryProjection; +import com.querydsl.core.group.GroupBy; + +public class GroupBy2Test { + +// select u1.id,u1.name,r1.id,r1.name,s1.name from users u1 +// join roles r1 on u1.role = r1.id +// join security_groups s1 on r1.secgroup = s1.id + + @QueryEntity + public static class User { + public Long id; + public String name; + public List roles; + } + + @QueryEntity + public static class Role { + public Long id; + public String name; + public List groups; + } + + @QueryEntity + public static class SecurityGroup { + public Long id; + public String name; + + public SecurityGroup(Long id, String name) { + this.id = id; + this.name = name; + } + } + + public static class UserDto { + public Long id; + public String name; + public List roleIds; + public List roleNames; + public List secIds; + + @QueryProjection + public UserDto(Long id, String name, List roleIds, List roleNames, List secIds) { + this.id = id; + this.name = name; + this.roleIds = roleIds; + this.roleNames = roleNames; + this.secIds = secIds; + } + + @QueryProjection + public UserDto(Long id, String name, Map roles, Map groups) { + this.id = id; + this.name = name; + this.roleIds = new ArrayList<>(roles.keySet()); + this.roleNames = new ArrayList<>(roles.values()); + this.secIds = new ArrayList<>(groups.keySet()); + } + } + + private List users; + + @Before + public void setUp() { + Role r1 = new Role(); + r1.id = 1L; + r1.name = "User"; + r1.groups = Arrays.asList(new SecurityGroup(1L, "User 1")); + + Role r2 = new Role(); + r2.id = 2L; + r2.name = null; // NOTE this is null on purpose + r2.groups = Arrays.asList(new SecurityGroup(2L, "Admin 1"), + new SecurityGroup(3L, "Admin 2")); + + User u1 = new User(); + u1.id = 3L; + u1.name = "Bob"; + u1.roles = Arrays.asList(r1); + + User u2 = new User(); + u2.id = 32L; + u2.name = "Ann"; + u2.roles = Arrays.asList(r1, r2); + + users = Arrays.asList(u1, u2); + } + + @Test + public void test() { + QGroupBy2Test_User user = QGroupBy2Test_User.user; + QGroupBy2Test_Role role = QGroupBy2Test_Role.role; + QGroupBy2Test_SecurityGroup group = QGroupBy2Test_SecurityGroup.securityGroup; + + Map userDtos = CollQueryFactory.from(user, users) + .innerJoin(user.roles, role) + .innerJoin(role.groups, group) + .transform(GroupBy.groupBy(user.id) + .as(new QGroupBy2Test_UserDto( + user.id, + user.name, + list(role.id), + list(role.name), + list(group.id)))); + + UserDto dto1 = userDtos.get(3L); + assertEquals(1, dto1.roleIds.size()); + assertEquals(1, dto1.roleNames.size()); + assertEquals(1, dto1.secIds.size()); + + UserDto dto2 = userDtos.get(32L); + assertEquals(3, dto2.roleIds.size()); + assertEquals(1, dto2.roleNames.size()); + assertEquals(3, dto2.secIds.size()); + } + + @Test + public void test2() { + QGroupBy2Test_User user = QGroupBy2Test_User.user; + QGroupBy2Test_Role role = QGroupBy2Test_Role.role; + QGroupBy2Test_SecurityGroup group = QGroupBy2Test_SecurityGroup.securityGroup; + + Map userDtos = CollQueryFactory.from(user, users) + .innerJoin(user.roles, role) + .innerJoin(role.groups, group) + .transform(GroupBy.groupBy(user.id) + .as(new QGroupBy2Test_UserDto( + user.id, + user.name, + map(role.id, role.name), + map(group.id, group.name)))); + + UserDto dto1 = userDtos.get(3L); + assertEquals(1, dto1.roleIds.size()); + assertEquals(1, dto1.roleNames.size()); + assertEquals(1, dto1.secIds.size()); + + UserDto dto2 = userDtos.get(32L); + assertEquals(2, dto2.roleIds.size()); + assertEquals(2, dto2.roleNames.size()); + assertEquals(3, dto2.secIds.size()); + } + +} diff --git a/querydsl-collections/src/test/java/com/querydsl/collections/GroupBy3Test.java b/querydsl-collections/src/test/java/com/querydsl/collections/GroupBy3Test.java new file mode 100644 index 0000000000..362c5ffc33 --- /dev/null +++ b/querydsl-collections/src/test/java/com/querydsl/collections/GroupBy3Test.java @@ -0,0 +1,101 @@ +package com.querydsl.collections; + +import static com.querydsl.core.group.GroupBy.groupBy; +import static com.querydsl.core.group.GroupBy.set; +import static org.easymock.EasyMock.*; + +import java.util.Map; +import java.util.Set; + +import org.junit.Test; + +import com.mysema.commons.lang.CloseableIterator; +import com.querydsl.core.FetchableQuery; +import com.querydsl.core.ResultTransformer; +import com.querydsl.core.annotations.QueryEntity; +import com.querydsl.core.group.Group; +import com.querydsl.core.types.Projections; + +public class GroupBy3Test { + + @QueryEntity + public static class RiskAnalysis { + public String id; + public Set assetThreats; + } + + @QueryEntity + public static class AssetThreat { + public String id; + public Set threats; + } + + @QueryEntity + public static class Threat { + public String id; + } + + @Test + public void nested_expressions() { + QGroupBy3Test_RiskAnalysis riskAnalysis = QGroupBy3Test_RiskAnalysis.riskAnalysis; + QGroupBy3Test_AssetThreat assetThreat = QGroupBy3Test_AssetThreat.assetThreat; + QGroupBy3Test_Threat threat = QGroupBy3Test_Threat.threat; + + ResultTransformer> transformer = + groupBy(riskAnalysis.id) + .as(Projections.bean(RiskAnalysis.class, + riskAnalysis.id, + set(Projections.bean(AssetThreat.class, + assetThreat.id, + set(Projections.bean(Threat.class, threat.id)).as("threats"))) + .as("assetThreats"))); + + CloseableIterator iter = createMock(CloseableIterator.class); + FetchableQuery projectable = createMock(FetchableQuery.class); + expect(projectable.select(Projections.tuple( + riskAnalysis.id, + riskAnalysis.id, + assetThreat.id, + Projections.bean(Threat.class, threat.id)))) + .andReturn(projectable); + expect(projectable.iterate()).andReturn(iter); + expect(iter.hasNext()).andReturn(false); + iter.close(); + replay(iter, projectable); + + transformer.transform(projectable); + verify(projectable); + } + + @Test + public void alias_usage() { + QGroupBy3Test_RiskAnalysis riskAnalysis = QGroupBy3Test_RiskAnalysis.riskAnalysis; + QGroupBy3Test_AssetThreat assetThreat = QGroupBy3Test_AssetThreat.assetThreat; + QGroupBy3Test_Threat threat = QGroupBy3Test_Threat.threat; + + ResultTransformer> transformer = + groupBy(riskAnalysis.id) + .as(riskAnalysis.id, + set(Projections.bean(AssetThreat.class, + assetThreat.id, + set(Projections.bean(Threat.class, threat.id)).as("threats")) + .as("assetThreats"))); + + CloseableIterator iter = createMock(CloseableIterator.class); + FetchableQuery projectable = createMock(FetchableQuery.class); + expect(projectable.select(Projections.tuple( + riskAnalysis.id, + riskAnalysis.id, + assetThreat.id, + Projections.bean(Threat.class, threat.id)))) + .andReturn(projectable); + expect(projectable.iterate()).andReturn(iter); + expect(iter.hasNext()).andReturn(false); + iter.close(); + replay(iter, projectable); + + transformer.transform(projectable); + verify(projectable); + } + +} diff --git a/querydsl-collections/src/test/java/com/querydsl/collections/GroupBy4Test.java b/querydsl-collections/src/test/java/com/querydsl/collections/GroupBy4Test.java new file mode 100644 index 0000000000..16d4f79084 --- /dev/null +++ b/querydsl-collections/src/test/java/com/querydsl/collections/GroupBy4Test.java @@ -0,0 +1,273 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ + +package com.querydsl.collections; + +import com.google.common.collect.HashMultimap; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableMultimap; +import com.google.common.collect.ImmutableTable; +import com.google.common.collect.Lists; +import com.google.common.collect.Multimap; +import com.querydsl.core.annotations.QueryEntity; +import com.querydsl.core.group.guava.GuavaGroupBy; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Map; + +import static com.querydsl.core.group.GroupBy.list; +import static com.querydsl.core.group.guava.GuavaGroupBy.groupBy; +import static com.querydsl.core.group.guava.GuavaGroupBy.map; +import static org.junit.Assert.assertEquals; + + +public class GroupBy4Test { + + @QueryEntity + public static class Table { + String col1, col2, col3; + + public Table(String c1, String c2, String c3) { + col1 = c1; + col2 = c2; + col3 = c3; + } + } + + @Test + public void test() { + List
data = new ArrayList<>(); + data.add(new Table("1", "abc", "111")); + data.add(new Table("1", "pqr", "222")); + data.add(new Table("2", "abc", "333")); + data.add(new Table("2", "pqr", "444")); + data.add(new Table("3", "abc", "555")); + data.add(new Table("3", "pqr", "666")); + + QGroupBy4Test_Table table = QGroupBy4Test_Table.table; + Map> grouped = CollQueryFactory + .from(table, data) + .transform(groupBy(table.col1).as(map(table.col2, table.col3))); + + assertEquals(3, grouped.size()); + assertEquals(2, grouped.get("1").size()); + assertEquals(new HashSet<>(Arrays.asList("abc", "pqr")), grouped.get("1").keySet()); + + } + + @Test + public void test2() { + List
data = Lists.newArrayList(); + data.add(new Table("1", "abc", "111")); + data.add(new Table("1", "pqr", "222")); + data.add(new Table("2", "abc", "333")); + data.add(new Table("2", "pqr", "444")); + data.add(new Table("3", "abc", "555")); + data.add(new Table("3", "pqr", "666")); + + QGroupBy4Test_Table table = QGroupBy4Test_Table.table; + Multimap transform = CollQueryFactory + .from(table, data) + .transform(groupBy(table.col1).asMultimap(table.col2)); + + Multimap expected = HashMultimap.create( + ImmutableMultimap. builder() + .putAll("1", "abc", "pqr") + .putAll("2", "abc", "pqr") + .putAll("3", "abc", "pqr") + .build()); + + assertEquals(expected, transform); + } + + @Test + public void test3() { + List
data = Lists.newArrayList(); + data.add(new Table("1", "abc", "111")); + data.add(new Table("1", "pqr", "222")); + data.add(new Table("2", "abc", "333")); + data.add(new Table("2", "pqr", "444")); + data.add(new Table("3", "abc", "555")); + data.add(new Table("3", "pqr", "666")); + + QGroupBy4Test_Table table = QGroupBy4Test_Table.table; + Multimap> transform = CollQueryFactory + .from(table, data) + .transform(groupBy(table.col1).asMultimap( + map(table.col2, table.col3) + )); + + HashMultimap> expected = HashMultimap.create(ImmutableMultimap.>builder() + .putAll("1", ImmutableMap.of("abc", "111"), ImmutableMap.of("pqr", "222")) + .putAll("2", ImmutableMap.of("abc", "333"), ImmutableMap.of("pqr", "444")) + .putAll("3", ImmutableMap.of("abc", "555"), ImmutableMap.of("pqr", "666")) + .build() + ); + + assertEquals(expected, transform); + } + + @Test + public void test4() { + List
data = Lists.newArrayList(); + data.add(new Table("1", "abc", "111")); + data.add(new Table("1", "pqr", "222")); + data.add(new Table("2", "abc", "333")); + data.add(new Table("2", "pqr", "444")); + data.add(new Table("3", "abc", "555")); + data.add(new Table("3", "pqr", "666")); + + + QGroupBy4Test_Table table = QGroupBy4Test_Table.table; + com.google.common.collect.Table transform = CollQueryFactory + .from(table, data) + .transform(groupBy(table.col1).asTable(table.col2, table.col3)); + + ImmutableTable expected = ImmutableTable. builder() + .put("1", "abc", "111") + .put("1", "pqr", "222") + .put("2", "abc", "333") + .put("2", "pqr", "444") + .put("3", "abc", "555") + .put("3", "pqr", "666") + .build(); + + assertEquals(expected, transform); + } + + @Test + public void test5() { + List
data = Lists.newArrayList(); + data.add(new Table("1", "abc", "111")); + data.add(new Table("1", "pqr", "222")); + data.add(new Table("2", "abc", "333")); + data.add(new Table("2", "pqr", "444")); + data.add(new Table("3", "abc", "555")); + data.add(new Table("3", "pqr", "666")); + data.add(new Table("3", "pqr", "777")); + + + QGroupBy4Test_Table table = QGroupBy4Test_Table.table; + com.google.common.collect.Table> transform = CollQueryFactory + .from(table, data) + .transform(groupBy(table.col1).asTable(table.col2, list(table.col3))); + + ImmutableTable> expected = ImmutableTable.> builder() + .put("1", "abc", ImmutableList.of("111")) + .put("1", "pqr", ImmutableList.of("222")) + .put("2", "abc", ImmutableList.of("333")) + .put("2", "pqr", ImmutableList.of("444")) + .put("3", "abc", ImmutableList.of("555")) + .put("3", "pqr", ImmutableList.of("666", "777")) + .build(); + + assertEquals(expected, transform); + } + + @Test + public void test6() { + List
data = Lists.newArrayList(); + data.add(new Table("1", "abc", "111")); + data.add(new Table("1", "pqr", "222")); + data.add(new Table("2", "abc", "333")); + data.add(new Table("2", "pqr", "444")); + data.add(new Table("3", "abc", "555")); + data.add(new Table("3", "pqr", "666")); + data.add(new Table("3", "pqr", "777")); + + + QGroupBy4Test_Table table = QGroupBy4Test_Table.table; + Map> transform = CollQueryFactory + .from(table, data) + .transform(groupBy(table.col1).as(GuavaGroupBy.multimap(table.col2, table.col3))); + + ImmutableMap> expected = ImmutableMap.> builder() + .put("1", HashMultimap.create(ImmutableMultimap. builder().putAll("abc", "111").putAll("pqr", "222").build())) + .put("2", HashMultimap.create(ImmutableMultimap. builder().putAll("abc", "333").putAll("pqr", "444").build())) + .put("3", HashMultimap.create(ImmutableMultimap. builder().putAll("abc", "555").putAll("pqr", "666", "777").build())) + .build(); + + assertEquals(expected, transform); + } + + @Test + public void test7() { + List
data = Lists.newArrayList(); + data.add(new Table("1", "abc", "111")); + data.add(new Table("1", "pqr", "222")); + data.add(new Table("2", "abc", "333")); + data.add(new Table("2", "pqr", "444")); + data.add(new Table("3", "abc", "555")); + data.add(new Table("3", "pqr", "666")); + data.add(new Table("3", "pqr", "777")); + + QGroupBy4Test_Table table = QGroupBy4Test_Table.table; + Map>>> transform = CollQueryFactory + .from(table, data) + .transform(groupBy(table.col1).as(GuavaGroupBy.table( + table.col1, table.col2, map(table.col2, list(table.col3))))); + + ImmutableMap>>> expected = + ImmutableMap.>>>builder() + .put("1", ImmutableTable.>>builder() + .put("1", "abc", ImmutableMap.> of("abc", ImmutableList.of("111"))) + .put("1", "pqr", ImmutableMap.> of("pqr", ImmutableList.of("222"))) + .build()) + .put("2", ImmutableTable.>>builder() + .put("2", "abc", ImmutableMap.> of("abc", ImmutableList.of("333"))) + .put("2", "pqr", ImmutableMap.> of("pqr", ImmutableList.of("444"))) + .build()) + .put("3", ImmutableTable.>>builder() + .put("3", "abc", ImmutableMap.> of("abc", ImmutableList.of("555"))) + .put("3", "pqr", ImmutableMap.> of("pqr", ImmutableList.of("666", "777"))) + .build()) + .build(); + + assertEquals(expected, transform); + } + + @Test + public void test8() { + List
data = Lists.newArrayList(); + data.add(new Table("1", "abc", "111")); + data.add(new Table("1", "pqr", "222")); + data.add(new Table("2", "abc", "333")); + data.add(new Table("2", "pqr", "444")); + data.add(new Table("3", "abc", "555")); + data.add(new Table("3", "pqr", "666")); + data.add(new Table("3", "pqr", "777")); + + QGroupBy4Test_Table table = QGroupBy4Test_Table.table; + com.google.common.collect.Table, List> transform = CollQueryFactory + .from(table, data) + .transform(groupBy(table.col1).asTable(map(table.col1, table.col2), GuavaGroupBy.list(table.col3))); + + ImmutableTable, List> expected = ImmutableTable., List> builder() + .put("1", ImmutableMap.of("1", "abc"), ImmutableList.of("111")) + .put("1", ImmutableMap.of("1", "pqr"), ImmutableList.of("222")) + .put("2", ImmutableMap.of("2", "abc"), ImmutableList.of("333")) + .put("2", ImmutableMap.of("2", "pqr"), ImmutableList.of("444")) + .put("3", ImmutableMap.of("3", "abc"), ImmutableList.of("555")) + .put("3", ImmutableMap.of("3", "pqr"), ImmutableList.of("666", "777")) + .build(); + + assertEquals(expected, transform); + } + +} diff --git a/querydsl-collections/src/test/java/com/querydsl/collections/GroupByTest.java b/querydsl-collections/src/test/java/com/querydsl/collections/GroupByTest.java new file mode 100644 index 0000000000..f88d0d8323 --- /dev/null +++ b/querydsl-collections/src/test/java/com/querydsl/collections/GroupByTest.java @@ -0,0 +1,276 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.collections; + + +import static com.querydsl.core.group.GroupBy.*; +import static org.junit.Assert.*; + +import java.util.*; + +import org.junit.Ignore; +import org.junit.Test; + +import com.querydsl.core.group.Group; +import com.querydsl.core.types.ConstructorExpression; +import com.querydsl.core.types.Projections; + +public class GroupByTest { + + private static final List users = Arrays.asList(new User("Bob"), new User("Jane"), new User("Jack")); + + private static final List posts = Arrays.asList( + new Post(1, "Post 1", users.get(0)), + new Post(2, "Post 2", users.get(0)), + new Post(3, "Post 3", users.get(1))); + + private static final List comments = Arrays.asList( + new Comment(1, "Comment 1", users.get(0), posts.get(0)), + new Comment(2, "Comment 2", users.get(1), posts.get(1)), + new Comment(3, "Comment 3", users.get(2), posts.get(1)), + new Comment(4, "Comment 4", users.get(0), posts.get(2)), + new Comment(5, "Comment 5", users.get(1), posts.get(2)), + new Comment(6, "Comment 6", users.get(2), posts.get(2))); + + private static final QUser user = QUser.user; + + private static final QComment comment = QComment.comment; + + private static final QPost post = QPost.post; + + private static final ConstructorExpression qComment = QComment.create(comment.id, comment.text); + + @Test + public void group_min() { + Map results = CollQueryFactory.from(post, posts).from(comment, comments) + .where(comment.post.id.eq(post.id)) + .transform(groupBy(post.id).as(min(comment.text))); + + assertEquals("Comment 1", results.get(1)); + assertEquals("Comment 2", results.get(2)); + assertEquals("Comment 4", results.get(3)); + } + + public void comments_by_post() { + Map> results = CollQueryFactory.from(post, posts).from(comment, comments) + .where(comment.post.id.eq(post.id)) + .transform(groupBy(post.id).as(list(comment))); + + assertEquals(1, results.get(1).size()); + assertEquals(2, results.get(2).size()); + assertEquals(3, results.get(3).size()); + } + + @Test + public void group_max() { + Map results = CollQueryFactory.from(post, posts).from(comment, comments) + .where(comment.post.id.eq(post.id)) + .transform(groupBy(post.id).as(max(comment.text))); + + assertEquals("Comment 1", results.get(1)); + assertEquals("Comment 3", results.get(2)); + assertEquals("Comment 6", results.get(3)); + } + + @Test + public void group_sum() { + Map results = CollQueryFactory.from(post, posts).from(comment, comments) + .where(comment.post.id.eq(post.id)) + .transform(groupBy(post.id).as(sum(comment.id))); + + assertEquals(1, results.get(1).intValue()); + assertEquals(5, results.get(2).intValue()); + assertEquals(15, results.get(3).intValue()); + } + + @Test + public void group_avg() { + Map results = CollQueryFactory.from(post, posts).from(comment, comments) + .where(comment.post.id.eq(post.id)) + .transform(groupBy(post.id).as(avg(comment.id))); + + assertEquals(1, results.get(1).intValue()); + assertEquals(2, results.get(2).intValue()); + assertEquals(5, results.get(3).intValue()); + } + + @Test + public void group_order() { + Map results = CollQueryFactory.from(post, posts).from(comment, comments) + .where(comment.post.id.eq(post.id)) + .transform(groupBy(post.id).as(post.name, set(comment.id))); + + assertEquals(3, results.size()); + } + + @Test + public void first_set_and_list() { + Map results = CollQueryFactory.from(post, posts).from(comment, comments) + .where(comment.post.id.eq(post.id)) + .transform(groupBy(post.id).as(post.name, set(comment.id), list(comment.text))); + + Group group = results.get(1); + assertEquals(toInt(1), group.getOne(post.id)); + assertEquals("Post 1", group.getOne(post.name)); + assertEquals(toSet(1), group.getSet(comment.id)); + assertEquals(Collections.singletonList("Comment 1"), group.getList(comment.text)); + } + + @Test + @Ignore + public void group_by_null() { + Map results = CollQueryFactory.from(post, posts).from(comment, comments) + .where(comment.post.id.eq(post.id)) + .transform(groupBy(post.id).as(post.name, set(comment.id), list(comment.text))); + + Group group = results.get(null); + assertNull(group.getOne(post.id)); + assertEquals("null post", group.getOne(post.name)); + assertEquals(toSet(7, 8), group.getSet(comment.id)); + assertEquals(Arrays.asList("comment 7", "comment 8"), group.getList(comment.text)); + + } + +// @Test(expected=NoSuchElementException.class) +// public void noSuchElementException() { +// Map results = BASIC_RESULTS.transform( +// groupBy(postId, postName, set(commentId), list(commentText))); +// +// Group group = results.get(1); +// group.getSet(qComment); +// } + + @Test(expected = ClassCastException.class) + public void classCastException() { + Map results = CollQueryFactory.from(post, posts).from(comment, comments) + .where(comment.post.id.eq(post.id)) + .transform(groupBy(post.id).as(post.name, set(comment.id), list(comment.text))); + + Group group = results.get(1); + group.getList(comment.id); + } + + @Test + @Ignore + public void map_() { + Map results = CollQueryFactory.from(post, posts).from(comment, comments) + .where(comment.post.id.eq(post.id)) + .transform(groupBy(post.id).as(post.name, map(comment.id, comment.text))); + + Group group = results.get(1); + Map comments = group.getMap(comment.id, comment.text); + assertEquals(1, comments.size()); +// assertEquals("comment 2", comments.get(2)); + } + + @Test + public void array_access() { + Map results = CollQueryFactory.from(post, posts).from(comment, comments) + .where(comment.post.id.eq(post.id)) + .transform(groupBy(post.id).as(post.name, set(comment.id), list(comment.text))); + + Group group = results.get(1); + Object[] array = group.toArray(); + assertEquals(toInt(1), array[0]); + assertEquals("Post 1", array[1]); + assertEquals(toSet(1), array[2]); + assertEquals(Collections.singletonList("Comment 1"), array[3]); + } + + @Test + public void transform_results() { + Map results = CollQueryFactory.from(post, posts).from(comment, comments) + .where(comment.post.id.eq(post.id)) + .transform(groupBy(post.id).as(QPost.create(post.id, post.name, set(qComment)))); + + Post post = results.get(1); + assertNotNull(post); + assertEquals(1, post.getId()); + assertEquals("Post 1", post.getName()); + assertEquals(1, post.getComments().size()); + } + + @Test + public void transform_as_bean() { + Map results = CollQueryFactory.from(post, posts).from(comment, comments) + .where(comment.post.id.eq(post.id)) + .transform(groupBy(post.id).as(Projections.bean(Post.class, post.id, post.name, set(qComment).as("comments")))); + + Post post = results.get(1); + assertNotNull(post); + assertEquals(1, post.getId()); + assertEquals("Post 1", post.getName()); + assertEquals(1, post.getComments().size()); + } + + + @Test + public void oneToOneToMany_projection() { + Map results = CollQueryFactory.from(user, users).from(post, posts).from(comment, comments) + .where(user.name.eq(post.user.name), post.id.eq(comment.post.id)) + .transform(groupBy(user.name).as(Projections.constructor(User.class, user.name, + QPost.create(post.id, post.name, set(qComment))))); + + assertEquals(2, results.size()); + + User user = results.get("Jane"); + Post post = user.getLatestPost(); + assertEquals(3, post.getId()); + assertEquals("Post 3", post.getName()); + assertEquals(3, post.getComments().size()); + } + + + @Test + public void oneToOneToMany_projection_as_bean() { + Map results = CollQueryFactory.from(user, users).from(post, posts).from(comment, comments) + .where(user.name.eq(post.user.name), post.id.eq(comment.post.id)) + .transform(groupBy(user.name).as(Projections.bean(User.class, user.name, + Projections.bean(Post.class, post.id, post.name, set(qComment).as("comments")).as("latestPost")))); + + assertEquals(2, results.size()); + + User user = results.get("Jane"); + Post post = user.getLatestPost(); + assertEquals(3, post.getId()); + assertEquals("Post 3", post.getName()); + assertEquals(3, post.getComments().size()); + } + + @Test + public void oneToOneToMany_projection_as_bean_and_constructor() { + Map results = CollQueryFactory.from(user, users).from(post, posts).from(comment, comments) + .where(user.name.eq(post.user.name), post.id.eq(comment.post.id)) + .transform(groupBy(user.name).as(Projections.bean(User.class, user.name, + QPost.create(post.id, post.name, set(qComment)).as("latestPost")))); + + assertEquals(2, results.size()); + + User user = results.get("Jane"); + Post post = user.getLatestPost(); + assertEquals(3, post.getId()); + assertEquals("Post 3", post.getName()); + assertEquals(3, post.getComments().size()); + } + + private Integer toInt(int i) { + return i; + } + + private Set toSet(T... s) { + return new HashSet(Arrays.asList(s)); + } + + +} diff --git a/querydsl-collections/src/test/java/com/querydsl/collections/InnerClassTest.java b/querydsl-collections/src/test/java/com/querydsl/collections/InnerClassTest.java new file mode 100644 index 0000000000..940313f5fa --- /dev/null +++ b/querydsl-collections/src/test/java/com/querydsl/collections/InnerClassTest.java @@ -0,0 +1,45 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.collections; + +import static com.querydsl.core.alias.Alias.$; +import static com.querydsl.core.alias.Alias.alias; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.util.Collections; + +import org.junit.Test; + +public class InnerClassTest { + + public static class Example { + + public String getId() { + return null; + } + } + + @Test + public void query() { + Example example = alias(Example.class); + assertFalse(CollQueryFactory. from($(example), Collections.singletonList(new Example())) + .where($(example.getId()).isNull()) + .fetch().isEmpty()); + assertTrue(CollQueryFactory. from($(example), Collections.singletonList(new Example())) + .where($(example.getId()).isNotNull()) + .fetch().isEmpty()); + } + +} diff --git a/querydsl-collections/src/test/java/com/mysema/query/collections/InnerJoinTest.java b/querydsl-collections/src/test/java/com/querydsl/collections/InnerJoinTest.java similarity index 85% rename from querydsl-collections/src/test/java/com/mysema/query/collections/InnerJoinTest.java rename to querydsl-collections/src/test/java/com/querydsl/collections/InnerJoinTest.java index f197d08b93..d47ff18cf0 100644 --- a/querydsl-collections/src/test/java/com/mysema/query/collections/InnerJoinTest.java +++ b/querydsl-collections/src/test/java/com/querydsl/collections/InnerJoinTest.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,10 +11,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.collections; +package com.querydsl.collections; -import static com.mysema.query.alias.Alias.$; -import static com.mysema.query.alias.Alias.alias; +import static com.querydsl.core.alias.Alias.$; +import static com.querydsl.core.alias.Alias.alias; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -25,7 +25,7 @@ import org.junit.Before; import org.junit.Test; -public class InnerJoinTest extends AbstractQueryTest{ +public class InnerJoinTest extends AbstractQueryTest { private QCat cat, kitten; @@ -50,36 +50,36 @@ public void setUp() { } @Test - public void List() { + public void list() { List rv = CollQueryFactory.from(cat, cats) .innerJoin(cat.kittens, kitten) .where(cat.name.eq(kitten.name)) .orderBy(cat.name.asc()) - .list(cat); + .fetch(); assertEquals("Bob", rv.get(0).getName()); assertEquals("Kate", rv.get(1).getName()); } - + @Test - public void Alias() { + public void alias_() { Cat cc = alias(Cat.class, "cat1"); Cat ck = alias(Cat.class, "cat2"); List rv = CollQueryFactory.from($(cc), cats) .innerJoin($(cc.getKittens()), $(ck)) .where($(cc.getName()).eq($(ck.getName()))) - .list($(cc)); + .fetch(); assertFalse(rv.isEmpty()); } @Test - public void Map() { + public void map() { List rv = CollQueryFactory.from(cat, cats) .innerJoin(cat.kittensByName, kitten) .where(cat.name.eq(kitten.name)) .orderBy(cat.name.asc()) - .list(cat); + .fetch(); assertEquals("Bob", rv.get(0).getName()); assertEquals("Kate", rv.get(1).getName()); } diff --git a/querydsl-collections/src/test/java/com/querydsl/collections/IterationTest.java b/querydsl-collections/src/test/java/com/querydsl/collections/IterationTest.java new file mode 100644 index 0000000000..a4f924eaa9 --- /dev/null +++ b/querydsl-collections/src/test/java/com/querydsl/collections/IterationTest.java @@ -0,0 +1,62 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.collections; + +import static com.querydsl.core.alias.Alias.$; +import static com.querydsl.core.alias.Alias.alias; +import static org.junit.Assert.assertEquals; + +import java.util.Arrays; +import java.util.List; + +import org.junit.Test; + +public class IterationTest { + + public static class Data { + + private String data = "data"; + + public String getData() { + return data; + } + + } + + private List allData = Arrays.asList(new Data(), new Data()); + + private Data lt = alias(Data.class,"Data"); + + private List expected = Arrays.asList("data","data"); + + @Test + public void test() { + assertEquals(expected, CollQueryFactory.from($(lt), allData).select($(lt.getData())).fetch()); + } + + @Test + public void test2() { + assertEquals(expected, CollQueryFactory. from($(lt), Arrays. asList(allData.toArray(new Data[0]))).select($(lt.getData())).fetch()); + } + + @Test + public void test3() { + assertEquals(expected, CollQueryFactory.from(lt, allData).select($(lt.getData())).fetch()); + } + + @Test + public void test4() { + assertEquals(expected, CollQueryFactory. from(lt, Arrays. asList(allData.toArray(new Data[0]))).select($(lt.getData())).fetch()); + } +} diff --git a/querydsl-collections/src/test/java/com/mysema/query/collections/JacocoTest.java b/querydsl-collections/src/test/java/com/querydsl/collections/JacocoTest.java similarity index 78% rename from querydsl-collections/src/test/java/com/mysema/query/collections/JacocoTest.java rename to querydsl-collections/src/test/java/com/querydsl/collections/JacocoTest.java index b0e4d9b471..00651842c3 100644 --- a/querydsl-collections/src/test/java/com/mysema/query/collections/JacocoTest.java +++ b/querydsl-collections/src/test/java/com/querydsl/collections/JacocoTest.java @@ -1,19 +1,20 @@ -package com.mysema.query.collections; +package com.querydsl.collections; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; import java.util.ArrayList; import java.util.List; import org.junit.Test; -import com.mysema.query.alias.Alias; -import com.mysema.query.types.path.EntityPathBase; +import com.querydsl.core.alias.Alias; +import com.querydsl.core.types.dsl.EntityPathBase; public class JacocoTest { - - public static class CloneableVO {} - + + public static class CloneableVO { } + public static class CloneableKlasse implements Cloneable { private CloneableVO value; private Integer otherValue; @@ -43,9 +44,9 @@ public Object clone() { } } } - + @Test - public void WithSimpleClass() { + public void withSimpleClass() { List vos = new ArrayList(); for (int i = 0; i < 5; i++) { CloneableKlasse vo = new CloneableKlasse(); @@ -54,12 +55,12 @@ public void WithSimpleClass() { } CloneableKlasse vo = Alias.alias(CloneableKlasse.class, "vo"); assertNotNull(vo); - CollQuery query = new CollQuery(); + CollQuery query = new CollQuery(); final EntityPathBase fromVo = Alias.$(vo); assertNotNull(fromVo); query.from(fromVo, vos); query.where(Alias.$(vo.getOtherValue()).eq(1)); - List result = query.list(Alias.$(vo)); + List result = query.select(Alias.$(vo)).fetch(); assertNotNull(result); assertEquals(1, result.size()); diff --git a/querydsl-collections/src/test/java/com/querydsl/collections/JodaTimeTemplatesTest.java b/querydsl-collections/src/test/java/com/querydsl/collections/JodaTimeTemplatesTest.java new file mode 100644 index 0000000000..ccfe4859bc --- /dev/null +++ b/querydsl-collections/src/test/java/com/querydsl/collections/JodaTimeTemplatesTest.java @@ -0,0 +1,46 @@ +package com.querydsl.collections; + +import java.util.Arrays; + +import org.joda.time.DateTime; +import org.joda.time.LocalDate; +import org.joda.time.LocalTime; +import org.junit.Test; + +import com.querydsl.core.types.dsl.DatePath; +import com.querydsl.core.types.dsl.DateTimePath; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.TimePath; + +public class JodaTimeTemplatesTest { + + private CollQuery query = new CollQuery(JodaTimeTemplates.DEFAULT); + + @Test + public void dateTime() { + DateTimePath entity = Expressions.dateTimePath(DateTime.class, "entity"); + query.from(entity, Arrays.asList(new DateTime(), new DateTime(0L))) + .select(entity.year(), entity.yearMonth(), entity.month(), entity.week(), + entity.dayOfMonth(), entity.dayOfWeek(), entity.dayOfYear(), + entity.hour(), entity.minute(), entity.second(), entity.milliSecond()) + .fetch(); + } + + @Test + public void localDate() { + DatePath entity = Expressions.datePath(LocalDate.class, "entity"); + query.from(entity, Arrays.asList(new LocalDate(), new LocalDate(0L))) + .select(entity.year(), entity.yearMonth(), entity.month(), entity.week(), + entity.dayOfMonth(), entity.dayOfWeek(), entity.dayOfYear()) + .fetch(); + } + + @Test + public void localTime() { + TimePath entity = Expressions.timePath(LocalTime.class, "entity"); + query.from(entity, Arrays.asList(new LocalTime(), new LocalTime(0L))) + .select(entity.hour(), entity.minute(), entity.second(), entity.milliSecond()) + .fetch(); + } + +} diff --git a/querydsl-collections/src/test/java/com/mysema/query/collections/LeftJoinTest.java b/querydsl-collections/src/test/java/com/querydsl/collections/LeftJoinTest.java similarity index 87% rename from querydsl-collections/src/test/java/com/mysema/query/collections/LeftJoinTest.java rename to querydsl-collections/src/test/java/com/querydsl/collections/LeftJoinTest.java index 7438207241..5d2b7ecde9 100644 --- a/querydsl-collections/src/test/java/com/mysema/query/collections/LeftJoinTest.java +++ b/querydsl-collections/src/test/java/com/querydsl/collections/LeftJoinTest.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,10 +11,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.collections; +package com.querydsl.collections; -import static com.mysema.query.alias.Alias.$; -import static com.mysema.query.alias.Alias.alias; +import static com.querydsl.core.alias.Alias.$; +import static com.querydsl.core.alias.Alias.alias; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -50,36 +50,36 @@ public void setUp() { } @Test - public void List() { + public void list() { List rv = CollQueryFactory.from(cat, cats) .leftJoin(cat.kittens, kitten) .where(kitten.isNotNull(), cat.name.eq(kitten.name)) .orderBy(cat.name.asc()) - .list(cat); - + .fetch(); + assertEquals(1, rv.size()); assertEquals("Bob", rv.get(0).getName()); } - + @Test - public void Alias() { + public void alias_() { Cat cc = alias(Cat.class, "cat1"); Cat ck = alias(Cat.class, "cat2"); List rv = CollQueryFactory.from($(cc), cats) .leftJoin($(cc.getKittens()), $(ck)) .where($(ck).isNotNull(), $(cc.getName()).eq($(ck.getName()))) - .list($(cc)); + .fetch(); assertFalse(rv.isEmpty()); } @Test - public void Map() { + public void map() { List rv = CollQueryFactory.from(cat, cats) .leftJoin(cat.kittensByName, kitten) .where(cat.name.eq(kitten.name)) .orderBy(cat.name.asc()) - .list(cat); + .fetch(); assertEquals("Bob", rv.get(0).getName()); assertEquals("Kate", rv.get(1).getName()); } diff --git a/querydsl-collections/src/test/java/com/mysema/query/collections/LoadTest.java b/querydsl-collections/src/test/java/com/querydsl/collections/LoadTest.java similarity index 79% rename from querydsl-collections/src/test/java/com/mysema/query/collections/LoadTest.java rename to querydsl-collections/src/test/java/com/querydsl/collections/LoadTest.java index 678e1fa083..5e0f63729d 100644 --- a/querydsl-collections/src/test/java/com/mysema/query/collections/LoadTest.java +++ b/querydsl-collections/src/test/java/com/querydsl/collections/LoadTest.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.collections; +package com.querydsl.collections; import static org.junit.Assert.assertEquals; @@ -21,10 +21,13 @@ import java.util.List; import org.junit.Test; +import org.junit.experimental.categories.Category; -import com.mysema.query.DefaultQueryMetadata; -import com.mysema.query.QueryMetadata; +import com.querydsl.core.DefaultQueryMetadata; +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.testutil.Performance; +@Category(Performance.class) public class LoadTest { private QCat cat = QCat.cat; @@ -34,13 +37,13 @@ public class LoadTest { private QueryMetadata metadata = new DefaultQueryMetadata(); @Test - public void Creation() { + public void creation() { System.out.println("Evaluator creation #1"); for (int i = 0; i < 5; i++) { long s = System.currentTimeMillis(); evaluatorFactory.create(metadata, Collections.singletonList(cat), cat.name.startsWith("Bob")); long e = System.currentTimeMillis(); - System.out.println(" " + (e-s)+"ms"); + System.out.println(" " + (e - s) + "ms"); } System.out.println(); @@ -49,7 +52,7 @@ public void Creation() { long s = System.currentTimeMillis(); evaluatorFactory.create(metadata, Collections.singletonList(cat), cat.name.startsWith("Bob" + i)); long e = System.currentTimeMillis(); - System.out.println(" " + (e-s)+"ms"); + System.out.println(" " + (e - s) + "ms"); } System.out.println(); } @@ -71,10 +74,10 @@ public void test() { System.out.println("Querydsl iteration"); for (int i = 0; i < 5; i++) { long s1 = System.currentTimeMillis(); - List bobs1 = CollQueryFactory.from(cat, data).where(cat.name.startsWith("Bob")).list(cat); + List bobs1 = CollQueryFactory.from(cat, data).where(cat.name.startsWith("Bob")).fetch(); assertEquals(1000, bobs1.size()); long e1 = System.currentTimeMillis(); - System.out.println(" " + (e1-s1)+"ms"); + System.out.println(" " + (e1 - s1) + "ms"); } System.out.println(); @@ -84,11 +87,13 @@ public void test() { long s2 = System.currentTimeMillis(); List bobs2 = new ArrayList(); for (Cat c : data) { - if (c.getName().startsWith("Bob")) bobs2.add(c); + if (c.getName().startsWith("Bob")) { + bobs2.add(c); + } } assertEquals(1000, bobs2.size()); long e2 = System.currentTimeMillis(); - System.out.println(" " + (e2-s2)+"ms"); + System.out.println(" " + (e2 - s2) + "ms"); } System.out.println(); } diff --git a/querydsl-collections/src/test/java/com/querydsl/collections/MappingProjectionTest.java b/querydsl-collections/src/test/java/com/querydsl/collections/MappingProjectionTest.java new file mode 100644 index 0000000000..f160ac3303 --- /dev/null +++ b/querydsl-collections/src/test/java/com/querydsl/collections/MappingProjectionTest.java @@ -0,0 +1,48 @@ +package com.querydsl.collections; + +import static org.junit.Assert.assertEquals; + +import java.util.List; + +import org.junit.Test; + +import com.querydsl.core.Tuple; +import com.querydsl.core.types.MappingProjection; + +@SuppressWarnings("serial") +public class MappingProjectionTest extends AbstractQueryTest { + + public class ResultPart { + + } + + public class ResultObject { + + } + + @Test + public void test() { + final MappingProjection key = new MappingProjection(ResultPart.class, + cat.name) { + + @Override + protected ResultPart map(Tuple row) { + return new ResultPart(); + } + + }; + + List list = query().from(cat, cats).select( + new MappingProjection(ResultObject.class, key) { + + @Override + protected ResultObject map(Tuple row) { + ResultPart consolidationKey = row.get(key); + return new ResultObject(); + } + }).fetch(); + + assertEquals(cats.size(), list.size()); + } + +} diff --git a/querydsl-collections/src/test/java/com/querydsl/collections/MathTest.java b/querydsl-collections/src/test/java/com/querydsl/collections/MathTest.java new file mode 100644 index 0000000000..c8eeabb825 --- /dev/null +++ b/querydsl-collections/src/test/java/com/querydsl/collections/MathTest.java @@ -0,0 +1,69 @@ +package com.querydsl.collections; + +import static org.junit.Assert.assertEquals; + +import java.util.Collections; + +import org.junit.Test; + +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.MathExpressions; +import com.querydsl.core.types.dsl.NumberPath; + +public class MathTest { + + private NumberPath num = Expressions.numberPath(Double.class, "num"); + + @Test + public void math() { + Expression expr = num; + + assertEquals(Math.acos(0.5), unique(MathExpressions.acos(expr)), 0.001); + assertEquals(Math.asin(0.5), unique(MathExpressions.asin(expr)), 0.001); + assertEquals(Math.atan(0.5), unique(MathExpressions.atan(expr)), 0.001); + assertEquals(Math.cos(0.5), unique(MathExpressions.cos(expr)), 0.001); + assertEquals(Math.cosh(0.5), unique(MathExpressions.cosh(expr)), 0.001); + assertEquals(cot(0.5), unique(MathExpressions.cot(expr)), 0.001); + assertEquals(coth(0.5), unique(MathExpressions.coth(expr)), 0.001); + assertEquals(degrees(0.5), unique(MathExpressions.degrees(expr)), 0.001); + assertEquals(Math.exp(0.5), unique(MathExpressions.exp(expr)), 0.001); + assertEquals(Math.log(0.5), unique(MathExpressions.ln(expr)), 0.001); + assertEquals(log(0.5, 10), unique(MathExpressions.log(expr, 10)), 0.001); + assertEquals(0.25, unique(MathExpressions.power(expr, 2)), 0.001); + assertEquals(radians(0.5), unique(MathExpressions.radians(expr)), 0.001); + assertEquals(Integer.valueOf(1), + unique(MathExpressions.sign(expr))); + assertEquals(Math.sin(0.5), unique(MathExpressions.sin(expr)), 0.001); + assertEquals(Math.sinh(0.5), unique(MathExpressions.sinh(expr)), 0.001); + assertEquals(Math.tan(0.5), unique(MathExpressions.tan(expr)), 0.001); + assertEquals(Math.tanh(0.5), unique(MathExpressions.tanh(expr)), 0.001); + + } + + private double cot(double x) { + return Math.cos(x) / Math.sin(x); + } + + private double coth(double x) { + return Math.cosh(x) / Math.sinh(x); + } + + private double degrees(double x) { + return x * 180.0 / Math.PI; + } + + private double radians(double x) { + return x * Math.PI / 180.0; + } + + private double log(double x, int y) { + return Math.log(x) / Math.log(y); + } + + private T unique(Expression expr) { + //return query().fetchOne(expr); + return CollQueryFactory. from(num, Collections.singletonList(0.5)).select(expr).fetchOne(); + } + +} diff --git a/querydsl-collections/src/test/java/com/querydsl/collections/MockTest.java b/querydsl-collections/src/test/java/com/querydsl/collections/MockTest.java new file mode 100644 index 0000000000..64fe6a8d0e --- /dev/null +++ b/querydsl-collections/src/test/java/com/querydsl/collections/MockTest.java @@ -0,0 +1,24 @@ +package com.querydsl.collections; + +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; +import java.util.List; + +import org.easymock.EasyMock; +import org.junit.Test; + +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.SimplePath; + +public class MockTest { + + @Test + public void test() { + List tests = Arrays.asList(new MockTest(), new MockTest(), new MockTest()); + SimplePath path = Expressions.path(MockTest.class, "obj"); + MockTest mock = EasyMock.createMock(MockTest.class); + assertTrue(CollQueryFactory.from(path, tests).where(path.eq(mock)).fetch().isEmpty()); + } + +} diff --git a/querydsl-collections/src/test/java/com/mysema/query/collections/MultiComparatorTest.java b/querydsl-collections/src/test/java/com/querydsl/collections/MultiComparatorTest.java similarity index 81% rename from querydsl-collections/src/test/java/com/mysema/query/collections/MultiComparatorTest.java rename to querydsl-collections/src/test/java/com/querydsl/collections/MultiComparatorTest.java index 577c680a36..0714878981 100644 --- a/querydsl-collections/src/test/java/com/mysema/query/collections/MultiComparatorTest.java +++ b/querydsl-collections/src/test/java/com/querydsl/collections/MultiComparatorTest.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,17 +11,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.collections; +package com.querydsl.collections; -import static org.junit.Assert.*; +import static org.junit.Assert.assertTrue; import org.junit.Test; -import com.mysema.codegen.Evaluator; -import com.mysema.query.collections.MultiComparator; +import com.querydsl.codegen.utils.Evaluator; public class MultiComparatorTest { - + private final Evaluator evaluator = new Evaluator() { @Override public Object[] evaluate(Object... args) { @@ -30,12 +29,13 @@ public Object[] evaluate(Object... args) { @Override public Class getType() { return Object[].class; - } + } }; - + @Test public void test() { - MultiComparator comparator = new MultiComparator(evaluator, new boolean[]{true, true}); + MultiComparator comparator = new MultiComparator(evaluator, new boolean[]{true, true}, + new boolean[]{true, true}); assertTrue(comparator.compare(new Object[]{"a", "b"}, new Object[]{"a","c"}) < 0); assertTrue(comparator.compare(new Object[]{"b", "a"}, new Object[]{"a","b"}) > 0); assertTrue(comparator.compare(new Object[]{"b", "b"}, new Object[]{"b","b"}) == 0); diff --git a/querydsl-collections/src/test/java/com/querydsl/collections/NullSafetyTest.java b/querydsl-collections/src/test/java/com/querydsl/collections/NullSafetyTest.java new file mode 100644 index 0000000000..aaaf30dd7c --- /dev/null +++ b/querydsl-collections/src/test/java/com/querydsl/collections/NullSafetyTest.java @@ -0,0 +1,32 @@ +package com.querydsl.collections; + +import static org.junit.Assert.assertEquals; + +import java.util.Arrays; + +import org.junit.Test; + +public class NullSafetyTest extends AbstractQueryTest { + + @Test + public void filters() { + QCat cat = QCat.cat; + CollQuery query = CollQueryFactory. from(cat, Arrays. asList(new Cat(), new Cat("Bob"))); + assertEquals(1L, query.where(cat.name.eq("Bob")).fetchCount()); + } + + @Test + public void joins() { + Cat kitten1 = new Cat(); + Cat kitten2 = new Cat("Bob"); + Cat cat1 = new Cat(); + cat1.setKittens(Arrays.asList(kitten1, kitten2)); + Cat cat2 = new Cat(); + + QCat cat = QCat.cat; + QCat kitten = new QCat("kitten"); + CollQuery query = CollQueryFactory. from(cat, Arrays. asList(cat1, cat2)).innerJoin(cat.kittens, kitten); + assertEquals(1, query.where(kitten.name.eq("Bob")).fetchCount()); + } + +} diff --git a/querydsl-collections/src/test/java/com/querydsl/collections/NumberTest.java b/querydsl-collections/src/test/java/com/querydsl/collections/NumberTest.java new file mode 100644 index 0000000000..1c701f79a4 --- /dev/null +++ b/querydsl-collections/src/test/java/com/querydsl/collections/NumberTest.java @@ -0,0 +1,22 @@ +package com.querydsl.collections; + +import static org.junit.Assert.assertEquals; + +import java.math.BigDecimal; +import java.util.Arrays; + +import org.junit.Test; + +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberPath; + +public class NumberTest { + + @Test + public void sum() throws Exception { + NumberPath num = Expressions.numberPath(BigDecimal.class, "num"); + CollQuery query = CollQueryFactory. from(num, Arrays. asList(new BigDecimal("1.6"), new BigDecimal("1.3"))); + + assertEquals(new BigDecimal("2.9"), query. select(num.sum()).fetchOne()); + } +} diff --git a/querydsl-collections/src/test/java/com/querydsl/collections/OrderTest.java b/querydsl-collections/src/test/java/com/querydsl/collections/OrderTest.java new file mode 100644 index 0000000000..f515888e11 --- /dev/null +++ b/querydsl-collections/src/test/java/com/querydsl/collections/OrderTest.java @@ -0,0 +1,84 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.collections; + +import static org.junit.Assert.*; + +import java.util.Arrays; +import java.util.List; + +import org.junit.Test; + +public class OrderTest extends AbstractQueryTest { + + @Test + public void test() { + query().from(cat, cats).orderBy(cat.name.asc()).select(cat.name).fetch(); + assertArrayEquals(new Object[] {"Alex", "Bob", "Francis", "Kitty"}, last.res.toArray()); + + query().from(cat, cats).orderBy(cat.name.desc()).select(cat.name).fetch(); + assertArrayEquals(new Object[] {"Kitty", "Francis", "Bob", "Alex"}, last.res.toArray()); + + query().from(cat, cats).orderBy(cat.name.substring(1).asc()).select(cat.name).fetch(); + assertArrayEquals(new Object[] {"Kitty", "Alex", "Bob", "Francis"}, last.res.toArray()); + + query().from(cat, cats).from(otherCat, cats) + .orderBy(cat.name.asc(), otherCat.name.desc()) + .select(cat.name, otherCat.name).fetch(); + + // TODO : more tests + } + + @Test + public void test2() { + List orderedNames = Arrays.asList("Alex","Bob","Francis","Kitty"); + assertEquals(orderedNames, query().from(cat,cats).orderBy(cat.name.asc()).select(cat.name).fetch()); + assertEquals(orderedNames, query().from(cat,cats).orderBy(cat.name.asc()).distinct().select(cat.name).fetch()); + } + + @Test + public void with_count() { + CollQuery q = new CollQuery(); + q.from(cat, cats); + long size = q.distinct().fetchCount(); + assertTrue(size > 0); + q.offset(0).limit(10); + q.orderBy(cat.name.asc()); + assertEquals(Arrays.asList("Alex","Bob","Francis","Kitty"), q.distinct().select(cat.name).fetch()); + } + + @Test + public void with_null() { + Cat unknown = new Cat(); + Cat bob = new Cat("Bob"); + Cat alex = new Cat("Alex"); + List cats = Arrays.asList(alex, unknown, bob); + assertEquals(Arrays.asList(unknown, alex, bob), + query().from(cat, cats).orderBy(cat.name.asc()).select(cat).fetch()); + assertEquals(Arrays.asList(unknown, bob, alex), + query().from(cat, cats).orderBy(cat.name.desc()).select(cat).fetch()); + } + + @Test + public void with_nulls_last() { + Cat unknown = new Cat(); + Cat bob = new Cat("Bob"); + Cat alex = new Cat("Alex"); + List cats = Arrays.asList(alex, unknown, bob); + assertEquals(Arrays.asList(bob, alex, unknown), + query().from(this.cat, cats).orderBy(this.cat.name.desc().nullsLast()).select(this.cat).fetch()); + assertEquals(Arrays.asList(alex, bob, unknown), + query().from(this.cat, cats).orderBy(this.cat.name.asc().nullsLast()).select(this.cat).fetch()); + } +} diff --git a/querydsl-collections/src/test/java/com/querydsl/collections/PagingTest.java b/querydsl-collections/src/test/java/com/querydsl/collections/PagingTest.java new file mode 100644 index 0000000000..aaa7754890 --- /dev/null +++ b/querydsl-collections/src/test/java/com/querydsl/collections/PagingTest.java @@ -0,0 +1,70 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.collections; + +import static org.junit.Assert.assertEquals; + +import java.util.Arrays; +import java.util.List; + +import org.junit.Test; + +import com.mysema.commons.lang.IteratorAdapter; +import com.querydsl.core.QueryModifiers; +import com.querydsl.core.QueryResults; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberPath; + +public class PagingTest extends AbstractQueryTest { + + private List ints = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9); + + private NumberPath var = Expressions.numberPath(Integer.class, "var"); + + @Test + public void test() { + assertResultSize(9, 9, QueryModifiers.EMPTY); + assertResultSize(9, 2, new QueryModifiers(2L, null)); + assertResultSize(9, 2, new QueryModifiers(2L, 0L)); + assertResultSize(9, 2, new QueryModifiers(2L, 3L)); + assertResultSize(9, 9, new QueryModifiers(20L, null)); + assertResultSize(9, 9, new QueryModifiers(20L, 0L)); + assertResultSize(9, 5, new QueryModifiers(20L, 4L)); + assertResultSize(9, 0, new QueryModifiers(10L, 9L)); + } + + private void assertResultSize(int total, int size, QueryModifiers modifiers) { + // via fetch + assertEquals(size, createQuery(modifiers).select(var).fetch().size()); + + // via results + QueryResults results = createQuery(modifiers).select(var).fetchResults(); + assertEquals(total, results.getTotal()); + assertEquals(size, results.getResults().size()); + + // via fetchCount (ignore limit and offset) + assertEquals(total, createQuery(modifiers).fetchCount()); + + // via iterator + assertEquals(size, IteratorAdapter.asList(createQuery(modifiers).select(var).iterate()).size()); + } + + private CollQuery createQuery(QueryModifiers modifiers) { + CollQuery query = new CollQuery().from(var, ints); + if (modifiers != null) { + query.restrict(modifiers); + } + return query; + } +} diff --git a/querydsl-collections/src/test/java/com/mysema/query/collections/PathComparatorTest.java b/querydsl-collections/src/test/java/com/querydsl/collections/PathComparatorTest.java similarity index 75% rename from querydsl-collections/src/test/java/com/mysema/query/collections/PathComparatorTest.java rename to querydsl-collections/src/test/java/com/querydsl/collections/PathComparatorTest.java index db7ffbb917..c7f3f24202 100644 --- a/querydsl-collections/src/test/java/com/mysema/query/collections/PathComparatorTest.java +++ b/querydsl-collections/src/test/java/com/querydsl/collections/PathComparatorTest.java @@ -1,6 +1,6 @@ -package com.mysema.query.collections; +package com.querydsl.collections; -import static com.mysema.query.collections.PathComparator.pathComparator; +import static com.querydsl.collections.PathComparator.pathComparator; import static org.junit.Assert.assertEquals; import java.util.Comparator; @@ -11,50 +11,50 @@ public class PathComparatorTest { private Comparator comparator; - + @Before public void setUpComparator() { comparator = pathComparator(QCar.car.horsePower); } @Test - public void EqualReference() { + public void equalReference() { Car car = new Car(); assertEquals(0, comparator.compare(car, car)); } - + @Test - public void SemanticallyEqual() { + public void semanticallyEqual() { Car car = new Car(); car.setModel("car"); car.setHorsePower(50); - + Car similarCar = new Car(); similarCar.setModel("car"); similarCar.setHorsePower(50); - + assertEquals(0, comparator.compare(car, similarCar)); } - + @Test - public void LeftIsNull() { + public void leftIsNull() { assertEquals(-1, comparator.compare(null, new Car())); } - + @Test - public void RightIsNull() { + public void rightIsNull() { assertEquals(1, comparator.compare(new Car(), null)); } - + @Test - public void CompareOnValue() { + public void compareOnValue() { Car car = new Car(); car.setHorsePower(50); - + Car betterCar = new Car(); betterCar.setHorsePower(150); - + assertEquals(-1, comparator.compare(car, betterCar)); } - + } diff --git a/querydsl-collections/src/test/java/com/mysema/query/collections/PathMatcherTest.java b/querydsl-collections/src/test/java/com/querydsl/collections/PathMatcherTest.java similarity index 82% rename from querydsl-collections/src/test/java/com/mysema/query/collections/PathMatcherTest.java rename to querydsl-collections/src/test/java/com/querydsl/collections/PathMatcherTest.java index b1849d6278..a7c172f950 100644 --- a/querydsl-collections/src/test/java/com/mysema/query/collections/PathMatcherTest.java +++ b/querydsl-collections/src/test/java/com/querydsl/collections/PathMatcherTest.java @@ -1,7 +1,7 @@ -package com.mysema.query.collections; +package com.querydsl.collections; +import static com.querydsl.collections.PathMatcher.hasValue; import static org.hamcrest.core.IsEqual.equalTo; -import static com.mysema.query.collections.PathMatcher.hasValue; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThat; @@ -10,33 +10,33 @@ import org.junit.Test; public class PathMatcherTest { - + private static final QCar $ = QCar.car; @Test - public void Match() { + public void match() { Car car = new Car(); car.setHorsePower(123); - + assertThat(car, hasValue($.horsePower)); assertThat(car, hasValue($.horsePower, equalTo(123))); } - + @Test - public void Mismatch() { + public void mismatch() { Car car = new Car(); car.setHorsePower(123); - + Description mismatchDescription = new StringDescription(); hasValue($.horsePower, equalTo(321)).describeMismatch(car, mismatchDescription); assertEquals("value \"car.horsePower\" was <123>", mismatchDescription.toString()); } - + @Test - public void Describe() { + public void describe() { Description description = new StringDescription(); hasValue($.horsePower, equalTo(321)).describeTo(description); assertEquals("valueOf(\"car.horsePower\", <321>)", description.toString()); } - + } diff --git a/querydsl-collections/src/test/java/com/mysema/query/collections/PatternsTest.java b/querydsl-collections/src/test/java/com/querydsl/collections/PatternsTest.java similarity index 87% rename from querydsl-collections/src/test/java/com/mysema/query/collections/PatternsTest.java rename to querydsl-collections/src/test/java/com/querydsl/collections/PatternsTest.java index 45a1428998..9269f0fe21 100644 --- a/querydsl-collections/src/test/java/com/mysema/query/collections/PatternsTest.java +++ b/querydsl-collections/src/test/java/com/querydsl/collections/PatternsTest.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.collections; +package com.querydsl.collections; import static org.junit.Assert.assertTrue; @@ -22,7 +22,7 @@ public class PatternsTest { @Test - public void Matches() { + public void matches() { assertTrue(Pattern.matches("Bob","Bob")); assertTrue(Pattern.matches("^Bob$","Bob")); assertTrue(Pattern.matches("^Bo.*","Bob")); diff --git a/querydsl-collections/src/test/java/com/querydsl/collections/Person.java b/querydsl-collections/src/test/java/com/querydsl/collections/Person.java new file mode 100644 index 0000000000..9bf494b9a1 --- /dev/null +++ b/querydsl-collections/src/test/java/com/querydsl/collections/Person.java @@ -0,0 +1,13 @@ +package com.querydsl.collections; + +public class Person { + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/querydsl-collections/src/test/java/com/querydsl/collections/Post.java b/querydsl-collections/src/test/java/com/querydsl/collections/Post.java new file mode 100644 index 0000000000..a07ee2e8e6 --- /dev/null +++ b/querydsl-collections/src/test/java/com/querydsl/collections/Post.java @@ -0,0 +1,82 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.collections; + +import java.util.Set; + +import com.querydsl.core.annotations.QueryEntity; +import com.querydsl.core.annotations.QueryProjection; + +@QueryEntity +public class Post { + + private int id; + + private String name; + + private User user; + + private Set comments; + + public Post() { } + + @QueryProjection + public Post(int id, String name, User user) { + this.id = id; + this.name = name; + this.user = user; + } + + @QueryProjection + public Post(int id, String name, Set comments) { + this.id = id; + this.name = name; + this.comments = comments; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public User getUser() { + return user; + } + + public void setUser(User user) { + this.user = user; + } + + public Set getComments() { + return comments; + } + + public void setComments(Set comments) { + this.comments = comments; + } + + + +} \ No newline at end of file diff --git a/querydsl-collections/src/test/java/com/querydsl/collections/Projection.java b/querydsl-collections/src/test/java/com/querydsl/collections/Projection.java new file mode 100644 index 0000000000..c5633fd3a1 --- /dev/null +++ b/querydsl-collections/src/test/java/com/querydsl/collections/Projection.java @@ -0,0 +1,8 @@ +package com.querydsl.collections; + +public class Projection { + + public Projection(String str, Cat cat) { + } + +} \ No newline at end of file diff --git a/querydsl-collections/src/test/java/com/querydsl/collections/PropertiesTest.java b/querydsl-collections/src/test/java/com/querydsl/collections/PropertiesTest.java new file mode 100644 index 0000000000..3e6e41ad03 --- /dev/null +++ b/querydsl-collections/src/test/java/com/querydsl/collections/PropertiesTest.java @@ -0,0 +1,28 @@ +package com.querydsl.collections; + +import static org.junit.Assert.assertEquals; + +import java.util.Collections; +import java.util.List; + +import org.junit.Test; + +public class PropertiesTest { + + @Test + public void hidden() { + QStateHistory history = QStateHistory.stateHistory; + List histories = Collections.singletonList(new StateHistory()); + assertEquals(1, CollQueryFactory.from(history, histories) + .where(history.changedAt.isNull()).fetch().size()); + } + + @Test + public void hidden2() { + QStateHistoryOwner historyOwner = QStateHistoryOwner.stateHistoryOwner; + List historyOwners = Collections.singletonList(new StateHistoryOwner()); + assertEquals(1, CollQueryFactory.from(historyOwner, historyOwners) + .where(historyOwner.stateHistory.isNull()).fetch().size()); + } + +} diff --git a/querydsl-collections/src/test/java/com/querydsl/collections/QCar.java b/querydsl-collections/src/test/java/com/querydsl/collections/QCar.java new file mode 100644 index 0000000000..4f10df5f9f --- /dev/null +++ b/querydsl-collections/src/test/java/com/querydsl/collections/QCar.java @@ -0,0 +1,26 @@ +package com.querydsl.collections; + +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.BeanPath; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.StringPath; + +public class QCar extends BeanPath { + + public final StringPath model = createString("model"); + + public final NumberPath horsePower = createNumber("horsePower", Integer.class); + + public final QPerson owner = new QPerson(new BeanPath(Person.class, this, "owner")); + + public static QCar car = new QCar(new BeanPath(Car.class, "car")); + + public QCar(BeanPath entity) { + super(entity.getType(), entity.getMetadata()); + } + + public QCar(PathMetadata metadata) { + super(Car.class, metadata); + } + +} diff --git a/querydsl-collections/src/test/java/com/querydsl/collections/QPerson.java b/querydsl-collections/src/test/java/com/querydsl/collections/QPerson.java new file mode 100644 index 0000000000..767d56ad66 --- /dev/null +++ b/querydsl-collections/src/test/java/com/querydsl/collections/QPerson.java @@ -0,0 +1,21 @@ +package com.querydsl.collections; + +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.BeanPath; +import com.querydsl.core.types.dsl.StringPath; + +public class QPerson extends BeanPath { + + public final StringPath name = createString("name"); + + public static QPerson car = new QPerson(new BeanPath(Person.class, "person")); + + public QPerson(BeanPath entity) { + super(entity.getType(), entity.getMetadata()); + } + + public QPerson(PathMetadata metadata) { + super(Person.class, metadata); + } + +} diff --git a/querydsl-collections/src/test/java/com/querydsl/collections/QueryMetadataTest.java b/querydsl-collections/src/test/java/com/querydsl/collections/QueryMetadataTest.java new file mode 100644 index 0000000000..c5d7a172dd --- /dev/null +++ b/querydsl-collections/src/test/java/com/querydsl/collections/QueryMetadataTest.java @@ -0,0 +1,39 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.collections; + +import static org.junit.Assert.assertEquals; + +import java.util.Collections; + +import org.junit.Test; + +import com.querydsl.core.DefaultQueryMetadata; +import com.querydsl.core.JoinType; +import com.querydsl.core.QueryMetadata; + +public class QueryMetadataTest extends AbstractQueryTest { + + @Test + public void reusage() { + QueryMetadata metadata = new DefaultQueryMetadata(); + metadata.addJoin(JoinType.DEFAULT, cat); + metadata.addWhere(cat.name.startsWith("A")); + + CollQuery query = new CollQuery(metadata); + query.bind(cat, cats); + assertEquals(Collections.singletonList(c3), query.select(cat).fetch()); + } + +} diff --git a/querydsl-collections/src/test/java/com/querydsl/collections/QueryMutabilityTest.java b/querydsl-collections/src/test/java/com/querydsl/collections/QueryMutabilityTest.java new file mode 100644 index 0000000000..e9bfe8567a --- /dev/null +++ b/querydsl-collections/src/test/java/com/querydsl/collections/QueryMutabilityTest.java @@ -0,0 +1,37 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.collections; + +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.util.Collections; + +import org.junit.Test; + +import com.querydsl.core.QueryMutability; + +public class QueryMutabilityTest { + + @Test + public void test() throws SecurityException, IllegalArgumentException, + NoSuchMethodException, IllegalAccessException, + InvocationTargetException, IOException { + QCat cat = QCat.cat; + CollQuery query = new CollQuery(); + query.from(cat, Collections. emptyList()); + new QueryMutability(query).test(cat.id, cat.name); + + } + +} diff --git a/querydsl-collections/src/test/java/com/querydsl/collections/QueryPerformanceTest.java b/querydsl-collections/src/test/java/com/querydsl/collections/QueryPerformanceTest.java new file mode 100644 index 0000000000..a2dc102f10 --- /dev/null +++ b/querydsl-collections/src/test/java/com/querydsl/collections/QueryPerformanceTest.java @@ -0,0 +1,67 @@ +package com.querydsl.collections; + +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ThreadLocalRandom; +import java.util.concurrent.TimeUnit; + +import org.junit.BeforeClass; +import org.junit.Ignore; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +import com.querydsl.core.testutil.Performance; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; +import org.openjdk.jmh.runner.options.TimeValue; + +@Ignore +@Category(Performance.class) +public class QueryPerformanceTest { + + private static final int size = 1000; + + private static List cats = new ArrayList(size); + + @BeforeClass + public static void setUpClass() throws SQLException, ClassNotFoundException { + for (int i = 0; i < size; i++) { + cats.add(new Cat(String.valueOf(i), i)); + } + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.MICROSECONDS) + public void benchmark1() { + // 15857 + QCat cat = QCat.cat; + CollQueryFactory.from(cat, cats).where(cat.id.eq(ThreadLocalRandom.current().nextInt(100) % size)).select(cat).fetch(); + } + + @Test + public void launchBenchmark() throws Exception { + Options opt = new OptionsBuilder() + .include(this.getClass().getName() + ".*") + .mode(Mode.AverageTime) + .timeUnit(TimeUnit.MICROSECONDS) + .warmupTime(TimeValue.seconds(1)) + .warmupIterations(3) + .measurementTime(TimeValue.seconds(1)) + .measurementIterations(3) + .threads(2) + .forks(1) + .shouldFailOnError(true) + .shouldDoGC(true) + .build(); + + new Runner(opt).run(); + } + +} diff --git a/querydsl-collections/src/test/java/com/querydsl/collections/SerializationTest.java b/querydsl-collections/src/test/java/com/querydsl/collections/SerializationTest.java new file mode 100644 index 0000000000..74c3469ff4 --- /dev/null +++ b/querydsl-collections/src/test/java/com/querydsl/collections/SerializationTest.java @@ -0,0 +1,162 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.collections; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Ignore; +import org.junit.Test; + +import com.querydsl.core.Tuple; +import com.querydsl.core.types.Projections; +import com.querydsl.core.types.QTuple; + +public class SerializationTest extends AbstractQueryTest { + + // TODO : order + + // TODO : subqueries + + private QTuple tuple = Projections.tuple(cat, otherCat); + + @Test + public void oneSource_list() { + query().from(cat, cats).select(cat).fetch(); + } + + public List oneSource_list(List cats) { + return cats; + } + + @Test + public void twoSources_list() { + query().from(cat,cats).from(otherCat, cats).select(cat).fetch(); + } + + public List twoSources_list(List cats, List otherCats) { + return cats; + } + + @Test + public void oneSource_filteredList() { + query().from(cat, cats).where(cat.name.eq("Kitty")).select(cat).fetch(); + } + + public List oneSource_filteredList(List cats) { + List rv = new ArrayList(); + for (Cat cat : cats) { // from + if (cat.getName().equals("Kitty")) { // where + rv.add(cat); // list + } + } + return rv; + } + + @Test + public void oneSource_projectedList() { + query().from(cat, cats).select(cat.name).fetch(); + } + + public List oneSource_projectedList(List cats) { + List rv = new ArrayList(); + for (Cat cat : cats) { // from + rv.add(cat.getName()); // list + } + return rv; + } + + @Test + public void oneSource_filtered_projectedList() { + query().from(cat, cats).where(cat.name.eq("Kitty")).select(cat.name).fetch(); + } + + public List oneSource_filtered_projectedList(List cats) { + List rv = new ArrayList(); + for (Cat cat : cats) { // from + if (cat.getName().equals("Kitty")) { // where + rv.add(cat.getName()); // list + } + } + return rv; + } + + @Test + public void oneSource_filtered_projectedUnique() { + query().from(cat, cats).where(cat.name.eq("Kitty")).select(cat.name).fetchOne(); + } + + public String oneSource_filtered_projectedUnique(List cats) { + for (Cat cat : cats) { // from + if (cat.getName().equals("Kitty")) { // where + return cat.getName(); // unique + } + } + throw new IllegalArgumentException(); + } + + @Test + @Ignore + public void join_list() { + query().from(cat, cats) + .innerJoin(cat.kittens, kitten).where(kitten.name.eq("Kitty")) + .select(cat).fetch(); + } + + public List join_list(List cats) { + List rv = new ArrayList(); + for (Cat cat : cats) { // from + for (Cat kitten : cat.getKittens()) { // inner join + if (kitten.getName().equals("Kitty")) { // where + rv.add(cat); // list + } + } + } + return rv; + } + + public List pairs(List cats, List otherCats) { + query().from(cat, cats) + .from(otherCat, otherCats) + .where(cat.name.eq(otherCat.name)) + .select(cat, otherCat).fetch(); + + List rv = new ArrayList(); + for (Cat cat : cats) { // from + for (Cat otherCat : otherCats) { // from + if (cat.getName().equals(otherCat.getName())) { // where + rv.add(new Object[]{cat,otherCat}); // list + } + } + } + return rv; + } + + public List pairsAsTuple(List cats, List otherCats) { + query().from(cat, cats).from(otherCat, cats) + .where(cat.name.eq(otherCat.name)) + .select(Projections.tuple(cat, otherCat)).fetch(); + + List rv = new ArrayList(); + for (Cat cat : cats) { // from + for (Cat otherCat : otherCats) { // from + if (cat.getName().equals(otherCat.getName())) { // where + rv.add(tuple.newInstance(cat, otherCat)); // list + } + } + } + return rv; + } + +} diff --git a/querydsl-collections/src/test/java/com/querydsl/collections/StateHistory.java b/querydsl-collections/src/test/java/com/querydsl/collections/StateHistory.java new file mode 100644 index 0000000000..7bb5eaf131 --- /dev/null +++ b/querydsl-collections/src/test/java/com/querydsl/collections/StateHistory.java @@ -0,0 +1,16 @@ +package com.querydsl.collections; + +import java.util.Date; + +import com.querydsl.core.annotations.QueryEntity; + +@QueryEntity +public class StateHistory { + + private Date changedAt; + + protected final Date getChangedAtTime() { + return changedAt; + } + +} \ No newline at end of file diff --git a/querydsl-collections/src/test/java/com/querydsl/collections/StateHistoryOwner.java b/querydsl-collections/src/test/java/com/querydsl/collections/StateHistoryOwner.java new file mode 100644 index 0000000000..18ede574d3 --- /dev/null +++ b/querydsl-collections/src/test/java/com/querydsl/collections/StateHistoryOwner.java @@ -0,0 +1,14 @@ +package com.querydsl.collections; + +import com.querydsl.core.annotations.QueryEntity; + +@QueryEntity +public class StateHistoryOwner { + + private StateHistory stateHistory; + + protected final StateHistory getStateHistory() { + return stateHistory; + } + +} diff --git a/querydsl-collections/src/test/java/com/querydsl/collections/StringHandlingTest.java b/querydsl-collections/src/test/java/com/querydsl/collections/StringHandlingTest.java new file mode 100644 index 0000000000..3ed08e2198 --- /dev/null +++ b/querydsl-collections/src/test/java/com/querydsl/collections/StringHandlingTest.java @@ -0,0 +1,64 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.collections; + +import static org.junit.Assert.assertEquals; + +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; + +import org.junit.Test; + +import com.querydsl.core.Tuple; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.StringPath; + +public class StringHandlingTest extends AbstractQueryTest { + + private List data1 = Arrays.asList("petER", "THomas", "joHAN"); + + private List data2 = Arrays.asList("PETer", "thOMAS", "JOhan"); + + private List data = Arrays.asList("abc", "aBC", "def"); + + private final StringPath a = Expressions.stringPath("a"); + + private final StringPath b = Expressions.stringPath("b"); + + @Test + public void equalsIgnoreCase() { + Iterator res = Arrays.asList("petER - PETer", + "THomas - thOMAS", "joHAN - JOhan").iterator(); + for (Tuple arr : query() + .from(a, data1) + .from(b, data2) + .where(a.equalsIgnoreCase(b)).select(a, b).fetch()) { + assertEquals(res.next(), arr.get(a) + " - " + arr.get(b)); + } + } + + @Test + public void startsWithIgnoreCase() { + assertEquals(2, CollQueryFactory.from(a, data).where(a.startsWithIgnoreCase("AB")).fetchCount()); + assertEquals(2, CollQueryFactory.from(a, data).where(a.startsWithIgnoreCase("ab")).fetchCount()); + } + + @Test + public void endsWithIgnoreCase() { + assertEquals(2, CollQueryFactory.from(a, data).where(a.endsWithIgnoreCase("BC")).fetchCount()); + assertEquals(2, CollQueryFactory.from(a, data).where(a.endsWithIgnoreCase("bc")).fetchCount()); + } + +} diff --git a/querydsl-collections/src/test/java/com/querydsl/collections/TemplatesTest.java b/querydsl-collections/src/test/java/com/querydsl/collections/TemplatesTest.java new file mode 100644 index 0000000000..3301c50b4c --- /dev/null +++ b/querydsl-collections/src/test/java/com/querydsl/collections/TemplatesTest.java @@ -0,0 +1,22 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team). + * + * 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. + */ +package com.querydsl.collections; + +import com.querydsl.core.TemplatesTestBase; + +public class TemplatesTest extends TemplatesTestBase { + +} diff --git a/querydsl-collections/src/test/java/com/querydsl/collections/TypeCastTest.java b/querydsl-collections/src/test/java/com/querydsl/collections/TypeCastTest.java new file mode 100644 index 0000000000..65921a7562 --- /dev/null +++ b/querydsl-collections/src/test/java/com/querydsl/collections/TypeCastTest.java @@ -0,0 +1,33 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.collections; + +import java.util.Collections; + +import org.junit.Ignore; +import org.junit.Test; + +import com.querydsl.core.types.dsl.PathInits; + +public class TypeCastTest { + + @Test(expected = IllegalStateException.class) + @Ignore + public void cast() { + QAnimal animal = QAnimal.animal; + QCat cat = new QCat(animal.getMetadata(), new PathInits("*")); + CollQueryFactory.from(animal, Collections. emptyList()).from(cat, Collections. emptyList()); + } + +} diff --git a/querydsl-collections/src/test/java/com/querydsl/collections/UniqueResultContractTest.java b/querydsl-collections/src/test/java/com/querydsl/collections/UniqueResultContractTest.java new file mode 100644 index 0000000000..b38d77af3d --- /dev/null +++ b/querydsl-collections/src/test/java/com/querydsl/collections/UniqueResultContractTest.java @@ -0,0 +1,33 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.collections; + +import org.junit.Test; + +import com.querydsl.core.NonUniqueResultException; +import com.querydsl.core.types.Expression; + +public class UniqueResultContractTest extends AbstractQueryTest { + + @Test(expected = NonUniqueResultException.class) + public void unique_result_throws_exception_on_multiple_results() { + CollQueryFactory.from(cat, cats).where(cat.name.isNotNull()).fetchOne(); + } + + @Test + public void uniqueResult_with_array() { + CollQueryFactory.from(cat, cats).where(cat.name.isNotNull()).limit(1).select(new Expression[]{cat}).fetchOne(); + } + +} diff --git a/querydsl-collections/src/test/java/com/querydsl/collections/User.java b/querydsl-collections/src/test/java/com/querydsl/collections/User.java new file mode 100644 index 0000000000..7ce184bc28 --- /dev/null +++ b/querydsl-collections/src/test/java/com/querydsl/collections/User.java @@ -0,0 +1,58 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.collections; + +import com.querydsl.core.annotations.QueryEntity; +import com.querydsl.core.annotations.QueryProjection; + + +@QueryEntity +public class User { + + private String name; + + private Post latestPost; + + public User() { } + + @QueryProjection + public User(String name) { + this.name = name; + } + + @QueryProjection + public User(String name, Post latestPost) { + this.name = name; + this.latestPost = latestPost; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Post getLatestPost() { + return latestPost; + } + + public void setLatestPost(Post latestPost) { + this.latestPost = latestPost; + } + + + +} \ No newline at end of file diff --git a/querydsl-collections/template.mf b/querydsl-collections/template.mf deleted file mode 100644 index 1200daf67b..0000000000 --- a/querydsl-collections/template.mf +++ /dev/null @@ -1,14 +0,0 @@ -Bundle-SymbolicName: com.mysema.querydsl.collections -Bundle-Name: Querydsl Collections -Bundle-Vendor: Mysema -Bundle-ManifestVersion: 2 -Import-Template: - com.mysema.codegen.*;version="${codegen.version}", - com.mysema.commons.lang.*;version="${mysema.lang.version}", - com.mysema.query.*;version="${project.version}", - com.mysema.util.*;version="${project.version}", - javax.annotation.*;version="0", - javax.tools.*;version="1";resolution:=optional, - org.eclipse.jdt.*;version="3.7.2", - com.google.common.*;version="${guava.version}", - org.hamcrest.*;version="1.3";resolution:=optional diff --git a/querydsl-core/etc/readme.txt b/querydsl-core/etc/readme.txt deleted file mode 100644 index 2c4776fe1c..0000000000 --- a/querydsl-core/etc/readme.txt +++ /dev/null @@ -1,3 +0,0 @@ -REFACTORING - -* move types.operation.* and types.expr.* into types diff --git a/querydsl-core/pom.xml b/querydsl-core/pom.xml index 7f5cb1c160..fc3a422bca 100644 --- a/querydsl-core/pom.xml +++ b/querydsl-core/pom.xml @@ -1,15 +1,15 @@ - + 4.0.0 - com.mysema.querydsl + com.querydsl querydsl-root - 3.4.1.BUILD-SNAPSHOT - ../querydsl-root/pom.xml + 5.1.0 + ../pom.xml - com.mysema.querydsl + com.querydsl querydsl-core Querydsl - Core module core module for querydsl @@ -24,40 +24,30 @@ - com.google.guava - guava - ${guava.version} + org.jetbrains + annotations + provided - - com.google.code.findbugs - jsr305 - 1.3.9 - com.mysema.commons mysema-commons-lang ${mysema.lang.version} - + + + io.github.classgraph + classgraph + test + cglib cglib ${cglib.version} + true - - com.infradna.tool - bridge-method-annotation - ${bridge-method.version} - - - org.jenkins-ci - annotation-indexer - - - org.jvnet.hudson annotation-indexer @@ -71,45 +61,14 @@ jdepend 2.9.1 test - + - com.springsource.bundlor - com.springsource.bundlor.maven - - - com.infradna.tool - bridge-method-injector - ${bridge-method.version} - - - - process - - - - - - com.infradna.tool - bridge-method-annotation - ${bridge-method.version} - true - - - org.jenkins-ci - annotation-indexer - - - - - org.jvnet.hudson - annotation-indexer - 1.2 - - + org.apache.felix + maven-bundle-plugin org.apache.maven.plugins @@ -122,6 +81,13 @@ + + + + com.querydsl.core + + + maven-source-plugin @@ -136,8 +102,57 @@ - - - 1.11 - - + + + + java-11 + + [11,) + + + + javax.annotation + javax.annotation-api + 1.3.2 + provided + + + + + java-21 + + [21,) + + + + cglib + cglib + ${cglib.version} + true + + + org.ow2.asm + asm + + + org.ow2.asm + asm-commons + + + + + org.ow2.asm + asm + ${asm.version} + true + + + org.ow2.asm + asm-commons + ${asm.version} + true + + + + + diff --git a/querydsl-core/src/main/java/com/mysema/query/BooleanBuilder.java b/querydsl-core/src/main/java/com/mysema/query/BooleanBuilder.java deleted file mode 100644 index e2cfa97626..0000000000 --- a/querydsl-core/src/main/java/com/mysema/query/BooleanBuilder.java +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query; - -import javax.annotation.Nullable; - -import com.google.common.base.Objects; -import com.mysema.query.types.ExpressionUtils; -import com.mysema.query.types.Predicate; -import com.mysema.query.types.Visitor; - -/** - * BooleanBuilder is a cascading builder for {@link Predicate} expressions. BooleanBuilder is a mutable - * Expression implementation. - * - *

Usage example:

- *
- * QEmployee employee = QEmployee.employee;
- * BooleanBuilder builder = new BooleanBuilder();
- * for (String name : names) {
- *     builder.or(employee.name.equalsIgnoreCase(name));      
- * }
- * 
- * - * @author tiwe - */ -public final class BooleanBuilder implements Predicate, Cloneable { - - private static final long serialVersionUID = -4129485177345542519L; - - @Nullable - private Predicate predicate; - - /** - * Create an empty BooleanBuilder - */ - public BooleanBuilder() { } - - /** - * Create a BooleanBuilder with the given initial value - * - * @param initial - */ - public BooleanBuilder(Predicate initial) { - predicate = (Predicate)ExpressionUtils.extract(initial); - } - - @Override - public R accept(Visitor v, C context) { - if (predicate != null) { - return predicate.accept(v, context); - } else { - return null; - } - } - - /** - * Create the insertion of this and the given predicate - * - * @param right - * @return - */ - public BooleanBuilder and(@Nullable Predicate right) { - if (right != null) { - if (predicate == null) { - predicate = right; - } else { - predicate = ExpressionUtils.and(predicate, right); - } - } - return this; - } - - /** - * Create the intersection of this and the union of the given args - *

(this && (arg1 || arg2 ... || argN))

- * - * @param args - * @return - */ - public BooleanBuilder andAnyOf(Predicate... args) { - if (args.length > 0) { - and(ExpressionUtils.anyOf(args)); - } - return this; - } - - /** - * Create the insertion of this and the negation of the given predicate - * - * @param right - * @return - */ - public BooleanBuilder andNot(Predicate right) { - return and(right.not()); - } - - @Override - public BooleanBuilder clone() throws CloneNotSupportedException{ - return (BooleanBuilder) super.clone(); - } - - @Override - public boolean equals(Object o) { - if (o == this) { - return true; - } else if (o instanceof BooleanBuilder) { - return Objects.equal(((BooleanBuilder)o).getValue(), predicate); - } else { - return false; - } - } - - @Nullable - public Predicate getValue() { - return predicate; - } - - @Override - public int hashCode() { - return predicate != null ? predicate.hashCode() : 0; - } - - /** - * Returns true if the value is set, and false, if not - * - * @return - */ - public boolean hasValue() { - return predicate != null; - } - - @Override - public BooleanBuilder not() { - if (predicate != null) { - predicate = predicate.not(); - } - return this; - } - - /** - * Create the union of this and the given predicate - * - * @param right - * @return - */ - public BooleanBuilder or(@Nullable Predicate right) { - if (right != null) { - if (predicate == null) { - predicate = right; - } else { - predicate = ExpressionUtils.or(predicate, right); - } - } - return this; - } - - /** - * Create the union of this and the intersection of the given args - *

(this || (arg1 && arg2 ... && argN))

- * - * @param args - * @return - */ - public BooleanBuilder orAllOf(Predicate... args) { - if (args.length > 0) { - or(ExpressionUtils.allOf(args)); - } - return this; - } - - /** - * Create the union of this and the negation of the given predicate - * - * @param right - * @return - */ - public BooleanBuilder orNot(Predicate right) { - return or(right.not()); - } - - @Override - public Class getType() { - return Boolean.class; - } - - @Override - public String toString() { - return predicate != null ? predicate.toString() : super.toString(); - } - -} diff --git a/querydsl-core/src/main/java/com/mysema/query/DefaultQueryMetadata.java b/querydsl-core/src/main/java/com/mysema/query/DefaultQueryMetadata.java deleted file mode 100644 index c8ad7127e9..0000000000 --- a/querydsl-core/src/main/java/com/mysema/query/DefaultQueryMetadata.java +++ /dev/null @@ -1,403 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query; - -import static com.mysema.query.util.CollectionUtils.add; -import static com.mysema.query.util.CollectionUtils.addSorted; -import static com.mysema.query.util.CollectionUtils.copyOf; -import static com.mysema.query.util.CollectionUtils.copyOfSorted; -import static com.mysema.query.util.CollectionUtils.put; -import static com.mysema.query.util.CollectionUtils.removeSorted; - -import java.util.List; -import java.util.Map; -import java.util.Set; - -import javax.annotation.Nullable; - -import com.google.common.base.Objects; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; -import com.mysema.query.types.Expression; -import com.mysema.query.types.ExpressionUtils; -import com.mysema.query.types.OrderSpecifier; -import com.mysema.query.types.ParamExpression; -import com.mysema.query.types.ParamsVisitor; -import com.mysema.query.types.Path; -import com.mysema.query.types.Predicate; -import com.mysema.query.types.ValidatingVisitor; - -/** - * DefaultQueryMetadata is the default implementation of the {@link QueryMetadata} interface - * - * @author tiwe - */ -public class DefaultQueryMetadata implements QueryMetadata, Cloneable { - - private static final long serialVersionUID = 317736313966701232L; - - private boolean distinct; - - private Set> exprInJoins = ImmutableSet.of(); - - private List> groupBy = ImmutableList.of(); - - @Nullable - private Predicate having; - - private List joins = ImmutableList.of(); - - private Expression joinTarget; - - private JoinType joinType; - - @Nullable - private Predicate joinCondition; - - private Set joinFlags = ImmutableSet.of(); - - @Nullable - private QueryModifiers modifiers = QueryModifiers.EMPTY; - - private List> orderBy = ImmutableList.of(); - - private List> projection = ImmutableList.of(); - - // NOTE : this is not necessarily serializable - private Map,Object> params = ImmutableMap., Object>of(); - - private boolean unique; - - @Nullable - private Predicate where; - - private Set flags = ImmutableSet.of(); - - private boolean extractParams = true; - - private boolean validate = true; - - private ValidatingVisitor validatingVisitor = ValidatingVisitor.DEFAULT; - - private static Predicate and(Predicate lhs, Predicate rhs) { - if (lhs == null) { - return rhs; - } else { - return ExpressionUtils.and(lhs, rhs); - } - } - - /** - * Create an empty DefaultQueryMetadata instance - */ - public DefaultQueryMetadata() {} - - /** - * Disable validation - * - * @return - */ - public DefaultQueryMetadata noValidate() { - validate = false; - return this; - } - - - @Override - public void addFlag(QueryFlag flag) { - flags = addSorted(flags, flag); - } - - @Override - public void addJoinFlag(JoinFlag flag) { - joinFlags = addSorted(joinFlags, flag); - } - - @Override - public void addGroupBy(Expression o) { - addLastJoin(); - validate(o); - groupBy = add(groupBy, o); - } - - @Override - public void addHaving(Predicate e) { - addLastJoin(); - if (e == null) { - return; - } - e = (Predicate)ExpressionUtils.extract(e); - if (e != null) { - validate(e); - having = and(having, e); - } - } - - private void addLastJoin() { - if (joinTarget == null) { - return; - } - joins = add(joins, new JoinExpression(joinType, joinTarget, joinCondition, joinFlags)); - - joinType = null; - joinTarget = null; - joinCondition = null; - joinFlags = ImmutableSet.of(); - } - - @Override - public void addJoin(JoinType joinType, Expression expr) { - addLastJoin(); - if (!exprInJoins.contains(expr)) { - if (expr instanceof Path && ((Path)expr).getMetadata().isRoot()) { - exprInJoins = add(exprInJoins, expr); - } else { - validate(expr); - } - this.joinType = joinType; - this.joinTarget = expr; - } else if (validate) { - throw new IllegalStateException(expr + " is already used"); - } - } - - @Override - public void addJoinCondition(Predicate o) { - validate(o); - joinCondition = and(joinCondition, o); - } - - @Override - public void addOrderBy(OrderSpecifier o) { - addLastJoin(); - // order specifiers can't be validated, since they can refer to projection elements - // that are declared later - orderBy = add(orderBy, o); - } - - @Override - public void addProjection(Expression o) { - addLastJoin(); - validate(o); - projection = add(projection, o); - } - - @Override - public void addWhere(Predicate e) { - if (e == null) { - return; - } - addLastJoin(); - e = (Predicate)ExpressionUtils.extract(e); - if (e != null) { - validate(e); - where = and(where, e); - } - } - - @Override - public void clearOrderBy() { - orderBy = ImmutableList.of(); - } - - @Override - public void clearProjection() { - projection = ImmutableList.of(); - } - - @Override - public void clearWhere() { - where = new BooleanBuilder(); - } - - @Override - public QueryMetadata clone() { - try { - DefaultQueryMetadata clone = (DefaultQueryMetadata) super.clone(); - clone.exprInJoins = copyOf(exprInJoins); - clone.groupBy = copyOf(groupBy); - clone.having = having; - clone.joins = copyOf(joins); - clone.modifiers = modifiers; - clone.orderBy = copyOf(orderBy); - clone.projection = copyOf(projection); - clone.params = copyOf(params); - clone.where = where; - clone.flags = copyOfSorted(flags); - return clone; - } catch (CloneNotSupportedException e) { - throw new QueryException(e); - } - } - - @Override - public List> getGroupBy() { - return groupBy; - } - - @Override - public Predicate getHaving() { - return having; - } - - @Override - public List getJoins() { - addLastJoin(); - return joins; - } - - @Override - @Nullable - public QueryModifiers getModifiers() { - return modifiers; - } - - @Override - public Map,Object> getParams() { - return params; - } - - @Override - public List> getOrderBy() { - return orderBy; - } - - @Override - public List> getProjection() { - return projection; - } - - @Override - public Predicate getWhere() { - return where; - } - - @Override - public boolean isDistinct() { - return distinct; - } - - @Override - public boolean isUnique() { - return unique; - } - - @Override - public void reset() { - clearProjection(); - params = ImmutableMap.of(); - modifiers = QueryModifiers.EMPTY; - } - - @Override - public void setDistinct(boolean distinct) { - this.distinct = distinct; - } - - @Override - public void setLimit(Long limit) { - if (modifiers == null || modifiers.getOffset() == null) { - modifiers = QueryModifiers.limit(limit); - } else { - modifiers = new QueryModifiers(limit, modifiers.getOffset()); - } - } - - @Override - public void setModifiers(@Nullable QueryModifiers restriction) { - this.modifiers = restriction; - } - - @Override - public void setOffset(Long offset) { - if (modifiers == null || modifiers.getLimit() == null) { - modifiers = QueryModifiers.offset(offset); - } else { - modifiers = new QueryModifiers(modifiers.getLimit(), offset); - } - } - - @Override - public void setUnique(boolean unique) { - this.unique = unique; - } - - @Override - public void setParam(ParamExpression param, T value) { - params = put(params, param, value); - } - - @Override - public Set getFlags() { - return flags; - } - - @Override - public boolean hasFlag(QueryFlag flag) { - return flags.contains(flag); - } - - @Override - public void removeFlag(QueryFlag flag) { - flags = removeSorted(flags, flag); - } - - private void validate(Expression expr) { - if (extractParams) { - expr.accept(ParamsVisitor.DEFAULT, this); - } - if (validate) { - exprInJoins = expr.accept(validatingVisitor, exprInJoins); - } - } - - @Override - public void setValidate(boolean v) { - this.validate = v; - } - - public void setValidatingVisitor(ValidatingVisitor visitor) { - this.validatingVisitor = visitor; - } - - @Override - public boolean equals(Object o) { - if (o instanceof QueryMetadata) { - QueryMetadata q = (QueryMetadata)o; - return q.getFlags().equals(flags) - && q.getGroupBy().equals(groupBy) - && Objects.equal(q.getHaving(), having) - && q.isDistinct() == distinct - && q.isUnique() == unique - && q.getJoins().equals(joins) - && Objects.equal(q.getModifiers(), modifiers) - && q.getOrderBy().equals(orderBy) - && q.getParams().equals(params) - && q.getProjection().equals(projection) - && Objects.equal(q.getWhere(), where); - - } else { - return false; - } - } - - @Override - public int hashCode() { - return Objects.hashCode(flags, groupBy, having, joins, modifiers, - orderBy, params, projection, unique, where); - } - - -} diff --git a/querydsl-core/src/main/java/com/mysema/query/Detachable.java b/querydsl-core/src/main/java/com/mysema/query/Detachable.java deleted file mode 100644 index f14bb0586e..0000000000 --- a/querydsl-core/src/main/java/com/mysema/query/Detachable.java +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query; - -import com.mysema.query.types.Expression; -import com.mysema.query.types.Predicate; -import com.mysema.query.types.expr.BooleanExpression; -import com.mysema.query.types.expr.ComparableExpression; -import com.mysema.query.types.expr.DateExpression; -import com.mysema.query.types.expr.DateTimeExpression; -import com.mysema.query.types.expr.NumberExpression; -import com.mysema.query.types.expr.StringExpression; -import com.mysema.query.types.expr.TimeExpression; -import com.mysema.query.types.query.BooleanSubQuery; -import com.mysema.query.types.query.ComparableSubQuery; -import com.mysema.query.types.query.DateSubQuery; -import com.mysema.query.types.query.DateTimeSubQuery; -import com.mysema.query.types.query.ListSubQuery; -import com.mysema.query.types.query.NumberSubQuery; -import com.mysema.query.types.query.SimpleSubQuery; -import com.mysema.query.types.query.StringSubQuery; -import com.mysema.query.types.query.TimeSubQuery; - -/** - * Detachable defines methods for the construction of SubQuery instances - * - * @author tiwe - * - */ -public interface Detachable { - - /** - * Return the count of matched rows as a sub query - * - * @return - */ - NumberSubQuery count(); - - /** - * Create an exists(this) expression - * - * @return - */ - BooleanExpression exists(); - - /** - * Create a projection expression for the given projection - * - * @param args - * @return - */ - ListSubQuery list(Expression... args); - - /** - * Create a projection expression for the given projection - * Non expression arguments are converted into constant expressions - * - * @param args - * @return - */ - ListSubQuery list(Object... args); - - /** - * Create a projection expression for the given projection - * - * @param - * generic type of the List - * @param projection - * @return a List over the projection - */ - ListSubQuery list(Expression projection); - - - /** - * Create an not exists(this) expression - * - * @return - */ - BooleanExpression notExists(); - - /** - * Create a projection expression for the given projection - * - * @param args - * @return - */ - SimpleSubQuery unique(Expression... args); - - /** - * Create a projection expression for the given projection - * Non expression arguments are converted into constant expressions - * - * @param args - * @return - */ - SimpleSubQuery unique(Object... args); - - /** - * Create a subquery expression for the given projection - * - * @param - * return type - * @param projection - * @return the result or null for an empty result - */ - SimpleSubQuery unique(Expression projection); - - /** - * Create a subquery expression for the given projection - * - * @param projection - * @return - */ - BooleanSubQuery unique(Predicate projection); - - /** - * Create a subquery expression for the given projection - * - * @param projection - * @return - */ - StringSubQuery unique(StringExpression projection); - - /** - * Create a subquery expression for the given projection - * - * @param - * @param projection - * @return - */ - > ComparableSubQuery unique(ComparableExpression projection); - - /** - * Create a subquery expression for the given projection - * - * @param - * @param projection - * @return - */ - > DateSubQuery unique(DateExpression projection); - - /** - * Create a subquery expression for the given projection - * - * @param - * @param projection - * @return - */ - > DateTimeSubQuery unique(DateTimeExpression projection); - - /** - * Create a subquery expression for the given projection - * - * @param - * @param projection - * @return - */ - > TimeSubQuery unique(TimeExpression projection); - - /** - * Create a subquery expression for the given projection - * - * @param - * @param projection - * @return - */ - > NumberSubQuery unique(NumberExpression projection); - -} diff --git a/querydsl-core/src/main/java/com/mysema/query/JoinExpression.java b/querydsl-core/src/main/java/com/mysema/query/JoinExpression.java deleted file mode 100644 index ed9a391e1b..0000000000 --- a/querydsl-core/src/main/java/com/mysema/query/JoinExpression.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query; - -import java.io.Serializable; -import java.util.Set; - -import javax.annotation.Nullable; -import javax.annotation.concurrent.Immutable; - -import com.google.common.base.Objects; -import com.google.common.collect.ImmutableSet; -import com.mysema.query.types.Expression; -import com.mysema.query.types.Predicate; - -/** - * JoinExpression is a join element in a {@link Query} instance. - * - * @author tiwe - */ -@Immutable -public final class JoinExpression implements Serializable { - - private static final long serialVersionUID = -1131755765747174886L; - - @Nullable - private final Predicate condition; - - private final ImmutableSet flags; - - private final Expression target; - - private final JoinType type; - - /** - * Create a new JoinExpression instance - * - * @param type - * @param target - */ - public JoinExpression(JoinType type, Expression target) { - this(type, target, null, ImmutableSet.of()); - } - - - /** - * Create a new JoinExpression instance - * - * @param type - * @param target - * @param condition - * @param flags - */ - public JoinExpression(JoinType type, Expression target, @Nullable Predicate condition, - Set flags) { - this.type = type; - this.target = target; - this.condition = condition; - this.flags = ImmutableSet.copyOf(flags); - } - - @Nullable - public Predicate getCondition() { - return condition; - } - - public Expression getTarget() { - return target; - } - - public JoinType getType() { - return type; - } - - public boolean hasFlag(JoinFlag flag) { - return flags.contains(flag); - } - - public Set getFlags() { - return flags; - } - - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append(type).append(" ").append(target); - if (condition != null) { - builder.append(" on ").append(condition); - } - return builder.toString(); - } - - @Override - public int hashCode() { - return Objects.hashCode(condition, target, type); - } - - @Override - public boolean equals(Object o) { - if (o == this) { - return true; - } else if (o instanceof JoinExpression) { - JoinExpression j = (JoinExpression) o; - return Objects.equal(condition, j.condition) && - Objects.equal(target, j.target) && - Objects.equal(type, j.type); - } else { - return false; - } - } - -} diff --git a/querydsl-core/src/main/java/com/mysema/query/JoinFlag.java b/querydsl-core/src/main/java/com/mysema/query/JoinFlag.java deleted file mode 100644 index 9271477d5e..0000000000 --- a/querydsl-core/src/main/java/com/mysema/query/JoinFlag.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query; - -import java.io.Serializable; - -import javax.annotation.concurrent.Immutable; - -import com.mysema.query.types.Expression; -import com.mysema.query.types.TemplateExpressionImpl; - -/** - * JoinFlag defines a join related flag using an Expression instance - * - * @author tiwe - * - */ -@Immutable -public class JoinFlag implements Serializable{ - - public enum Position { - - /** - * before the join - */ - START, - - /** - * as a replacement for the join symbol - */ - OVERRIDE, - - /** - * before the join target - */ - BEFORE_TARGET, - - /** - * before the join condition - */ - BEFORE_CONDITION, - - /** - * after the join - */ - END - - } - - private static final long serialVersionUID = -688265393547206465L; - - private final Expression flag; - - private final Position position; - - public JoinFlag(String flag) { - this(TemplateExpressionImpl.create(Object.class, flag), Position.BEFORE_TARGET); - } - - public JoinFlag(String flag, Position position) { - this(TemplateExpressionImpl.create(Object.class, flag), position); - } - - - public JoinFlag(Expression flag) { - this(flag, Position.BEFORE_TARGET); - } - - public JoinFlag(Expression flag, Position position) { - this.flag = flag; - this.position = position; - } - - @Override - public int hashCode() { - return flag.hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (obj == this) { - return true; - } else if (obj instanceof JoinFlag) { - return ((JoinFlag)obj).flag.equals(flag); - } else { - return false; - } - } - - @Override - public String toString() { - return flag.toString(); - } - - public Expression getFlag() { - return flag; - } - - public Position getPosition() { - return position; - } - -} diff --git a/querydsl-core/src/main/java/com/mysema/query/NonUniqueResultException.java b/querydsl-core/src/main/java/com/mysema/query/NonUniqueResultException.java deleted file mode 100644 index 1e900137fb..0000000000 --- a/querydsl-core/src/main/java/com/mysema/query/NonUniqueResultException.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query; - -/** - * NonUniqueResultException is thrown for query results where one result row is expected, but multiple - * are retrieved. - * - * @author tiwe - * - */ -public class NonUniqueResultException extends QueryException{ - - private static final long serialVersionUID = -1757423191400510323L; - - public NonUniqueResultException() { - super("Only one result is allowed for uniqueResult calls"); - } - - public NonUniqueResultException(String message) { - super(message); - } - -} diff --git a/querydsl-core/src/main/java/com/mysema/query/Projectable.java b/querydsl-core/src/main/java/com/mysema/query/Projectable.java deleted file mode 100644 index 927f6d604b..0000000000 --- a/querydsl-core/src/main/java/com/mysema/query/Projectable.java +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query; - -import java.util.List; -import java.util.Map; - -import javax.annotation.Nonnegative; -import javax.annotation.Nullable; - -import com.mysema.commons.lang.CloseableIterator; -import com.mysema.query.types.Expression; - -/** - * Projectable defines default projection methods for {@link Query} implementations. - * All Querydsl query implementations should implement either this interface or - * {@link SimpleProjectable}. - * - * @author tiwe - * @see SimpleProjectable - */ -public interface Projectable { - /** - * return the amount of matched rows - */ - @Nonnegative - long count(); - - /** - * @return true, if rows matching the given criteria exist, otherwise false - */ - boolean exists(); - - /** - * @return true, if no rows matching the given criteria exist, otherwise false - */ - boolean notExists(); - - /** - * iterate over the results for the given projection - * - * @param args - * @return - */ - CloseableIterator iterate(Expression... args); - - /** - * iterate over the results for the given projection - * - * @param - * generic type of the Iterator - * @param projection - * @return an Iterator over the projection - */ - CloseableIterator iterate(Expression projection); - - /** - * list the results for the given projection - * - * An empty list is returned for no results. - * - * @param args - * @return - */ - List list(Expression... args); - - /** - * list the results for the given projection - * - * An empty list is returned for no results. - * - * @param - * generic type of the List - * @param projection - * @return a List over the projection - */ - List list(Expression projection); - - /** - * list the results for the given projection - * - * @param args - * @return - */ - SearchResults listResults(Expression... args); - - /** - * list the results for the given projection - * - * @param - * @param projection - * @return - */ - SearchResults listResults(Expression projection); - - /** - * return the given projection as a Map instance using key and value for Map population - * - * An empty map is returned for no results. - * - * @param - * @param - * @param key - * @param value - * @return - */ - Map map(Expression key, Expression value); - - /** - * return a single result for the given projection or null if no result is found - * - *

There is some ambiguity for missing results and null valued results, for disambiguation - * use the list or iterate methods instead.

- * - *

for multiple results only the first one is returned

- * - * @param args - * @return - */ - @Nullable - Tuple singleResult(Expression... args); - - /** - * return a single result for the given projection or null if no result is found - * - *

There is some ambiguity for missing results and null valued results, for disambiguation - * use the list or iterate methods instead.

- * - *

for multiple results only the first one is returned

- * - * @param - * return type - * @param projection - * @return the result or null for an empty result - */ - @Nullable - RT singleResult(Expression projection); - - /** - * Apply the given transformer to this Projectable instance and return the results - * - * @param - * @param transformer - * @return - */ - T transform(ResultTransformer transformer); - - /** - * return a unique result for the given projection or null if no result is found - * - *

There is some ambiguity for missing results and null valued results, for disambiguation - * use the list or iterate methods instead.

- * - * @param args - * @throws NonUniqueResultException if there is more than one matching result - * @return - */ - @Nullable - Tuple uniqueResult(Expression... args); - - /** - * return a unique result for the given projection or null if no result is found - * - *

There is some ambiguity for missing results and null valued results, for disambiguation - * use the list or iterate methods instead.

- * - * @param - * return type - * @param projection - * @throws NonUniqueResultException if there is more than one matching result - * @return the result or null for an empty result - */ - @Nullable - RT uniqueResult(Expression projection); - -} diff --git a/querydsl-core/src/main/java/com/mysema/query/Query.java b/querydsl-core/src/main/java/com/mysema/query/Query.java deleted file mode 100644 index 254e90591d..0000000000 --- a/querydsl-core/src/main/java/com/mysema/query/Query.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query; - -import com.mysema.query.types.Expression; -import com.mysema.query.types.Predicate; - -/** - * Query defines the main query interface of the fluent query language. - * - *

Note that the from method has been left out, since there are implementation - * specific variants of it.

- * - * @author tiwe - * @see SimpleQuery - */ -public interface Query> extends SimpleQuery { - - /** - * Add grouping/aggregation expressions - * - * @param o - * @return - */ - Q groupBy(Expression... o); - - /** - * Add filters for aggregation - * - * @param o - * @return - */ - Q having(Predicate... o); - -} diff --git a/querydsl-core/src/main/java/com/mysema/query/QueryFactory.java b/querydsl-core/src/main/java/com/mysema/query/QueryFactory.java deleted file mode 100644 index cde5044657..0000000000 --- a/querydsl-core/src/main/java/com/mysema/query/QueryFactory.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query; - - -/** - * Common interface for QueryFactory implementations - * - * @author tiwe - * - * @param Query type - * @param Subquery type - */ -public interface QueryFactory, SQ extends Detachable> { - /** - * Create a new Query - * - * @return - */ - Q query(); - - /** - * Create a new Sub query - * - * @return - */ - SQ subQuery(); -} \ No newline at end of file diff --git a/querydsl-core/src/main/java/com/mysema/query/QueryMetadata.java b/querydsl-core/src/main/java/com/mysema/query/QueryMetadata.java deleted file mode 100644 index 95574cc4e9..0000000000 --- a/querydsl-core/src/main/java/com/mysema/query/QueryMetadata.java +++ /dev/null @@ -1,249 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query; - -import java.io.Serializable; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import javax.annotation.Nullable; - -import com.mysema.query.types.Expression; -import com.mysema.query.types.OrderSpecifier; -import com.mysema.query.types.ParamExpression; -import com.mysema.query.types.Predicate; - -/** - * QueryMetadata defines query metadata such as query sources, filtering - * conditions and the projection - * - * @author tiwe - */ -public interface QueryMetadata extends Serializable { - - /** - * Add the given group by expressions - * - * @param o - */ - void addGroupBy(Expression o); - - /** - * Add the given having expressions - * - * @param o - */ - void addHaving(Predicate o); - - /** - * Add the given query join - * - * @param joinType - * @param expr - */ - void addJoin(JoinType joinType, Expression expr); - - /** - * Add the given join flag to the last given join - * - * @param flag - */ - void addJoinFlag(JoinFlag flag); - - /** - * Add the given join condition to the last given join - * - * @param o - */ - void addJoinCondition(Predicate o); - - /** - * Add the given order specifiers - * - * @param o - */ - void addOrderBy(OrderSpecifier o); - - /** - * Add the given projections - * - * @param o - */ - void addProjection(Expression o); - - /** - * Add the given where expressions - * - * @param o - */ - void addWhere(Predicate o); - - /** - * Clear the order expressions - */ - void clearOrderBy(); - - /** - * Clear the projection - */ - void clearProjection(); - - /** - * Clear the where expressions - */ - void clearWhere(); - - /** - * Clone this QueryMetadata instance - * - * @return - */ - QueryMetadata clone(); - - /** - * Get the group by expressions - * - * @return - */ - List> getGroupBy(); - - /** - * Get the having expressions - * - * @return - */ - Predicate getHaving(); - - /** - * Get the query joins - * - * @return - */ - List getJoins(); - - /** - * Get the QueryModifiers - * - * @return - */ - QueryModifiers getModifiers(); - - /** - * Get the OrderSpecifiers - * - * @return - */ - List> getOrderBy(); - - /** - * Get the projection - * - * @return - */ - List> getProjection(); - - /** - * Get the parameters - * - * @return - */ - Map,Object> getParams(); - - /** - * Get the expressions aggregated into a single boolean expression or null, - * if none where defined - * - * @return - */ - @Nullable - Predicate getWhere(); - - /** - * Get whether the projection is distinct - * - * @return - */ - boolean isDistinct(); - - /** - * Get whether the projection is unique - * - * @return - */ - boolean isUnique(); - - /** - * Reset the projection - */ - void reset(); - - /** - * @param distinct - */ - void setDistinct(boolean distinct); - - /** - * @param limit - */ - void setLimit(@Nullable Long limit); - - /** - * @param restriction - */ - void setModifiers(QueryModifiers restriction); - - /** - * @param offset - */ - void setOffset(@Nullable Long offset); - - /** - * @param unique - */ - void setUnique(boolean unique); - - /** - * @param - * @param param - * @param value - */ - void setParam(ParamExpression param, T value); - - /** - * @param flag - */ - void addFlag(QueryFlag flag); - - /** - * @param flag - * @return - */ - boolean hasFlag(QueryFlag flag); - - /** - * @param flag - */ - void removeFlag(QueryFlag flag); - - /** - * @return - */ - Set getFlags(); - - /** - * @param v - */ - void setValidate(boolean v); -} diff --git a/querydsl-core/src/main/java/com/mysema/query/QueryModifiers.java b/querydsl-core/src/main/java/com/mysema/query/QueryModifiers.java deleted file mode 100644 index a4f5722d69..0000000000 --- a/querydsl-core/src/main/java/com/mysema/query/QueryModifiers.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query; - -import java.io.Serializable; -import java.util.List; - -import javax.annotation.Nonnegative; -import javax.annotation.Nullable; - -import com.google.common.base.Objects; - -/** - * QueryModifiers combines limit and offset info into a single type. - * - * @author tiwe - */ -public final class QueryModifiers implements Serializable{ - - private static final long serialVersionUID = 2934344588433680339L; - - public static final QueryModifiers EMPTY = new QueryModifiers(); - - private static int toInt(Long l) { - if (l.longValue() <= Integer.MAX_VALUE) { - return l.intValue(); - } else { - return Integer.MAX_VALUE; - } - } - - public static QueryModifiers limit(@Nonnegative long limit) { - return new QueryModifiers(Long.valueOf(limit), null); - } - - public static QueryModifiers offset(@Nonnegative long offset) { - return new QueryModifiers(null, Long.valueOf(offset)); - } - - @Nullable - private final Long limit, offset; - - private QueryModifiers() { - limit = null; - offset = null; - } - - public QueryModifiers(@Nullable Long limit, @Nullable Long offset) { - this.limit = limit; - if (limit != null && limit <= 0) { - throw new IllegalArgumentException("Limit must be greater than 0."); - } - this.offset = offset; - if (offset != null && offset < 0) { - throw new IllegalArgumentException("Offset must not be negative."); - } - } - - public QueryModifiers(QueryModifiers modifiers) { - this.limit = modifiers.getLimit(); - this.offset = modifiers.getOffset(); - } - - @Nullable - public Long getLimit() { - return limit; - } - - @Nullable - public Integer getLimitAsInteger() { - return limit != null ? toInt(limit) : null; - } - - @Nullable - public Long getOffset() { - return offset; - } - - @Nullable - public Integer getOffsetAsInteger() { - return offset != null ? toInt(offset) : null; - } - - /** - * Checks if is restricting. - * - * @return true, if is restricting - */ - public boolean isRestricting() { - return limit != null || offset != null; - } - - /** - * Get a sublist based on the restriction of limit and offset - * - * @param - * @param list - * @return - */ - public List subList(List list) { - if (!list.isEmpty()) { - int from = offset != null ? toInt(offset) : 0; - int to = limit != null ? (from + toInt(limit)) : list.size(); - return list.subList(from, Math.min(to,list.size())); - } else { - return list; - } - } - - @Override - public boolean equals(Object o) { - if (o == this) { - return true; - } else if (o instanceof QueryModifiers) { - QueryModifiers qm = (QueryModifiers)o; - return Objects.equal(qm.getLimit(), limit) && Objects.equal(qm.getOffset(), offset); - } else { - return false; - } - } - - @Override - public int hashCode() { - return Objects.hashCode(limit, offset); - } - -} diff --git a/querydsl-core/src/main/java/com/mysema/query/ResultTransformer.java b/querydsl-core/src/main/java/com/mysema/query/ResultTransformer.java deleted file mode 100644 index f079f6bc1e..0000000000 --- a/querydsl-core/src/main/java/com/mysema/query/ResultTransformer.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query; - - -/** - * Executes query on a {@link Projectable} and transforms results into T. This can be used for example - * to group projected columns or to filter out duplicate results. - * - * @see com.mysema.query.group.GroupBy - * @author sasa - * - * @param Transformations target type - */ -public interface ResultTransformer { - - /** - * @param projectable - * @return - */ - T transform(Projectable projectable); - -} diff --git a/querydsl-core/src/main/java/com/mysema/query/SearchResults.java b/querydsl-core/src/main/java/com/mysema/query/SearchResults.java deleted file mode 100644 index a7810d5183..0000000000 --- a/querydsl-core/src/main/java/com/mysema/query/SearchResults.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query; - -import java.util.List; - -import javax.annotation.Nullable; - -import com.google.common.collect.ImmutableList; - -/** - * SearchResults bundles data for paged search results - * - * @author tiwe - */ -public final class SearchResults { - - private static final SearchResults EMPTY = new SearchResults( - ImmutableList.of(), Long.MAX_VALUE, 0l, 0l); - - @SuppressWarnings("unchecked") - public static SearchResults emptyResults() { - return (SearchResults)EMPTY; - }; - - private final long limit, offset, total; - - private final List results; - - /** - * Create a new SearchResults instance - * - * @param results paged results - * @param limit used limit - * @param offset used offset - * @param total total result rows count - */ - public SearchResults(List results, @Nullable Long limit, @Nullable Long offset, long total) { - this.limit = limit != null ? limit : Long.MAX_VALUE; - this.offset = offset != null ? offset : 0l; - this.total = total; - this.results = results; - } - - /** - * Create a new SearchResults instance - * - * @param results paged results - * @param mod limit and offset - * @param total total result rows count - */ - public SearchResults(List results, QueryModifiers mod, long total) { - this(results, mod.getLimit(), mod.getOffset(), total); - } - - /** - * Get the results in List form - * - * An empty list is returned for no results. - * - * @return - */ - public List getResults() { - return results; - } - - /** - * Get the number of total results - * - * @return - */ - public long getTotal() { - return total; - } - - /** - * @return - */ - public boolean isEmpty() { - return results.isEmpty(); - } - - /** - * @return - */ - public long getLimit() { - return limit; - } - - /** - * @return - */ - public long getOffset() { - return offset; - } - -} diff --git a/querydsl-core/src/main/java/com/mysema/query/SimpleProjectable.java b/querydsl-core/src/main/java/com/mysema/query/SimpleProjectable.java deleted file mode 100644 index 5eb1e58abe..0000000000 --- a/querydsl-core/src/main/java/com/mysema/query/SimpleProjectable.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query; - -import java.util.List; - -import javax.annotation.Nullable; - -import com.mysema.commons.lang.CloseableIterator; - -/** - * SimpleProjectable defines a simpler projection interface than {@link Projectable}. - * - * @author tiwe - * @see Projectable - */ -public interface SimpleProjectable { - - /** - * @return true, if rows matching the given criteria exist, otherwise false - */ - boolean exists(); - - /** - * @return true, if no rows matching the given criteria exist, otherwise false - */ - boolean notExists(); - - /** - * Get the projection as a typed closeable Iterator - * - * @return - */ - CloseableIterator iterate(); - - /** - * Get the projection as a typed List - * - * @return - */ - List list(); - - /** - * Get the projection as a single result or null if no result is found - * - *

for multiple results only the first one is returned

- * - * @return - */ - @Nullable - T singleResult(); - - /** - * Get the projection as a unique result or null if no result is found - * - * @throws NonUniqueResultException if there is more than one matching result - * @return - */ - @Nullable - T uniqueResult(); - - /** - * Get the projection in {@link SearchResults} form - * - * @return - */ - SearchResults listResults(); - - /** - * Get the count of matched elements - * - * @return - */ - long count(); - -} diff --git a/querydsl-core/src/main/java/com/mysema/query/SimpleQuery.java b/querydsl-core/src/main/java/com/mysema/query/SimpleQuery.java deleted file mode 100644 index e2041441ce..0000000000 --- a/querydsl-core/src/main/java/com/mysema/query/SimpleQuery.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query; - -import javax.annotation.Nonnegative; - -import com.mysema.query.types.OrderSpecifier; -import com.mysema.query.types.ParamExpression; - -/** - * SimpleQuery defines a simple querying interface than {@link Query} - * - * @author tiwe - * - * @param concrete subtype - * @see Query - */ -public interface SimpleQuery> extends FilteredClause { - - /** - * Set the limit / max results for the query results - * - * @param limit - * @return - */ - Q limit(@Nonnegative long limit); - - /** - * Set the offset for the query results - * - * @param offset - * @return - */ - Q offset(@Nonnegative long offset); - - /** - * Set both limit and offset of the query results - * - * @param modifiers - * @return - */ - Q restrict(QueryModifiers modifiers); - - /** - * Add order expressions - * - * @param o - * @return - */ - Q orderBy(OrderSpecifier... o); - - /** - * Set the given parameter to the given value - * - * @param - * @param param - * @param value - * @return - */ - Q set(ParamExpression param, T value); - - /** - * Set the Query to return distinct results - * - * @return - */ - Q distinct(); - -} diff --git a/querydsl-core/src/main/java/com/mysema/query/Tuple.java b/querydsl-core/src/main/java/com/mysema/query/Tuple.java deleted file mode 100644 index 2caeff3765..0000000000 --- a/querydsl-core/src/main/java/com/mysema/query/Tuple.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query; - -import javax.annotation.Nullable; - -import com.mysema.query.types.Expression; - -/** - * Tuple defines an interface for generic query result projection - * - *

Usage example:

- *
- * {@code 
- * List result = query.from(employee).list(new QTuple(employee.firstName, employee.lastName));
- * for (Tuple row : result) {
- *     System.out.println("firstName " + row.get(employee.firstName));
- *     System.out.println("lastName " + row.get(employee.lastName)); 
- * }
- * } 
- * 
- * - * @author tiwe - * - */ -public interface Tuple { - - /** - * Get a Tuple element by index - * - * @param - * @param index - * @param type - * @return - */ - @Nullable - T get(int index, Class type); - - /** - * Get a tuple element by expression - * - * @param - * @param expr - * @return - */ - @Nullable - T get(Expression expr); - - /** - * Get the size of the Tuple - * - * @return - */ - int size(); - - /** - * Get the content as an Object array - * - * @return - */ - Object[] toArray(); - - /** - * All Tuples should override equals and hashCode. For compatibility - * across different Tuple implementations, equality check should use - * {@link java.util.Arrays#equals(Object[], Object[])} with {@link #toArray()} as parameters. - * - * @see Object#equals(Object) - */ - boolean equals(Object o); - - /** - * All Tuples should override equals and hashCode. For compatibility - * across different Tuple implementations, hashCode should use - * {@link java.util.Arrays#hashCode(Object[])} with {@link #toArray()} as parameter. - * - * @see Object#hashCode() - */ - int hashCode(); - - -} diff --git a/querydsl-core/src/main/java/com/mysema/query/alias/Alias.java b/querydsl-core/src/main/java/com/mysema/query/alias/Alias.java deleted file mode 100644 index 7d5108f5c7..0000000000 --- a/querydsl-core/src/main/java/com/mysema/query/alias/Alias.java +++ /dev/null @@ -1,273 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.alias; - -import java.math.BigDecimal; -import java.math.BigInteger; -import java.sql.Time; -import java.sql.Timestamp; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import javax.annotation.Nullable; - -import com.google.common.base.CaseFormat; -import com.mysema.query.types.EntityPath; -import com.mysema.query.types.Expression; -import com.mysema.query.types.Path; -import com.mysema.query.types.PathMetadataFactory; -import com.mysema.query.types.expr.SimpleExpression; -import com.mysema.query.types.path.ArrayPath; -import com.mysema.query.types.path.BooleanPath; -import com.mysema.query.types.path.CollectionPath; -import com.mysema.query.types.path.ComparablePath; -import com.mysema.query.types.path.DatePath; -import com.mysema.query.types.path.DateTimePath; -import com.mysema.query.types.path.EntityPathBase; -import com.mysema.query.types.path.EnumPath; -import com.mysema.query.types.path.ListPath; -import com.mysema.query.types.path.MapPath; -import com.mysema.query.types.path.NumberPath; -import com.mysema.query.types.path.PathBuilder; -import com.mysema.query.types.path.SetPath; -import com.mysema.query.types.path.SimplePath; -import com.mysema.query.types.path.StringPath; -import com.mysema.query.types.path.TimePath; - -/** - * Alias provides alias factory methods - * - * @author tiwe - */ -@SuppressWarnings("PMD") -public final class Alias { - - private static final AliasFactory aliasFactory = new AliasFactory(new DefaultPathFactory(), new DefaultTypeSystem()); - - private static final SimplePath it = new SimplePath(Object.class, PathMetadataFactory.forVariable("it")); - - // exclude $-methods from Checkstyle checks - //CHECKSTYLE:OFF - /** - * Convert the given alias to an expression - * - * @param - * @return - */ - public static > D $() { - return aliasFactory.getCurrentAndReset(); - } - - public static ArrayPath $(D[] arg) { - return aliasFactory.> getCurrentAndReset(); - } - - public static NumberPath $(BigDecimal arg) { - return aliasFactory.> getCurrentAndReset(); - } - - public static NumberPath $(BigInteger arg) { - return aliasFactory.> getCurrentAndReset(); - } - - public static BooleanPath $(Boolean arg) { - return aliasFactory. getCurrentAndReset(); - } - - public static NumberPath $(Byte arg) { - return aliasFactory.> getCurrentAndReset(); - } - - public static > EnumPath $(T arg) { - return aliasFactory.> getCurrentAndReset(); - } - - public static CollectionPath> $(Collection args) { - return aliasFactory.>> getCurrentAndReset(); - } - - public static > ComparablePath $(D arg) { -// return aliasFactory.> getCurrentAndReset(); - return Alias.>getPath(arg); - } - - public static NumberPath $(Double arg) { - return aliasFactory.> getCurrentAndReset(); - } - - public static NumberPath $(Float arg) { - return aliasFactory.> getCurrentAndReset(); - } - - public static NumberPath $(Integer arg) { - return aliasFactory.> getCurrentAndReset(); - } - - public static DatePath $(java.sql.Date arg) { - return aliasFactory.> getCurrentAndReset(); - } - - public static DateTimePath $(java.util.Date arg) { - return aliasFactory.> getCurrentAndReset(); - } - - public static ListPath> $(List args) { - return aliasFactory.>> getCurrentAndReset(); - } - - public static NumberPath $(Long arg) { - return aliasFactory.> getCurrentAndReset(); - } - - public static MapPath> $(Map args) { - return aliasFactory.>> getCurrentAndReset(); - } - - public static SetPath> $(Set args) { - return aliasFactory.>> getCurrentAndReset(); - } - - public static NumberPath $(Short arg) { - return aliasFactory.> getCurrentAndReset(); - } - - public static StringPath $(String arg) { - return aliasFactory. getCurrentAndReset(); - } - - public static TimePath
Config options @@ -115,18 +115,18 @@ class Customer{ Customization of package content: @@ -135,7 +135,7 @@ import com.mysema.query.annotations.Config; If you want to customize the serializer configuration globally, you can do this via the following APT options - +
APT options @@ -187,7 +187,7 @@ import com.mysema.query.annotations.Config; querydsl.includedClasses comma separated list of class names to be included into code generation (default: all) - + querydsl.excludedPackages comma separated list of packages to be excluded from code generation (default: none) @@ -196,10 +196,26 @@ import com.mysema.query.annotations.Config; querydsl.excludedClasses comma separated list of class names to be excluded from code generation (default: none) - + + querydsl.useFields + set whether fields are used as metadata source (default: true) + + + querydsl.useGetters + set whether accessors are used as metadata source (default: true) + + + querydsl.generatedAnnotationClass + + The fully qualified class name of the Single-Element Annotation (with String element) to be added on the generated sources. Build in + com.querydsl.core.annotations.Generatedhas CLASS retention which can be used for byte code analysis tools like Jacoco. + (default: javax.annotation.Generated orjavax.annotation.processing.Generated depending on the java version). See also + Single-Element Annotation + + -
+ Using the Maven APT plugin this works for example like this: @@ -212,7 +228,7 @@ import com.mysema.query.annotations.Config; com.mysema.maven apt-maven-plugin - 1.0.9 + 1.1.3 @@ -220,10 +236,11 @@ import com.mysema.query.annotations.Config; target/generated-sources/java - com.mysema.query.apt.jpa.JPAAnnotationProcessor + com.querydsl.apt.jpa.JPAAnnotationProcessor true - + false + @@ -234,6 +251,125 @@ import com.mysema.query.annotations.Config; ]]> + + Alternatively maven-compiler-plugin can be configured + to hook APT directly into compilation: + + + + + + ... + + maven-compiler-plugin + + target/generated-sources/java + + -Aquerydsl.entityAccessors=true + -Aquerydsl.useFields=false + + + + + com.querydsl + querydsl-apt + ${querydsl.version} + jpa + + + org.hibernate.javax.persistence + hibernate-jpa-2.1-api + 1.0.0.Final + + + + ... + + + +]]> + + + Notice that you need to use a proper classifier when defining dependency + to com.querydsl:querydsl-apt. Those additional artifacts + define the annotation processor to be used in + META-INF/services/javax.annotation.processing.Processor. + + + Available classifiers include: + + + + general + + + hibernate + + + jdo + + + jpa + + + + + With this configuration query objects can have their sources generated + and compiled during compilation of the domain objects. This will also + automatically add the generated sources directory to Maven project + source roots. + + + + The great advantage of this approach is that it can also handle + annotated Groovy classes using groovy-eclipse compiler: + + + + + + ... + + maven-compiler-plugin + + groovy-eclipse-compiler + target/generated-sources/java + + -Aquerydsl.entityAccessors=true + -Aquerydsl.useFields=false + + + + + org.codehaus.groovy + groovy-eclipse-compiler + 2.9.1-01 + + + org.codehaus.groovy + groovy-eclipse-batch + 2.3.7-01 + + + com.querydsl + querydsl-apt + ${querydsl.version} + jpa + + + org.hibernate.javax.persistence + hibernate-jpa-2.1-api + 1.0.0.Final + + + + ... + + + +]]> @@ -245,27 +381,27 @@ import com.mysema.query.annotations.Config; type. This can be useful for example in cases where comparison and String operations should be blocked on certain String paths or Date / Time support for custom types needs to be added. Support for Date / Time types of the Joda time API - and JDK (java.util.Date, Calendar and subtypes) is built in, but other APIs might need + and JDK (java.util.Date, Calendar and subtypes) is built in, but other APIs might need to be supported using this feature. The following example demonstrates the usage: - The value PropertyType.NONE can be used to skip a property in the + The value PropertyType.NONE can be used to skip a property in the query type generation. This case is different from @Transient or @QueryTransient annotated properties, where properties are not persisted. PropertyType.NONE just omits the property from the Querydsl query type. @@ -283,62 +419,62 @@ public class MyEntity{ Here is a simple example from a unit test: - - And the generated methods in the QUser query type: - Delegate methods can also be used to extend built-in types. Here are some examples - date, Pair period){ + public static BooleanExpression inPeriod(DatePath date, Pair period) { return date.goe(period.getFirst()).and(date.loe(period.getSecond())); } @QueryDelegate(Timestamp.class) - public static BooleanExpression inDatePeriod(DateTimePath timestamp, Pair period){ + public static BooleanExpression inDatePeriod(DateTimePath timestamp, Pair period) { Timestamp first = new Timestamp(DateUtils.truncate(period.getFirst(), Calendar.DAY_OF_MONTH).getTime()); Calendar second = Calendar.getInstance(); second.setTime(DateUtils.truncate(period.getSecond(), Calendar.DAY_OF_MONTH)); second.add(1, Calendar.DAY_OF_MONTH); return timestamp.goe(first).and(timestamp.lt(new Timestamp(second.getTimeInMillis()))); } - -} + +} ]]> When delegate methods are declared for builtin types then subclasses with the proper delegate method usages are created: - { public QDate(BeanPath entity) { @@ -385,7 +521,7 @@ public class QTimestamp extends DateTimePath { - To actually create the types use the com.mysema.query.apt.QuerydslAnnotationProcessor. + To actually create the types use the com.querydsl.apt.QuerydslAnnotationProcessor. In Maven you do it like this: @@ -397,7 +533,7 @@ public class QTimestamp extends DateTimePath { com.mysema.maven apt-maven-plugin - 1.0.9 + 1.1.3 @@ -405,7 +541,7 @@ public class QTimestamp extends DateTimePath { target/generated-sources/java - com.mysema.query.apt.QuerydslAnnotationProcessor + com.querydsl.apt.QuerydslAnnotationProcessor @@ -421,7 +557,7 @@ public class QTimestamp extends DateTimePath { Classpath based code generation - + For cases where annotated Java sources are not available, such as the usage of a different JVM language such as Scala or Groovy or annotation addition via bytecode manipulation the @@ -431,21 +567,21 @@ public class QTimestamp extends DateTimePath { To make GenericExporter available add a dependency to the querydsl-codegen module to your project, or to be more precise - com.mysema.querydsl:querydsl-codegen:${querydsl.version}. + com.querydsl:querydsl-codegen:${querydsl.version}. Below is an example for JPA - This will export all the JPA annotated classes in the package of the DomainClass @@ -459,13 +595,13 @@ exporter.export(DomainClass.class.getPackage()); The goals generic-export, jpa-export and jdo-export of the querydsl-maven-plugin can be used for GenericExporter usage via Maven. - + - The different goals are mapped to the Querydsl, JPA and JDO annotations. + The different goals are mapped to the Querydsl, JPA and JDO annotations. - + The configuration elements are - + Maven configuration @@ -485,8 +621,8 @@ exporter.export(DomainClass.class.getPackage()); targetFolder target folder for generated sources - - boolean + + boolean scala true, if Scala sources should be generated instead (default: false) @@ -495,7 +631,7 @@ exporter.export(DomainClass.class.getPackage()); packages packages to be introspected for entity classes - + boolean handleFields true, if fields should be treated as properties (default: true) @@ -517,40 +653,48 @@ exporter.export(DomainClass.class.getPackage()); -
+ Here is an example for JPA annotated classes - - com.mysema.querydsl - querydsl-maven-plugin - ${querydsl.version} - - - process-classes - - jpa-export - - - target/generated-sources/java - - com.example.domain - - - - -
+ + + + ... + + com.querydsl + querydsl-maven-plugin + ${querydsl.version} + + + process-classes + + jpa-export + + + target/generated-sources/java + + com.example.domain + + + + + + ... + + + ]]> This will export the JPA annotated classes of the com.example.domain package and - subpackages to the target/generated-sources/java directory. + subpackages to the target/generated-sources/java directory. - + If you need to compile the generated sources directly after that, then you can use the compile goal for that. - - compile @@ -558,11 +702,11 @@ exporter.export(DomainClass.class.getPackage()); target/generated-sources/scala - -]]> - + +]]> + The compile goal has the following configuration elements - + Maven configuration @@ -606,59 +750,67 @@ exporter.export(DomainClass.class.getPackage()); Map compilerOptions options for the compiler - + -
- + + All options except sourceFolder are optional. - + - + - - Scala support + + Scala support If you need Scala output of the classes, use a variant of the following configuration - - - com.mysema.querydsl - querydsl-maven-plugin - ${querydsl.version} - - - com.mysema.querydsl - querydsl-scala - ${project.version} - - - org.scala-lang - scala-library - ${scala.version} - - - - - - jpa-export - - - target/generated-sources/scala - true - - com.example.domain - - - - -
+ + + + + ... + + com.querydsl + querydsl-maven-plugin + ${querydsl.version} + + + com.querydsl + querydsl-scala + ${querydsl.version} + + + org.scala-lang + scala-library + ${scala.version} + + + + + + jpa-export + + + target/generated-sources/scala + true + + com.example.domain + + + + + + ... + + + ]]> - + diff --git a/querydsl-docs/src/main/docbook/en-US/content/general/creating-queries.xml b/querydsl-docs/src/main/docbook/en-US/content/general/creating-queries.xml index 955abca83a..e5fa188b1d 100644 --- a/querydsl-docs/src/main/docbook/en-US/content/general/creating-queries.xml +++ b/querydsl-docs/src/main/docbook/en-US/content/general/creating-queries.xml @@ -3,58 +3,58 @@ Creating queries Query construction in Querydsl involves calling query methods with expression arguments. Since - query methods are mostly module specific and have already been presented in the tutorial section, + query methods are mostly module specific and have already been presented in the tutorial section, this part will focus on expressions. - - Expressions are normally constructed by accessing fields and calling methods on the generated - expression types of your domain module. For cases where code generation is not applicable generic ways + + Expressions are normally constructed by accessing fields and calling methods on the generated + expression types of your domain module. For cases where code generation is not applicable generic ways to construct expressions can be used instead. - + Complex predicates - To construct complex boolean expressions, use the com.mysema.query.BooleanBuilder class. It + To construct complex boolean expressions, use the com.querydsl.core.BooleanBuilder class. It implements Predicate and can be used in cascaded form: getCustomer(String... names){ - QCustomer customer = QCustomer.customer; - JPAQuery query = new JPAQuery(entityManager).from(customer); +public List getCustomer(String... names) { + QCustomer customer = QCustomer.customer; + JPAQuery query = queryFactory.selectFrom(customer); BooleanBuilder builder = new BooleanBuilder(); - for (String name : names){ + for (String name : names) { builder.or(customer.name.eq(name)); } - query.where(builder); // customer.name eq name1 OR customer.name eq name2 OR ... - return query.list(customer); + query.where(builder); // customer.name eq name1 OR customer.name eq name2 OR ... + return query.fetch(); } ]]> BooleanBuilder is mutable and represents initially null and after each and or or call the result of the operation. - + Dynamic expressions - The com.mysema.query.support.Expressions + The com.querydsl.core.types.dsl.Expressions class is a static factory class for dynamic expression construction. The factory methods are named by the returned type and are mostly self-documenting. - + In general the Expressions class should be used only in cases where fluent DSL forms - can't be used, such as dynamic paths, custom syntax or custom operations. + can't be used, such as dynamic paths, custom syntax or custom operations. - + The following expression @@ -73,20 +73,20 @@ Expressions.predicate(Ops.STARTS_WITH, personFirstName, constant); - + - + Dynamic paths In addition to the Expressions based expression creation Querydsl provides also a more fluent API for dynamic path creation. - For dynamic path generation the com.mysema.query.types.path.PathBuilder class can be used. It extends + For dynamic path generation the com.querydsl.core.types.dsl.PathBuilder class can be used. It extends EntityPathBase and can be used as an alternative to class generation and alias-usage for path generation. - + Compared to the Expressions API PathBuilder doesn't provide direct support for unknown operations or custom syntax, but the syntax is closer to the normal DSL. @@ -129,6 +129,18 @@ entityPath.getMap("map", String.class, String.class).get("key"); entityPath.getMap("map", String.class, String.class, StringPath.class).get("key").lower(); ]]> + For PathBuilder validation a PathBuilderValidator can be used. It can be injected in the constructor + and will be used transitively for the new PathBuilder + + customer = new PathBuilder(Customer.class, "customer", validator); +]]> + + PathBuilderValidator.FIELDS will verify field existence, PathBuilderValidator.PROPERTIES validates + Bean properties and JPAPathBuilderValidator validates using a JPA metamodel. + + + @@ -138,33 +150,33 @@ entityPath.getMap("map", String.class, String.class, StringPath.class).get("key" CaseBuilder class like this: - cases = new CaseBuilder() .when(customer.annualSpending.gt(10000)).then("Premier") .when(customer.annualSpending.gt(5000)).then("Gold") .when(customer.annualSpending.gt(2000)).then("Silver") .otherwise("Bronze"); -// The cases expression can now be used in a projection or condition +// The cases expression can now be used in a projection or condition ]]> For case expressions with equals-operations use the following simpler form instead: - cases = customer.annualSpending .when(10000).then("Premier") .when(5000).then("Gold") .when(2000).then("Silver") .otherwise("Bronze"); -// The cases expression can now be used in a projection or condition +// The cases expression can now be used in a projection or condition ]]> Case expressions are not yet supported in JDOQL. - + Casting expressions @@ -172,9 +184,9 @@ Expression cases = customer.annualSpending To avoid a generic signature in expression types the type hierarchies are flattened. The result is that all generated query types are direct subclasses of - com.mysema.query.types.path.EntityPathBase + com.querydsl.core.types.dsl.EntityPathBase or - com.mysema.query.types.path.BeanPath + com.querydsl.core.types.dsl.BeanPath and cannot be directly cast to their logical supertypes. @@ -186,17 +198,17 @@ Expression cases = customer.annualSpending { +QAccount extends EntityPathBase { // ... } // from BankAccount extends Account -QBankAccount extends EntityPathBase{ +QBankAccount extends EntityPathBase { public final QAccount _super = new QAccount(this); - + // ... -} +} ]]> To cast from a supertype to a subtype you can use the @@ -206,24 +218,24 @@ QBankAccount extends EntityPathBase{ - - + + - + Select literals - - Literals can be selected by refering to them via Constant expressions. Here is a simple example - + + Literals can be selected by referring to them via Constant expressions. Here is a simple example + +query.select(Expressions.constant(1), + Expressions.constant("abc")); +]]> + + Constant expressions are often used in subqueries. - Constant expressions are often used in subqueries. - - + diff --git a/querydsl-docs/src/main/docbook/en-US/content/general/result-handling.xml b/querydsl-docs/src/main/docbook/en-US/content/general/result-handling.xml index 0db418c64c..9b1ffc8b52 100644 --- a/querydsl-docs/src/main/docbook/en-US/content/general/result-handling.xml +++ b/querydsl-docs/src/main/docbook/en-US/content/general/result-handling.xml @@ -1,43 +1,45 @@ Result handling - + Querydsl provides two ways to customize results, FactoryExpressions for row based transformation and ResultTransformer for aggregation. - The com.mysema.query.types.FactoryExpression interface is used for Bean creation, - constructor invocation and for the creation of more complex objects. The functionality of the - FactoryExpression implementations of Querydsl can be accessed via the - com.mysema.query.types.Projections class. - - For the com.mysema.query.ResultTransformer interface GroupBy is the + The com.querydsl.core.types.FactoryExpression interface is used for Bean creation, + constructor invocation and for the creation of more complex objects. The functionality of the + FactoryExpression implementations of Querydsl can be accessed via the + com.querydsl.core.types.Projections class. + + For the com.querydsl.core.ResultTransformer interface GroupBy is the main implementation. - + Returning multiple columns - - Since Querydsl 3.0 the default type for multi-column results is com.mysema.query.Tuple. - Tuple provides provides a typesafe Map like interface to access column data from a Tuple row object. - + + Since Querydsl 3.0 the default type for multi-column results is com.querydsl.core.Tuple. + Tuple provides a typesafe Map like interface to access column data from a Tuple row object. + result = query.from(employee).list(employee.firstName, employee.lastName); +List result = query.select(employee.firstName, employee.lastName) + .from(employee).fetch(); for (Tuple row : result) { System.out.println("firstName " + row.get(employee.firstName)); - System.out.println("lastName " + row.get(employee.lastName)); -}} -]]> + System.out.println("lastName " + row.get(employee.lastName)); +}} +]]> This example could also have been written via the QTuple expression class like this - + result = query.from(employee).list(new QTuple(employee.firstName, employee.lastName)); +List result = query.select(new QTuple(employee.firstName, employee.lastName)) + .from(employee).fetch(); for (Tuple row : result) { System.out.println("firstName " + row.get(employee.firstName)); - System.out.println("lastName " + row.get(employee.lastName)); -}} -]]> - + System.out.println("lastName " + row.get(employee.lastName)); +}} +]]> + @@ -46,30 +48,30 @@ for (Tuple row : result) { In cases where Beans need to be populated based on the results of the query, Bean projections can be used like this - + dtos = query.list( - Projections.bean(UserDTO.class, user.firstName, user.lastName)); +List dtos = query.select( + Projections.bean(UserDTO.class, user.firstName, user.lastName)).fetch(); ]]> When fields should be directly used instead of setters the following variant can be used instead - + dtos = query.list( - Projections.fields(UserDTO.class, user.firstName, user.lastName)); -]]> +List dtos = query.select( + Projections.fields(UserDTO.class, user.firstName, user.lastName)).fetch(); +]]> Constructor usage - + Constructor based row transformation can be used like this - + dtos = query.list( - Projections.bean(UserDTO.class, user.firstName, user.lastName)); +List dtos = query.select( + Projections.constructor(UserDTO.class, user.firstName, user.lastName)).fetch(); ]]> As an alternative to the generic Constructor expression usage constructors @@ -80,7 +82,7 @@ List dtos = query.list( class CustomerDTO { @QueryProjection - public CustomerDTO(long id, String name){ + public CustomerDTO(long id, String name) { ... } @@ -92,7 +94,8 @@ class CustomerDTO { dtos = query.from(customer).list(new QCustomerDTO(customer.id, customer.name)); +List dtos = query.select(new QCustomerDTO(customer.id, customer.name)) + .from(customer).fetch(); ]]> While the example is Hibernate specific, this feature is @@ -100,8 +103,8 @@ List dtos = query.from(customer).list(new QCustomerDTO(customer.id, If the type with the QueryProjection annotation is not an annotated entity - type, you can use the constructor projection like in the example, but if the - annotated type would be an entity type, then the constructor projection would need to be + type, you can use the constructor projection like in the example, but if the + annotated type would be an entity type, then the constructor projection would need to be created via a call to the static create method of the query type: @@ -110,7 +113,7 @@ List dtos = query.from(customer).list(new QCustomerDTO(customer.id, class Customer { @QueryProjection - public Customer(long id, String name){ + public Customer(long id, String name) { ... } @@ -120,7 +123,8 @@ class Customer { dtos = query.from(customer).list(QCustomer.create(customer.id, customer.name)); +List dtos = query.select(QCustomer.create(customer.id, customer.name)) + .from(customer).fetch(); ]]> Alternatively, if code generation is not an option, you can @@ -128,8 +132,9 @@ List dtos = query.from(customer).list(QCustomer.create(customer.id, cu dtos = query.from(customer) - .list(ConstructorExpression.create(Customer.class, customer.id, customer.name)); +List dtos = query + .select(Projections.constructor(Customer.class, customer.id, customer.name)) + .from(customer).fetch(); ]]> @@ -140,7 +145,7 @@ List dtos = query.from(customer) The - com.mysema.query.group.GroupBy + com.querydsl.core.group.GroupBy class provides aggregation functionality which can be used to aggregate query results in memory. Below are some usage examples. @@ -150,8 +155,8 @@ List dtos = query.from(customer) > results = query.from(post, comment) .where(comment.post.id.eq(post.id)) .transform(groupBy(post.id).as(list(comment))); @@ -161,7 +166,7 @@ Map> results = query.from(post, comment) Multiple result columns - results = query.from(post, comment) .where(comment.post.id.eq(post.id)) .transform(groupBy(post.id).as(post.name, set(comment.id))); @@ -177,11 +182,11 @@ Map results = query.from(post, comment) More examples can be found here . - \ No newline at end of file + diff --git a/querydsl-docs/src/main/docbook/en-US/content/intro.xml b/querydsl-docs/src/main/docbook/en-US/content/intro.xml index ae25667e7f..eb3af3d5b1 100644 --- a/querydsl-docs/src/main/docbook/en-US/content/intro.xml +++ b/querydsl-docs/src/main/docbook/en-US/content/intro.xml @@ -1,60 +1,59 @@ - - - - Introduction - - - Background - - - Querydsl was born out of the need to maintain HQL queries in a typesafe way. - Incremental construction of HQL queries requires String concatenation and results - in hard to read code. Unsafe references to domain types and properties - via plain Strings were another issue with String based HQL construction. - - - - With a changing domain model type-safety brings huge benefits in software - development. Domain changes are directly reflected in queries and autocomplete in - query construction makes query construction faster and safer. - - - - HQL for Hibernate was the first target language for Querydsl, but nowadays it - supports JPA, JDO, JDBC, Lucene, Hibernate Search, MongoDB, Collections and RDFBean - as backends. - - - - - - - Principles - - - Type safety - is the core principle of Querydsl. Queries are constructed based on generated query - types that reflect the properties of your domain types. Also function/method - invocations are constructed in a fully type-safe manner. - - - - Consistency - is another important principle. The query paths and operations are the same - in all implementations and also the Query interfaces have a common base interface. - - - - All query instances can be reused multiple times. After the projection the paging data - (limit and offset) and the definition of the projection are removed. - - - - To get an impression of the expressivity of the Querydsl query and expression types go to - the javadocs and explore com.mysema.query.Query, com.mysema.query.Projectable - and com.mysema.query.types.Expression. - - - - - \ No newline at end of file + + + + Introduction + + + Background + + + Querydsl was born out of the need to maintain HQL queries in a typesafe way. + Incremental construction of HQL queries requires String concatenation and results + in hard to read code. Unsafe references to domain types and properties + via plain Strings were another issue with String based HQL construction. + + + + With a changing domain model type-safety brings huge benefits in software + development. Domain changes are directly reflected in queries and autocomplete in + query construction makes query construction faster and safer. + + + + HQL for Hibernate was the first target language for Querydsl, but nowadays it + supports JPA, JDO, JDBC, Lucene, Hibernate Search, MongoDB, Collections and RDFBean + as backends. + + + + If you are completely new to database access in Java,https://www.marcobehler.com/guides/a-guide-to-accessing-databases-in-java contains a good overview of the various parts, pieces and options and shows you where exactly QueryDSL fits in. + + + + + + + Principles + + + Type safety + is the core principle of Querydsl. Queries are constructed based on generated query + types that reflect the properties of your domain types. Also function/method + invocations are constructed in a fully type-safe manner. + + + + Consistency + is another important principle. The query paths and operations are the same + in all implementations and also the Query interfaces have a common base interface. + + + + To get an impression of the expressivity of the Querydsl query and expression types go to + the javadocs and explore com.querydsl.core.Query, com.querydsl.core.Fetchable + and com.querydsl.core.types.Expression. + + + + + diff --git a/querydsl-docs/src/main/docbook/en-US/content/preface.xml b/querydsl-docs/src/main/docbook/en-US/content/preface.xml index 4bf454c3a9..593af57ff5 100644 --- a/querydsl-docs/src/main/docbook/en-US/content/preface.xml +++ b/querydsl-docs/src/main/docbook/en-US/content/preface.xml @@ -1,33 +1,33 @@ - - - - Preface - - - Querydsl is a framework which enables the construction of statically - typed SQL-like queries. Instead of writing queries as inline strings or externalizing them - into XML files they can be constructed via a fluent API like Querydsl. - - - - The benefits of using a fluent API in comparison to simple strings are for example - - - - - code completion in IDE - - - almost none syntactically invalid queries allowed - - - domain types and properties can be referenced safely - - - adopts better to refactoring changes in domain types - - - - - - + + + + Preface + + + Querydsl is a framework which enables the construction of statically + typed SQL-like queries. Instead of writing queries as inline strings or externalizing them + into XML files they can be constructed via a fluent API like Querydsl. + + + + The benefits of using a fluent API in comparison to simple strings are for example + + + + + code completion in IDE + + + almost none syntactically invalid queries allowed + + + domain types and properties can be referenced safely + + + adopts better to refactoring changes in domain types + + + + + + diff --git a/querydsl-docs/src/main/docbook/en-US/content/troubleshooting.xml b/querydsl-docs/src/main/docbook/en-US/content/troubleshooting.xml index 4e6b328c31..22d719db9d 100644 --- a/querydsl-docs/src/main/docbook/en-US/content/troubleshooting.xml +++ b/querydsl-docs/src/main/docbook/en-US/content/troubleshooting.xml @@ -1,106 +1,74 @@ - - - - Troubleshooting - - - Insufficient type arguments - - - Querydsl needs properly encoded List Set, Collection and Map properties in all code generation - scenarios. - - - When using improperly encoded fields or getters you might the following - stacktrace: - - (APTTypeModel.java:55) - at com.mysema.query.apt.APTTypeModel.get(APTTypeModel.java:48) - at com.mysema.query.apt.Processor$2.visitType(Processor.java:114) - ... 35 more -]]> - - - Examples of problematic field declarations and their corrections: - - - names; // RIGHT - - private Map employeesByName; // WRONG - - private Map employeesByName; // RIGHT -]]> - - - - - - - Multithreaded initialization of Querydsl Q-types - - When Querydsl Q-types are initialized from multiple threads, deadlocks can - occur, if the Q-types have circular dependencies. - - An easy to use solution is to initialize the classes in a single thread before - they are used in different threads. - - The com.mysema.util.ClassPathUtils class can be used for that like this: - - - - Replace packageToLoad with the package of the classes you want to initialize. - - - - - - - JDK5 usage - - - When compiling your project with JDK 5, you might get the following compilation failure: - - - - - - The class file version 50.0 is used by Java 6.0, and 49.0 is used by Java 5.0. - - - - Querydsl is tested against JDK 6.0 only, as we use APT extensively, which is available only - since JDK 6.0. - - - - If you want to use it with JDK 5.0 you might want to try to compile Querydsl yourself. - - - - - - + + + + Troubleshooting + + + Insufficient type arguments + + + Querydsl needs properly encoded List Set, Collection and Map properties in all code generation + scenarios. + + + When using improperly encoded fields or getters you might the following + stacktrace: + + (APTTypeModel.java:55) + at com.querydsl.apt.APTTypeModel.get(APTTypeModel.java:48) + at com.querydsl.apt.Processor$2.visitType(Processor.java:114) + ... 35 more +]]> + + + Examples of problematic field declarations and their corrections: + + + names; // RIGHT + + private Map employeesByName; // WRONG + + private Map employeesByName; // RIGHT +]]> + + + + + + + Multithreaded initialization of Querydsl Q-types + + When Querydsl Q-types are initialized from multiple threads, deadlocks can + occur, if the Q-types have circular dependencies. + + An easy to use solution is to initialize the classes in a single thread before + they are used in different threads. + + The com.querydsl.codegen.ClassPathUtils class can be used for that like this: + + + + Replace packageToLoad with the package of the classes you want to initialize. + + + + + + diff --git a/querydsl-docs/src/main/docbook/en-US/content/tutorials.xml b/querydsl-docs/src/main/docbook/en-US/content/tutorials.xml index d033996654..13b7bfbd2e 100644 --- a/querydsl-docs/src/main/docbook/en-US/content/tutorials.xml +++ b/querydsl-docs/src/main/docbook/en-US/content/tutorials.xml @@ -1,22 +1,22 @@ - - - - Tutorials - - - Instead of a general Getting started guide we provide integration - guides for the main backends of Querydsl. - - - - - - - - - - - - - - \ No newline at end of file + + + + Tutorials + + + Instead of a general Getting started guide we provide integration + guides for the main backends of Querydsl. + + + + + + + + + + + + + + \ No newline at end of file diff --git a/querydsl-docs/src/main/docbook/en-US/content/tutorials/collections.xml b/querydsl-docs/src/main/docbook/en-US/content/tutorials/collections.xml index 500b2d4056..669880cbe1 100644 --- a/querydsl-docs/src/main/docbook/en-US/content/tutorials/collections.xml +++ b/querydsl-docs/src/main/docbook/en-US/content/tutorials/collections.xml @@ -1,282 +1,276 @@ - - - - - Querying Collections - - The querydsl-collections module can be used with generated query types and - without. - The first section describes the usage without generated query types: - - - - Usage without generated query types - - - To use querydsl-collections without generated query types you need to - use the - Querydsl alias feature. Here are some examples. - - - - To get started, add the following static imports: - - - - - - And now create an alias instance for the Cat class. Alias instances can only be - created for non-final classes with an empty constructor. Make sure your class has one. - - - - The alias instance of type Cat and its getter invocations are - transformed into paths by wrapping them into dollar method invocations. - The call - c.getKittens() - for example is internally - transformed into the property path c.kittens inside the - dollar method. - - - - - - The following example is a variation of the previous, where the access - to the - list size happens inside the dollar-method invocation. - - - - - - All non-primitive and non-final typed properties of aliases are aliases - themselves. So you may cascade method calls until you hit a - primitive or non-final type (e.g. java.lang.String) in the dollar-method scope. - - - - e.g. - - - - - - is transformed into - c.mate.name - internally, but - - - - - - is not transformed properly, since the toLowerCase() invocation is not tracked. - - - Note also that you may only invoke getters, size(), contains(Object) and - get(int) on alias types. All other invocations throw exceptions. - - - - - - - Usage with generated query types - - - The example above can be expressed like this with generated expression types - - - - - When you use generated query types, you instantiate expressions instead of alias - instances - and use the property paths directly without any dollar-method wrapping. - - - - - - - Maven integration - - - Add the following dependencies to your Maven project: - - - - com.mysema.querydsl - querydsl-apt - ${querydsl.version} - provided - - - - com.mysema.querydsl - querydsl-collections - ${querydsl.version} - - - - org.slf4j - slf4j-log4j12 - 1.6.1 - -]]> - - - - If you are not using JPA or JDO you can generate expression types for your - domain types by - annotating them with the - com.mysema.query.annotations.QueryEntity - annotation and adding the - following plugin configuration into your Maven configuration (pom.xml): - - - - - - ... - - com.mysema.maven - apt-maven-plugin - 1.0.9 - - - - process - - - target/generated-sources/java - com.mysema.query.apt.QuerydslAnnotationProcessor - - - - - ... - - - -]]> - - - - - - Ant integration - - Place the jar files from the full-deps bundle on your classpath and use the - following tasks for Querydsl code generation: - - - - - - - - - - - - - - - - -]]> - - - Replace - src - with your main source folder, - generated - with your folder for generated sources and - build - with your target folder. - - - - - - - Hamcrest matchers - - Querydsl Collections provides Hamcrest matchers. With these imports - - - - they can be used like this: - - - - - The Hamcrest matchers have been contributed by - Jeroen van Schagen - . - - - - - - - Usage with the Eclipse Compiler for Java - - If Querydsl Collections is used with a JRE where the system compiler is not available, - CollQuery instances can also be configured to use the Eclipse Compiler for Java (ECJ) instead: - - - - - + + + + + Querying Collections + + The querydsl-collections module can be used with generated query types and + without. + The first section describes the usage without generated query types: + + + + Usage without generated query types + + + To use querydsl-collections without generated query types you need to + use the + Querydsl alias feature. Here are some examples. + + + + To get started, add the following static imports: + + + + + + And now create an alias instance for the Cat class. Alias instances can only be + created for non-final classes with an empty constructor. Make sure your class has one. + + + + The alias instance of type Cat and its getter invocations are + transformed into paths by wrapping them into dollar method invocations. + The call + c.getKittens() + for example is internally + transformed into the property path c.kittens inside the + dollar method. + + + + + + The following example is a variation of the previous, where the access + to the + list size happens inside the dollar-method invocation. + + + + + + All non-primitive and non-final typed properties of aliases are aliases + themselves. So you may cascade method calls until you hit a + primitive or non-final type (e.g. java.lang.String) in the dollar-method scope. + + + + e.g. + + + + + + is transformed into + c.mate.name + internally, but + + + + + + is not transformed properly, since the toLowerCase() invocation is not tracked. + + + Note also that you may only invoke getters, size(), contains(Object) and + get(int) on alias types. All other invocations throw exceptions. + + + + + + + Usage with generated query types + + + The example above can be expressed like this with generated expression types + + + + + When you use generated query types, you instantiate expressions instead of alias + instances + and use the property paths directly without any dollar-method wrapping. + + + + + + + Maven integration + + + Add the following dependencies to your Maven project: + + + + com.querydsl + querydsl-apt + ${querydsl.version} + provided + + + + com.querydsl + querydsl-collections + ${querydsl.version} + +]]> + + + + If you are not using JPA or JDO you can generate expression types for your + domain types by + annotating them with the + com.querydsl.core.annotations.QueryEntity + annotation and adding the + following plugin configuration into your Maven configuration (pom.xml): + + + + + + ... + + com.mysema.maven + apt-maven-plugin + 1.1.3 + + + + process + + + target/generated-sources/java + com.querydsl.apt.QuerydslAnnotationProcessor + + + + + ... + + + +]]> + + + + + + Ant integration + + Place the jar files from the full-deps bundle on your classpath and use the + following tasks for Querydsl code generation: + + + + + + + + + + + + + + + + +]]> + + + Replace + src + with your main source folder, + generated + with your folder for generated sources and + build + with your target folder. + + + + + + + Hamcrest matchers + + Querydsl Collections provides Hamcrest matchers. With these imports + + + + they can be used like this: + + + + + The Hamcrest matchers have been contributed by + Jeroen van Schagen + . + + + + + + + Usage with the Eclipse Compiler for Java + + If Querydsl Collections is used with a JRE where the system compiler is not available, + CollQuery instances can also be configured to use the Eclipse Compiler for Java (ECJ) instead: + + + + + \ No newline at end of file diff --git a/querydsl-docs/src/main/docbook/en-US/content/tutorials/hibernate-search.xml b/querydsl-docs/src/main/docbook/en-US/content/tutorials/hibernate-search.xml index 0668d6f02b..9e2cb18a89 100644 --- a/querydsl-docs/src/main/docbook/en-US/content/tutorials/hibernate-search.xml +++ b/querydsl-docs/src/main/docbook/en-US/content/tutorials/hibernate-search.xml @@ -25,8 +25,8 @@ QUser user = QUser.user; SearchQuery query = new SearchQuery(session, user); List list = query - .where(user.firstName.eq("Bob")) - .list(); + .where(user.firstName.eq("Bob")) + .fetch(); ]]> diff --git a/querydsl-docs/src/main/docbook/en-US/content/tutorials/jdo.xml b/querydsl-docs/src/main/docbook/en-US/content/tutorials/jdo.xml index 4534b82b28..3f54a7c3b6 100644 --- a/querydsl-docs/src/main/docbook/en-US/content/tutorials/jdo.xml +++ b/querydsl-docs/src/main/docbook/en-US/content/tutorials/jdo.xml @@ -1,510 +1,526 @@ - - - - Querying JDO - - - Querydsl defines a general statically typed syntax for querying on top of - persisted domain model data. JDO and JPA are the primary integration - technologies for - Querydsl. This guide describes how to use Querydsl - in combination with JDO. - - - - Maven integration - - - Add the following dependencies to your Maven project: - - - - com.mysema.querydsl - querydsl-apt - ${querydsl.version} - provided - - - - com.mysema.querydsl - querydsl-jdo - ${querydsl.version} - - - - org.slf4j - slf4j-log4j12 - 1.6.1 - -]]> - - - And now, configure the Maven APT plugin which generates the query types - used by - Querydsl: - - - - - - ... - - com.mysema.maven - apt-maven-plugin - 1.0.9 - - - - process - - - target/generated-sources/java - com.mysema.query.apt.jdo.JDOAnnotationProcessor - - - - - ... - - - -]]> - - - The JDOAnnotationProcessor finds domain types annotated with the - javax.jdo.annotations.PersistenceCapable annotation and generates - query types for them. - - - - Run clean install and you will get your query types generated into - target/generated-sources/java. - - - - If you use Eclipse, run mvn eclipse:eclipse to update your Eclipse project to - include target/generated-sources/java as a source folder. - - - - Now you are able to construct JDO query instances and instances of the query domain model. - - - - - - - Ant integration - - Place the jar files from the full-deps bundle on your classpath and use the - following tasks for Querydsl code generation: - - - - - - - - - - - - - - - - -]]> - - - Replace - src - with your main source folder, - generated - with your folder for generated sources - and - build - with your target folder. - - - - - - - Using query types - - - To create queries with Querydsl you need to instantiate variables and Query - implementations. We will start with the variables. - - - - Let's assume that your project has the following domain type: - - - - - - Querydsl will generate a query type with the simple name QCustomer into the - same package as Customer. QCustomer can be used as a statically - typed variable in Querydsl as a representative for the - Customer type. - - - - QCustomer has a default instance variable which can be accessed as a static - field: - - - - - - Alternatively you can define your own Customer variables like this: - - - - - - QCustomer reflects all the properties of the original type Customer as public - fields. The firstName field can be accessed like this - - - - - - - - - Querying with JDO - - - For the JDO-module JDOQuery is the main Query implementation. It - is instantiated like this: - - - - - - To retrieve the customer with the first name Bob you would construct a - query like this: - - - - - - The from call defines the query source, the where part defines the - filter and uniqueResult defines the projection and tells Querydsl - to return a single element. Easy, right? - - - - To create a query with multiple sources you just use the JDOQuery class like this: - - - - - - And to use multiple filters use it like this - - - - - Or like this - - - - If you want to combine the filters via "or" then use the following pattern - - - - - - - - - General usage - - Use the the cascading methods of the JDOQuery class like this - - - from: - Add query sources here, the first argument becomes the main source - and the others are treated as variables. - - - - where: - Add query filters, either in varargs form separated via commas or - cascaded via the and-operator. - - - - groupBy: - Add group by arguments in varargs form. - - - - having: - Add having filters of the "group by" grouping as an varargs array of - Predicate expressions. - - - - orderBy: - Add ordering of the result as an varargs array of order expressions. - Use asc() and desc() on numeric, string and other comparable expression to access the - OrderSpecifier instances. - - - - limit, offset, restrict: - Set the paging of the result. Limit for max results, - offset for skipping rows and restrict for defining both in one call. - - - - - - - Ordering - - The syntax for declaring ordering is - - - - - - - - Grouping - - Grouping can be done in the following form - - - - - - - - Delete clauses - Delete clauses in Querydsl JDO follow a simple delete-where-execute form. Here - are some examples: - - - - - The second parameter of the JDODeleteClause constructor is the entity to be - deleted. The where call is optional and the execute call performs the deletion and - returns the amount of deleted entities. - - - - - - - Subqueries - - To create a subquery you create a JDOSubQuery instance, add the query parameters - via from, where etc and use unique or list to create a subquery, which is just a type-safe - expression for the query. unique is used for a unique result and list for a list result. - - - - - represents the following native JDO query - - -SELECT this FROM com.mysema.query.jdoql.models.company.Department -WHERE this.employees.size() == -(SELECT max(d.employees.size()) FROM com.mysema.query.jdoql.models.company.Department d) - - - Another example - - - - which represents the following native JDO query - - -SELECT this FROM com.mysema.query.jdoql.models.company.Employee -WHERE this.weeklyhours > -(SELECT avg(e.weeklyhours) FROM this.department.employees e WHERE e.manager == this.manager) - - - - - - - Using Native SQL - - Querydsl supports Native SQL in JDO via the JDOSQLQuery class. - - To use it, you must generate Querydsl query types for your SQL schema. This can - be done for example with the following Maven configuration: - - - - com.mysema.querydsl - querydsl-maven-plugin - ${project.version} - - - - export - - - - - org.apache.derby.jdbc.EmbeddedDriver - jdbc:derby:target/demoDB;create=true - com.mycompany.mydomain - ${project.basedir}/target/generated-sources/java - - - - org.apache.derby - derby - ${derby.version} - - - -]]> - - When the query types have successfully been generated into the location of your - choice, you can use them in your queries. - - - Single column query: - - names = query.from(cat).list(cat.name); -]]> - - Query multiple columns: - - rows = query.from(cat).list(cat.id, cat.name); -]]> - - Query all columns: - - rows = query.from(cat).list(cat.all()); - ]]> - - Query with joins: - - - - Query and project into DTO: - - catDTOs = query.from(cat) - .orderBy(cat.name.asc()) - .list(ConstructorExpression.create(CatDTO.class, cat.id, cat.name)); -]]> - - - + + + + Querying JDO + + + Querydsl defines a general statically typed syntax for querying on top of + persisted domain model data. JDO and JPA are the primary integration + technologies for + Querydsl. This guide describes how to use Querydsl + in combination with JDO. + + + + Maven integration + + + Add the following dependencies to your Maven project: + + + + com.querydsl + querydsl-apt + ${querydsl.version} + provided + + + + com.querydsl + querydsl-jdo + ${querydsl.version} + +]]> + + + And now, configure the Maven APT plugin which generates the query types + used by + Querydsl: + + + + + + ... + + com.mysema.maven + apt-maven-plugin + 1.1.3 + + + + process + + + target/generated-sources/java + com.querydsl.apt.jdo.JDOAnnotationProcessor + + + + + ... + + + +]]> + + + The JDOAnnotationProcessor finds domain types annotated with the + javax.jdo.annotations.PersistenceCapable annotation and generates + query types for them. + + + + Run clean install and you will get your query types generated into + target/generated-sources/java. + + + + If you use Eclipse, run mvn eclipse:eclipse to update your Eclipse project to + include target/generated-sources/java as a source folder. + + + + Now you are able to construct JDO query instances and instances of the query domain model. + + + + + + + Ant integration + + Place the jar files from the full-deps bundle on your classpath and use the + following tasks for Querydsl code generation: + + + + + + + + + + + + + + + + +]]> + + + Replace + src + with your main source folder, + generated + with your folder for generated sources + and + build + with your target folder. + + + + + + + Using query types + + + To create queries with Querydsl you need to instantiate variables and Query + implementations. We will start with the variables. + + + + Let's assume that your project has the following domain type: + + + + + + Querydsl will generate a query type with the simple name QCustomer into the + same package as Customer. QCustomer can be used as a statically + typed variable in Querydsl as a representative for the + Customer type. + + + + QCustomer has a default instance variable which can be accessed as a static + field: + + + + + + Alternatively you can define your own Customer variables like this: + + + + + + QCustomer reflects all the properties of the original type Customer as public + fields. The firstName field can be accessed like this + + + + + + + + + Querying with JDO + + + For the JDO-module JDOQuery is the main Query implementation. It + is instantiated like this: + + + query = new JDOQuery(pm); +]]> + + For the examples of this chapter the queries are created via a JDOQueryFactory instance. + JDOQueryFactory should be the preferred option to obtain JDOQuery instances. + + + To retrieve the customer with the first name Bob you would construct a + query like this: + + + + + + The selectFrom call defines the query source and projection, the where part defines the + filter and fetchOne tells Querydsl to return a single element. Easy, right? + + + Alternatively you can express it also like this + + + + + To create a query with multiple sources you just use the JDOQuery class like this: + + + + + + And to use multiple filters use it like this + + + + + Or like this + + + + If you want to combine the filters via "or" then use the following pattern + + + + + + + + + General usage + + Use the the cascading methods of the JDOQuery class like this + + + select: + Set the projection of the query. (Not necessary if created via query factory) + + + + from: + Add query sources here, the first argument becomes the main source + and the others are treated as variables. + + + + where: + Add query filters, either in varargs form separated via commas or + cascaded via the and-operator. + + + + groupBy: + Add group by arguments in varargs form. + + + + having: + Add having filters of the "group by" grouping as an varargs array of + Predicate expressions. + + + + orderBy: + Add ordering of the result as an varargs array of order expressions. + Use asc() and desc() on numeric, string and other comparable expression to access the + OrderSpecifier instances. + + + + limit, offset, restrict: + Set the paging of the result. Limit for max results, + offset for skipping rows and restrict for defining both in one call. + + + + + + + Ordering + + The syntax for declaring ordering is + + + + + + + + Grouping + + Grouping can be done in the following form + + + + + + + + Delete clauses + + Delete clauses in Querydsl JDO follow a simple delete-where-execute form. Here + are some examples: + + + + + The second parameter of the JDODeleteClause constructor is the entity to be + deleted. The where call is optional and the execute call performs the deletion and + returns the amount of deleted entities. + + + + + + + Subqueries + + To create a subquery you can use one of the factory methods of JDOExpressions + and add the query parameters via from, where etc. + + + + + represents the following native JDO query + + +SELECT this FROM com.querydsl.jdo.models.company.Department +WHERE this.size == +(SELECT max(d.size) FROM com.querydsl.jdo.models.company.Department d) + + + Another example + + + + which represents the following native JDO query + + +SELECT this FROM com.querydsl.jdo.models.company.Employee +WHERE this.weeklyhours > +(SELECT avg(e.weeklyhours) FROM this.department.employees e WHERE e.manager == this.manager) + + + + + + + Using Native SQL + + Querydsl supports Native SQL in JDO via the JDOSQLQuery class. + + To use it, you must generate Querydsl query types for your SQL schema. This can + be done for example with the following Maven configuration: + + + + + + ... + + com.querydsl + querydsl-maven-plugin + ${querydsl.version} + + + + export + + + + + org.apache.derby.jdbc.EmbeddedDriver + jdbc:derby:target/demoDB;create=true + com.mycompany.mydomain + ${project.basedir}/target/generated-sources/java + + + + org.apache.derby + derby + ${derby.version} + + + + ... + + + +]]> + + When the query types have successfully been generated into the location of your + choice, you can use them in your queries. + + + Single column query: + + query = new JDOSQLQuery(pm, templates); +List names = query.select(cat.name).from(cat).fetch(); +]]> + + Query multiple columns: + + (pm, templates); +List rows = query.select(cat.id, cat.name).from(cat).fetch(); +]]> + + Query all columns: + + rows = query.select(cat.all()).from(cat).fetch(); + ]]> + + Query with joins: + + (pm, templates); +cats = query.select(catEntity).from(cat) + .innerJoin(mate).on(cat.mateId.eq(mate.id)) + .where(cat.dtype.eq("Cat"), mate.dtype.eq("Cat")) + .fetch(); +]]> + + Query and project into DTO: + + (pm, templates); +List catDTOs = query.select(Projections.constructor(CatDTO.class, cat.id, cat.name)) + .from(cat) + .orderBy(cat.name.asc()) + .fetch(); +]]> + + + \ No newline at end of file diff --git a/querydsl-docs/src/main/docbook/en-US/content/tutorials/jpa.xml b/querydsl-docs/src/main/docbook/en-US/content/tutorials/jpa.xml index 5a07af0a02..8a7653439e 100644 --- a/querydsl-docs/src/main/docbook/en-US/content/tutorials/jpa.xml +++ b/querydsl-docs/src/main/docbook/en-US/content/tutorials/jpa.xml @@ -1,715 +1,708 @@ - - - - - Querying JPA - - - Querydsl defines a general statically typed syntax for querying on top of - persisted domain model data. JDO and JPA are the primary integration - technologies for Querydsl. This guide describes how to use Querydsl - in combination with JPA. - - - - Querydsl for JPA is an alternative to both JPQL and Criteria queries. It combines the - dynamic nature of Criteria queries with the expressiveness of JPQL and all that in a fully - typesafe manner. - - - - Maven integration - - - Add the following dependencies to your Maven project: - - - - com.mysema.querydsl - querydsl-apt - ${querydsl.version} - provided - - - - com.mysema.querydsl - querydsl-jpa - ${querydsl.version} - - - - org.slf4j - slf4j-log4j12 - 1.6.1 - -]]> - - - And now, configure the Maven APT plugin: - - - - - - ... - - com.mysema.maven - apt-maven-plugin - 1.0.9 - - - - process - - - target/generated-sources/java - com.mysema.query.apt.jpa.JPAAnnotationProcessor - - - - - ... - - - -]]> - - - The JPAAnnotationProcessor finds domain types annotated with the - javax.persistence.Entity annotation and generates query types for them. - - - - If you use Hibernate annotations in your domain types you should use - the APT processor - com.mysema.query.apt.hibernate.HibernateAnnotationProcessor - instead. - - - - Run clean install and you will get your Query types generated into - target/generated-sources/java. - - - - If you use Eclipse, run mvn eclipse:eclipse to update your Eclipse project to - include target/generated-sources/java as a source folder. - - - - Now you are able to construct JPA query instances and instances of - the query domain model. - - - - - - - Ant integration - - Place the jar files from the full-deps bundle on your classpath and use the - following tasks for Querydsl code generation: - - - - - - - - - - - - - - - - -]]> - - - Replace - src - with your main source folder, - generated - with your folder for generated sources - and - build - with your target folder. - - - - - - - Using Querydsl JPA in Roo - - - If you are using Querydsl JPA with Spring Roo you can replace - com.mysema.query.apt.jpa.JPAAnnotationProcessor - with - com.mysema.query.apt.roo.RooAnnotationProcessor - which will handle - @RooJpaEntity and @RooJpaActiveRecord - annotated classes instead of - @Entity - annotated classes. - - - - APT based code generation doesn't work well with AspectJ IDTs. - - - - - - - Generating the model from hbm.xml files - - If you are using Hibernate with an XML based configuration, you can use the XML - metadata to create your Querydsl model. - - - com.mysema.query.jpa.codegen.HibernateDomainExporter provides the - functionality for this: - - - - The HibernateDomainExporter needs to be executed within a classpath where the - domain types are visible, since the property types are resolved - via reflection. - - - All JPA annotations are ignored, but Querydsl annotations such as @QueryInit and - @QueryType are taken into account. - - - - - - - Using query types - - - To create queries with Querydsl you need to instantiate variables and - Query implementations. We will start with the variables. - - - - Let's assume that your project has the following domain type: - - - - - - Querydsl will generate a query type with the simple name QCustomer into the - same package as Customer. QCustomer can be used as a statically - typed variable in Querydsl queries as a representative for the - Customer type. - - - - QCustomer has a default instance variable which can be accessed as a static - field: - - - - - - Alternatively you can define your own Customer variables like this: - - - - - - - - - Querying - - The Querydsl JPA module supports both the JPA and the Hibernate API. - - - To use the JPA API you use JPAQuery instances for your queries like - this: - - - - - If you are using the Hibernate API instead, you can instantiate a - HibernateQuery like this: - - - - - - Both JPAQuery and HibernateQuery implement the JPQLQuery interface. - - - To retrieve the customer with the first name Bob you would construct a - query like this: - - - - - - The from call defines the query source, the where part defines the - filter and uniqueResult defines the projection and tells Querydsl - to return a single element. Easy, right? - - - - To create a query with multiple sources you use the query like this: - - - - - - And to use multiple filters use it like this - - - - - Or like this - - - - In native JPQL form the query would be written like this: - - -from Customer as customer - where customer.firstName = "Bob" and customer.lastName = "Wilson" - - - If you want to combine the filters via "or" then use the following pattern - - - - - - - - - Using joins - - Querydsl supports the following join variants in JPQL: inner join, join, left - join and full join. Join usage is typesafe, and follows the following pattern: - - - - - The native JPQL version of the query would be - - -from Cat as cat - inner join cat.mate as mate - left outer join cat.kittens as kitten - - - Another example - - - - With the following JPQL version - - -from Cat as cat - left join cat.kittens as kitten - on kitten.bodyWeight > 10.0 - - - - - - - General usage - - Use the the cascading methods of the JPQLQuery interface like this - - - from: - Add the query sources here. - - - - innerJoin, join, leftJoin, fullJoin, on: - Add join elements using these constructs. - For the join methods the first argument is the join source and the second the target - (alias). - - - - where: - Add query filters, either in varargs form separated via commas or - cascaded via the and-operator. - - - - groupBy: - Add group by arguments in varargs form. - - - - having: - Add having filters of the "group by" grouping as an varags array of - Predicate expressions. - - - - orderBy: - Add ordering of the result as an varargs array of order expressions. - Use asc() and desc() on numeric, string and other comparable expression to access the - OrderSpecifier instances. - - - - limit, offset, restrict: - Set the paging of the result. Limit for max results, - offset for skipping rows and restrict for defining both in one call. - - - - - - - Ordering - - The syntax for declaring ordering is - - - - which is equivalent to the following native JPQL - - -from Customer as customer - order by customer.lastName asc, customer.firstName desc - - - - - - - Grouping - - Grouping can be done in the following form - - - - which is equivalent to the following native JPQL - - -select customer.lastName - from Customer as customer - group by customer.lastName - - - - - - - Delete clauses - Delete clauses in Querydsl JPA follow a simple delete-where-execute form. Here - are some - examples: - - - - - The second parameter of the JPADeleteClause constructor is the entity to - be deleted. - The where call is optional and the execute call performs the deletion and returns the - amount of - deleted entities. - - - For Hibernate based Delete usage, use the HibernateDeleteClause instead. - - DML clauses in JPA don't take JPA level cascade rules into account and don't provide - finegrained second level cache interaction. - - - - Update clauses - - Update clauses in Querydsl JPA follow a simple update-set/where-execute form. - Here are some examples: - - - - - The second parameter of the JPAUpdateClause constructor is the entity to - be updated. - The set invocations define the property updates in SQL-Update-style and the execute call - performs - the Update and returns the amount of updated entities. - - - For Hibernate based Update usage, use the HibernateUpdateClause instead. - - DML clauses in JPA don't take JPA level cascade rules into account and don't provide - finegrained second level cache interaction. - - - - - - Subqueries - - To create a subquery you create a JPASubQuery instance, define the query - parameters - via from, where etc and use - unique or list to create a subquery, which is just a type-safe Querydsl expression for the - query. - unique is used for a unique (single) result and list for a list result. - - - - - Another example - - - - For Hibernate based sub query usage, use the HibernateSubQuery instead. - - - - - Exposing the original query - - If you need to tune the original Query before the execution of the query you - can expose it like this: - - - - - - - - Using Native SQL in JPA queries - - Querydsl supports Native SQL in JPA via the JPASQLQuery class. - - - To use it, you must generate Querydsl query types for your SQL schema. This can - be done for example with the following Maven configuration: - - - - com.mysema.querydsl - querydsl-maven-plugin - ${project.version} - - - - export - - - - - org.apache.derby.jdbc.EmbeddedDriver - jdbc:derby:target/demoDB;create=true - com.mycompany.mydomain - ${project.basedir}/target/generated-sources/java - - - - org.apache.derby - derby - ${derby.version} - - - -]]> - - When the query types have successfully been generated into the location of your - choice, you can use them in your queries. - - - Single column query: - - names = query.from(cat).list(cat.name); -]]> - - If you mix entity (e.g. QCat) and table (e.g. SAnimal) references in your query you need to make sure that they - use the same variable names. SAnimal.animal has the variable name "animal", so a new instance - (new SAnimal("cat")) was used instead. - - An alternative pattern could be - - - - Query multiple columns: - - rows = query.from(cat).list(cat.id, cat.name); -]]> - - Query all columns: - - rows = query.from(cat).list(cat.all()); - ]]> - - Query in SQL, but project as entity: - - cats = query.from(cat).orderBy(cat.name.asc()).list(catEntity); -]]> - - Query with joins: - - - - Query and project into DTO: - - catDTOs = query.from(cat) - .orderBy(cat.name.asc()) - .list(ConstructorExpression.create(CatDTO.class, cat.id, cat.name)); -]]> - - If you are using the Hibernate API instead of the JPA API, then use - HibernateSQLQuery instead. - - - - - + + + + + Querying JPA + + + Querydsl defines a general statically typed syntax for querying on top of + persisted domain model data. JDO and JPA are the primary integration + technologies for Querydsl. This guide describes how to use Querydsl + in combination with JPA. + + + + Querydsl for JPA is an alternative to both JPQL and Criteria queries. It combines the + dynamic nature of Criteria queries with the expressiveness of JPQL and all that in a fully + typesafe manner. + + + + Maven integration + + + Add the following dependencies to your Maven project: + + + + com.querydsl + querydsl-apt + ${querydsl.version} + provided + + + + com.querydsl + querydsl-jpa + ${querydsl.version} + +]]> + + + And now, configure the Maven APT plugin: + + + + + + ... + + com.mysema.maven + apt-maven-plugin + 1.1.3 + + + + process + + + target/generated-sources/java + com.querydsl.apt.jpa.JPAAnnotationProcessor + + + + + ... + + + +]]> + + + The JPAAnnotationProcessor finds domain types annotated with the + javax.persistence.Entity annotation and generates query types for them. + + + + If you use Hibernate annotations in your domain types you should use + the APT processor + com.querydsl.apt.hibernate.HibernateAnnotationProcessor + instead. + + + + Run clean install and you will get your Query types generated into + target/generated-sources/java. + + + + If you use Eclipse, run mvn eclipse:eclipse to update your Eclipse project to + include target/generated-sources/java as a source folder. + + + + Now you are able to construct JPA query instances and instances of + the query domain model. + + + + + + + Ant integration + + Place the jar files from the full-deps bundle on your classpath and use the + following tasks for Querydsl code generation: + + + + + + + + + + + + + + + + +]]> + + + Replace + src + with your main source folder, + generated + with your folder for generated sources + and + build + with your target folder. + + + + + + + Using Querydsl JPA in Roo + + + If you are using Querydsl JPA with Spring Roo you can replace + com.querydsl.apt.jpa.JPAAnnotationProcessor + with + com.querydsl.apt.roo.RooAnnotationProcessor + which will handle + @RooJpaEntity and @RooJpaActiveRecord + annotated classes instead of + @Entity + annotated classes. + + + + APT based code generation doesn't work well with AspectJ IDTs. + + + + + + + Generating the model from hbm.xml files + + If you are using Hibernate with an XML based configuration, you can use the XML + metadata to create your Querydsl model. + + + com.querydsl.jpa.codegen.HibernateDomainExporter provides the + functionality for this: + + + + The HibernateDomainExporter needs to be executed within a classpath where the + domain types are visible, since the property types are resolved + via reflection. + + + All JPA annotations are ignored, but Querydsl annotations such as @QueryInit and + @QueryType are taken into account. + + + + + + + Using query types + + + To create queries with Querydsl you need to instantiate variables and + Query implementations. We will start with the variables. + + + + Let's assume that your project has the following domain type: + + + + + + Querydsl will generate a query type with the simple name QCustomer into the + same package as Customer. QCustomer can be used as a statically + typed variable in Querydsl queries as a representative for the + Customer type. + + + + QCustomer has a default instance variable which can be accessed as a static + field: + + + + + + Alternatively you can define your own Customer variables like this: + + + + + + + + + Querying + + The Querydsl JPA module supports both the JPA and the Hibernate API. + + + To use the JPA API you use JPAQuery instances for your queries like + this: + + + query = new JPAQuery(entityManager); +]]> + + If you are using the Hibernate API instead, you can instantiate a + HibernateQuery like this: + + + query = new HibernateQuery(session); +]]> + + Both JPAQuery and HibernateQuery implement the JPQLQuery interface. + + For the examples of this chapter the queries are created via a JPAQueryFactory instance. + JPAQueryFactory should be the preferred option to obtain JPAQuery instances. + + For the Hibernate API HibernateQueryFactory can be used + + + To retrieve the customer with the first name Bob you would construct a + query like this: + + + + + + The selectFrom call defines the query source and projection, the where part defines the + filter and fetchOne tells Querydsl to return a single element. Easy, right? + + + + To create a query with multiple sources you use the query like this: + + + + + + And to use multiple filters use it like this + + + + + Or like this + + + + In native JPQL form the query would be written like this: + + +select customer from Customer as customer +where customer.firstName = "Bob" and customer.lastName = "Wilson" + + + If you want to combine the filters via "or" then use the following pattern + + + + + + + + + Using joins + + Querydsl supports the following join variants in JPQL: inner join, join, left + join and right join. Join usage is typesafe, and follows the following pattern: + + + + + The native JPQL version of the query would be + + +select cat from Cat as cat +inner join cat.mate as mate +left outer join cat.kittens as kitten + + + Another example + + + + With the following JPQL version + + +select cat from Cat as cat +left join cat.kittens as kitten +on kitten.bodyWeight > 10.0 + + + + + + + General usage + + Use the the cascading methods of the JPQLQuery interface like this + + + select: + Set the projection of the query. (Not necessary if created via query factory) + + + + from: + Add the query sources here. + + + + innerJoin, join, leftJoin, rightJoin, on: + Add join elements using these constructs. + For the join methods the first argument is the join source and the second the target + (alias). + + + + where: + Add query filters, either in varargs form separated via commas or + cascaded via the and-operator. + + + + groupBy: + Add group by arguments in varargs form. + + + + having: + Add having filters of the "group by" grouping as an varags array of + Predicate expressions. + + + + orderBy: + Add ordering of the result as an varargs array of order expressions. + Use asc() and desc() on numeric, string and other comparable expression to access the + OrderSpecifier instances. + + + + limit, offset, restrict: + Set the paging of the result. Limit for max results, + offset for skipping rows and restrict for defining both in one call. + + + + + + + Ordering + + The syntax for declaring ordering is + + + + which is equivalent to the following native JPQL + + +select customer from Customer as customer +order by customer.lastName asc, customer.firstName desc + + + + + + + Grouping + + Grouping can be done in the following form + + + + which is equivalent to the following native JPQL + + +select customer.lastName +from Customer as customer +group by customer.lastName + + + + + + + Delete clauses + Delete clauses in Querydsl JPA follow a simple delete-where-execute form. Here + are some + examples: + + + + + The where call is optional and the execute call performs the deletion and returns the + amount of deleted entities. + + + DML clauses in JPA don't take JPA level cascade rules into account and don't provide + fine-grained second level cache interaction. + + + + Update clauses + + Update clauses in Querydsl JPA follow a simple update-set/where-execute form. + Here are some examples: + + + + + The set invocations define the property updates in SQL-Update-style and the execute call + performs the Update and returns the amount of updated entities. + + + DML clauses in JPA don't take JPA level cascade rules into account and don't provide + fine-grained second level cache interaction. + + + + + + Subqueries + + To create a subquery you use the static factory methods of JPAExpressions and + define the query parameters via from, where etc. + + + + + Another example + + + + + + + Exposing the original query + + If you need to tune the original Query before the execution of the query you + can expose it like this: + + + + + + + + Using Native SQL in JPA queries + + Querydsl supports Native SQL in JPA via the JPASQLQuery class. + + + To use it, you must generate Querydsl query types for your SQL schema. This can + be done for example with the following Maven configuration: + + + + + + ... + + com.querydsl + querydsl-maven-plugin + ${querydsl.version} + + + + export + + + + + org.apache.derby.jdbc.EmbeddedDriver + jdbc:derby:target/demoDB;create=true + com.mycompany.mydomain + ${project.basedir}/target/generated-sources/java + + + + org.apache.derby + derby + ${derby.version} + + + + ... + + + +]]> + + When the query types have successfully been generated into the location of your + choice, you can use them in your queries. + + + Single column query: + + query = new JPASQLQuery(entityManager, templates); +List names = query.select(cat.name).from(cat).fetch(); +]]> + + If you mix entity (e.g. QCat) and table (e.g. SAnimal) references in your query you need to make sure that they + use the same variable names. SAnimal.animal has the variable name "animal", so a new instance + (new SAnimal("cat")) was used instead. + + An alternative pattern could be + + + + Query multiple columns: + + (entityManager, templates); +List rows = query.select(cat.id, cat.name).from(cat).fetch(); +]]> + + Query all columns: + + rows = query.select(cat.all()).from(cat).fetch(); + ]]> + + Query in SQL, but project as entity: + + (entityManager, templates); +List cats = query.select(catEntity).from(cat).orderBy(cat.name.asc()).fetch(); +]]> + + Query with joins: + + (entityManager, templates); +cats = query.select(catEntity).from(cat) + .innerJoin(mate).on(cat.mateId.eq(mate.id)) + .where(cat.dtype.eq("Cat"), mate.dtype.eq("Cat")) + .fetch(); +]]> + + Query and project into DTO: + + (entityManager, templates); +List catDTOs = query.select(Projections.constructor(CatDTO.class, cat.id, cat.name)) + .from(cat) + .orderBy(cat.name.asc()) + .fetch(); +]]> + + If you are using the Hibernate API instead of the JPA API, then use + HibernateSQLQuery instead. + + + + + diff --git a/querydsl-docs/src/main/docbook/en-US/content/tutorials/lucene.xml b/querydsl-docs/src/main/docbook/en-US/content/tutorials/lucene.xml index 0c62b6e5f4..5890297c8c 100644 --- a/querydsl-docs/src/main/docbook/en-US/content/tutorials/lucene.xml +++ b/querydsl-docs/src/main/docbook/en-US/content/tutorials/lucene.xml @@ -5,47 +5,45 @@ Querying Lucene This chapter describes the querying functionality of the Lucene module. - + Maven integration - Querydsl Lucene can be used via the querydsl-lucene3 module for Lucene 3 and querydsl-lucene4 - for Lucene 4 + Querydsl Lucene can be used via the querydsl-lucene3 module for Lucene 3, querydsl-lucene4 + for Lucene 4 and querydsl-lucene5 for Lucene 5 - + Lucene 3: - com.mysema.querydsl + com.querydsl querydsl-lucene3 ${querydsl.version} - - - org.slf4j - slf4j-log4j12 - 1.6.1 - ]]> Lucene 4: - + - com.mysema.querydsl + com.querydsl querydsl-lucene4 ${querydsl.version} +]]> - - org.slf4j - slf4j-log4j12 - 1.6.1 - -]]> + Lucene 5: + + + com.querydsl + querydsl-lucene5 + ${querydsl.version} + +]]> @@ -55,16 +53,16 @@ With fields year and title a manually created query type could look something like this: - { + { private static final long serialVersionUID = -4872833626508344081L; - + public QDocument(String var) { super(Document.class, PathMetadataFactory.forVariable(var)); } public final StringPath year = createString("year"); - + public final StringPath title = createString("title"); } ]]> @@ -81,19 +79,19 @@ public class QDocument extends EntityPathBase{ Querying with Querydsl Lucene is as simple as this: - documents = query .where(doc.year.between("1800", "2000").and(doc.title.startsWith("Huckle")) - .list(); + .fetch(); ]]> which is transformed into the following Lucene query: - @@ -143,16 +141,16 @@ List documents = query The syntax for declaring ordering is - which is equivalent to the following Lucene query - + title:* @@ -163,11 +161,11 @@ title:* @@ -177,11 +175,11 @@ query The syntax for declaring a limit is - @@ -191,11 +189,11 @@ query The syntax for declaring an offset is - @@ -205,13 +203,13 @@ query Fuzzy searches Fuzzy searches can be expressed via fuzzyLike methods in the - com.mysema.query.lucene.LuceneExpressions class: + com.querydsl.lucene3.LuceneExpressions class: - @@ -222,21 +220,21 @@ query It is possible to apply a single Lucene filter to the query like this: - A shortcut for distinct filtering is provided via the distinct(Path) method: - diff --git a/querydsl-docs/src/main/docbook/en-US/content/tutorials/mongodb.xml b/querydsl-docs/src/main/docbook/en-US/content/tutorials/mongodb.xml index aa6444c823..3bcc1c3d4a 100644 --- a/querydsl-docs/src/main/docbook/en-US/content/tutorials/mongodb.xml +++ b/querydsl-docs/src/main/docbook/en-US/content/tutorials/mongodb.xml @@ -15,23 +15,17 @@ - com.mysema.querydsl + com.querydsl querydsl-apt ${querydsl.version} provided - - + + - com.mysema.querydsl + com.querydsl querydsl-mongodb ${querydsl.version} - - - org.slf4j - slf4j-log4j12 - 1.6.1 - ]]> @@ -47,7 +41,7 @@ com.mysema.maven apt-maven-plugin - 1.0.9 + 1.1.3 @@ -55,7 +49,7 @@ target/generated-sources/java - com.mysema.query.apt.morphia.MorphiaAnnotationProcessor + com.querydsl.apt.morphia.MorphiaAnnotationProcessor @@ -99,12 +93,12 @@ query = new MorphiaQuery(morphia, datastore, user); List list = query - .where(user.firstName.eq("Bob")) - .list(); + .where(user.firstName.eq("Bob")) + .fetch(); ]]> @@ -153,11 +147,11 @@ List list = query The syntax for declaring ordering is - The results are sorted ascending based on title and year. @@ -169,11 +163,11 @@ query The syntax for declaring a limit is - @@ -183,11 +177,11 @@ query The syntax for declaring an offset is - @@ -200,10 +194,10 @@ query via the near-method: - @@ -213,13 +207,13 @@ query Select only relevant fields To select only relevant fields you can use the overloaded projection methods - list, iterate, uniqueResult and singleResult methods like this + fetch, iterate, fetchOne and fetchFirst methods like this - This query will load only the title and path fields of the documents. diff --git a/querydsl-docs/src/main/docbook/en-US/content/tutorials/scala.xml b/querydsl-docs/src/main/docbook/en-US/content/tutorials/scala.xml index 79db49679a..5cf0ab4213 100644 --- a/querydsl-docs/src/main/docbook/en-US/content/tutorials/scala.xml +++ b/querydsl-docs/src/main/docbook/en-US/content/tutorials/scala.xml @@ -5,12 +5,12 @@ Querying in Scala Generic support for Querydsl usage in Scala is available via querydsl-scala - module. To add it to your Maven build, use the following snippet : + module. To add it to your Maven build, use the following snippet: - com.mysema.querydsl + com.querydsl querydsl-scala ${querydsl.version} @@ -38,7 +38,7 @@ expr eq "Ben" expr === "Ben" expr ne "Ben" expr !== "Ben" expr append "X" expr + "X" expr isEmpty expr is empty -expr isNotEmpoty expr not empty +expr isNotEmpty expr not empty // boolean left and right left && right @@ -52,7 +52,7 @@ expr gt 5 expr > 5 expr goe 5 expr >= 5 expr notBetween(2,6) expr not between (2,6) expr negate -expr - + // numeric expr add 3 expr + 3 expr subtract 3 expr - 3 @@ -67,66 +67,23 @@ map.get("X") map("X") - - Improved projections - - The Querydsl Scala module offers a few implicit conversion to make Querydsl - query projections more Scala compatible. - - - - The RichProjectable and RichSimpleProjectable wrappers should be used to enable - Scala projections for Querydsl queries. - By importing the contents of com.mysema.query.scala.Helpers - the needed implicit conversions become available. - - - - For example the following query with the standard API would return a java.util.List of - type Object[]. - - - - - With the added conversions you can use select instead of list for Scala list - typed results, unique instead of uniqueResult for - Option typed results and single instead of singleResult for Option typed results. - - - The previous query could be expressed like this with the implicit conversions: - - - - - In this case the result type would be List[(String,String,Integer)] or in other - words List of Tuple3[String,String,Integer]. - - - - Querying with SQL Like with Querydsl SQL for Java you need to generate Query types to be able to construct - your queries. The following code examples show how this is done : + your queries. The following code examples show how this is done: Generation without Bean types : - Generation with Bean types : - - - - - Compact queries - - Querydsl Scala provides a compact query syntax for Querydsl SQL. The syntax is - inspired by domain oriented query syntaxes like that from the Rogue framework. - - - - The domain oriented queries are implemented as implicit conversions from - RelationalPath instances into queries. This functionality - can be made available by implementing the - com.mysema.query.scala.sql.SQLHelpers - trait in your service or DAO classes. - - - Using this compact syntax you can use your meta model classes as a starting - point for queries. - - - Instead of the following normal syntax - - - - you could use the companion object of Employee or QEmployee and write it like - this - - - - Instead of giving expressions to orderBy, where, select, single and unique you - can give functions which take the root expression of - the query and return another expression. The expanded form of the previous example would be - - - e.firstName }, { e => e.lastName }) +exporter.export(connection.getMetaData) ]]> - - See the signature of the com.mysema.query.scala.sql.RichSimpleQuery - class for details. - - - @@ -209,39 +118,47 @@ Employee.select({ e => e.firstName }, { e => e.lastName }) querydsl-maven-plugin. Here is an example configuration - - com.mysema.querydsl - querydsl-maven-plugin - ${querydsl.version} - - com.mysql.jdbc.Driver - jdbc:mysql://localhost:3306/test - matko - matko - com.example.schema - ${project.basedir}/src/main/scala - true - true - - - - mysql - mysql-connector-java - 5.1.16 - - - com.mysema.querydsl - querydsl-scala - ${querydsl.version} - - - org.scala-lang - scala-library - ${scala.version} - - - + + + + ... + + com.querydsl + querydsl-maven-plugin + ${querydsl.version} + + com.mysql.jdbc.Driver + jdbc:mysql://localhost:3306/test + matko + matko + com.example.schema + ${project.basedir}/src/main/scala + true + true + + + + mysql + mysql-connector-java + 5.1.16 + + + com.querydsl + querydsl-scala + ${querydsl.version} + + + org.scala-lang + scala-library + ${scala.version} + + + + ... + + + ]]> The maven goal to execute is querydsl:export. @@ -259,7 +176,7 @@ Employee.select({ e => e.firstName }, { e => e.lastName }) Here is a minimal example with JPA : - Unique result Long where Order Not null The factory method for query creation is @@ -336,4 +253,4 @@ val person = Person as "person" - + diff --git a/querydsl-docs/src/main/docbook/en-US/content/tutorials/spatial.xml b/querydsl-docs/src/main/docbook/en-US/content/tutorials/spatial.xml index 15ecd81276..96f07affbd 100644 --- a/querydsl-docs/src/main/docbook/en-US/content/tutorials/spatial.xml +++ b/querydsl-docs/src/main/docbook/en-US/content/tutorials/spatial.xml @@ -3,33 +3,33 @@ Querydsl Spatial - - Support for Spatial queries is available via the Querydsl Spatial module, which is an extension + + Support for Spatial queries is available via the Querydsl Spatial module, which is an extension module to the SQL module. The Spatial module supports the object model of Simple Feature Access in queries and object binding. - + The geolatte project is used for the object model. - + - + Maven integration - + Add the following dependency to your Maven project: - + - com.mysema.querydsl - querydsl-spatial + com.querydsl + querydsl-sql-spatial ${querydsl.version} - + ]]> Additionally the following database specific extra dependencies: - - org.postgis @@ -46,39 +46,47 @@ provided ]]> - + - + Code generation via Maven - + The code generation for Querydsl SQL can be set to detect the usage of spatial types in database schemas and use geolatte types in these case via the spatial property: - - - com.mysema.querydsl - querydsl-maven-plugin - ${querydsl.version} - ... - - ... - true - - -]]> - - - + + + + + ... + + com.querydsl + querydsl-maven-plugin + ${querydsl.version} + ... + + ... + true + + + ... + + + +]]> + + + - + Runtime configuration - + The runtime configuration aspect of the spatial module is that instead of the normal SQLTemplates instances, spatial enabled instances are used. Below is a list of spatial enabled SQLTemplates classes. - + GeoDBTemplates (for H2) @@ -98,81 +106,81 @@ TeradataSpatialTemplates - - + + - + - + Querying - - With code generation and runtime configuration set for spatial types we can now try + + With code generation and runtime configuration set for spatial types we can now try queries with it. - + - + Filter by Distance - + +Geometry point = Wkt.fromWkt("Point(2 2)"); +query.where(table.geo.distance(point).lt(5.0)); +]]> - In addition to straight distance between geometries spherical and spherodial distance are provided via + In addition to straight distance between geometries spherical and spheroidal distance are provided via distanceSphere and distanceSpheroid. - + - + - + Contains - + - +Geometry point = Wkt.fromWkt("Point(2 2)"); +query.where(table.geo.contains(point)); +]]> + - + - + Intersection - + - + - + - - Access to the SPATIAL_REF_SYS table - - Unified access to the SPATIAL_REF_SYS standard table is provided via the QSpatialRefSys + + Access to the SPATIAL_REF_SYS table + + Unified access to the SPATIAL_REF_SYS standard table is provided via the QSpatialRefSys and SpatialRefSys classes. SPATIAL_REF_SYS contains data about the supported spatial reference systems. - + referenceSystems = query.from(spatialRefSys).list(spatialRefSys); -]]> - +List referenceSystems = query.select(spatialRefSys).from(spatialRefSys).fetch(); +]]> + - + - + - + Inheritance - + In case you use only generic geometry types in your database schema you can use conversion methods in the object model to convert to more specific types. - + geometry = shapes.geometry; PointPath point = geometry.asPoint(); NumberExpression pointX = point.x(); // x() is not available on GeometryExpression/GeometryPath ]]> - + - - \ No newline at end of file + + diff --git a/querydsl-docs/src/main/docbook/en-US/content/tutorials/sql.xml b/querydsl-docs/src/main/docbook/en-US/content/tutorials/sql.xml index 8ea98f762d..b05e40f10e 100644 --- a/querydsl-docs/src/main/docbook/en-US/content/tutorials/sql.xml +++ b/querydsl-docs/src/main/docbook/en-US/content/tutorials/sql.xml @@ -1,1101 +1,1287 @@ - - - - - Querying SQL - - This chapter describes the query type generation and querying functionality of the - SQL module. - - - Maven integration - - - Add the following dependencies to your Maven project: - - - - com.mysema.querydsl - querydsl-sql - ${querydsl.version} - - - - com.mysema.querydsl - querydsl-sql-codegen - ${querydsl.version} - provided - - - - org.slf4j - slf4j-log4j12 - 1.6.1 - -]]> - - The querydsl-sql-codegen dependency can be skipped, if code generation happens - via Maven or Ant. - - - - - - Code generation via Maven - - This functionality should be primarily used via the Maven plugin. Here is an example: - - - - com.mysema.querydsl - querydsl-maven-plugin - ${querydsl.version} - - - - export - - - - - org.apache.derby.jdbc.EmbeddedDriver - jdbc:derby:target/demoDB;create=true - com.myproject.domain - ${project.basedir}/target/generated-sources/java - - - - org.apache.derby - derby - ${derby.version} - - - -]]> - - - Use the goal test-export - to add the targetFolder as a test compile source root - instead of a compile source root. - - - - Parameters - - - - - - Name - Description - - - - - jdbcDriver - class name of the JDBC driver - - - jdbcUrl - JDBC url - - - jdbcUser - JDBC user - - - jdbcPassword - JDBC password - - - namePrefix - name prefix for generated query classes (default: Q) - - - nameSuffix - name suffix for generated query classes (default: ) - - - beanPrefix - name prefix for generated bean classes - - - beanSuffix - name suffix for generated bean classes - - - packageName - package name where source files should be generated - - - beanPackageName - package name where bean files should be generated, (default: - packageName) - - - beanInterfaces - array of interface classnames to add to the bean classes (default: empty) - - - beanAddToString - set to true to create a default toString() implementation (default: false) - - - beanAddFullConstructor - set to true to create a full constructor in addition to public empty (default: false) - - - beanPrintSupertype - set to true to print the supertype as well (default: false) - - - schemaPattern - a schema name pattern; must match the schema name as it is stored in the database; - (default: null) - - - tableNamePattern - a table name pattern; must match the table name as it is stored in the database, - multiple can be separated by comma - (default: null) - - - targetFolder - target folder where source filder should be generated - - - namingStrategyClass - class name of the NamingStrategy class (default: DefaultNamingStrategy) - - - - beanSerializerClass - class name of the BeanSerializer class (default: BeanSerializer) - - - serializerClass - class name of the Serializer class (default: MetaDataSerializer) - - - exportBeans - set to true to generate beans as well, see section 2.14.13 (default: - false) - - - innerClassesForKeys - set to true to generate inner classes for keys (default: false) - - - validationAnnotations - set to true to enable serialization of validation annotations - (default: false) - - - columnAnnotations - export column annotations (default: false) - - - createScalaSources - whether to export Scala sources instead of Java sources, (default: - false) - - - schemaToPackage - append schema name to package (default: false) - - - lowerCase - lower case transformation of names (default: false) - - - exportTables - export tables (default: true) - - - exportViews - export views (default: true) - - - exportPrimaryKeys - export primary keys (default: true) - - - exportForeignKeys - export foreign keys (default: true) - - - customTypes - Custom user types (default: none) - - - typeMappings - Mappings of table.column to Java type (default: none) - - - numericMappings - Mappings of size/digits to Java type (default: none) - - - imports - Array of java imports added to generated query classes: com.bar for package (without .* notation), com.bar.Foo for class (default: empty) - - - - -
- - Custom types can be used to register additional Type implementations: - - - com.mysema.query.sql.types.InputStreamType - -]]> - - Type mappings can be used to register table.column specific java types: - - - - IMAGE
- CONTENTS - java.io.InputStream -
- -]]>
- - - The defaults for the numeric mappings are - - - Numeric mappings - - - - - - Total digits - Decimal digits - Type - - - - - > 18 - 0 - BigInteger - - - > 9 - 0 - Long - - - > 4 - 0 - Integer - - - > 2 - 0 - Short - - - > 0 - 0 - Byte - - - > 16 - > 0 - BigDecimal - - - > 0 - > 0 - Double - - - -
- - They can be customized for specific total/decimal digits combinations like this: - - - - 1 - 0 - java.lang.Byte - - -]]> - - Imports can be used to add cross-schema foreign keys support. - - Compared to APT based code generation certain functionality is not available such as QueryDelegate annotation handling. - -
- - - - Code generation via ANT - - - The ANT task com.mysema.query.sql.ant.AntMetaDataExporter - of the querydsl-sql module provides the same functionality as an ANT task. - The configuration parameters of the task are the same as for the Maven plugin. - - - - - - - Creating the query types - - To get started export your schema into Querydsl query types like this: - - - - This declares that the database schema is to be mirrored into the - com.myproject.domain package in the target/generated-sources/java folder. - - - - The generated types have the table name transformed to mixed case as the class name and a - similar mixed case transformation applied to the columns which are available as property - paths in the query type. - - - - In addition to this primary key and foreign key constraints are provided as fields - which can be used for compact join declarations. - - - - - - - Configuration - - The configuration is done via the com.mysema.query.sql.Configuration class which takes the - Querydsl SQL dialect as an argument. For H2 you would create it like this - - - - Querydsl uses SQL dialects to customize the SQL serialization needed for - different relational databases. The available dialects are: - - - - - CUBRIDTemplates (tested with 8.4) - - - DerbyTemplates (tested with 10.8.2.2) - - - HSQLDBTemplates (tested with 2.2.4) - - - H2Templates (tested with 1.3.164) - - - MySQLTemplates (tested with MySQL 5.5) - - - OracleTemplates (test with Oracle 10 and 11) - - - PostgresTemplates (tested with 9.1) - - - SQLiteTemplates (tested with xerial JDBC 3.7.2) - - - SQLServerTemplates (tested with SQL Server) - - - SQLServer2005Templates (for SQL Server 2005) - - - SQLServer2008Templates (for SQL Server 2008) - - - SQLServer2012Templates (for SQL Server 2012 and later) - - - TeradataTemplates (tested with Teradata 14) - - - - - For customized SQLTemplates instances you can use the builder pattern like this - - - - The methods of the Configuration class can be used to enable direct serialization of literals - via setUseLiterals(true), override schema and tables and register custom types. For full details look - at the javadocs of Configuration. - - - - - - Querying - - Querying with Querydsl SQL is as simple as this: - - lastNames = query.from(customer) - .where(customer.firstName.eq("Bob")) - .list(customer.lastName); -]]> - - - which is transformed into the following sql query, assuming that the related table - name is customer - and the columns first_name - and last_name: - - - - - - - - - General usage - - Use the the cascading methods of the SQLQuery class like this - - - from: - Add the query sources here. - - - - innerJoin, join, leftJoin, fullJoin, on: - Add join elements using these constructs. - For the join methods the first argument is the join source and the second the target - (alias). - - - - where: - Add query filters, either in varargs form separated via commas or - cascaded via the and-operator. - - - - groupBy: - Add group by arguments in varargs form. - - - - having: - Add having filter of the "group by" grouping as an varags array of - Predicate expressions. - - - - orderBy: - Add ordering of the result as an varargs array of order expressions. - Use asc() and desc() on numeric, string and other comparable expression to access the - OrderSpecifier instances. - - - - limit, offset, restrict: - Set the paging of the result. Limit for max results, - offset for skipping rows and restrict for defining both in one call. - - - - - - - Joins - - Joins are constructed using the following syntax: - - - - and for a left join: - - - - Alternatively the join condition can also be written out: - - - - - - - - - Ordering - - The syntax for declaring ordering is - - - - which is equivalent to the following native SQL - - -SELECT c.first_name, c.last_name -FROM customer c -ORDER BY c.last_name ASC, c.first_name ASC - - - - - - - Grouping - - Grouping can be done in the following form - - - - which is equivalent to the following native SQL - - -SELECT c.last_name -FROM customer c -GROUP BY c.last_name - - - - - - - - - Using Subqueries - - - To create a subquery you create a SQLSubQuery instance, define the query parameters via - from, where etc and use unique or list to create a subquery, which is just a type-safe Querydsl - expression for the query. unique is used for a unique (single) result and list for a - list result. - - - - - Another example - - - - - - - - Selecting literals - - To select literals you need to create constant instances for them like this: - - - - The class com.mysema.query.support.Expressions offers also other useful static methods for - projections, operation and template creation. - - - - - - Query extension support - - Custom query extensions to support engine specific syntax can be created by - subclassing AbstractSQLQuery and adding flagging methods like - in the given MySQLQuery example: - - - { - - public MySQLQuery(Connection conn) { - this(conn, new MySQLTemplates(), new DefaultQueryMetadata()); - } - - public MySQLQuery(Connection conn, SQLTemplates templates) { - this(conn, templates, new DefaultQueryMetadata()); - } - - protected MySQLQuery(Connection conn, SQLTemplates templates, QueryMetadata metadata) { - super(conn, new Configuration(templates), metadata); - } - - public MySQLQuery bigResult(){ - return addFlag(Position.AFTER_SELECT, "SQL_BIG_RESULT "); - } - - public MySQLQuery bufferResult(){ - return addFlag(Position.AFTER_SELECT, "SQL_BUFFER_RESULT "); - } - - - // ... -} -]]> - - - The flags are custom SQL snippets that can be inserted at specific points in the - serialization. The supported positions are the enums of the - com.mysema.query.QueryFlag.Position enum class. - - - - - - - Window functions - - Window functions are supported in Querydsl via the methods in the SQLExpressions class. - - Usage example: - - - - - - - - Other SQL expressions - - - Other SQL expressions are also available from the SQLExpressions class as static methods. - - - - - - - Using Data manipulation commands - - All the DMLClause implementation in the Querydsl SQL module take three - parameters, the Connection, the SQLTemplates instance - used in the queries and the main entity the DMLClause is bound to. - - - - - Insert - - With columns - - - - Without columns - - - - With subquery - - - - With subquery, without columns - - - - As an alternative to the columns/values usage, Querydsl provides also a set - method which can be used like this - - - - which is equivalent to the first example. Usage of the set method always - expands internally to columns and values. - - Beware that - - - - maps the result set of the given query to be inserted whereas - - To get the created keys out instead of modified rows count use one of the executeWithKey/s method. - - - - maps single columns and nulls are used for empty subquery results. - - To populate a clause instance based on the contents of a bean you can use - - - - This will exclude null bindings, if you need also null bindings use - - - - - - - - Update - - With where - - - - Without where - - - - Using bean population - - - - - - - - Delete - - With where - - - - Without where - - - - - - - - - - Batch support in DML clauses - - Querydsl SQL supports usage of JDBC batch updates through the DML APIs. If you - have consecutive DML calls with a similar structure, - you can bundle the the calls via addBatch() usage into one DMLClause. See the examples how - it works for UPDATE, DELETE and INSERT. - - - Update: - - - - Delete: - - - - Insert: - - - - - - - - - Bean class generation - - To create JavaBean DTO types for the tables of your schema use the - MetaDataExporter like this: - - - - Now you can use the bean types as arguments to the populate method in DML - clauses and you can project directly - to bean types in queries. Here is a simple example in JUnit form: - - - - - The factory methods used in the previous example are here: - - e){ - return new SQLUpdateClause(Connections.getConnection(), templates, e); -} - -protected SQLInsertClause insert(RelationalPath e){ - return new SQLInsertClause(Connections.getConnection(), templates, e); -} - -protected SQLDeleteClause delete(RelationalPath e){ - return new SQLDeleteClause(Connections.getConnection(), templates, e); -} - -protected SQLMergeClause merge(RelationalPath e){ - return new SQLMergeClause(Connections.getConnection(), templates, e); -} - -protected SQLQuery query() { - return new SQLQuery(Connections.getConnection(), templates); -} - -]]> - - - - - - - - Extracting the SQL query and bindings - - The SQL query and bindings can be extracted via the getSQL method: - - - - If you need also all literals in the SQL string you can enable literal serialization on the - query or configuration level via setUseLiterals(true). - - - - - - Custom types - - Querydsl SQL provides the possibility to declare custom type mappings for - ResultSet/Statement interaction. The custom type mappings can be - declared in com.mysema.query.sql.Configuration instances, which are supplied as constructor - arguments to the actual queries: - - - - - And for a table column - - (Gender.class)); -]]> - - To customize a numeric mapping you can use the registerNumeric method like this - - - - - This will map the Float type to the NUMERIC(5,2) type. - - - - - - Listening to queries and clauses - - SQLListener is a listener interface that can be used to listen to queries and DML clause. SQLListener - instances can be registered either on the configuration and on the query/clause level via the addListener method. - - Use cases for listeners are data synchronization, logging, cacheing and validation. - - - - -
+ + + + + Querying SQL + + This chapter describes the query type generation and querying functionality of the + SQL module. + + + Maven integration + + + Add the following dependencies to your Maven project: + + + + com.querydsl + querydsl-sql + ${querydsl.version} + + + + com.querydsl + querydsl-sql-codegen + ${querydsl.version} + provided + +]]> + + The querydsl-sql-codegen dependency can be skipped, if code generation happens + via Maven. + + + + + + Code generation via Maven + + This functionality should be primarily used via the Maven plugin. Here is an example: + + + + + + ... + + com.querydsl + querydsl-maven-plugin + ${querydsl.version} + + + + export + + + + + org.apache.derby.jdbc.EmbeddedDriver + jdbc:derby:target/demoDB;create=true + com.myproject.domain + ${project.basedir}/target/generated-sources/java + + + + org.apache.derby + derby + ${derby.version} + + + + ... + + + +]]> + + + Use the goal test-export + to treat the target folder as a test source folder for use with test code. + + + + Parameters + + + + + + Name + Description + + + + + jdbcDriver + class name of the JDBC driver + + + jdbcUrl + JDBC url + + + jdbcUser + JDBC user + + + jdbcPassword + JDBC password + + + namePrefix + name prefix for generated query classes (default: Q) + + + nameSuffix + name suffix for generated query classes (default: ) + + + beanPrefix + name prefix for generated bean classes + + + beanSuffix + name suffix for generated bean classes + + + packageName + package name where source files should be generated + + + beanPackageName + package name where bean files should be generated, (default: + packageName) + + + beanInterfaces + array of interface classnames to add to the bean classes (default: empty) + + + beanAddToString + set to true to create a default toString() implementation (default: false) + + + beanAddFullConstructor + set to true to create a full constructor in addition to public empty (default: false) + + + beanPrintSupertype + set to true to print the supertype as well (default: false) + + + schemaPattern + a schema name pattern in LIKE pattern form; must match the schema name as it is stored in the database, + multiple can be separated by comma + (default: null) + + + tableNamePattern + a table name pattern in LIKE pattern form; must match the table name as it is stored in the database, + multiple can be separated by comma + (default: null) + + + targetFolder + target folder where sources should be generated + + + beansTargetFolder + target folder where bean sources should be generated, defaults to the same value as targetFolder + + + namingStrategyClass + class name of the NamingStrategy class (default: DefaultNamingStrategy) + + + + beanSerializerClass + class name of the BeanSerializer class (default: BeanSerializer) + + + serializerClass + class name of the Serializer class (default: MetaDataSerializer) + + + exportBeans + set to true to generate beans as well, see section 2.14.13 (default: + false) + + + innerClassesForKeys + set to true to generate inner classes for keys (default: false) + + + validationAnnotations + set to true to enable serialization of validation annotations + (default: false) + + + columnAnnotations + export column annotations (default: false) + + + createScalaSources + whether to export Scala sources instead of Java sources, (default: + false) + + + schemaToPackage + append schema name to package (default: false) + + + lowerCase + lower case transformation of names (default: false) + + + exportTables + export tables (default: true) + + + exportViews + export views (default: true) + + + exportPrimaryKeys + export primary keys (default: true) + + + tableTypesToExport + Comma-separated list of table types to export (allowable values will depend on JDBC driver). Allows for arbitrary set of types to be exported, e.g.: "TABLE, MATERIALIZED VIEW". The exportTables and exportViews parameters will be ignored if this parameter is set. (default: none) + + + exportForeignKeys + export foreign keys (default: true) + + + exportDirectForeignKeys + export direct foreign keys (default: true) + + + exportInverseForeignKeys + export inverse foreign keys (default: true) + + + customTypes + Custom user types (default: none) + + + typeMappings + Mappings of table.column to Java type (default: none) + + + numericMappings + Mappings of size/digits to Java type (default: none) + + + imports + Array of java imports added to generated query classes: com.bar for package (without .* notation), com.bar.Foo for class (default: empty) + + + generatedAnnotationClass + + The fully qualified class name of the Single-Element Annotation (with String element) to be added on the generated sources. Build in + com.querydsl.core.annotations.Generatedhas CLASS retention which can be used for byte code analysis tools like Jacoco. + (default: javax.annotation.Generated orjavax.annotation.processing.Generated depending on the java version). See also + Single-Element Annotation + + + + +
+ + Custom types can be used to register additional Type implementations: + + + com.querydsl.sql.types.InputStreamType + +]]> + + Type mappings can be used to register table.column specific java types: + + + + IMAGE
+ CONTENTS + java.io.InputStream +
+ +]]>
+ + The defaults for the numeric mappings are + + + Numeric mappings + + + + + + Total digits + Decimal digits + Type + + + + + > 18 + 0 + BigInteger + + + > 9 + 0 + Long + + + > 4 + 0 + Integer + + + > 2 + 0 + Short + + + > 0 + 0 + Byte + + + > 0 + > 0 + BigDecimal + + + +
+ + They can be customized for specific total/decimal digits combinations like this: + + + + 1 + 0 + java.lang.Byte + + +]]> + + Imports can be used to add cross-schema foreign keys support. + + Schemas, tables and columns can also be renamed using the plugin. Here are some examples: + Renaming a schema: + + + PROD + TEST + + +]]> + + Renaming a table: + + + PROD + CUSTOMER + CSTMR + + +]]> + + Renaming a column: + + + PROD + CUSTOMER + ID + IDX + + +]]> + + Note: fromSchema can be omitted when renaming tables and columns. + + Compared to APT based code generation certain functionality is not available such as QueryDelegate annotation handling. + +
+ + + + Code generation via ANT + + + The ANT task com.querydsl.sql.codegen.ant.AntMetaDataExporter + of the querydsl-sql module provides the same functionality as an ANT task. + The configuration parameters of the task are the same as for the Maven plugin, except for the composite types. + + + + The composite types are used without the wrapper element like in this example. + + + + + + + + + + + + +]]> + + + + + + Creating the query types + + To get started export your schema into Querydsl query types like this: + + + + This declares that the database schema is to be mirrored into the + com.myproject.domain package in the target/generated-sources/java folder. + + + + The generated types have the table name transformed to mixed case as the class name and a + similar mixed case transformation applied to the columns which are available as property + paths in the query type. + + + + In addition to this primary key and foreign key constraints are provided as fields + which can be used for compact join declarations. + + + + + + + Configuration + + The configuration is done via the com.querydsl.sql.Configuration class which takes + the + Querydsl SQL dialect as an argument. For H2 you would create it like this + + + + Querydsl uses SQL dialects to customize the SQL serialization needed for + different relational databases. The available dialects are: + + + + + CUBRIDTemplates (tested with CUBRID 8.4) + + + DB2Templates (tested with DB2 10.1.2) + + + DerbyTemplates (tested with Derby 10.8.2.2) + + + FirebirdTemplates (tested with Firebird 2.5) + + + HSQLDBTemplates (tested with HSQLDB 2.2.4) + + + H2Templates (tested with H2 1.3.164) + + + MySQLTemplates (tested with MySQL 5.5) + + + OracleTemplates (test with Oracle 10 and 11) + + + PostgreSQLTemplates (tested with PostgreSQL 9.1) + + + SQLiteTemplates (tested with xerial JDBC 3.7.2) + + + SQLServerTemplates (tested with SQL Server) + + + SQLServer2005Templates (for SQL Server 2005) + + + SQLServer2008Templates (for SQL Server 2008) + + + SQLServer2012Templates (for SQL Server 2012 and later) + + + TeradataTemplates (tested with Teradata 14) + + + + + For customized SQLTemplates instances you can use the builder pattern like this + + + + The methods of the Configuration class can be used to enable direct serialization of literals + via setUseLiterals(true), override schema and tables and register custom types. For full details look + at the javadocs of Configuration. + + + + + + Querying + + For the following examples we will be using the SQLQueryFactory class for query creation. + Using it results in more concise code compared to constructor based query creation. + + + + Querying with Querydsl SQL is as simple as this: + + lastNames = queryFactory.select(customer.lastName).from(customer) + .where(customer.firstName.eq("Bob")) + .fetch(); +]]> + + + which is transformed into the following sql query, assuming that the related table + name is customer + and the columns first_name + and last_name: + + + + + + + + + General usage + + Use the the cascading methods of the SQLQuery class like this + + + select: + Set the projection of the query. (Not necessary if created via query factory) + + + + from: + Add the query sources here. + + + + innerJoin, join, leftJoin, rightJoin, fullJoin, on: + Add join elements using these constructs. + For the join methods the first argument is the join source and the second the target + (alias). + + + + where: + Add query filters, either in varargs form separated via commas or + cascaded via the and-operator. + + + + groupBy: + Add group by arguments in varargs form. + + + + having: + Add having filter of the "group by" grouping as an varags array of + Predicate expressions. + + + + orderBy: + Add ordering of the result as an varargs array of order expressions. + Use asc() and desc() on numeric, string and other comparable expression to access the + OrderSpecifier instances. + + + + limit, offset, restrict: + Set the paging of the result. Limit for max results, + offset for skipping rows and restrict for defining both in one call. + + + + + + + Joins + + Joins are constructed using the following syntax: + + + + and for a left join: + + + + Alternatively the join condition can also be written out: + + + + + + + + + Ordering + + The syntax for declaring ordering is + + + + which is equivalent to the following native SQL + + +SELECT c.first_name, c.last_name +FROM customer c +ORDER BY c.last_name ASC, c.first_name ASC + + + + + + + Grouping + + Grouping can be done in the following form + + + + which is equivalent to the following native SQL + + +SELECT c.last_name +FROM customer c +GROUP BY c.last_name + + + + + + + + + Using Subqueries + + To create a subquery you can use one of the factory methods of SQLExpressions + and add the query parameters via from, where etc. + + + + + Another example + + + + + + + + Selecting literals + + To select literals you need to create constant instances for them like this: + + + + The class com.querydsl.core.types.dsl.Expressions offers also other useful static methods for + projections, operation and template creation. + + + + + + Query extension support + + Custom query extensions to support engine specific syntax can be created by + subclassing AbstractSQLQuery and adding flagging methods like + in the given MySQLQuery example: + + + extends AbstractSQLQuery> { + + public MySQLQuery(Connection conn) { + this(conn, new MySQLTemplates(), new DefaultQueryMetadata()); + } + + public MySQLQuery(Connection conn, SQLTemplates templates) { + this(conn, templates, new DefaultQueryMetadata()); + } + + protected MySQLQuery(Connection conn, SQLTemplates templates, QueryMetadata metadata) { + super(conn, new Configuration(templates), metadata); + } + + public MySQLQuery bigResult() { + return addFlag(Position.AFTER_SELECT, "SQL_BIG_RESULT "); + } + + public MySQLQuery bufferResult() { + return addFlag(Position.AFTER_SELECT, "SQL_BUFFER_RESULT "); + } + + + // ... +} +]]> + + + The flags are custom SQL snippets that can be inserted at specific points in the + serialization. The supported positions are the enums of the + com.querydsl.core.QueryFlag.Position enum class. + + + + + + + Window functions + + Window functions are supported in Querydsl via the methods in the SQLExpressions class. + + Usage example: + + + + + + + + Common table expressions + + Common table expressions are supported in Querydsl SQL via two syntax variants + + + + And using a column listing + + + + If the columns of the common table expression are a subset of an existing table or view + it is advisable to use a generated path type for it, e.g. QEmployee in this case, but if the + columns don't fit any existing table PathBuilder can be used instead. + + Below is an example for such a case + + emp = new PathBuilder(Tuple.class, "emp"); +queryFactory.with(emp, SQLExpressions.select(employee.id, employee.name, employee.departmentId, + department.name.as("departmentName")) + .from(employee) + .innerJoin(department).on(employee.departmentId.eq(department.id)))) + .from(...) +]]> + + + + + + Other SQL expressions + + + Other SQL expressions are also available from the SQLExpressions class as static methods. + + + + + + + Using Data manipulation commands + + + + Insert + + With columns + + + + Without columns + + + + With subquery + + + + With subquery, without columns + + + + As an alternative to the columns/values usage, Querydsl provides also a set + method which can be used like this + + + + which is equivalent to the first example. Usage of the set method always + expands internally to columns and values. + + Beware that + + + + maps the result set of the given query to be inserted whereas + + To get the created keys out instead of modified rows count use one of the executeWithKey/s method. + + + + maps single columns and nulls are used for empty subquery results. + + To populate a clause instance based on the contents of a bean you can use + + + + This will exclude null bindings, if you need also null bindings use + + + + + + + + Update + + With where + + + + Without where + + + + Using bean population + + + + + + + + Delete + + With where + + + + Without where + + + + + + + + + + Batch support in DML clauses + + Querydsl SQL supports usage of JDBC batch updates through the DML APIs. If you + have consecutive DML calls with a similar structure, + you can bundle the the calls via addBatch() usage into one DMLClause. See the examples how + it works for UPDATE, DELETE and INSERT. + + + Update: + + + + Delete: + + + + Insert: + + + + + + + + + Bean class generation + + To create JavaBean DTO types for the tables of your schema use the + MetaDataExporter like this: + + + + Now you can use the bean types as arguments to the populate method in DML + clauses and you can project directly + to bean types in queries. Here is a simple example in JUnit form: + + + + + + + + + + + Extracting the SQL query and bindings + + The SQL query and bindings can be extracted via the getSQL method: + + + + If you need also all literals in the SQL string you can enable literal serialization on the + query or configuration level via setUseLiterals(true). + + + + + + Custom types + + Querydsl SQL provides the possibility to declare custom type mappings for + ResultSet/Statement interaction. The custom type mappings can be + declared in com.querydsl.sql.Configuration instances, which are supplied as constructor + arguments to the actual queries: + + + + + And for a table column + + (Gender.class)); +]]> + + To customize a numeric mapping you can use the registerNumeric method like this + + + + + This will map the Float type to the NUMERIC(5,2) type. + + + + + + Listening to queries and clauses + + SQLListener is a listener interface that can be used to listen to queries and DML clause. SQLListener + instances can be registered either on the configuration and on the query/clause level via the addListener method. + + Use cases for listeners are data synchronization, logging, caching and validation. + + + + + + Spring integration + + Querydsl SQL integrates with Spring through the querydsl-sql-spring module: + + + com.querydsl + querydsl-sql-spring + ${querydsl.version} + +]]> + + It provides Spring exception translation and a Spring connection provider for usage of Querydsl SQL + with Spring transaction managers. Below is a configuration example: + + + + + + + +
diff --git a/querydsl-docs/src/main/docbook/en-US/legal_notice.xml b/querydsl-docs/src/main/docbook/en-US/legal_notice.xml index 807303cb66..4fc7c34162 100644 --- a/querydsl-docs/src/main/docbook/en-US/legal_notice.xml +++ b/querydsl-docs/src/main/docbook/en-US/legal_notice.xml @@ -1,10 +1,9 @@ - - - - Legal Notice - - Copyright 2007-2013 by Mysema Ltd. This copyrighted material is made available to - anyone wishing to use, modify, copy, or redistribute it subject to the terms and conditions of the - Apache License, Version 2.0. - - + + + + + This copyrighted material is made available to + anyone wishing to use, modify, copy, or redistribute it subject to the terms and conditions of the + Apache License, Version 2.0. + + diff --git a/querydsl-docs/src/main/docbook/ko-KR/Querydsl_Reference.xml b/querydsl-docs/src/main/docbook/ko-KR/Querydsl_Reference.xml deleted file mode 100644 index 66f6f39f1c..0000000000 --- a/querydsl-docs/src/main/docbook/ko-KR/Querydsl_Reference.xml +++ /dev/null @@ -1,57 +0,0 @@ - - - - -]> - - - Querydsl - 레퍼런스 문서 - - Querydsl - &versionNumber; - - - Timo - Westkämper - - - Samppa - Saarela - - - Vesa - Marttila - - - Lassi - Immonen - - - - - - - - - - - - - ©rightYear; - ©rightHolder; - - - - - - - - - - - - - - - diff --git a/querydsl-docs/src/main/docbook/ko-KR/content/general.xml b/querydsl-docs/src/main/docbook/ko-KR/content/general.xml deleted file mode 100644 index ddd2a8c6f8..0000000000 --- a/querydsl-docs/src/main/docbook/ko-KR/content/general.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - 일반 사용법 - - - 본 장은 레퍼런스 튜토리얼에서 다루지 않은 내용을 설명한다. - - - - - - - - \ No newline at end of file diff --git a/querydsl-docs/src/main/docbook/ko-KR/content/general/alias.xml b/querydsl-docs/src/main/docbook/ko-KR/content/general/alias.xml deleted file mode 100644 index 3f97f64a20..0000000000 --- a/querydsl-docs/src/main/docbook/ko-KR/content/general/alias.xml +++ /dev/null @@ -1,91 +0,0 @@ - - - 별칭 사용법 - - - 코드 생성을 할 수 없는 경우, 표현식 생성을 위한 경로 참조 목적으로 별칭 객체를 사용할 수 있다. - 자바빈 객체의 프록시를 생성하고 프록시 객체의 getter 메서드를 경로로 사용할 수 있다. - - - - 다음 예제는 생성된 타입을 이용한 표현식 생성을 대신해서 어떻게 별칭 객체를 사용할 수 있는 보여준다. - - - - 먼저 다음 예제는 APT가 생성된 도메인 타입을 이용해서 쿼리를 실행하는 코드를 보자. - - - - - - 그리고, 다음은 Cal 클래스를 이용해서 별칭 인스턴스를 사용하는 예이다. - $ 메서드 파라미터인 c.getKittens()는 내부적으로 프로퍼티 경로 c.kittens로 변환된다. - - - - - - 별칭 기능을 사용하려면 다음의 두 import를 추가해야 한다. - - - - - - 다음 예는 앞 예제의 변형이다. $ 메서드 안에서 리스트의 size()에 접근하고 있다. - - - - - - 기본 데이터 타입이 아니고 final이 아닌 모든 별칭 프로퍼티는 별칭 자체이다. - 따라서, $ 메서드 내에서 기본 데이터 타입이나 final 타입이 나오기 전까지 메서드를 - 이어서 호출할 수 있다. 다음은 예이다. - - - - - - is transformed into *c.mate.name* internally, but - - - - - - 이 코드는 내부적으로 toLowerCase()으로 변환된다. - - - - 별칭 타입에서는 getters, size(), contains(Object), get(int)만 호출할 수 있음에 유의하자. - 모든 다른 메서드 호출은 익셉션을 발생시킨다. - - - - diff --git a/querydsl-docs/src/main/docbook/ko-KR/content/general/codegen.xml b/querydsl-docs/src/main/docbook/ko-KR/content/general/codegen.xml deleted file mode 100644 index eca90495c9..0000000000 --- a/querydsl-docs/src/main/docbook/ko-KR/content/general/codegen.xml +++ /dev/null @@ -1,649 +0,0 @@ - - - 코드 생성 - - Querydsl은 JPA, JDO, Mongodb 모듈에서 코드 생성을 위해 자바6의 APT 어노테이션 처리 기능을 사용한다. -이 절에서는 코드 생성을 위한 다양한 설정 옵션과 APT에 대한 대안을 설명한다. - - - - 경로 초기화 - - - 기본적으로 Querydsl은 처음 2레벨의 레퍼런스 프로퍼티만 초기화한다. 더 깊은 경로로 초기화해야 한다면, - com.mysema.query.annotations.QueryInit 애노테이션을 도메인 타입에 적용해야 한다. - 더 깊은 레벨로 초기화가 필요한 프로퍼티에 QueryInit 어노테이션을 적용한다. 다음은 적용 예를 보여주고 있다. - - - - - - 이 예제는 Event 경로가 루트 경로인 /로 초기화될 때, account.customer 경로의 초기화를 실행한다. - 경로 초기화 포맷은 와일드카드 문자(customer.* 또는 그냥 * 등)를 지원한다. - - - - 자동 경로 초기화는 수동 초기화를 대신하며, 엔티티 필드가 final이어선 안 된다. - 선언적 포맷은 쿼리 타입의 모든 최상위 레벨 인스턴스에 적용할 수 있고 - final 엔티티 필드의 사용을 가능하게 해주는 이점이 있다. - - - - 선호하는 초기화 방식은 자동 경로 초기화지만, 다음에 설명할 Config 어노테이션을 이용해서 - 수동 초기화를 활성화시킬 수 있다. - - - - - - 커스터마이징 - - - 패키지나 타입에 Config 어노테이션을 사용해서 Querydsl의 직렬화를 커스터마이징할 수 있다. - Querydsl은 어노테이션이 적용된 패키지와 타입의 직렬화 방식을 변경한다. - - - - 직렬화 옵션은 다음과 같다. - - - - Config 옵션 - - - - - - 이름 - 설명 - - - - - entityAccessors - public final 필드 대신 엔티티 경로로 사용할 접근 메서드 (기본값: false) - - - listAccessors - listProperty(int index) 형식의 메서드 (기본값: false) - - - mapAccessors - mapProperty(Key key) 형식의 접근 메서드 (기본값: false) - - - createDefaultVariable - 기본 변수 생성 (기본값: true) - - - defaultVariableName - 기본 변수의 이름 - - - -
- - 다음은 몇 가지 예이다. - - 엔티티 타입 직렬화 커스터마이징:: - - - - 엔티티 타입 직렬화 커스터마이징:: - - - - - - - 만약 직렬화 설정을 글로벌하게 변경하고 싶다면, 다음의 APT 옵셥을 사용하면 된다. - - - - APT 옵션 - - - - - - 이름 - 설명 - - - - - querydsl.entityAccessors - 레퍼런스 필드 접근 활성화 - - - querydsl.listAccessors - 인덱스 이용한 리스트 직접 겁근 활성화 - - - querydsl.mapAccessors - 키 기반 맵 직접 접근 활성화 - - - querydsl.prefix - 쿼리 타입을 위한 접두어 (기본값: Q) - - - querydsl.suffix - 쿼리 타입을 위한 접미사 - - - querydsl.packageSuffix - 쿼리 타입 패키지를 위한 접미사 - - - querydsl.createDefaultVariable - 기본 변수 만들지 여부 - - - querydsl.unknownAsEmbeddable - 애노테이션 비적용 클래스를 embeddable로 처리할지 여부 (기본값: false) - - - querydsl.includedPackages - 코드 생성에 포함될 패키지 목록 (콤마로 구분) (default: all) - - - querydsl.includedClasses - 코드 생성에 포함될 클래스 이름 목록 (콤마로 구분) (default: all) - - - querydsl.excludedPackages - 코드 생성에서 제외할 패키지 이름 (콤마로 구분) (default: none) - - - querydsl.excludedClasses - 코드 생성에서 제외할 클래스 이름 (콤마로 구분) (default: none) - - - - -
- - 다음은 메이븐 APT 플러그인 옵션 사용 예다. - - - - - - ... - - com.mysema.maven - apt-maven-plugin - 1.0.9 - - - - process - - - target/generated-sources/java - com.mysema.query.apt.jpa.JPAAnnotationProcessor - - true - - - - - - ... - - - -]]> - - -
- - - 커스텀 타입 매핑 - - - 경로 타입을 바꾸고 싶으면 커스텀 타입 매핑을 사용하면 된다. 특정 String 경로에 대해 비교나 - String 연산을 막아야 하거나 커스텀 타입을 위해 Date/Time 지원이 추가되어야 하는 경우에 - 커스텀 타입 매핑을 유용하게 사용할 수 있다. Joda time API와 JDK(java.util.Date, Calendar 그리고 하위 타입)의 - 시간 타입은 기본으로 지원하며, 다른 API가 필요할 경우 이 기능을 사용하면 된다. - - - 다음은 예시다. - - - - PropertyType.NONE은 쿼리 타입 생성시 프로퍼티를 생략할 때 사용된다. - @Transient나 @QueryTransient 어노테이션이 적용된 프로퍼티가 영속 대상에서 빠지는 것과 차이가 난다. - PropertyType.NONE은 단지 Querydsl 쿼리 타입에서 해당 프로퍼티를 제외한다. - - - - - - 위임 메서드(Delegate methods) - - 정적 메서드를 위임 메서드로 선언하려면, 해당하는 도메인 타입을 값으로 갖는 - QueryDelegate 어노테이션을 정적 메서드에 적용하고, 정적 메서드의 첫 번째 파라미터로 - 해당하는 Querydsl 쿼리 타입을 제공한다. - - - 다음은 예제다. - - - - - - QUser 쿼리 타입의 생성된 메서드는 다음과 같다. - - - - 내장 타입을 확장하는데 위임 메서드를 사용할 수도 있다. 다음은 몇 가지 예제다. - - - date, Pair period){ - return date.goe(period.getFirst()).and(date.loe(period.getSecond())); - } - - @QueryDelegate(Timestamp.class) - public static BooleanExpression inDatePeriod(DateTimePath timestamp, Pair period){ - Timestamp first = new Timestamp(DateUtils.truncate(period.getFirst(), Calendar.DAY_OF_MONTH).getTime()); - Calendar second = Calendar.getInstance(); - second.setTime(DateUtils.truncate(period.getSecond(), Calendar.DAY_OF_MONTH)); - second.add(1, Calendar.DAY_OF_MONTH); - return timestamp.goe(first).and(timestamp.lt(new Timestamp(second.getTimeInMillis()))); - } - -} -]]> - - 내장 타입을 위한 위임 메서드를 선언하면, 위임 메서드를 알맞게 사용하는 하위 클래스가 만들어진다. - - - { - - public QDate(BeanPath entity) { - super(entity.getType(), entity.getMetadata()); - } - - public QDate(PathMetadata metadata) { - super(java.sql.Date.class, metadata); - } - - public BooleanExpression inPeriod(com.mysema.commons.lang.Pair period) { - return QueryExtensions.inPeriod(this, period); - } - -} - -public class QTimestamp extends DateTimePath { - - public QTimestamp(BeanPath entity) { - super(entity.getType(), entity.getMetadata()); - } - - public QTimestamp(PathMetadata metadata) { - super(java.sql.Timestamp.class, metadata); - } - - public BooleanExpression inDatePeriod(com.mysema.commons.lang.Pair period) { - return QueryExtensions.inDatePeriod(this, period); - } - -} -]]> - - - - - - 애노테이션 비적용 타입 - - - @QueryEntities 애노테이션을 만들면, 애노테이션이 적용되지 않은 타입에 대해서도 - Querydsl 쿼리 타입을 생성하는 것이 가능하다. QueryEntities 애노테이션을 선택한 - 패키지에 넣고, value 속성에 복제할 클래스를 값으로 지정한다. - - - - 실제로 타입을 생성하려면 com.mysema.query.apt.QuerydslAnnotationProcessor를 사용한다. - 메이븐 설정 방법은 다음과 같다. - - - - - - ... - - com.mysema.maven - apt-maven-plugin - 1.0.9 - - - - process - - - target/generated-sources/java - com.mysema.query.apt.QuerydslAnnotationProcessor - - - - - ... - - - -]]> - - - - - - 클래스패스 기반 코드 생성 - - 어노테이션이 적용된 자바 소스를 사용할 수 없는 경우(예를 들어, Scala나 Groovy와 같은 - 다른 JVM 언어를 사용했거나, 바이트코드 조작을 이용해서 어노테이션을 추가한 경우 등), - GenericExporter 클래스를 사용해서 클래스패스에서 어노테이션이 적용된 클래스를 - 스캔하고 검색된 클래스를 위한 쿼리 타입을 생성할 수 있다. - - - - GenericExporter를 사용하려면 querydsl-codegen 모듈을 의존에 추가해주어야 한다. - (더 정확하게는 com.mysema.querydsl:querydsl-codegen:${querydsl.version} 모듈) - - - 다음은 JPA를 위한 예제다. - - - - 이 코드는 DomainClass의 패키지 및 그 하위패키지에 위치한 모든 JPA 애노테이션 적용 클래스를 - 찾아 target/generated-sources/java 디렉토리에 쿼리 타입을 생성한다. - - - - - 메이븐 사용법 - - querydsl-maven-plugin의 generic-export, jpa-exportㅡjdo-export 골을 통해 - GenericExporter를 사용할 수 있다. - - - - 각 골은 Querydsl, JPA, JDO 어노테이션에 매핑된다. - - - 설정 엘리먼트는 다음과 같다. - - - 메이븐 설정 - - - - - - - 타입 - 엘리먼트 - 설명 - - - - - File - targetFolder - 생성된 소스가 위치할 대상 폴더 - - - boolean - scala - Scala 소스를 생성하려면 true (기본값: false) - - - String[] - packages - 엔티티 클래스를 검색할 패키지 - - - boolean - handleFields - 필드를 프로퍼티로 처리할 경우 true (기본값: true) - - - boolean - handleMethods - getter를 프로퍼티로 처리할 경우 true (기본값: true) - - - String - sourceEncoding - 생성할 소스 파일의 캐릭터 인코딩 - - - boolean - testClasspath - 테스트 클래스패스를 사용하려면 true - - - -
- - 다음은 JPA 어노테이션이 적용된 클래스를 위한 예다. - - - com.mysema.querydsl - querydsl-maven-plugin - ${querydsl.version} - - - process-classes - - jpa-export - - - target/generated-sources/java - - com.example.domain - - - - - -]]> - - - 위 메이븐 설정은 com.example.domain 및 그 하위 패키지의 - JPA 애노테이션 적용 클래스를 찾아 target/generated-sources/java 디렉토리에 코드를 생성한다. - - - 생성 후에, 직접 생성된 소스를 컴파일하려면 그 소스 폴더를 위한 compile 골을 사용하면 된다. - - - - compile - - - target/generated-sources/scala - - -]]> - - compile 골은 다음 설정 엘리먼트를 갖는다. - - - 메이븐 설정 - - - - - - - 타입 - 엘리먼트 - 설명 - - - - - File - sourceFolder - 소스를 생성할 소스 폴더 - - - String - sourceEncoding - 소스의 캐릭터 인코딩 - - - String - source - 컴파일러의 -source 옵션 - - - String - target - 컴파일러의 -target 옵션 - - - boolean - testClasspath - 테스트 클래스패스를 사용할 경우 true - - - Map - compilerOptions - 컴파일러 옵션 - - - -
- - sourceFolder를 제외한 모든 옵션은 선택사항이다. - -
- - - - Scala 지원 - - Scala 출력을 원하면, 다음 설정을 사용하자. - - - - com.mysema.querydsl - querydsl-maven-plugin - ${querydsl.version} - - - com.mysema.querydsl - querydsl-scala - ${project.version} - - - org.scala-lang - scala-library - ${scala.version} - - - - - - jpa-export - - - target/generated-sources/scala - true - - com.example.domain - - - - - -]]> - - - -
- -
diff --git a/querydsl-docs/src/main/docbook/ko-KR/content/general/creating-queries.xml b/querydsl-docs/src/main/docbook/ko-KR/content/general/creating-queries.xml deleted file mode 100644 index 1cc3d26573..0000000000 --- a/querydsl-docs/src/main/docbook/ko-KR/content/general/creating-queries.xml +++ /dev/null @@ -1,215 +0,0 @@ - - - 쿼리 생성 - - Querydsl에서 Query를 생성하려면 표현식 인자를 이용해서 query 메서드를 호출한다. - query 메서드는 모듈에 따라 다르고 이미 튜토리얼에서 설명했으므로, 본 절에서는 표현식에 초점을 맞출 것이다. - - 표현식을 생성할 때에는 도메인 모듈에서 생성한 표현식 타입의 필드와 메서드를 이용한다. - 코드 생성할 수 없는 경우, 표현식을 생성하기 위한 범용 방법을 사용하면 된다. - - - 복합 조건(complext predicates) - - - 복합 불리언 표현식을 작성하려면 com.mysema.query.BooleanBuilder 클래스를 사용한다. - 이 클래스는 Predicate을 구현하고 있고 메서드 체인 형식으로 사용할 수 있다. - - - getCustomer(String... names){ - QCustomer customer = QCustomer.customer; - JPAQuery query = new JPAQuery(entityManager).from(customer); - BooleanBuilder builder = new BooleanBuilder(); - for (String name : names){ - builder.or(customer.name.eq(name)); - } - query.where(builder); // customer.name eq name1 OR customer.name eq name2 OR ... - return query.list(customer); -} -]]> - - BooleanBuilder는 상태변경이 되며(mutable) 초기에는 null을, - 각 and 또는 or 호출 뒤에는 오퍼레이션의 결과를 표현한다. - - - - - - - 동적 표현식 - - - com.mysema.query.support.Expressions 클래스는 동적인 표현식 생성을 위한 정적 팩토리 클래스다. - 팩토리 메서드는 리턴 타입에 따라 이름을 지었으므로 쉽게 유추할 수 있다. - - - - 일반적으로 동적 경로, 커스텀 구문이나 커스텀 오퍼레이션과 같이 Fluent DSL 형식을 사용할 수 없는 경우에 한해 Expressions 클래스를 사용한다. - - - 다음 표현식을 보자. - - - - 만약 Q타입 생성이 가능하지 않으면 다음과 같이 위와 동일한 표현식을 만들 수 있다. - - person = Expressions.path(Person.class, "person"); -Path personFirstName = Expressions.path(String.class, person, "firstName"); -Constant constant = Expressions.constant("P"); -Expressions.predicate(Ops.STARTS_WITH, personFirstName, constant); -]]> - - Path 인스턴스는 변수와 프로퍼티를 의미하고, Constant는 상수를, Operation은 오퍼레이션을 표현하며, - TemplateExpression 인스턴스를 사용해서 String 템플릿으로 표현식을 표현할 수 있다. - - - - - - - 동적 경로 - - Expressions 기반의 표현식 생성 외에 Querydsl은 동적 경로 생성을 위한 더 표현력이 좋은 API를 제공한다. - - - 동적 경로 생성을 위해 com.mysema.query.types.path.PathBuilder 클래스를 사용할 수 있다. - 이 클래스는 EntityPathBase 클래스를 확장하고 있고 경로 생성을 위해 클래스 생성과 별칭 사용 대신에 사용가능하다. - - - - Expressions API와 비교하면 PathBuilder 커스텀 구문이나 unknown 오퍼레이션을 직접 지원하진 않지만, - 구문이 일반 DSL에 더 가깝다. - - - Strign 프로퍼티: - - entityPath = new -PathBuilder(User.class, "entity"); -// fully generic access -entityPath.get("userName"); -// .. or with supplied type -entityPath.get("userName", String.class); -// .. and correct signature -entityPath.getString("userName").lower(); -]]> - - 컴포넌트 타입을 가진 List 프로퍼티: - - - - 복합 표현식 타입 사용: - - - - 키와 값 타입을 갖는 맵 프로퍼티: - - - - 복합 표현식 타입 사용: - - - - - - - Case 표현식 - - case-when-then-else 표현식을 만들 땐, 다음과 같이 CaseBuilder 클래스를 사용한다. - - - cases = new CaseBuilder() - .when(customer.annualSpending.gt(10000)).then("Premier") - .when(customer.annualSpending.gt(5000)).then("Gold") - .when(customer.annualSpending.gt(2000)).then("Silver") - .otherwise("Bronze"); -// The cases expression can now be used in a projection or condition -]]> - - equals-operations을 가진 case 표현식은 다음과 같이 단순한 형태를 사용하면 된다. - - - cases = customer.annualSpending - .when(10000).then("Premier") - .when(5000).then("Gold") - .when(2000).then("Silver") - .otherwise("Bronze"); -// The cases expression can now be used in a projection or condition -]]> - - JDOQL에서는 아직 Case 표현식을 지원하지 않는다. - - - - - - Casting 표현식 - - - 표현식 타입에서 지네릭 시그너처를 피하기 위해, 타입 계층을 단순화시킨다. 그 결과로 모든 생성된 쿼리 타입은 - com.mysema.query.types.path.EntityPathBasecom.mysema.query.types.path.BeanPath를 - 직접 상속받으며, 논리적인 상위 타입으로 타입 변환할 수 없다. - - - - 자바 타입 변환을 직접 사용하는 대신, _super 필드를 통해서 상위 타입에 대한 레퍼런스에 접근할 수 있다. 생성된 쿼리 타입이 한 개 상위 타입을 가질 경우, _super 필드를 사용할 수 있다. - - - { - // ... -} - -// from BankAccount extends Account -QBankAccount extends EntityPathBase{ - - public final QAccount _super = new QAccount(this); - - // ... -} -]]> - - 상위 타입에서 하위 타입으로 변환하려면 EntityPathBase 클래스의 as 메서드를 사용하면 된다. - - - - - - - - - 리터럴 선택 - - Constant 표현식을 통해 리터럴을 선택할 수 있다. 다음은 간단한 예다. - - - - 서브쿼리에서 Constant 표현식을 종종 사용한다. - - - - diff --git a/querydsl-docs/src/main/docbook/ko-KR/content/general/result-handling.xml b/querydsl-docs/src/main/docbook/ko-KR/content/general/result-handling.xml deleted file mode 100644 index dfc5d5f921..0000000000 --- a/querydsl-docs/src/main/docbook/ko-KR/content/general/result-handling.xml +++ /dev/null @@ -1,176 +0,0 @@ - - - 결과 처리 - - Querydsl은 결과 처리를 커스터마이징 하기 위해 행 기반 변환을 위한 FactoryExpressions과 - 집합을 위한 ResultTransformer를 제공하고 있다. - - com.mysema.query.types.FactoryExpression 인터페이스는 빈 생성, 생성자 호출 - 그리고 더 복잡한 객체를 생성하기 위해 사용된다. com.mysema.query.types.Projections 클래스를 - 이용해서 FactoryExpression 구현체 기능에 접근할 수 있다. - - com.mysema.query.ResultTransformer 인터페이스의 주요 구현체는 GroupBy 클래스이다. - - - - 다중 컬럼 리턴 - - Querydsl 3.0 부터 다중 컬럼 결과를 위한 기본 타입은 com.mysema.query.Tuple 이다. - Tuple은 타입에 안전한 Map을 제공하고, 이를 통해 Tuple 행 객체로부터 컬럼 데이터에 접근할 수 있다. - - result = query.from(employee).list(employee.firstName, employee.lastName); -for (Tuple row : result) { - System.out.println("firstName " + row.get(employee.firstName)); - System.out.println("lastName " + row.get(employee.lastName)); -}} -]]> - - 위 예제를 QTuple 클래스를 이용하면 다음과 같이 작성할 수 있다. - - result = query.from(employee).list(new QTuple(employee.firstName, employee.lastName)); -for (Tuple row : result) { - System.out.println("firstName " + row.get(employee.firstName)); - System.out.println("lastName " + row.get(employee.lastName)); -}} -]]> - - - - - - 빈 생성(population) - - 쿼리 결과로부터 빈을 생성하고 싶다면, Bean 프로젝션을 사용하면 된다. - - dtos = query.list( - Projections.bean(UserDTO.class, user.firstName, user.lastName)); -]]> - - setter 메서드 대신 필드에 직접 접근해야 한다면 다음 코드를 사용하면 된다. - - dtos = query.list( - Projections.fields(UserDTO.class, user.firstName, user.lastName)); -]]> - - - - - 생성자 사용 - - 생성자 기반의 행 변환을 하는 방법은 다음과 같다. - - dtos = query.list( - Projections.bean(UserDTO.class, user.firstName, user.lastName)); -]]> - - 지네릭 생성자 표현식을 사용하는 대신, QueryProjection 어노테이션을 적용한 생성자를 사용할 수도 있다. - - - - - 그리고, 이 클래스를 다음과 같이 쿼리에서 사용 가능하다. - - dtos = query.from(customer).list(new QCustomerDTO(customer.id, customer.name)); -]]> - - 이 예제가 Hibernate용 코드이긴 하지만, 다른 모든 모듈에서도 이 기능을 사용할 수 있다. - - - 만약 QueryProjection 어노테이션이 적용된 타입이 엔티티(@Entity) 타입이 아니라면, - 예제처럼 생성자 프로젝션을 사용할 수 있다. 하지만, 어노테이션이 적용된 타입이 - 엔티티(@Entity) 타입이라면 쿼리 타입의 정적 create 메서드를 실행해서 생성자 프로젝션을 - 만들 필요가 있다. - - - - - dtos = query.from(customer).list(QCustomer.create(customer.id, customer.name)); -]]> - - 코드 생성을 할 수 없다면, 다음과 같이 생성자 프로젝션을 생성할 수 있다. - - - dtos = query.from(customer) - .list(ConstructorExpression.create(Customer.class, customer.id, customer.name)); -]]> - - - - - - 결과 집합(aggregation) - - - com.mysema.query.group.GroupBy 클래스는 메모리에서 쿼리 결과에 대한 집합 연산을 수행하는 - 집합 함수를 제공한다. 다음은 사용 예이다. - - - - 부모 자식 관계에 대한 집합 연산 - - - > results = query.from(post, comment) - .where(comment.post.id.eq(post.id)) - .transform(groupBy(post.id).as(list(comment))); -]]> - - 이 코드는 post id와 관련된 커멘트를 매핑한다. - - 다중 결과 컬럼 - - results = query.from(post, comment) - .where(comment.post.id.eq(post.id)) - .transform(groupBy(post.id).as(post.name, set(comment.id))); -]]> - - 이 코드는 post id와 Group을 매핑한다. Group은 post name과 comment id를 갖는다. - - - Group은 GroupBy에 대해 Tuple 인터페이스와 같은 역할을 한다. - - - 더 많은 예제는 - 여기를 참고한다. - . - - - - - \ No newline at end of file diff --git a/querydsl-docs/src/main/docbook/ko-KR/content/intro.xml b/querydsl-docs/src/main/docbook/ko-KR/content/intro.xml deleted file mode 100644 index 222316443f..0000000000 --- a/querydsl-docs/src/main/docbook/ko-KR/content/intro.xml +++ /dev/null @@ -1,60 +0,0 @@ - - - - Introduction - - - Background - - - Querydsl은 타입에 안전한 방식으로 HQL 쿼리를 실행하기 위한 목적으로 만들어졌다. - HQL 쿼리를 작성하다보면 String 연결을 이용하게 되고, - 이는 결과적으로 읽기 어려운 코드를 만드는 문제를 야기한다. - String을 이용해서 도메인 타입과 프로퍼티를 참조하다보면 - 오타 등으로 잘못된 참조를 하게 될 수 있으며, - 이는 String을 이용해서 HQL 작성할 때 발생하는 또 다른 문제다. - - - - 타입에 안전하도록 도메인 모델을 변경하면 소프트웨어 개발에서 큰 이득을 얻게 된다. - 도메인의 변경이 직접적으로 쿼리에 반영되고, 쿼리 작성 과정에서 코드 자동완성 기능을 - 사용함으로써 쿼리를 더 빠르고 안전하게 만들 수 있게 된다. - - - - Querydsl의 최초 쿼리 언어 대상은 Hibernate의 HQL이었으나, - 현재는 JPA, JDO, JDBC, Lucene, Hibernate Search, MongoDB, 콜렉션 그리고 RDFBean을 지원한다. - - - - - - - 원칙 - - - Querydsl의 핵심 원칙은 타입 안정성(Type safety)이다. - 도메인 타입의 프로퍼티를 반영해서 생성한 쿼리 타입을 이용해서 쿼리를 작성하게 된다. - 또한, 완전히 타입에 안전한 방법으로 함수/메서드 호출이 이루어진다. - - - - 또 다른 중요한 원칙은 일관성(consistency)이다. - 기반 기술에 상관없이 쿼리 경로와 오퍼레이션은 모두 동일하며, - Query 인터페이스는 공통의 상위 인터페이스를 갖는다. - - - - 모든 쿼리 인스턴스는 여러 차례 재사용 가능하다. - 쿼리 실행 이후 페이징 데이터와 프로젝션 정의는 제거된다. - - - - Javadoc에서 com.mysema.query.Query, com.mysema.query.Projectable 그리고 - com.mysema.query.types.Expression의 내용을 보면 Querydsl 쿼리와 표현 타입이 제공하는 - 표현력을 알게 될 것이다. - - - - - \ No newline at end of file diff --git a/querydsl-docs/src/main/docbook/ko-KR/content/preface.xml b/querydsl-docs/src/main/docbook/ko-KR/content/preface.xml deleted file mode 100644 index 7fb7471488..0000000000 --- a/querydsl-docs/src/main/docbook/ko-KR/content/preface.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - 서문 - - - Querydsl 정적 타입을 이용해서 SQL과 같은 쿼리를 생성할 수 있도록 해 주는 프레임워크다. - 문자열로 작성하거나 XML 파일에 쿼리를 작성하는 대신, - Querydsl이 제공하는 플루언트(Fluent) API를 이용해서 쿼리를 생성할 수 있다. - - - - 단순 문자열과 비교해서 Fluent API를 사용할 때의 장점은 다음과 같다. - - - - - IDE의 코드 자동 완성 기능 사용 - - - 문법적으로 잘못된 쿼리를 허용하지 않음 - - - 도메인 타입과 프로퍼티를 안전하게 참조할 수 있음 - - - 도메인 타입의 리팩토링을 더 잘 할 수 있음 - - - - - - diff --git a/querydsl-docs/src/main/docbook/ko-KR/content/troubleshooting.xml b/querydsl-docs/src/main/docbook/ko-KR/content/troubleshooting.xml deleted file mode 100644 index 286fed3964..0000000000 --- a/querydsl-docs/src/main/docbook/ko-KR/content/troubleshooting.xml +++ /dev/null @@ -1,100 +0,0 @@ - - - - 문제해결 - - - 불충분한 타입 인자 - - - Querydsl이 코드 생성을 하려면 List, Set, Collection, Map 프로퍼티가 올바르게 인코딩 되어 있어야 한다. - - - 올바르게 인코딩되지 않은 필드나 getter를 사용할 경우, 다음과 같은 에러가 발생한다. - - (APTTypeModel.java:55) - at com.mysema.query.apt.APTTypeModel.get(APTTypeModel.java:48) - at com.mysema.query.apt.Processor$2.visitType(Processor.java:114) - ... 35 more -]]> - - - 다음은 문제가 되는 필드 선언과 올바른 선언의 예를 보여주고 있다. - - - names; // RIGHT - - private Map employeesByName; // WRONG - - private Map employeesByName; // RIGHT -]]> - - - - - - - 멀티쓰레드 환경에서 Querydsl Q타입의 초기화 - - Q타입이 순환 의존을 가질 경우, 멀티 쓰레드 환경에서 Q타입을 초기화하면 데드락이 발생할 수 있다. - - 이에 대한 가장 쉬운 해결책은 멀티쓰레드 환경에서 사용되기 전에 단일 쓰레드에서 클래스를 초기화하는 것이다. - - 이런 목적으로 com.mysema.util.ClassPathUtils 클래스를 사용할 수 있다. - - - - packageToLoad를 실제 초기화하길 원하는 클래스의 패키지로 바꾸면 된다. - - - - - - JDK5 사용 - - - JDK 5로 프로젝트를 컴파일할 때, 다음과 같이 컴파일에 실패할 수 있다. - - - - - - 자바6에서 사용되는 클래스 파일 버전은 50.0이고 자바5는 49.0이다. - - - - JDK 6.0 이후 버전에서 사용가능한 APT를 광범위하게 사용하고 있기 때문에, Querydsl을 JDK 6.0에서만 테스트 했다. - - - - 만약 JDK 5.0에서 Querydsl을 사용하길 원한다면 Querydsl 자체를 직접 컴파일해야 한다. - - - - - - diff --git a/querydsl-docs/src/main/docbook/ko-KR/content/tutorials.xml b/querydsl-docs/src/main/docbook/ko-KR/content/tutorials.xml deleted file mode 100644 index 8114a0cef8..0000000000 --- a/querydsl-docs/src/main/docbook/ko-KR/content/tutorials.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - 튜토리얼 - - - 일반적인 시작 안내 문서 대신 Querydsl이 지원하는 주요 백엔드 기술에 대한 안내 문서를 제공한다. - - - - - - - - - - - - - \ No newline at end of file diff --git a/querydsl-docs/src/main/docbook/ko-KR/content/tutorials/collections.xml b/querydsl-docs/src/main/docbook/ko-KR/content/tutorials/collections.xml deleted file mode 100644 index db6e7057f2..0000000000 --- a/querydsl-docs/src/main/docbook/ko-KR/content/tutorials/collections.xml +++ /dev/null @@ -1,244 +0,0 @@ - - - - - 콜렉션 쿼리 - - 생성된 쿼리 타입을 이용하거나 또는 쿼리 타입 없이 querydsl-collections 모듈을 사용할 수 있다. - 첫 번째 절에서는 생성된 쿼리 타입 없이 사용하는 방법을 설명한다. - - - - 생성된 쿼리 타입 없이 사용하기 - - - 생성된 쿼리 타입 없이 querydsl-collections 모듈을 사용하려면, Querydsl 별칭 기능을 사용해야 한다. 다음은 몇 가지 예다. - - - - 먼저 다음의 정적 임포트를 추가한다. - - - - - - 이제 Cat 클래스에 대한 별칭 인스턴스를 만들어보자. - 기본 생성자를 가진 non-final 클래스에 대해서만 Alias 인스턴스를 만들수 있다. - - - - $ 메서드로 감싸는 방법으로 Cat 타입의 별칭 인스턴스 및 그것의 getter 메서드 호출을 - 경로로 바꾼다. 예를 들어, c.getKittens()에 대한 호출은 - $ 메서드를 통해 c.kittends 경로로 바뀐다. - - - - - - 다음은 앞 예제를 다르게 작성해본 것이다. 아래 코드는 List의 size() 메서드를 $ 메서드로 감쌌다. - - - - - - 별칭의 모든 비-기본타입과 non-final 타입 프로퍼티는 별칭 그 자체이다. - 따라서, $ 메서드 범위안에서 기본 타입이나 non-final 타입 (예, java.lang.String)을 만날 때 까지 - 연속된 메서드 호출이 가능하다. - - - - 예를 들어, - - - - - - 이 코드는 c.mate.name으로 바뀐다. - 하지만, 아래 코드는 올바르게 바뀌지 않는다. - - - - - - 그 이유는 toLowerCase() 호출은 추적되지 않기 때문이다. - - - 별칭 타입에 대해 getter, size(), contains(Object), get(int) 만 호출할 수 있다. - 나머지 다른 메서드에 대한 호출은 익셉션을 발생시킨다. - - - - - - - 생성된 쿼리 타입을 갖고 사용하기 - - - 앞서 예제를 생성된 쿼리 타입을 이용하면 다음과 같이 표현할 수 있다. - - - - - 생성된 쿼리 타입을 사용하면, 별칭 인스턴스 대신 표현식을 생성할 수 있고 - $ 메서드를 사용할 필요 없이 프로퍼티 경로를 바로 사용할 수 있다. - - - - - - - 메이븐 통합 - - - 다음 의존을 메이븐 프로젝트에 추가한다. - - - - com.mysema.querydsl - querydsl-apt - ${querydsl.version} - provided - - - - com.mysema.querydsl - querydsl-collections - ${querydsl.version} - - - - org.slf4j - slf4j-log4j12 - 1.6.1 - -]]> - - - - JPA나 JDO를 사용하지 않는다면, 도메인 타입에 com.mysema.query.annotations.QueryEntity - 애노테이션을 적용하고 메이븐 설정(pom.xml)에 다음 플러그인 설정을 추가함으로써 - 표현식 타입을 생성할 수 있다. - - - - - - ... - - com.mysema.maven - apt-maven-plugin - 1.0.9 - - - - process - - - target/generated-sources/java - com.mysema.query.apt.QuerydslAnnotationProcessor - - - - - ... - - - -]]> - - - - - - Ant 통합 - - 클래스패스에 full-deps에 포함된 jar 파일들을 위치시키고, 다음 태스크를 이용해서 Querydsl 코드를 생성한다. - - - - - - - - - - - - - - - - -]]> - - - src를 메인 소스 폴더로 변경하고, - generated를 생성된 소스를 위한 폴더로 변경하고, - build를 클래스 생성 폴더로 변경한다. - - - - - - - Hamcrest matchers - - Querydsl Collections 모듈은 Hamcrest matchers를 제공한다. 다음의 import를 통해 사용하면 된다. - - - - 다음과 같이 사용할 수 있다. - - - - - Jeroen van Schagen가 Hamcrest matchers를 기여했다. - - - - - \ No newline at end of file diff --git a/querydsl-docs/src/main/docbook/ko-KR/content/tutorials/hibernate-search.xml b/querydsl-docs/src/main/docbook/ko-KR/content/tutorials/hibernate-search.xml deleted file mode 100644 index 6b8f2ca4be..0000000000 --- a/querydsl-docs/src/main/docbook/ko-KR/content/tutorials/hibernate-search.xml +++ /dev/null @@ -1,46 +0,0 @@ - - - Hibernate Search 쿼리 - - Hibernate Search 모듈의 쿼리 기능을 설명한다. - - - - - Querydsl 쿼리 타입 생성 - - 쿼리 타입을 생성하는 방법은 본 문서의 JPA 쿼리 부분을 참고한다. - - - - - 쿼리 - - Querydsl Hibernate Search를 이용한 쿼리는 다음과 같이 간단하다. - - - query = new SearchQuery(session, user); -List list = query - .where(user.firstName.eq("Bob")) - .list(); -]]> - - - - - 일반 용법 - - - 일반 용법은 Querying Lucene의 일반 용법을 참고한다. - - - - 쿼리 직렬화 과정에서 Querydsl Lucene module과의 유일한 차이점은 경로를 다르게 - 처리한다는 것이다. org.hibernate.search.annotations.Field 애노테이션이 - 적용된 프로퍼티인 경우, 필드 이름에 대한 대체 방법으로 name 속성의 값을 사용한다. - - - - diff --git a/querydsl-docs/src/main/docbook/ko-KR/content/tutorials/jdo.xml b/querydsl-docs/src/main/docbook/ko-KR/content/tutorials/jdo.xml deleted file mode 100644 index 9b0155d6ac..0000000000 --- a/querydsl-docs/src/main/docbook/ko-KR/content/tutorials/jdo.xml +++ /dev/null @@ -1,491 +0,0 @@ - - - - JDO 쿼리 - - - Querydsl은 영속 도메인 모델에 대해 쿼리할 수 있는 범용적인 정적 타입 구문을 정의하고 있다. - JDO와 JPA는 Querydsl이 지원하는 주요 기술이다. 이 안내 문서에서는 JDO와 함께 Querydsl을 - 사용하는 방법을 설명한다. - - - - 메이븐 통합 - - - 메이븐 프로젝트의 의존 설정에 다음을 추가한다. - - - - com.mysema.querydsl - querydsl-apt - ${querydsl.version} - provided - - - - com.mysema.querydsl - querydsl-jdo - ${querydsl.version} - - - - org.slf4j - slf4j-log4j12 - 1.6.1 - -]]> - - - 다음으로 Querydsl에서 쿼리 타입을 생성하기 위해 사용하는 메이븐 APT 플러그인을 설정한다. - - - - - - ... - - com.mysema.maven - apt-maven-plugin - 1.0.9 - - - - process - - - target/generated-sources/java - com.mysema.query.apt.jdo.JDOAnnotationProcessor - - - - - ... - - - -]]> - - - JDOAnnotationProcessor는 javax.jdo.annotations.PersistenceCapable 애노테이션이 - 적용된 타입을 찾아서 그 타입을 위한 쿼리 타입을 생성한다. - - - - `mvn clean install`을 실행하면, target/generated-sources/java 디렉토리에 Query 타입이 생성된다. - - - - 이클립스를 사용할 경우, `mvn eclipse:eclipse`을 실행하면 - target/generated-sources/java 디렉토리가 소스 폴더에 추가된다. - - - - 생성된 Query 타입을 이용하면 JDO 쿼리 인스턴스와 쿼리 도메인 모델 인스턴스를 생성할 수 있다. - - - - - - - Ant 통합 - - 클래스패스에 full-deps에 포함된 jar 파일들을 위치시키고, - 다음 태스크를 이용해서 Querydsl 코드를 생성한다. - - - - - - - - - - - - - - - - -]]> - - - src를 메인 소스 폴더로 변경하고, - generated를 생성된 소스를 위한 폴더로 변경하고, - build를 클래스 생성 폴더로 변경한다. - - - - - - - 쿼리 타입 사용하기 - - - Querydsl을 이용해서 쿼리를 작성하려면, 변수와 Query 구현체를 생성해야 한다. - 먼저 변수부터 시작해보자. - - - - 다음과 같은 도메인 타입이 있다고 가정하다. - - - - - - Querydsl은 Customer와 동일한 패키지에 QCustomer라는 이름을 가진 쿼리 타입을 생성한다. - Querydsl 쿼리에서 Customer 타입을 위한 정적 타입 변수로 QCustomer를 사용한다. - - - - QCustomer는 기본 인스턴스 변수를 갖고 있으며, 다음과 같이 정적 필드로 접근할 수 있다. - - - - - - 다음처럼 Customer 변수를 직접 정의할 수도 있다. - - - - - - QCustomer는 원래 Customer 타입의 모든 프로퍼티를 public 필드로 반영한다. - firstName 필다는 다음과 같이 접근할 수 있다. - - - - - - - - - 쿼리 - - - JDOQuery가 JDO 모듈을 위한 Query 구현체이며, 다음과 같이 인스턴스를 생성한다. - - - - - - firstName 프로퍼티가 Bob인 Customer를 조회하고 싶다면 다음의 쿼리를 사용하면 된다. - - - - - - from 메서드는 쿼리 대상(소스)을 지정하고, where 부분은 필터를 정의하고, - uniqueResult는 프로젝션을 정의해서 1개 결과만 리턴하라고 지시한다. - - - - 여러 소스로부터 쿼리를 만들고 싶다면 다음처럼 쿼리를 사용한다. - - - - - - 여러 필터를 사용하는 방법은 다음과 같다. - - - - - 또는, 다음과 같이 해도 된다. - - - - 필터 조건을 or로 조합하고 싶다면 다음 패턴을 사용한다. - - - - - - - - - 일반 용법 - - JDOQuery 클래스의 cascading 메서드는 다음과 같다. - - - from: - 쿼리 소스를 추가한다. 첫 번째 인자는 메인 소스가 되고, 나머지는 변수로 취급한다. - - - - where: - 쿼리 필터를 추가한다. 가변인자나 and/or 메서드를 이용해서 필터를 추가한다. - - - - groupBy: - 가변인자 형식의 인자를 기준으로 그룹을 추가한다. - - - - having: - Predicate 표현식을 이용해서 "group by" 그룹핑의 필터를 추가한다. - - - - orderBy: - 정렬 표현식을 이용해서 정렬 순서를 지정한다. 숫자나 문자열에 대해서는 - asc()나 desc()를 사용하고, OrderSpecifier에 접근하기 위해 다른 비교 표현식을 사용한다. - - - - limit, offset, restrict: - 결과의 페이징을 설정한다. limit은 최대 결과 개수, offset은 결과의 시작 행, - restrict는 limit과 offset을 함께 정의한다. - - - - - - - 정렬 - - 정렬을 위한 구문은 다음과 같다. - - - - - - - - 그룹핑 - - 그룹핑은 다음과 같은 코드로 처리한다. - - - - - - - - DeleteClause - Querydsl JDO에서 DeleteClause는 간단한 delete-where-execute 형태를 취한다. - 다음은 몇 가지 예다. - - - - - JDODeleteClause 생성자의 두 번째 파라미터는 삭제할 엔티티 대상이다. - where는 필요에 따라 추가할 수 있으며, execute를 실행하면 삭제를 수행하고 - 삭제된 엔티티의 개수를 리턴한다. - - - - - - - 서브쿼리 - - 서브쿼리를 만들려면 JDOSubQuery를 사용하면 된다. - 서브쿼리를 만들기 위해 from 메서드로 쿼리 파라미터를 정의하고, unique나 list를 이용한다. - unique는 단일 결과를 위해 사용하고 list는 리스트 결과를 위해 사용한다. - 서브쿼리도 쿼리처럼 타입에 안전한 Querydsl 표현식이다. - - - - - 위 코드는 다음의 네이티브 JDO 쿼리를 표현한다. - - -SELECT this FROM com.mysema.query.jdoql.models.company.Department -WHERE this.employees.size() == -(SELECT max(d.employees.size()) FROM com.mysema.query.jdoql.models.company.Department d) - - - 다른 예제 - - - - 위 코드는 다음의 네이티브 JDO 쿼리를 표현한다. - - -SELECT this FROM com.mysema.query.jdoql.models.company.Employee -WHERE this.weeklyhours > -(SELECT avg(e.weeklyhours) FROM this.department.employees e WHERE e.manager == this.manager) - - - - - - - 네티이브 SQL 사용하기 - - JDOSQLQuery 클래스를 사용하면 JDO의 - 네이티브 SQL을 Querydsl에서 사용할 수 있다. - - - 이걸 사용하려면 SQL 스키마를 위한 Querydsl 쿼라 티입을 생성해야 한다. - 다음은 이를 위한 Maven 설정 예를 보여주고 있다. - - - - com.mysema.querydsl - querydsl-maven-plugin - ${project.version} - - - - export - - - - - org.apache.derby.jdbc.EmbeddedDriver - jdbc:derby:target/demoDB;create=true - com.mycompany.mydomain - ${project.basedir}/target/generated-sources/java - - - - org.apache.derby - derby - ${derby.version} - - - -]]> - - 지정한 위치에 쿼리 타입을 성공적으로 생성했다면, 쿼리에서 그 타입을 사용할 수 있다. - - - 한 개 컬럼 쿼리: - - names = query.from(cat).list(cat.name); -]]> - - 다중 컬럼 쿼리: - - rows = query.from(cat).list(cat.id, cat.name); -]]> - - 모든 컬럼 쿼리: - - rows = query.from(cat).list(cat.all()); - ]]> - - 조인을 이용한 쿼리: - - - - 쿼리 결과를 DTO로 구하기: - - catDTOs = query.from(cat) - .orderBy(cat.name.asc()) - .list(ConstructorExpression.create(CatDTO.class, cat.id, cat.name)); -]]> - - - - \ No newline at end of file diff --git a/querydsl-docs/src/main/docbook/ko-KR/content/tutorials/jpa.xml b/querydsl-docs/src/main/docbook/ko-KR/content/tutorials/jpa.xml deleted file mode 100644 index a53c7cd967..0000000000 --- a/querydsl-docs/src/main/docbook/ko-KR/content/tutorials/jpa.xml +++ /dev/null @@ -1,685 +0,0 @@ - - - - - JPA 쿼리 - - - Querydsl은 영속 도메인 모델에 대해 쿼리할 수 있는 범용적인 정적 타입 구문을 정의하고 있다. - JDO와 JPA는 Querydsl이 지원하는 주요 기술이다. - 이 안내 문서에서는 JPA와 함께 Querydsl을 사용하는 방법을 설명한다. - - - - Querydsl은 JPQL과 Criteria 쿼리를 모두 대체할 수 있다. - Querydsl은 Criteria 쿼리의 동적인 특징과 JPQL의 표현력을 타입에 안전한 방법으로 제공한다. - - - - 메이븐 통합 - - - 메이븐 프로젝트의 의존 설정에 다음을 추가한다. - - - - com.mysema.querydsl - querydsl-apt - ${querydsl.version} - provided - - - - com.mysema.querydsl - querydsl-jpa - ${querydsl.version} - - - - org.slf4j - slf4j-log4j12 - 1.6.1 - -]]> - - - 다음으로 메이븐 APT 플러그인을 설정한다. - - - - - - ... - - com.mysema.maven - apt-maven-plugin - 1.0.9 - - - - process - - - target/generated-sources/java - com.mysema.query.apt.jpa.JPAAnnotationProcessor - - - - - ... - - - -]]> - - - JPAAnnotationProcessor는 javax.persistence.Entity 애노테이션을 가진 - 도메인 타입을 찾아서 쿼리 타입을 생성한다. - - - - 도메인 타입으로 Hibernate 애노테이션을 사용하면, APT 프로세서로 - com.mysema.query.apt.hibernate.HibernateAnnotationProcessor를 사용해야 한다. - - - - mvn clean install 을 실행하면, - target/generated-sources/java 디렉토리에 Query 타입이 생성된다. - - - - 이클립스를 사용할 경우, mvn eclipse:eclipse 를 실행하면 - target/generated-sources/java 디렉토리가 소스 폴더에 추가된다. - - - - 생성된 Query 타입을 이용하면 JPA 쿼리 인스턴스와 - 쿼리 도메인 모델 인스턴스를 생성할 수 있다. - - - - - - - Ant 통합 - - - 클래스패스에 full-deps에 포함된 jar 파일들을 위치시키고, - 다음 태스크를 이용해서 Querydsl 코드를 생성한다. - - - - - - - - - - - - - - - - -]]> - - - src를 메인 소스 폴더로 변경하고, - generated를 생성된 소스를 위한 폴더로 변경하고, - build를 클래스 생성 폴더로 변경한다. - - - - - - - Roo에서 Querydsl JPA 사용하기 - - - 스프링 Roo에서 Querydsl JPA를 사용한다면, - com.mysema.query.apt.jpa.JPAAnnotationProcessor 대신 - com.mysema.query.apt.roo.RooAnnotationProcessor를 사용할 수 있다. - RooAnnotationProcessor는 @Entity가 적용된 클래스 대신 - @RooJpaEntity@RooJpaActiveRecord 애노테이션이 적용된 - 클래스를 처리한다. - - - - APT 기반의 코드 생성 기능은 AspectJ IDT에는 잘 동작하지 않는다. - - - - - - - hbm.xml 파일에서 쿼리 모델 생성하기 - - - 하이버네이트에서 XML 기반 설정을 사용하고 있다면, - Querydsl 모델을 생성하기 위해 XML 메타정보를 사용할 수 있다. - - - - com.mysema.query.jpa.codegen.HibernateDomainExporter가 이 기능을 제공한다. - - - - - - HibernateDomainExporter는 리플렉션을 이용해서 도메인의 프로퍼티 타입을 확인하기 때문에, - HibernateDomainExporter를 실행하려면 클래스패스에 도메인 타입이 위치해야 한다. - - - 모든 JPA 어노테이션은 무시되지만, @QueryInit이나 @QueryType과 같은 - Querydsl 애노테이션은 처리한다. - - - - - - - 쿼리 타입 사용하기 - - - Querydsl을 이용해서 쿼리를 작성하려면, 변수와 Query 구현체를 생성해야 한다. - 먼저 변수부터 시작해보자. - - - - 다음과 같은 도메인 타입이 있다고 가정하다. - - - - - - Querydsl은 Customer와 동일한 패키지에 QCustomer라는 이름을 가진 쿼리 타입을 생성한다. - Querydsl 쿼리에서 Customer 타입을 위한 정적 타입 변수로 QCustomer를 사용한다. - - - - QCustomer는 기본 인스턴스 변수를 갖고 있으며, 다음과 같이 정적 필드로 접근할 수 있다. - - - - - - 다음처럼 Customer 변수를 직접 정의할 수도 있다. - - - - - - - - - 쿼리 - - Querdsl JPA 모듈은 JPA와 Hibernate API를 모두 지원한다. - - - JPA API를 사용하려면 다음과 같이 JPAQuery 인스턴스를 사용하면 된다. - - - - - Hibernate를 사용한다면, HibernateQuery를 사용하면 된다. - - - - - JPAQuery와 HibernateQuery는 둘 다 JPQLQuery 인터페이스를 구현하고 있다. - - - firstName 프로퍼티가 Bob인 Customer를 조회하고 싶다면 다음의 쿼리를 사용하면 된다. - - - - - - from 메서드는 쿼리 대상(소스)을 지정하고, where 부분은 필터를 정의하고, - uniqueResult는 프로젝션을 정의하고, 1개 결과만 리턴하라고 지시한다. - - - - 여러 소스로부터 쿼리를 만들고 싶다면 다음처럼 쿼리를 사용한다. - - - - - - 여러 필터를 사용하는 방법은 다음과 같다. - - - - - 또는, 다음과 같이 해도 된다. - - - - 위 코드를 JPQL 쿼리로 작성하면 다음과 같을 것이다. - - -from Customer as customer - where customer.firstName = "Bob" and customer.lastName = "Wilson" - - - 필터 조건을 or로 조합하고 싶다면 다음 패턴을 사용한다. - - - - - - - - - 조인 - - Querydsl은 JPQL의 이너 조인, 조인, 레프트 조인, 풀조인을 지원한다. - 조인 역시 타입에 안전하며 다음 패턴에 따라 작성한다. - - - - - 위 쿼리를 JPQL로 작성하면 다음과 같다. - - -from Cat as cat - inner join cat.mate as mate - left outer join cat.kittens as kitten - - - 다음은 조인을 사용하는 또 다른 예다. - - - - 위 코드의 JPQL 버전은 다음과 같다. - - -from Cat as cat - left join cat.kittens as kitten - on kitten.bodyWeight > 10.0 - - - - - - - 일반 용법 - - JPQLQuery 인터페이스의 cascading 메서드는 다음과 같다. - - - from: - 쿼리 소스를 추가한다. - - - - innerJoin, join, leftJoin, fullJoin, on: - 조인 부분을 추가한다. 조인 메서드에서 첫 번째 인자는 조인 소스이고, - 두 번재 인자는 대상(별칭)이다. - - - - where: - 쿼리 필터를 추가한다. 가변인자나 and/or 메서드를 이용해서 필터를 추가한다. - - - - groupBy: - 가변인자 형식의 인자를 기준으로 그룹을 추가한다. - - - - having: - Predicate 표현식을 이용해서 "group by" 그룹핑의 필터를 추가한다. - - - - orderBy: - 정렬 표현식을 이용해서 정렬 순서를 지정한다. - 숫자나 문자열에 대해서는 asc()나 desc()를 사용하고, - OrderSpecifier에 접근하기 위해 다른 비교 표현식을 사용한다. - - - - limit, offset, restrict: - 결과의 페이징을 설정한다. limit은 최대 결과 개수, offset은 결과의 시작 행, - restrict는 limit과 offset을 함께 정의한다. - - - - - - - 정렬 - - 정렬을 위한 구문은 다음과 같다. - - - - 위 코드는 다음의 JPQL과 동일하다. - - -from Customer as customer - order by customer.lastName asc, customer.firstName desc - - - - - - - 그룹핑 - - 그룹핑은 다음과 같은 코드로 처리한다. - - - - 동등한 JPQL은 다음고 같다. - - -select customer.lastName - from Customer as customer - group by customer.lastName - - - - - - - DeleteClause - Querydsl JPA에서 DeleteClause는 간단한 delete-where-execute 형태를 취한다. - 다음은 몇 가지 예다. - - - - - JPADeleteClause 생성자의 두 번째 파라미터는 삭제할 엔티티 대상이다. - where는 필요에 따라 추가할 수 있으며, execute를 실행하면 삭제를 수행하고 - 삭제된 엔티티의 개수를 리턴한다. - - - Hibernate 이용시, HibernateDeleteClause를 사용하면 된다. - - JPA의 DML 절은 JPA 레벨의 영속성 전파 규칙을 따르지 않고, - 2차 레벨 캐시와의 연동되지 않는다. - - - - UpdateClause - - Querydsl JPA의 UpdateClause은 간단한 update-set/where-execute 형태를 취한다. - 다음은 몇 가지 예다. - - - - - JPAUpdateClause 생성자의 두 번째 파라미터는 수정할 엔티티 대상이다. - set은 SQL의 update 스타일로 프로퍼티 수정을 정의하고, - execute를 실행하면 수정을 실행하고 수정된 엔티티의 개수를 리턴한다. - - - Hibernate 이용시, HibernateUpdateClause를 사용한다. - - JPA에서 DML 절은 JPA 레벨의 영속성 전파 규칙을 따르지 않고, - 2차 레벨 캐시와 연동되지 않는다. - - - - - - 서브쿼리 - - 서브쿼리를 만들려면 JPASubQuery를 사용하면 된다. - 서브쿼리를 만들기 위해 from 메서드로 쿼리 파라미터를 정의하고, unique나 list를 이용한다. - unique는 단일 결과를 위해 사용하고 list는 리스트 결과를 위해 사용한다. - 서브쿼리도 쿼리처럼 타입에 안전한 Querydsl 표현식이다. - - - - - 다른 예제 - - - - Hibernate를 사용할 경우, HibernateSubQuery를 사용하면 된다. - - - - - 원래의 JPA Query 구하기 - - 만약 쿼리를 실행하기 전에 JPA Query를 구하고 싶다면, 다음 코드를 사용한다. - - - - - - - - JPA 쿼리에서 네이티브 SQL 사용하기 - - JPASQLQuery 클래스를 사용하면 JPA의 네이티브 SQL을 Querydsl에서 사용할 수 있다. - - - 이걸 사용하려면 SQL 스키마를 위한 Querydsl 쿼라 티입을 생성해야 한다. - 다음은 이를 위한 Maven 설정 예를 보여주고 있다. - - - - com.mysema.querydsl - querydsl-maven-plugin - ${project.version} - - - - export - - - - - org.apache.derby.jdbc.EmbeddedDriver - jdbc:derby:target/demoDB;create=true - com.mycompany.mydomain - ${project.basedir}/target/generated-sources/java - - - - org.apache.derby - derby - ${derby.version} - - - -]]> - - 지정한 위치에 쿼리 타입을 성공적으로 생성했다면, 쿼리에서 그 타입을 사용할 수 있다. - - - 한 개 컬럼 쿼리: - - names = query.from(cat).list(cat.name); -]]> - - 한 쿼리에서 엔티티(예, QCat)와 테이블(예, SAnimal)에 대한 참조를 섞어 쓰고 싶다면, - 같은 변수명을 갖도록 해야 한다. SAnimal.animal은 "animal"이란 변수명을 가지므로 - 새로운 인스턴스 (new SAnimal("cat"))을 대신 사용했다. - - 다음과 같이 할 수도 있다. - - - - 다중 컬럼 쿼리: - - rows = query.from(cat).list(cat.id, cat.name); -]]> - - 모든 컬럼 쿼리: - - rows = query.from(cat).list(cat.all()); - ]]> - - SQL로 쿼리를 하고, 결과는 엔티티로 구하기: - - cats = query.from(cat).orderBy(cat.name.asc()).list(catEntity); -]]> - - 조인을 이용한 쿼리: - - - - 쿼리 결과를 DTO로 구하기: - - catDTOs = query.from(cat) - .orderBy(cat.name.asc()) - .list(ConstructorExpression.create(CatDTO.class, cat.id, cat.name)); -]]> - - JPA API 대신 하이버네이트 API를 사용한다면, HibernateSQLQuery를 사용한다. - - - - - diff --git a/querydsl-docs/src/main/docbook/ko-KR/content/tutorials/lucene.xml b/querydsl-docs/src/main/docbook/ko-KR/content/tutorials/lucene.xml deleted file mode 100644 index faec988c32..0000000000 --- a/querydsl-docs/src/main/docbook/ko-KR/content/tutorials/lucene.xml +++ /dev/null @@ -1,231 +0,0 @@ - - - - - 루신 쿼리 - - 이 절에서는 루신 모듈의 쿼리 기능을 설명한다. - - - Maven integration - - - Querydsl 루신을 사용하려면 루신 3은 querydsl-lucene3 모듈을 그리고 루신 4는 querydsl-lucene4 모듈을 사용한다. - - - 루신 3: - - - com.mysema.querydsl - querydsl-lucene3 - ${querydsl.version} - - - - org.slf4j - slf4j-log4j12 - 1.6.1 - -]]> - - 루신 4: - - - com.mysema.querydsl - querydsl-lucene4 - ${querydsl.version} - - - - org.slf4j - slf4j-log4j12 - 1.6.1 - -]]> - - - - - - 쿼리 타입 생성 - - 다음과 같은 방식으로 year와 title 필드를 가진 쿼리 타입을 직접 작성할 수 있다. - - { - private static final long serialVersionUID = -4872833626508344081L; - - public QDocument(String var) { - super(Document.class, PathMetadataFactory.forVariable(var)); - } - - public final StringPath year = createString("year"); - - public final StringPath title = createString("title"); -} -]]> - - QDocument는 year와 title 필드를 가진 루신 Document를 표현한다. - - 루신의 경우 스키마 데이터를 사용할 수 없기 때문에 코드 생성 기능을 사용할 수 없다. - - - - - - 쿼리 - - Querydsl 루신으로 쿼리하는 것은 간단하다. - - documents = query - .where(doc.year.between("1800", "2000").and(doc.title.startsWith("Huckle")) - .list(); -]]> - - 위 코드는 다음의 루신 쿼리로 바뀐다. - - - - - - - - 일반 용법 - - LuceneQuery 클래스의 cascading 메서드는 다음과 같다. - - - where: - 쿼리 필터를 추가한다. 가변인자나 and/or 메서드를 이용해서 필터를 추가한다. - PStrings에 수행되는 오퍼레이션을 지원한다. - (matches, indexOf, charAt은 제외). - 현재 in은 지원되지 않으며, 향후 지원할 예정이다. - - - - orderBy: - 정렬 표현식을 이용해서 정렬 순서를 지정한다. 숫자나 문자열에 대해서는 asc()나 desc()를 - 사용하고, OrderSpecifier에 접근하기 위해 다른 비교 표현식을 사용한다. - - - - limit, offset, restrict: - 결과의 페이징을 설정한다. limit은 최대 결과 개수, offset은 결과의 시작 행, - restrict는 limit과 offset을 함께 정의한다. - - - - - - - 정렬 - - 정렬 구문은 다음과 같다. - - - - 위 코드는 다음 루신 쿼리와 동일하다. - - -title:* - - - title과 year의 오름차순으로 결과를 정렬한다. - - sort 메서드와 Sort 인스턴스를 사용해서 정렬을 지정할 수 있다. - - - - - - - - 결과 개수 제한 - - 결과 개수 제한은 다음과 같이 한다. - - - - - - - 오프셋 - - 오프셋은 다음과 같이 지정한다. - - - - - - - - 퍼지(fuzzy) 검색 - - com.mysema.query.lucene.LuceneExpressions 클래스에서 정의된 - fuzzyLike 메서드를 이용해서 퍼지 검색을 할 수 있다. - - - - - - - - - 루신 필터를 쿼리에 적용하기 - - 단일 루신 필터를 쿼리에 적용할 수 있다. - - - - distinct 필터링을 위한 distinct(Path) 메서드를 제공한다. - - - - - - - diff --git a/querydsl-docs/src/main/docbook/ko-KR/content/tutorials/mongodb.xml b/querydsl-docs/src/main/docbook/ko-KR/content/tutorials/mongodb.xml deleted file mode 100644 index 718595b01a..0000000000 --- a/querydsl-docs/src/main/docbook/ko-KR/content/tutorials/mongodb.xml +++ /dev/null @@ -1,213 +0,0 @@ - - - - - Mongodb 쿼리 - - Mongodb 모듈의 조회 기능을 설명한다. - - - 메이븐 통합 - - - 메이븐 프로젝트에 다음 의존을 추가한다. - - - - com.mysema.querydsl - querydsl-apt - ${querydsl.version} - provided - - - - com.mysema.querydsl - querydsl-mongodb - ${querydsl.version} - - - - org.slf4j - slf4j-log4j12 - 1.6.1 - -]]> - - - Querydsl을 이용해서 쿼리 타입을 생성하기 위해 메이븐 APT 플러그인을 설정한다. - - - - - - ... - - com.mysema.maven - apt-maven-plugin - 1.0.9 - - - - process - - - target/generated-sources/java - com.mysema.query.apt.morphia.MorphiaAnnotationProcessor - - - - - ... - - - -]]> - - - MorphiaAnnotationProcessor는 com.google.code.morphia.annotations.Entity - 애노테이션이 적용된 도메인 타입을 위한 Querydsl 쿼리 타입을 생성한다. - - - - mvn clean install 을 실행하면 target/generated-sources/java 폴더에 쿼라 타입 코드가 생성된다. - - - - 이클립스를 사용중이면, mvn eclipse:eclipse 을 실행해서 - target/generated-sources/java을 이클립스 프로젝트의 소스 폴더에 포함시킨다. - - - - 이제 쿼리 도메인 모델을 이용해서 Mongodb를 조회할 수 있다. - - - - - - - 쿼리 - - Querydsl Mongodb를 이용하면 다음과 같이 간단하게 쿼리할 수 있다. - - - query = new MorphiaQuery(morphia, datastore, user); -List list = query - .where(user.firstName.eq("Bob")) - .list(); -]]> - - - - - - 일반 용법 - - MongodbQuery 클래스의 cascading 메서드는 다음과 같다. - - - where: - 쿼리 필터를 추가한다. 가변인자나 and/or 메서드를 이용해서 필터를 추가한다. - PStrings에 수행되는 오퍼레이션을 지원한다. - (matches, indexOf, charAt은 제외). - 현재 in은 지원되지 않으며, 향후 지원할 예정이다. - - - - orderBy: - 정렬 표현식을 이용해서 정렬 순서를 지정한다. 숫자나 문자열에 대해서는 - asc()나 desc()를 사용하고, OrderSpecifier에 접근하기 위해 다른 비교 표현식을 사용한다. - - - - limit, offset, restrict: - 결과의 페이징을 설정한다. limit은 최대 결과 개수, offset은 결과의 시작 행, - restrict는 limit과 offset을 함께 정의한다. - - - - - - - 정렬 - - 정렬 구문은 다음과 같다. - - - - title과 year의 오름차순으로 결과를 정렬한다. - - - - - 결과 개수 제한 - - 다음과 같이 결과 개수를 제한한다. - - - - - - - 오프셋 - - 다음과 같이 오프셋을 지정한다. - - - - - - - - 공간(Geospatial) 쿼리 - - near(Douyble[]) 메서드를 이용해서 공간 검색을 할 수 있다. - - - - - - - - 관련 필드만 선택하기 - - 관련 필드만 선택하고 싶다면, 선택 대상 목록을 갖는 list, iterate, uniqueResult, - singleResult 메서드를 사용하면 된다. - - - - - 이 쿼리는 문서의 title과 path 필드만 조회한다. - - - - diff --git a/querydsl-docs/src/main/docbook/ko-KR/content/tutorials/scala.xml b/querydsl-docs/src/main/docbook/ko-KR/content/tutorials/scala.xml deleted file mode 100644 index 7f7c8f8253..0000000000 --- a/querydsl-docs/src/main/docbook/ko-KR/content/tutorials/scala.xml +++ /dev/null @@ -1,330 +0,0 @@ - - - - - Scala에서 쿼리하기 - - querydsl-scala 모듈을 통해 Scala에서 Querydsl을 사용할 수 있다. - 이 모듈을 사용하려면 메이븐 빌드에 다음의 코드를 추가한다. - - - - com.mysema.querydsl - querydsl-scala - ${querydsl.version} - -]]> - - - - Scala를 위한 DSL 표현 - - Scala 용 Querydsl은 표현식 생성을 위한 별도 DSL을 제공한다. - Scala DSL은 가독성과 간결함을 향상시키기 위해 - 연산자 오버로딩, 함수 포인터, 임의 임포트 등 언어의 특징을 활용한다. - - - 주요 대체 DSL은 다음과 같다. - - - - 5 -expr goe 5 expr >= 5 -expr notBetween(2,6) expr not between (2,6) -expr negate -expr - -// numeric -expr add 3 expr + 3 -expr subtract 3 expr - 3 -expr divide 3 expr / 3 -expr multiply 3 expr * 3 -expr mod 5 expr % 5 - -// collection -list.get(0) list(0) -map.get("X") map("X") -]]> - - - - - 향상된 프로젝션 - - Querydsl Scala 모듈은 Querydsl의 쿼리 프로젝션을 Scala에 더욱 알맞게 만들기 위해 - 몇몇 임의 변환을 제공한다. - - - - Querydsl 쿼리에서 Scala 프로젝션을 활성화하려면 - RichProjectableRichSimpleProjectable 래퍼를 사용해야 한다. - com.mysema.query.scala.Helpers를 임포트 함으로써 필요한 임의 변환이 가능해진다. - - - - 예를 들어, 표준 API를 이용한 다음 쿼리는 Object[] 타입의 java.util.List를 리턴한다. - - - - - 임의 변환을 추가함으로써, list대신에 select를 이용해서 Scala List 타입 결과를 사용할 수 있다. - 또한, uniqueResult나 singleResult 대신에 unique와 single를 이용해서 Option 타입으로 결과를 사용할 수 있다. - - - 임의 변환을 사용하면 앞서 쿼리를 다음과 같이 작성할 수 있다. - - - - - 이 경우 결과 타입은 List[(String,String,Integer)] 즉, Tuple3[String,String,Integer]의 List가 된다. - - - - - - - SQL을 이용한 쿼리 - - - 자바를 위한 Querydsl SQL과 마찬가지로, 쿼리를 만들려면 쿼리 타입을 생성해야 한다. - 다음은 쿼리 타입 생성을 위한 코드 예제다. - - - 빈 타입 없이 생성하기: - - - - 빈 타입을 이용해서 생성하기: - - - - - - 컴팩트 쿼리 - - Querydsl Scala은 Querydls SQL을 위한 컴팩트 쿼리를 제공한다. - 이 구문은 Rogue 프레임워크의 도메인 지향 쿼리 구문에서 영감을 얻었다. - - - - RelationalPath 인스턴스를 쿼리로 임의 변환해서 도메인 지향 쿼리를 구현한다. - 서비스나 DAO 클래스가 com.mysema.query.scala.sql.SQLHelpers 트레잇을 상속하면 - 이 기능을 사용할 수 있다. - - - 컴팩트 쿼리를 사용하면, 쿼리의 시작 지점으로 메타 모델 클래스를 사용할 수 있다. - - - 다음의 일반 쿼리를 사용하는 대신에 - - - - 다음과 같이 Employee 또는 QEmployee의 companio 객체를 사용할 수 있다. - - - - 표현식에 orderBy, where, select, single, unique를 사용하는 대신, - 쿼리의 루트 표현식을 파라미터로 받고 다른 표현식을 리턴하는 함수를 사용할 수 있다. - 다음은 앞 예제를 확장한 형식이다. - - - e.firstName }, { e => e.lastName }) -]]> - - - 자세한 내용은 com.mysema.query.scala.sql.RichSimpleQuery의 시그너처를 참고하기 바란다. - - - - - - - 코드 생성 - - querydsl-maven-plugin을 이용해서 SQL 메타타입과 프로젝션을 위한 Scala 소스를 생성한다. - 다음은 설정 예다. - - - - com.mysema.querydsl - querydsl-maven-plugin - ${querydsl.version} - - com.mysql.jdbc.Driver - jdbc:mysql://localhost:3306/test - matko - matko - com.example.schema - ${project.basedir}/src/main/scala - true - true - - - - mysql - mysql-connector-java - 5.1.16 - - - com.mysema.querydsl - querydsl-scala - ${querydsl.version} - - - org.scala-lang - scala-library - ${scala.version} - - - -]]> - - querydsl:export 메이븐 골을 실행한다. - - - - - - - 다른 백엔드에 대한 쿼리 - - 다른 백엔드에 대해 쿼리를 하려면, Expression 모델을 수동으로 만들거나 별칭 함수를 사용해야 한다. - - - 다음은 JPA를 이용할 때의 예제다. - - - - 다음은 몇 가지 쿼리 예제다. - - List - - - - Unique result - - - - Long where - - - - Order - - - - Not null - - - - 쿼리 생성을 위한 팩토리 메서드 - - - - 위 쿼리를 실행하려면 다음과 같이 변수를 생성해야 한다. - - - - 하이버네이트에서 XML 기반 설정을 사용할 경우, 아직 Scala 모듈을 사용할 수 없다. - HibernateDomainExporter는 현재 자바 소스 파일 생성만 지원한다. - - - - diff --git a/querydsl-docs/src/main/docbook/ko-KR/content/tutorials/sql.xml b/querydsl-docs/src/main/docbook/ko-KR/content/tutorials/sql.xml deleted file mode 100644 index 46f8133069..0000000000 --- a/querydsl-docs/src/main/docbook/ko-KR/content/tutorials/sql.xml +++ /dev/null @@ -1,1081 +0,0 @@ - - - - - SQL 쿼리 - - 본 절에서는 SQL 모듈의 쿼라 타입 생성과 쿼리 기능을 설명한다. - - - 메이븐 통합 - - - 메이븐 프로젝트에 다음의 의존을 추가한다. - - - - com.mysema.querydsl - querydsl-sql - ${querydsl.version} - - - - com.mysema.querydsl - querydsl-sql-codegen - ${querydsl.version} - provided - - - - org.slf4j - slf4j-log4j12 - 1.6.1 - -]]> - - 코드 생성을 메이븐이나 Ant에서 할 경우 querydsl-sql-codegen 의존은 생략할 수 있다. - - - - - - 메이븐을 통한 코드 생성 - - 코드 생성은 주로 메이븐 플러그인을 통해서 수행한다. 다음은 설정 예다. - - - com.mysema.querydsl - querydsl-maven-plugin - ${querydsl.version} - - - - export - - - - - org.apache.derby.jdbc.EmbeddedDriver - jdbc:derby:target/demoDB;create=true - com.myproject.domain - ${project.basedir}/target/generated-sources/java - - - - org.apache.derby - derby - ${derby.version} - - - -]]> - - - 컴파일 소스 루트 대신에 테스트 컴파일 소스 루트로 targetFolder를 추가하려면 - test-export 골을 사용하면 된다. - - - - 파라미터 - - - - - - 이름 - 설명 - - - - - jdbcDriver - JDBC 드라이버 클래스 이름 - - - jdbcUrl - JDBC URL - - - jdbcUser - JDBC 사용자 - - - jdbcPassword - JDBC 암호 - - - namePrefix - 생성될 쿼리 클래스의 접두어 (기본: Q) - - - nameSuffix - 생성될 쿼리 클래스의 접미사 (기본: ) - - - beanPrefix - 생성될 빈Bean 클래스의 접두어 - - - beanSuffix - 생성될 빈 클래스의 접미사 - - - packageName - 생성될 소스 파일이 위치할 패키지 - - - beanPackageName - 빈 파일이 생성될 패키지 이름 (기본: packageName) - - - beanInterfaces - 빈 클래스에 추가할 인터페이스 목록 (기본: 없음) - - - beanAddToString - true로 지정하면 기본 toString() 구현을 생성 (기본: false) - - - beanAddFullConstructor - true로 지정하면 기본 생성자 외에 완전한 생성자를 생성 (기본: false) - - - beanPrintSupertype - true로 지정하면 상위 타입을 출력 (기본: false) - - - schemaPattern - 스키마 이름 패턴. 반드시 데이터베이스에 존재하는 스키마 이름과 일치해야 한다. (기본: null) - - - tableNamePattern - 테이블 이름 패턴. 반드시 데이터베이스에 존재하는 테이블 이름과 일치해야 하며, - 콤마로 구분해서 두 개 이상 지정할 수 있다. (기본: null) - - - targetFolder - 소스 파일을 생성할 폴더를 지정 - - - namingStrategyClass - NamingStrategy로 사용할 클래스 이름을 입력 (기본: DefaultNamingStrategy) - - - - beanSerializerClass - BeanSerializer로 사용할 클래스 이름 (기본: BeanSerializer) - - - serializerClass - Serializer로 사용할 클래스 이름 (기본: MetaDataSerializer) - - - exportBeans - true로 지정하면 빈을 함께 생성. 2.14.13 참고. (기본: false) - - - innerClassesForKeys - true로 지정하면 키를 내부 클래스로 생성 (기본: false) - - - validationAnnotations - true로 지정하면 Validation 어노테이션의 직렬화를 가능하게 함 (기본: false) - - - columnAnnotations - true로 지정하면 컬럼 어노테이션을 추출함 (기본: false) - - - createScalaSources - true로 지정하면 자바 소스 대신 Scala 소스로 추찰함 (기본: false) - - - schemaToPackage - true로 지정하면 스키마 이름을 패키지에 붙임 (기본: false) - - - lowerCase - true로 지정하면 이름을 소문자로 변환 (기본: false) - - - exportTables - true로 지정하면 테이블을 추출 (기본: true) - - - exportViews - true로 지정한 뷰를 추출 (기본: true) - - - exportPrimaryKeys - true로 지정하면 PK를 추출 (기본: true) - - - exportForeignKeys - true로 지정하면 외부키를 추출 (기본: true) - - - customTypes - 커스텀 사용자 타입 (기본: 없음) - - - typeMappings - 테이블.컬럼에서 자바 타입으로 매핑 (기본: 없음) - - - numericMappings - 크기/숫자에서 자바 타입으로 매핑 (기본: 없음) - - - imports - 생성된 쿼리 클래스에 추가할 자바 import 목록: 패키지의 경우 (.* 없이) 패키지 이름만(예, com.bar), 클래스의 경우 완전한 클래스 이름 (예, com.bar.Foo) 사용. (기본: 없음) - - - - -
- - 추가로 타입 구현을 등록하고 싶을 때 customTypes을 사용한다. - - - com.mysema.query.sql.types.InputStreamType - -]]> - - 테이블.컬럼을 위한 자바 타입을 등록하고 싶을 때 typeMappings를 사용한다. - - - - IMAGE
- CONTENTS - java.io.InputStream -
- -]]>
- - - 숫자 매핑을 위한 기본 타입은 다음과 같다. - - - 숫자 매핑 - - - - - - 크기 - 자리(Digits) - 타입 - - - - - > 18 - 0 - BigInteger - - - > 9 - 0 - Long - - - > 4 - 0 - Integer - - - > 2 - 0 - Short - - - > 0 - 0 - Byte - - - > 16 - > 0 - BigDecimal - - - > 0 - > 0 - Double - - - -
- - 특정 크기/자리에 대한 커스텀 타입은 다음과 같이 설정한다. - - - - 1 - 0 - java.lang.Byte - - -]]> - - Import를 사용하면 크로스 스키마 외래키 지원을 추가할 수 있다. - - APT 기반 코드 생성과 비교할 때 특정 기능은 사용할 수 없다. (예, QueryDelegate 애노테이션 처리) - -
- - - - ANT를 통한 코드 생성 - - - Querydsl-sql 모듈이 제공하는 com.mysema.query.sql.ant.AntMetaDataExporter - ANT 태스크는 ANT 태스크(어떤 ANT 태스크?)와 같은 기능을 제공한다. - 태스크의 설정 파라미터느는 - 메이븐 플러그인과 동일하다. - - - - - - - 쿼리 타입 만들기 - - DB 스키마를 Querydsl의 쿼리 타입으로 만들려면 다음과 같이 하면 된다. - - - - 위 코드를 실행하면 데이터베이스 스키마로부터 - 생성한 쿼리 타입 소스 코드(com.myproject.mydomain 패키지에 속함)를 - target/generated-sources/java 디렉토리에 만든다. - - - - 생성된 타입의 클래스 이름은 변형된 테이블 이름이 되며, - 쿼리 티입 프로퍼티 경로의 이름을 변형된 컬럼 이름이 된다. - - - - 추가로, 간략한 조인 설정을 위해 PK와 FK를 위한 필드가 추가된다. - - - - - - - 설정 - - com.mysema.query.sql.Configuration 클래스를 이용해서 설정하며, - Configuration 클래스는 생성자 인자로 Querydsl SQL Dialect를 취한다. - 예를 들어, H2 DB 사용시 다음과 같이 생성한다. - - - - Querydsl은 서로 다른 RDBMS를 위한 SQL 직렬화를 커스터마이징하기 위해 - SQL Dialect를 사용한다. 사용가능한 Dialect는 다음과 같다. - - - - - CUBRIDTemplates (tested with 8.4) - - - DerbyTemplates (tested with 10.8.2.2) - - - HSQLDBTemplates (tested with 2.2.4) - - - H2Templates (tested with 1.3.164) - - - MySQLTemplates (tested with MySQL 5.5) - - - OracleTemplates (test with Oracle 10 and 11) - - - PostgresTemplates (tested with 9.1) - - - SQLiteTemplates (tested with xerial JDBC 3.7.2) - - - SQLServerTemplates (tested with SQL Server) - - - SQLServer2005Templates (for SQL Server 2005) - - - SQLServer2008Templates (for SQL Server 2008) - - - SQLServer2012Templates (for SQL Server 2012 and later) - - - TeradataTemplates (tested with Teradata 14) - - - - - SQLTemplate 객체의 설정을 변경하려면 다음과 같이 빌더 패턴을 사용할 수 있다. - - - - Configuration 클래스를 이용하면 setUseLiterals(true)를 통한 리터럴의 직접 직렬화 활성, - 스키마와 테이블 재정의, 커스텀 타입을 등록할 수 있다. 완전한 내용은 javadoc의 - Configuration를 참고한다. - - - - - - 쿼리 - - Querydsl SQL을 이용해서 쿼리하는 방법은 다음처럼 간단하다. - - lastNames = query.from(customer) - .where(customer.firstName.eq("Bob")) - .list(customer.lastName); -]]> - - - 위 코드는 다음의 SQL로 변환되어 실행된다. - (테이블 이름은 customer, 컬럼 이름은 first_name, - last_name이라고 가정) - - - - - - - - - 일반 용법 - - SQLQuery 클래스의 cascading 메서드는 다음과 같다. - - - from: - 쿼리 소스를 추가한다. - - - - innerJoin, join, leftJoin, fullJoin, on: - 조인 부분을 추가한다. 조인 메서드에서 첫 번째 인자는 조인 소스이고, - 두 번재 인자는 대상(별칭)이다. - - - - where: - 쿼리 필터를 추가한다. 가변인자나 and/or 메서드를 이용해서 필터를 추가한다. - - - - groupBy: - 가변인자 형식의 인자를 기준으로 그룹을 추가한다. - - - - having: - Predicate 표현식을 이용해서 "group by" 그룹핑의 필터를 추가한다. - - - - orderBy: - 정렬 표현식을 이용해서 정렬 순서를 지정한다. - 숫자나 문자열에 대해서는 asc()나 desc()를 사용하고, - OrderSpecifier에 접근하기 위해 다른 비교 표현식을 사용한다. - - - - limit, offset, restrict: - 결과의 페이징을 설정한다. limit은 최대 결과 개수, offset은 결과의 시작 행, - restrict는 limit과 offset을 함께 정의한다. - - - - - - - 조인 - - 다음 구문을 이용해서 조인을 한다. - - - - 레프트 조인은 다음과 같다. - - - - 조인 조건을 쓸 수도 있다. - - - - - - - - - 정렬 - - 다음은 정렬 구문이다. - - - - 위 코드는 아래 SQL 쿼리와 동등하다. - - -SELECT c.first_name, c.last_name -FROM customer c -ORDER BY c.last_name ASC, c.first_name ASC - - - - - - - 그룹핑 - - 다음 형식을 이용해서 그룹핑을 한다. - - - - 다음은 위 코드에 해당하는 SQL 쿼리다. - - -SELECT c.last_name -FROM customer c -GROUP BY c.last_name - - - - - - - - - 서브쿼리 - - - 서브쿼리를 만들려면 SQLSubQuery를 사용하면 된다. - 서브쿼리를 만들기 위해 from 메서드로 쿼리 파라미터를 정의하고, unique나 list를 이용한다. - unique는 단일 결과를 위해 사용하고 list는 리스트 결과를 위해 사용한다. - 서브쿼리도 쿼리처럼 타입에 안전한 Querydsl 표현식이다. - - - - - 다른 예제 - - - - - - - - 리터럴 조회 - - 리터럴을 조회하려면, 다음과 같이 constant 인스턴스를 생성해주면 된다. - - - - com.mysema.query.support.Expressions 클래스는 - 프로젝션, 오퍼레이션, 템플릿 생성을 위한 유용한 정적 메서드도 제공한다. - - - - - - 쿼리 확장 지원 - - 엔진에 특화된 구문을 사용하려면 커스텀 쿼리 확장을 사용한다. - 커스텀 쿼리 확장은 AbstractSQLQuery를 상속받아 구현할 수 있다. - 다음은 MySQLQuery 클래스에서 플래그를 추가하는 예를 보여주고 있다. - - - { - - public MySQLQuery(Connection conn) { - this(conn, new MySQLTemplates(), new DefaultQueryMetadata()); - } - - public MySQLQuery(Connection conn, SQLTemplates templates) { - this(conn, templates, new DefaultQueryMetadata()); - } - - protected MySQLQuery(Connection conn, SQLTemplates templates, QueryMetadata metadata) { - super(conn, new Configuration(templates), metadata); - } - - public MySQLQuery bigResult(){ - return addFlag(Position.AFTER_SELECT, "SQL_BIG_RESULT "); - } - - public MySQLQuery bufferResult(){ - return addFlag(Position.AFTER_SELECT, "SQL_BUFFER_RESULT "); - } - - - // ... -} -]]> - - - 플래그는 직렬화 과정에서 특정 위치에 삽입될 수 있는 커스텀 SQL 부분 코드다. - com.mysema.query.QueryFlag.Position 열거 타입에 지원되는 위치가 정의되어 있다. - - - - - - - 윈도우 함수 - - Querydsl은 SQLExpressions 클래스를 통해서 윈도우 함수를 지원한다. - - 다음은 사용 예다. - - - - - - - - 다른 SQL 표현식 - - - SQLExpressions 클래스의 정적 메서드를 이용해서 다른 SQL 표현식을 사용할 수 있다. - - - - - - - DML 명령 사용하기 - - Querydsl SQL 모듈의 모든 DMLClause 구현체는 Connection, 쿼리에 사용될 SQLTemplate, - DMLClause와 엮일 메인 엔티티의 세 개 파라미터를 필요로 한다. - - - - - 삽입 - - 컬럼 지정 - - - - 컬럼 없이 - - - - 서브쿼리 이용 - - - - 서브쿼리 이용, 컬럼 없이 - - - - columns/values를 사용하는 대신, set 메서드를 이용 - - - - 위 코드는 첫 번째 예제와 동일하다. - set 메서드를 사용하면 내부적으로 columns/values가 사용된다. - - 아래 형식의 코드에서는 컬럼과 쿼리 결과 집합을 매핑하는 것에 주의하자. - - - - 변경된 행 개수 대신 생성된 키를 구하고 싶다면 executeWithKey/s 메서드를 사용한다. - - - - 위 코드는 한 개 컬럼을 매핑한다. 서브 쿼리 결과가 없으면 null을 사용한다. - - 빈의 데이터에 기반해서 clause 인스턴스를 생성하려면 다음의 코드를 사용한다. - - - - 위 코드는 빈의 데이터 중 null은 제외한다. null도 포함시키고 싶다면 아래 코드를 사용한다. - - - - - - - - - 수정 - - where 절 포함 - - - - where 절 없이 - - - - 빈을 이용 - - - - - - - - 삭제 - - where 절 포함 - - - - where 없이 - - - - - - - - - - DMLClause의 배치 지원 - - Querydsl SQL은 DML API를 통해서 JDBC 배치 업데이터를 지원한다. - 같은 구조를 갖는 DML을 연속해서 실행할 경우, addBatch() 메서드를 이용해서 - 한 DMLClause로 묶을 수 있다. - UPDATE, DELETE, INSERT에 대해 어떻게 동작하는지 예제를 살펴보자. - - - 수정: - - - - 삭제: - - - - 삽입: - - - - - - - - - 빈 클래스 생성 - - MetaDataExporter를 이용해서 테이블에 대한 자바빈 DTO 타입을 생성한다. - - - - DMLClause의 populate 메서드의 인자로 빈 타입을 사용할 수 있으며, - 쿼리에서 빈 타입을 직접 선택할 수 있다. 다음은 JUnit으로 작성한 간단한 예이다. - - - - - 앞서 예제에서 사용한 팩토리 메서드는 다음과 같다. - - e){ - return new SQLUpdateClause(Connections.getConnection(), templates, e); -} - -protected SQLInsertClause insert(RelationalPath e){ - return new SQLInsertClause(Connections.getConnection(), templates, e); -} - -protected SQLDeleteClause delete(RelationalPath e){ - return new SQLDeleteClause(Connections.getConnection(), templates, e); -} - -protected SQLMergeClause merge(RelationalPath e){ - return new SQLMergeClause(Connections.getConnection(), templates, e); -} - -protected SQLQuery query() { - return new SQLQuery(Connections.getConnection(), templates); -} - -]]> - - - - - - - - SQL 쿼리와 바인딩 추출하기 - - getSQL 메서드를 통해서 SQL 쿼리와 바인딩 값을 구할 수 있다. - - - - SQL 문자열에 포함된 모든 리터럴이 필요하다면, setUseLiterals(true)를 이용해서 - 쿼리의 리터럴 직렬화를 활성화하면 된다. - - - - - - 커스텀 타입 - - Querydsl SQL은 ResultSet/Statement에서 커스텀 타입 매핑을 지원한다. - com.mysema.query.sql.Configuration 객체를 이용해서 커스텀 카입 매핑을 등록한다. - Configuration 객체는 실제 쿼리의 생성자 인자로 제공된다. - - - - - 특정 테이블 컬럼을 위한 커스텀 타입 매핑 등록 - - (Gender.class)); -]]> - - 숫자에 대한 커스텀 타입 매핑을 등록하려면 registerNumeric 메서드를 사용한다. - - - - - 이는 Float 타입을 NUMERIC(5,2) 타입으로 매핑한다. - - - - - - Query와 Clause 리스닝 - - SQLListener는 쿼리와 DMLClause를 리스닝 할 때 사용되는 리스너 인터페이스이다. - Configuration이나 Query, Clause의 addListener 메서드를 통해서 SQLListener 객체를 등록할 수 있다. - - 리스너의 적용 예로는 데이터 동기화, 로깅, 캐싱, 검증이 있다. - - - - -
diff --git a/querydsl-docs/src/main/docbook/ko-KR/legal_notice.xml b/querydsl-docs/src/main/docbook/ko-KR/legal_notice.xml deleted file mode 100644 index 2fa6055d6f..0000000000 --- a/querydsl-docs/src/main/docbook/ko-KR/legal_notice.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - Legal Notice - - 저작권 Mysema Ltd, 2007-2013. - 이 저작물은 Apache License, Version 2.0에 따라 - 누구나 사용, 편집, 복사, 재배포 가능합니다. - - diff --git a/querydsl-docs/src/main/styles/html/custom.xsl b/querydsl-docs/src/main/styles/html/custom.xsl index 04f4b43798..ab88ae1f37 100644 --- a/querydsl-docs/src/main/styles/html/custom.xsl +++ b/querydsl-docs/src/main/styles/html/custom.xsl @@ -1,126 +1,126 @@ - - - - -]> - - - - - - - 1 - 0 - 1 - - - - images/ - .gif - - 120 - images/callouts/ - .gif - - - css/stylesheet.css - text/css - book toc,title - - text-align: left - - - - - - - - - - - 3 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + +]> + + + + + + + 1 + 0 + 1 + + + + images/ + .gif + + 120 + images/callouts/ + .gif + + + css/stylesheet.css + text/css + book toc,title + + text-align: left + + + + + + + + + + + 3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/querydsl-docs/src/main/styles/html/titlepage.xsl b/querydsl-docs/src/main/styles/html/titlepage.xsl index fbc618183b..09539c068c 100644 --- a/querydsl-docs/src/main/styles/html/titlepage.xsl +++ b/querydsl-docs/src/main/styles/html/titlepage.xsl @@ -1,61 +1,61 @@ - - - - - - - - - - - - - <subtitle/> - <!-- <corpauthor/> - <authorgroup/> - <author/> - <mediaobject/> --> - <othercredit/> - <releaseinfo/> - <copyright/> - <legalnotice/> - <pubdate/> - <revision/> - <revhistory/> - <abstract/> - </t:titlepage-content> - - <t:titlepage-content t:side="verso"> - </t:titlepage-content> - - <t:titlepage-separator> - <hr/> - </t:titlepage-separator> - - <t:titlepage-before t:side="recto"> - </t:titlepage-before> - - <t:titlepage-before t:side="verso"> - </t:titlepage-before> -</t:titlepage> - -</t:templates> +<?xml version="1.0" encoding="UTF-8"?> + +<!-- + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you 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. +--> + +<t:templates xmlns:t="http://nwalsh.com/docbook/xsl/template/1.0" + xmlns:param="http://nwalsh.com/docbook/xsl/template/1.0/param" + xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> + +<!-- ==================================================================== --> + +<t:titlepage t:element="book" t:wrapper="div" class="titlepage"> + <t:titlepage-content t:side="recto"> + <productname/> + <title/> + <subtitle/> + <!-- <corpauthor/> + <authorgroup/> + <author/> + <mediaobject/> --> + <othercredit/> + <releaseinfo/> + <copyright/> + <legalnotice/> + <pubdate/> + <revision/> + <revhistory/> + <abstract/> + </t:titlepage-content> + + <t:titlepage-content t:side="verso"> + </t:titlepage-content> + + <t:titlepage-separator> + <hr/> + </t:titlepage-separator> + + <t:titlepage-before t:side="recto"> + </t:titlepage-before> + + <t:titlepage-before t:side="verso"> + </t:titlepage-before> +</t:titlepage> + +</t:templates> diff --git a/querydsl-docs/src/main/styles/html_single/custom.xsl b/querydsl-docs/src/main/styles/html_single/custom.xsl index 4036b803ba..a9b9c698ae 100644 --- a/querydsl-docs/src/main/styles/html_single/custom.xsl +++ b/querydsl-docs/src/main/styles/html_single/custom.xsl @@ -1,126 +1,126 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<!-- - Licensed to the Apache Software Foundation (ASF) under one - or more contributor license agreements. See the NOTICE file - distributed with this work for additional information - regarding copyright ownership. The ASF licenses this file - to you 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. ---> -<!DOCTYPE xsl:stylesheet [ - <!ENTITY db_xsl_path "http://docbook.sourceforge.net/release/xsl/current"> -]> -<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" - xmlns:xslthl="http://xslthl.sf.net" - exclude-result-prefixes="xslthl" - version='1.0'> - - <xsl:import href="&db_xsl_path;/html/docbook.xsl"/> - <xsl:import href="&db_xsl_path;/html/highlight.xsl"/> - -<!-- Extensions --> - <xsl:param name="use.extensions">1</xsl:param> - <xsl:param name="tablecolumns.extension">0</xsl:param> - <xsl:param name="callout.extensions">1</xsl:param> - -<!-- Activate Graphics --> - <xsl:param name="admon.graphics" select="1"/> - <xsl:param name="admon.graphics.path">images/</xsl:param> - <xsl:param name="admon.graphics.extension">.gif</xsl:param> - <xsl:param name="callout.graphics" select="1" /> - <xsl:param name="callout.defaultcolumn">120</xsl:param> - <xsl:param name="callout.graphics.path">images/callouts/</xsl:param> - <xsl:param name="callout.graphics.extension">.gif</xsl:param> - - <xsl:param name="table.borders.with.css" select="1"/> - <xsl:param name="html.stylesheet">css/stylesheet.css</xsl:param> - <xsl:param name="html.stylesheet.type">text/css</xsl:param> - <xsl:param name="generate.toc">book toc,title</xsl:param> - - <xsl:param name="admonition.title.properties">text-align: left</xsl:param> - -<!-- Label Chapters and Sections (numbering) --> - <xsl:param name="chapter.autolabel" select="1"/> - <xsl:param name="section.autolabel" select="1"/> - <xsl:param name="section.autolabel.max.depth" select="3"/> - - <xsl:param name="section.label.includes.component.label" select="1"/> - <xsl:param name="table.footnote.number.format" select="'1'"/> - -<!-- Show only Sections up to level 3 in the TOCs --> - <xsl:param name="toc.section.depth">3</xsl:param> - -<!-- Remove "Chapter" from the Chapter titles... --> - <xsl:param name="local.l10n.xml" select="document('')"/> - <l:i18n xmlns:l="http://docbook.sourceforge.net/xmlns/l10n/1.0"> - <l:l10n language="en"> - <l:context name="title-numbered"> - <l:template name="chapter" text="%n. %t"/> - <l:template name="section" text="%n %t"/> - </l:context> - </l:l10n> - </l:i18n> - -<!-- Use code syntax highlighting --> - <xsl:param name="highlight.source" select="1"/> - - <xsl:template match='xslthl:keyword'> - <span class="hl-keyword"><xsl:value-of select='.'/></span> - </xsl:template> - - <xsl:template match='xslthl:comment'> - <span class="hl-comment"><xsl:value-of select='.'/></span> - </xsl:template> - - <xsl:template match='xslthl:oneline-comment'> - <span class="hl-comment"><xsl:value-of select='.'/></span> - </xsl:template> - - <xsl:template match='xslthl:multiline-comment'> - <span class="hl-multiline-comment"><xsl:value-of select='.'/></span> - </xsl:template> - - <xsl:template match='xslthl:tag'> - <span class="hl-tag"><xsl:value-of select='.'/></span> - </xsl:template> - - <xsl:template match='xslthl:attribute'> - <span class="hl-attribute"><xsl:value-of select='.'/></span> - </xsl:template> - - <xsl:template match='xslthl:value'> - <span class="hl-value"><xsl:value-of select='.'/></span> - </xsl:template> - - <xsl:template match='xslthl:string'> - <span class="hl-string"><xsl:value-of select='.'/></span> - </xsl:template> - - <!-- fixes --> - - <xsl:template match='xslthl:annotation'> - <span class="hl-annotation"><xsl:apply-templates/></span> - </xsl:template> - - <xsl:template match='xslthl:number'> - <span class="hl-value"><xsl:apply-templates/></span> - </xsl:template> - - <xsl:template match='xslthl:doccomment'> - <xsl:apply-templates/> - </xsl:template> - - - -</xsl:stylesheet> +<?xml version="1.0" encoding="UTF-8"?> + +<!-- + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you 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. +--> +<!DOCTYPE xsl:stylesheet [ + <!ENTITY db_xsl_path "http://docbook.sourceforge.net/release/xsl/current"> +]> +<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" + xmlns:xslthl="http://xslthl.sf.net" + exclude-result-prefixes="xslthl" + version='1.0'> + + <xsl:import href="&db_xsl_path;/html/docbook.xsl"/> + <xsl:import href="&db_xsl_path;/html/highlight.xsl"/> + +<!-- Extensions --> + <xsl:param name="use.extensions">1</xsl:param> + <xsl:param name="tablecolumns.extension">0</xsl:param> + <xsl:param name="callout.extensions">1</xsl:param> + +<!-- Activate Graphics --> + <xsl:param name="admon.graphics" select="1"/> + <xsl:param name="admon.graphics.path">images/</xsl:param> + <xsl:param name="admon.graphics.extension">.gif</xsl:param> + <xsl:param name="callout.graphics" select="1" /> + <xsl:param name="callout.defaultcolumn">120</xsl:param> + <xsl:param name="callout.graphics.path">images/callouts/</xsl:param> + <xsl:param name="callout.graphics.extension">.gif</xsl:param> + + <xsl:param name="table.borders.with.css" select="1"/> + <xsl:param name="html.stylesheet">css/stylesheet.css</xsl:param> + <xsl:param name="html.stylesheet.type">text/css</xsl:param> + <xsl:param name="generate.toc">book toc,title</xsl:param> + + <xsl:param name="admonition.title.properties">text-align: left</xsl:param> + +<!-- Label Chapters and Sections (numbering) --> + <xsl:param name="chapter.autolabel" select="1"/> + <xsl:param name="section.autolabel" select="1"/> + <xsl:param name="section.autolabel.max.depth" select="3"/> + + <xsl:param name="section.label.includes.component.label" select="1"/> + <xsl:param name="table.footnote.number.format" select="'1'"/> + +<!-- Show only Sections up to level 3 in the TOCs --> + <xsl:param name="toc.section.depth">3</xsl:param> + +<!-- Remove "Chapter" from the Chapter titles... --> + <xsl:param name="local.l10n.xml" select="document('')"/> + <l:i18n xmlns:l="http://docbook.sourceforge.net/xmlns/l10n/1.0"> + <l:l10n language="en"> + <l:context name="title-numbered"> + <l:template name="chapter" text="%n. %t"/> + <l:template name="section" text="%n %t"/> + </l:context> + </l:l10n> + </l:i18n> + +<!-- Use code syntax highlighting --> + <xsl:param name="highlight.source" select="1"/> + + <xsl:template match='xslthl:keyword'> + <span class="hl-keyword"><xsl:value-of select='.'/></span> + </xsl:template> + + <xsl:template match='xslthl:comment'> + <span class="hl-comment"><xsl:value-of select='.'/></span> + </xsl:template> + + <xsl:template match='xslthl:oneline-comment'> + <span class="hl-comment"><xsl:value-of select='.'/></span> + </xsl:template> + + <xsl:template match='xslthl:multiline-comment'> + <span class="hl-multiline-comment"><xsl:value-of select='.'/></span> + </xsl:template> + + <xsl:template match='xslthl:tag'> + <span class="hl-tag"><xsl:value-of select='.'/></span> + </xsl:template> + + <xsl:template match='xslthl:attribute'> + <span class="hl-attribute"><xsl:value-of select='.'/></span> + </xsl:template> + + <xsl:template match='xslthl:value'> + <span class="hl-value"><xsl:value-of select='.'/></span> + </xsl:template> + + <xsl:template match='xslthl:string'> + <span class="hl-string"><xsl:value-of select='.'/></span> + </xsl:template> + + <!-- fixes --> + + <xsl:template match='xslthl:annotation'> + <span class="hl-annotation"><xsl:apply-templates/></span> + </xsl:template> + + <xsl:template match='xslthl:number'> + <span class="hl-value"><xsl:apply-templates/></span> + </xsl:template> + + <xsl:template match='xslthl:doccomment'> + <xsl:apply-templates/> + </xsl:template> + + + +</xsl:stylesheet> diff --git a/querydsl-docs/src/main/styles/html_single/titlepage.xsl b/querydsl-docs/src/main/styles/html_single/titlepage.xsl index fbc618183b..09539c068c 100644 --- a/querydsl-docs/src/main/styles/html_single/titlepage.xsl +++ b/querydsl-docs/src/main/styles/html_single/titlepage.xsl @@ -1,61 +1,61 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<!-- - Licensed to the Apache Software Foundation (ASF) under one - or more contributor license agreements. See the NOTICE file - distributed with this work for additional information - regarding copyright ownership. The ASF licenses this file - to you 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. ---> - -<t:templates xmlns:t="http://nwalsh.com/docbook/xsl/template/1.0" - xmlns:param="http://nwalsh.com/docbook/xsl/template/1.0/param" - xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> - -<!-- ==================================================================== --> - -<t:titlepage t:element="book" t:wrapper="div" class="titlepage"> - <t:titlepage-content t:side="recto"> - <productname/> - <title/> - <subtitle/> - <!-- <corpauthor/> - <authorgroup/> - <author/> - <mediaobject/> --> - <othercredit/> - <releaseinfo/> - <copyright/> - <legalnotice/> - <pubdate/> - <revision/> - <revhistory/> - <abstract/> - </t:titlepage-content> - - <t:titlepage-content t:side="verso"> - </t:titlepage-content> - - <t:titlepage-separator> - <hr/> - </t:titlepage-separator> - - <t:titlepage-before t:side="recto"> - </t:titlepage-before> - - <t:titlepage-before t:side="verso"> - </t:titlepage-before> -</t:titlepage> - -</t:templates> +<?xml version="1.0" encoding="UTF-8"?> + +<!-- + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you 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. +--> + +<t:templates xmlns:t="http://nwalsh.com/docbook/xsl/template/1.0" + xmlns:param="http://nwalsh.com/docbook/xsl/template/1.0/param" + xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> + +<!-- ==================================================================== --> + +<t:titlepage t:element="book" t:wrapper="div" class="titlepage"> + <t:titlepage-content t:side="recto"> + <productname/> + <title/> + <subtitle/> + <!-- <corpauthor/> + <authorgroup/> + <author/> + <mediaobject/> --> + <othercredit/> + <releaseinfo/> + <copyright/> + <legalnotice/> + <pubdate/> + <revision/> + <revhistory/> + <abstract/> + </t:titlepage-content> + + <t:titlepage-content t:side="verso"> + </t:titlepage-content> + + <t:titlepage-separator> + <hr/> + </t:titlepage-separator> + + <t:titlepage-before t:side="recto"> + </t:titlepage-before> + + <t:titlepage-before t:side="verso"> + </t:titlepage-before> +</t:titlepage> + +</t:templates> diff --git a/querydsl-docs/src/main/styles/pdf/custom.xsl b/querydsl-docs/src/main/styles/pdf/custom.xsl index 27c742853a..120ce5d0c1 100644 --- a/querydsl-docs/src/main/styles/pdf/custom.xsl +++ b/querydsl-docs/src/main/styles/pdf/custom.xsl @@ -1,522 +1,528 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<!-- - Licensed to the Apache Software Foundation (ASF) under one - or more contributor license agreements. See the NOTICE file - distributed with this work for additional information - regarding copyright ownership. The ASF licenses this file - to you 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. ---> -<!DOCTYPE xsl:stylesheet [ - <!ENTITY db_xsl_path "http://docbook.sourceforge.net/release/xsl/current"> -]> -<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" - xmlns:fo="http://www.w3.org/1999/XSL/Format" - xmlns:xslthl="http://xslthl.sf.net" - exclude-result-prefixes="xslthl" - version='1.0'> - - <xsl:import href="&db_xsl_path;/fo/docbook.xsl"/> - - <xsl:import href="&db_xsl_path;/fo/highlight.xsl"/> - -<!-- Use nice graphics for admonitions --> - <xsl:param name="admon.graphics">'1'</xsl:param> - <xsl:param name="admon.graphics.path">@file.prefix@@dbf.xsl@/images/</xsl:param> - <xsl:param name="draft.watermark.image" select="'@file.prefix@@dbf.xsl@/images/draft.png'"/> - <xsl:param name="paper.type" select="'@paper.type@'"/> - - <xsl:param name="page.margin.top" select="'1cm'"/> - <xsl:param name="region.before.extent" select="'1cm'"/> - <xsl:param name="body.margin.top" select="'1.5cm'"/> - - <xsl:param name="body.margin.bottom" select="'1.5cm'"/> - <xsl:param name="region.after.extent" select="'1cm'"/> - <xsl:param name="page.margin.bottom" select="'1cm'"/> - <xsl:param name="title.margin.left" select="'0cm'"/> - -<!--################################################### - Header - ################################################### --> - -<!-- More space in the center header for long text --> - <xsl:attribute-set name="header.content.properties"> - <xsl:attribute name="font-family"> - <xsl:value-of select="$body.font.family"/> - </xsl:attribute> - <xsl:attribute name="margin-left">-5em</xsl:attribute> - <xsl:attribute name="margin-right">-5em</xsl:attribute> - </xsl:attribute-set> - -<!--################################################### - Table of Contents - ################################################### --> - - <xsl:param name="generate.toc"> - book toc,title - </xsl:param> - -<!--################################################### - Custom Header - ################################################### --> - - <xsl:template name="header.content"> - <xsl:param name="pageclass" select="''"/> - <xsl:param name="sequence" select="''"/> - <xsl:param name="position" select="''"/> - <xsl:param name="gentext-key" select="''"/> - - <xsl:variable name="Version"> - <xsl:choose> - <xsl:when test="//productname"> - <xsl:value-of select="//productname"/><xsl:text> </xsl:text> - </xsl:when> - <xsl:otherwise> - <xsl:text>please define productname in your docbook file!</xsl:text> - </xsl:otherwise> - </xsl:choose> - </xsl:variable> - - <xsl:choose> - <xsl:when test="$sequence='blank'"> - <xsl:choose> - <xsl:when test="$position='center'"> - <xsl:value-of select="$Version"/> - </xsl:when> - - <xsl:otherwise> - <!-- nop --> - </xsl:otherwise> - </xsl:choose> - </xsl:when> - - <xsl:when test="$pageclass='titlepage'"> - <!-- nop: other titlepage sequences have no header --> - </xsl:when> - - <xsl:when test="$position='center'"> - <xsl:value-of select="$Version"/> - </xsl:when> - - <xsl:otherwise> - <!-- nop --> - </xsl:otherwise> - </xsl:choose> - </xsl:template> - -<!--################################################### - Custom Footer - ################################################### --> - - <xsl:template name="footer.content"> - <xsl:param name="pageclass" select="''"/> - <xsl:param name="sequence" select="''"/> - <xsl:param name="position" select="''"/> - <xsl:param name="gentext-key" select="''"/> - - <xsl:variable name="Version"> - <xsl:choose> - <xsl:when test="//releaseinfo"> - <xsl:value-of select="//releaseinfo"/> - </xsl:when> - <xsl:otherwise> - <!-- nop --> - </xsl:otherwise> - </xsl:choose> - </xsl:variable> - - <xsl:variable name="Title"> - <xsl:value-of select="//title"/> - </xsl:variable> - - <xsl:choose> - <xsl:when test="$sequence='blank'"> - <xsl:choose> - <xsl:when test="$double.sided != 0 and $position = 'left'"> - <xsl:value-of select="$Version"/> - </xsl:when> - - <xsl:when test="$double.sided = 0 and $position = 'center'"> - <!-- nop --> - </xsl:when> - - <xsl:otherwise> - <fo:page-number/> - </xsl:otherwise> - </xsl:choose> - </xsl:when> - - <xsl:when test="$pageclass='titlepage'"> - <!-- nop: other titlepage sequences have no footer --> - </xsl:when> - - <xsl:when test="$double.sided != 0 and $sequence = 'even' and $position='left'"> - <fo:page-number/> - </xsl:when> - - <xsl:when test="$double.sided != 0 and $sequence = 'odd' and $position='right'"> - <fo:page-number/> - </xsl:when> - - <xsl:when test="$double.sided = 0 and $position='right'"> - <fo:page-number/> - </xsl:when> - - <xsl:when test="$double.sided != 0 and $sequence = 'odd' and $position='left'"> - <xsl:value-of select="$Version"/> - </xsl:when> - - <xsl:when test="$double.sided != 0 and $sequence = 'even' and $position='right'"> - <xsl:value-of select="$Version"/> - </xsl:when> - - <xsl:when test="$double.sided = 0 and $position='left'"> - <xsl:value-of select="$Version"/> - </xsl:when> - - <xsl:when test="$position='center'"> - <xsl:value-of select="$Title"/> - </xsl:when> - - <xsl:otherwise> - <!-- nop --> - </xsl:otherwise> - </xsl:choose> - </xsl:template> - - <xsl:template match="processing-instruction('hard-pagebreak')"> - <fo:block break-before='page'/> - </xsl:template> - -<!--################################################### - Extensions - ################################################### --> - -<!-- These extensions are required for table printing and other stuff --> - <xsl:param name="use.extensions">1</xsl:param> - <xsl:param name="tablecolumns.extension">0</xsl:param> - <xsl:param name="callout.extensions">1</xsl:param> - <xsl:param name="fop.extensions">1</xsl:param> - -<!--################################################### - Paper & Page Size - ################################################### --> - -<!-- Paper type, no headers on blank pages, no double sided printing --> - <xsl:param name="double.sided">0</xsl:param> - <xsl:param name="headers.on.blank.pages">0</xsl:param> - <xsl:param name="footers.on.blank.pages">0</xsl:param> - -<!--################################################### - Fonts & Styles - ################################################### --> - - <xsl:param name="hyphenate">false</xsl:param> - -<!-- Default Font size --> - <xsl:param name="body.font.master">11</xsl:param> - <xsl:param name="body.font.small">8</xsl:param> - -<!-- Line height in body text --> - <xsl:param name="line-height">1.4</xsl:param> - -<!-- Chapter title size --> - <xsl:attribute-set name="chapter.titlepage.recto.style"> - <xsl:attribute name="text-align">left</xsl:attribute> - <xsl:attribute name="font-weight">bold</xsl:attribute> - <xsl:attribute name="font-size"> - <xsl:value-of select="$body.font.master * 1.8"/> - <xsl:text>pt</xsl:text> - </xsl:attribute> - </xsl:attribute-set> - -<!-- Why is the font-size for chapters hardcoded in the XSL FO templates? - Let's remove it, so this sucker can use our attribute-set only... --> - <xsl:template match="title" mode="chapter.titlepage.recto.auto.mode"> - <fo:block xmlns:fo="http://www.w3.org/1999/XSL/Format" - xsl:use-attribute-sets="chapter.titlepage.recto.style"> - <xsl:call-template name="component.title"> - <xsl:with-param name="node" select="ancestor-or-self::chapter[1]"/> - </xsl:call-template> - </fo:block> - </xsl:template> - -<!-- Sections 1, 2 and 3 titles have a small bump factor and padding --> - <xsl:attribute-set name="section.title.level1.properties"> - <xsl:attribute name="space-before.optimum">0.8em</xsl:attribute> - <xsl:attribute name="space-before.minimum">0.8em</xsl:attribute> - <xsl:attribute name="space-before.maximum">0.8em</xsl:attribute> - <xsl:attribute name="font-size"> - <xsl:value-of select="$body.font.master * 1.5"/> - <xsl:text>pt</xsl:text> - </xsl:attribute> - <xsl:attribute name="space-after.optimum">0.1em</xsl:attribute> - <xsl:attribute name="space-after.minimum">0.1em</xsl:attribute> - <xsl:attribute name="space-after.maximum">0.1em</xsl:attribute> - </xsl:attribute-set> - <xsl:attribute-set name="section.title.level2.properties"> - <xsl:attribute name="space-before.optimum">0.6em</xsl:attribute> - <xsl:attribute name="space-before.minimum">0.6em</xsl:attribute> - <xsl:attribute name="space-before.maximum">0.6em</xsl:attribute> - <xsl:attribute name="font-size"> - <xsl:value-of select="$body.font.master * 1.25"/> - <xsl:text>pt</xsl:text> - </xsl:attribute> - <xsl:attribute name="space-after.optimum">0.1em</xsl:attribute> - <xsl:attribute name="space-after.minimum">0.1em</xsl:attribute> - <xsl:attribute name="space-after.maximum">0.1em</xsl:attribute> - </xsl:attribute-set> - <xsl:attribute-set name="section.title.level3.properties"> - <xsl:attribute name="space-before.optimum">0.4em</xsl:attribute> - <xsl:attribute name="space-before.minimum">0.4em</xsl:attribute> - <xsl:attribute name="space-before.maximum">0.4em</xsl:attribute> - <xsl:attribute name="font-size"> - <xsl:value-of select="$body.font.master * 1.0"/> - <xsl:text>pt</xsl:text> - </xsl:attribute> - <xsl:attribute name="space-after.optimum">0.1em</xsl:attribute> - <xsl:attribute name="space-after.minimum">0.1em</xsl:attribute> - <xsl:attribute name="space-after.maximum">0.1em</xsl:attribute> - </xsl:attribute-set> - -<!-- Use code syntax highlighting --> - <xsl:param name="highlight.source" select="1"/> - <xsl:param name="highlight.default.language" select="xml" /> - - <xsl:template match='xslthl:keyword'> - <fo:inline font-weight="bold" color="#7F0055"><xsl:apply-templates/></fo:inline> - </xsl:template> - - <xsl:template match='xslthl:comment'> - <fo:inline font-style="italic" color="#3F5F5F"><xsl:apply-templates/></fo:inline> - </xsl:template> - - <xsl:template match='xslthl:oneline-comment'> - <fo:inline font-style="italic" color="#3F5F5F"><xsl:apply-templates/></fo:inline> - </xsl:template> - - <xsl:template match='xslthl:multiline-comment'> - <fo:inline font-style="italic" color="#3F5FBF"><xsl:apply-templates/></fo:inline> - </xsl:template> - - <xsl:template match='xslthl:tag'> - <fo:inline color="#3F7F7F"><xsl:apply-templates/></fo:inline> - </xsl:template> - - <xsl:template match='xslthl:attribute'> - <fo:inline color="#7F007F"><xsl:apply-templates/></fo:inline> - </xsl:template> - - <xsl:template match='xslthl:value'> - <fo:inline color="#2A00FF"><xsl:apply-templates/></fo:inline> - </xsl:template> - - <xsl:template match='xslthl:string'> - <fo:inline color="#2A00FF"><xsl:apply-templates/></fo:inline> - </xsl:template> - - <!-- fixes --> - - <xsl:template match='xslthl:annotation'> - <xsl:apply-templates/> - </xsl:template> - - <xsl:template match='xslthl:number'> - <fo:inline color="#2A00FF"><xsl:apply-templates/></fo:inline> - </xsl:template> - -<!--################################################### - Tables - ################################################### --> - - <!-- Some padding inside tables --> - <xsl:attribute-set name="table.cell.padding"> - <xsl:attribute name="padding-left">4pt</xsl:attribute> - <xsl:attribute name="padding-right">4pt</xsl:attribute> - <xsl:attribute name="padding-top">4pt</xsl:attribute> - <xsl:attribute name="padding-bottom">4pt</xsl:attribute> - </xsl:attribute-set> - -<!-- Only hairlines as frame and cell borders in tables --> - <xsl:param name="table.frame.border.thickness">0.1pt</xsl:param> - <xsl:param name="table.cell.border.thickness">0.1pt</xsl:param> - -<!--################################################### - Labels - ################################################### --> - -<!-- Label Chapters and Sections (numbering) --> - <xsl:param name="chapter.autolabel" select="1"/> - <xsl:param name="section.autolabel" select="1"/> - <xsl:param name="section.autolabel.max.depth" select="1"/> - - <xsl:param name="section.label.includes.component.label" select="1"/> - <xsl:param name="table.footnote.number.format" select="'1'"/> - -<!--################################################### - Programlistings - ################################################### --> - -<!-- Verbatim text formatting (programlistings) --> - <xsl:attribute-set name="monospace.verbatim.properties"> - <xsl:attribute name="font-size"> - <xsl:value-of select="$body.font.small * 1.0"/> - <xsl:text>pt</xsl:text> - </xsl:attribute> - </xsl:attribute-set> - - <xsl:attribute-set name="verbatim.properties"> - <xsl:attribute name="space-before.minimum">1em</xsl:attribute> - <xsl:attribute name="space-before.optimum">1em</xsl:attribute> - <xsl:attribute name="space-before.maximum">1em</xsl:attribute> - <xsl:attribute name="space-after.minimum">0.1em</xsl:attribute> - <xsl:attribute name="space-after.optimum">0.1em</xsl:attribute> - <xsl:attribute name="space-after.maximum">0.1em</xsl:attribute> - - <xsl:attribute name="border-color">#444444</xsl:attribute> - <xsl:attribute name="border-style">solid</xsl:attribute> - <xsl:attribute name="border-width">0.1pt</xsl:attribute> - <xsl:attribute name="padding-top">0.5em</xsl:attribute> - <xsl:attribute name="padding-left">0.5em</xsl:attribute> - <xsl:attribute name="padding-right">0.5em</xsl:attribute> - <xsl:attribute name="padding-bottom">0.5em</xsl:attribute> - <xsl:attribute name="margin-left">0.5em</xsl:attribute> - <xsl:attribute name="margin-right">0.5em</xsl:attribute> - </xsl:attribute-set> - - <!-- Shade (background) programlistings --> - <xsl:param name="shade.verbatim">1</xsl:param> - <xsl:attribute-set name="shade.verbatim.style"> - <xsl:attribute name="background-color">#F0F0F0</xsl:attribute> - </xsl:attribute-set> - - <xsl:attribute-set name="list.block.spacing"> - <xsl:attribute name="space-before.optimum">0.1em</xsl:attribute> - <xsl:attribute name="space-before.minimum">0.1em</xsl:attribute> - <xsl:attribute name="space-before.maximum">0.1em</xsl:attribute> - <xsl:attribute name="space-after.optimum">0.1em</xsl:attribute> - <xsl:attribute name="space-after.minimum">0.1em</xsl:attribute> - <xsl:attribute name="space-after.maximum">0.1em</xsl:attribute> - </xsl:attribute-set> - - <xsl:attribute-set name="example.properties"> - <xsl:attribute name="space-before.minimum">0.5em</xsl:attribute> - <xsl:attribute name="space-before.optimum">0.5em</xsl:attribute> - <xsl:attribute name="space-before.maximum">0.5em</xsl:attribute> - <xsl:attribute name="space-after.minimum">0.1em</xsl:attribute> - <xsl:attribute name="space-after.optimum">0.1em</xsl:attribute> - <xsl:attribute name="space-after.maximum">0.1em</xsl:attribute> - <xsl:attribute name="keep-together.within-column">always</xsl:attribute> - </xsl:attribute-set> - -<!--################################################### - Title information for Figures, Examples etc. - ################################################### --> - - <xsl:attribute-set name="formal.title.properties" use-attribute-sets="normal.para.spacing"> - <xsl:attribute name="font-weight">normal</xsl:attribute> - <xsl:attribute name="font-style">italic</xsl:attribute> - <xsl:attribute name="font-size"> - <xsl:value-of select="$body.font.master"/> - <xsl:text>pt</xsl:text> - </xsl:attribute> - <xsl:attribute name="hyphenate">false</xsl:attribute> - <xsl:attribute name="space-before.minimum">0.1em</xsl:attribute> - <xsl:attribute name="space-before.optimum">0.1em</xsl:attribute> - <xsl:attribute name="space-before.maximum">0.1em</xsl:attribute> - </xsl:attribute-set> - -<!--################################################### - Callouts - ################################################### --> - -<!-- don't use images for callouts --> - <xsl:param name="callout.graphics">0</xsl:param> - <xsl:param name="callout.unicode">1</xsl:param> - -<!-- Place callout marks at this column in annotated areas --> - <xsl:param name="callout.defaultcolumn">90</xsl:param> - -<!--################################################### - Misc - ################################################### --> - -<!-- Placement of titles --> - <xsl:param name="formal.title.placement"> - figure after - example after - equation before - table before - procedure before - </xsl:param> - -<!-- Format Variable Lists as Blocks (prevents horizontal overflow) --> - <xsl:param name="variablelist.as.blocks">1</xsl:param> - - <xsl:param name="body.start.indent">0pt</xsl:param> - -<!-- Show only Sections up to level 3 in the TOCs --> - <xsl:param name="toc.section.depth">3</xsl:param> - -<!-- Remove "Chapter" from the Chapter titles... --> - <xsl:param name="local.l10n.xml" select="document('')"/> - <l:i18n xmlns:l="http://docbook.sourceforge.net/xmlns/l10n/1.0"> - <l:l10n language="en"> - <l:context name="title-numbered"> - <l:template name="chapter" text="%n. %t"/> - <l:template name="section" text="%n %t"/> - </l:context> - <l:context name="title"> - <l:template name="example" text="Example %n %t"/> - </l:context> - </l:l10n> - </l:i18n> - -<!--################################################### - colored and hyphenated links - ################################################### --> - - <xsl:template match="ulink"> - <fo:basic-link external-destination="{@url}" - xsl:use-attribute-sets="xref.properties" - text-decoration="underline" - color="blue"> - <xsl:choose> - <xsl:when test="count(child::node())=0"> - <xsl:value-of select="@url"/> - </xsl:when> - <xsl:otherwise> - <xsl:apply-templates/> - </xsl:otherwise> - </xsl:choose> - </fo:basic-link> - </xsl:template> - - <xsl:template match="link"> - <fo:basic-link internal-destination="{@linkend}" - xsl:use-attribute-sets="xref.properties" - text-decoration="underline" - color="blue"> - <xsl:choose> - <xsl:when test="count(child::node())=0"> - <xsl:value-of select="@linkend"/> - </xsl:when> - <xsl:otherwise> - <xsl:apply-templates/> - </xsl:otherwise> - </xsl:choose> - </fo:basic-link> - </xsl:template> - +<?xml version="1.0" encoding="UTF-8"?> + +<!-- + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you 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. +--> +<!DOCTYPE xsl:stylesheet [ + <!ENTITY db_xsl_path "http://docbook.sourceforge.net/release/xsl/current"> +]> +<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" + xmlns:fo="http://www.w3.org/1999/XSL/Format" + xmlns:xslthl="http://xslthl.sf.net" + exclude-result-prefixes="xslthl" + version='1.0'> + + <xsl:import href="&db_xsl_path;/fo/docbook.xsl"/> + + <xsl:import href="&db_xsl_path;/fo/highlight.xsl"/> + +<!-- Use nice graphics for admonitions --> + <xsl:param name="admon.graphics">'1'</xsl:param> + <xsl:param name="admon.graphics.path">@file.prefix@@dbf.xsl@/images/</xsl:param> + <xsl:param name="draft.watermark.image" select="'@file.prefix@@dbf.xsl@/images/draft.png'"/> + <xsl:param name="paper.type" select="'@paper.type@'"/> + + <xsl:param name="page.margin.top" select="'1cm'"/> + <xsl:param name="region.before.extent" select="'1cm'"/> + <xsl:param name="body.margin.top" select="'1.5cm'"/> + + <xsl:param name="body.margin.bottom" select="'1.5cm'"/> + <xsl:param name="region.after.extent" select="'1cm'"/> + <xsl:param name="page.margin.bottom" select="'1cm'"/> + <xsl:param name="title.margin.left" select="'0cm'"/> + +<!--################################################### + Header + ################################################### --> + +<!-- More space in the center header for long text --> + <xsl:attribute-set name="header.content.properties"> + <xsl:attribute name="font-family"> + <xsl:value-of select="$body.font.family"/> + </xsl:attribute> + <xsl:attribute name="margin-left">-5em</xsl:attribute> + <xsl:attribute name="margin-right">-5em</xsl:attribute> + </xsl:attribute-set> + +<!--################################################### + Table of Contents + ################################################### --> + + <xsl:param name="generate.toc"> + book toc,title + </xsl:param> + +<!--################################################### + Custom Header + ################################################### --> + + <xsl:template name="header.content"> + <xsl:param name="pageclass" select="''"/> + <xsl:param name="sequence" select="''"/> + <xsl:param name="position" select="''"/> + <xsl:param name="gentext-key" select="''"/> + + <xsl:variable name="Version"> + <xsl:choose> + <xsl:when test="//productname"> + <xsl:value-of select="//productname"/><xsl:text> </xsl:text> + </xsl:when> + <xsl:otherwise> + <xsl:text>please define productname in your docbook file!</xsl:text> + </xsl:otherwise> + </xsl:choose> + </xsl:variable> + + <xsl:choose> + <xsl:when test="$sequence='blank'"> + <xsl:choose> + <xsl:when test="$position='center'"> + <xsl:value-of select="$Version"/> + </xsl:when> + + <xsl:otherwise> + <!-- nop --> + </xsl:otherwise> + </xsl:choose> + </xsl:when> + + <xsl:when test="$pageclass='titlepage'"> + <!-- nop: other titlepage sequences have no header --> + </xsl:when> + + <xsl:when test="$position='center'"> + <xsl:value-of select="$Version"/> + </xsl:when> + + <xsl:otherwise> + <!-- nop --> + </xsl:otherwise> + </xsl:choose> + </xsl:template> + +<!--################################################### + Custom Footer + ################################################### --> + + <xsl:template name="footer.content"> + <xsl:param name="pageclass" select="''"/> + <xsl:param name="sequence" select="''"/> + <xsl:param name="position" select="''"/> + <xsl:param name="gentext-key" select="''"/> + + <xsl:variable name="Version"> + <xsl:choose> + <xsl:when test="//releaseinfo"> + <xsl:value-of select="//releaseinfo"/> + </xsl:when> + <xsl:otherwise> + <!-- nop --> + </xsl:otherwise> + </xsl:choose> + </xsl:variable> + + <xsl:variable name="Title"> + <xsl:value-of select="//title"/> + </xsl:variable> + + <xsl:choose> + <xsl:when test="$sequence='blank'"> + <xsl:choose> + <xsl:when test="$double.sided != 0 and $position = 'left'"> + <xsl:value-of select="$Version"/> + </xsl:when> + + <xsl:when test="$double.sided = 0 and $position = 'center'"> + <!-- nop --> + </xsl:when> + + <xsl:otherwise> + <fo:page-number/> + </xsl:otherwise> + </xsl:choose> + </xsl:when> + + <xsl:when test="$pageclass='titlepage'"> + <!-- nop: other titlepage sequences have no footer --> + </xsl:when> + + <xsl:when test="$double.sided != 0 and $sequence = 'even' and $position='left'"> + <fo:page-number/> + </xsl:when> + + <xsl:when test="$double.sided != 0 and $sequence = 'odd' and $position='right'"> + <fo:page-number/> + </xsl:when> + + <xsl:when test="$double.sided = 0 and $position='right'"> + <fo:page-number/> + </xsl:when> + + <xsl:when test="$double.sided != 0 and $sequence = 'odd' and $position='left'"> + <xsl:value-of select="$Version"/> + </xsl:when> + + <xsl:when test="$double.sided != 0 and $sequence = 'even' and $position='right'"> + <xsl:value-of select="$Version"/> + </xsl:when> + + <xsl:when test="$double.sided = 0 and $position='left'"> + <xsl:value-of select="$Version"/> + </xsl:when> + + <xsl:when test="$position='center'"> + <xsl:value-of select="$Title"/> + </xsl:when> + + <xsl:otherwise> + <!-- nop --> + </xsl:otherwise> + </xsl:choose> + </xsl:template> + + <xsl:template match="processing-instruction('hard-pagebreak')"> + <fo:block break-before='page'/> + </xsl:template> + +<!--################################################### + Extensions + ################################################### --> + +<!-- These extensions are required for table printing and other stuff --> + <xsl:param name="use.extensions">1</xsl:param> + <xsl:param name="tablecolumns.extension">0</xsl:param> + <xsl:param name="callout.extensions">1</xsl:param> + <xsl:param name="fop.extensions">1</xsl:param> + +<!--################################################### + Paper & Page Size + ################################################### --> + +<!-- Paper type, no headers on blank pages, no double sided printing --> + <xsl:param name="double.sided">0</xsl:param> + <xsl:param name="headers.on.blank.pages">0</xsl:param> + <xsl:param name="footers.on.blank.pages">0</xsl:param> + +<!--################################################### + Fonts & Styles + ################################################### --> + + <xsl:param name="hyphenate">false</xsl:param> + +<!-- Default Font size --> + <xsl:param name="body.font.master">11</xsl:param> + <xsl:param name="body.font.small">8</xsl:param> + +<!-- Line height in body text --> + <xsl:param name="line-height">1.4</xsl:param> + +<!-- Chapter title size --> + <xsl:attribute-set name="chapter.titlepage.recto.style"> + <xsl:attribute name="text-align">left</xsl:attribute> + <xsl:attribute name="font-weight">bold</xsl:attribute> + <xsl:attribute name="font-size"> + <xsl:value-of select="$body.font.master * 1.8"/> + <xsl:text>pt</xsl:text> + </xsl:attribute> + </xsl:attribute-set> + +<!-- Why is the font-size for chapters hardcoded in the XSL FO templates? + Let's remove it, so this sucker can use our attribute-set only... --> + <xsl:template match="title" mode="chapter.titlepage.recto.auto.mode"> + <fo:block xmlns:fo="http://www.w3.org/1999/XSL/Format" + xsl:use-attribute-sets="chapter.titlepage.recto.style"> + <xsl:call-template name="component.title"> + <xsl:with-param name="node" select="ancestor-or-self::chapter[1]"/> + </xsl:call-template> + </fo:block> + </xsl:template> + + <!-- Start each chapter on a new page --> + <xsl:attribute-set name="chapter.title.properties"> + <xsl:attribute name="break-before">page</xsl:attribute> + </xsl:attribute-set> + +<!-- Sections 1, 2 and 3 titles have a small bump factor and padding --> + <xsl:attribute-set name="section.title.level1.properties"> + <xsl:attribute name="space-before.optimum">0.8em</xsl:attribute> + <xsl:attribute name="space-before.minimum">0.8em</xsl:attribute> + <xsl:attribute name="space-before.maximum">0.8em</xsl:attribute> + <xsl:attribute name="font-size"> + <xsl:value-of select="$body.font.master * 1.5"/> + <xsl:text>pt</xsl:text> + </xsl:attribute> + <xsl:attribute name="space-after.optimum">0.1em</xsl:attribute> + <xsl:attribute name="space-after.minimum">0.1em</xsl:attribute> + <xsl:attribute name="space-after.maximum">0.1em</xsl:attribute> + </xsl:attribute-set> + <xsl:attribute-set name="section.title.level2.properties"> + <xsl:attribute name="space-before.optimum">0.6em</xsl:attribute> + <xsl:attribute name="space-before.minimum">0.6em</xsl:attribute> + <xsl:attribute name="space-before.maximum">0.6em</xsl:attribute> + <xsl:attribute name="font-size"> + <xsl:value-of select="$body.font.master * 1.25"/> + <xsl:text>pt</xsl:text> + </xsl:attribute> + <xsl:attribute name="space-after.optimum">0.1em</xsl:attribute> + <xsl:attribute name="space-after.minimum">0.1em</xsl:attribute> + <xsl:attribute name="space-after.maximum">0.1em</xsl:attribute> + </xsl:attribute-set> + <xsl:attribute-set name="section.title.level3.properties"> + <xsl:attribute name="space-before.optimum">0.4em</xsl:attribute> + <xsl:attribute name="space-before.minimum">0.4em</xsl:attribute> + <xsl:attribute name="space-before.maximum">0.4em</xsl:attribute> + <xsl:attribute name="font-size"> + <xsl:value-of select="$body.font.master * 1.0"/> + <xsl:text>pt</xsl:text> + </xsl:attribute> + <xsl:attribute name="space-after.optimum">0.1em</xsl:attribute> + <xsl:attribute name="space-after.minimum">0.1em</xsl:attribute> + <xsl:attribute name="space-after.maximum">0.1em</xsl:attribute> + </xsl:attribute-set> + +<!-- Use code syntax highlighting --> + <xsl:param name="highlight.source" select="1"/> + <xsl:param name="highlight.default.language" select="xml" /> + + <xsl:template match='xslthl:keyword'> + <fo:inline font-weight="bold" color="#7F0055"><xsl:apply-templates/></fo:inline> + </xsl:template> + + <xsl:template match='xslthl:comment'> + <fo:inline font-style="italic" color="#3F5F5F"><xsl:apply-templates/></fo:inline> + </xsl:template> + + <xsl:template match='xslthl:oneline-comment'> + <fo:inline font-style="italic" color="#3F5F5F"><xsl:apply-templates/></fo:inline> + </xsl:template> + + <xsl:template match='xslthl:multiline-comment'> + <fo:inline font-style="italic" color="#3F5FBF"><xsl:apply-templates/></fo:inline> + </xsl:template> + + <xsl:template match='xslthl:tag'> + <fo:inline color="#3F7F7F"><xsl:apply-templates/></fo:inline> + </xsl:template> + + <xsl:template match='xslthl:attribute'> + <fo:inline color="#7F007F"><xsl:apply-templates/></fo:inline> + </xsl:template> + + <xsl:template match='xslthl:value'> + <fo:inline color="#2A00FF"><xsl:apply-templates/></fo:inline> + </xsl:template> + + <xsl:template match='xslthl:string'> + <fo:inline color="#2A00FF"><xsl:apply-templates/></fo:inline> + </xsl:template> + + <!-- fixes --> + + <xsl:template match='xslthl:annotation'> + <xsl:apply-templates/> + </xsl:template> + + <xsl:template match='xslthl:number'> + <fo:inline color="#2A00FF"><xsl:apply-templates/></fo:inline> + </xsl:template> + +<!--################################################### + Tables + ################################################### --> + + <!-- Some padding inside tables --> + <xsl:attribute-set name="table.cell.padding"> + <xsl:attribute name="padding-left">4pt</xsl:attribute> + <xsl:attribute name="padding-right">4pt</xsl:attribute> + <xsl:attribute name="padding-top">4pt</xsl:attribute> + <xsl:attribute name="padding-bottom">4pt</xsl:attribute> + </xsl:attribute-set> + +<!-- Only hairlines as frame and cell borders in tables --> + <xsl:param name="table.frame.border.thickness">0.1pt</xsl:param> + <xsl:param name="table.cell.border.thickness">0.1pt</xsl:param> + +<!--################################################### + Labels + ################################################### --> + +<!-- Label Chapters and Sections (numbering) --> + <xsl:param name="chapter.autolabel" select="1"/> + <xsl:param name="section.autolabel" select="1"/> + <xsl:param name="section.autolabel.max.depth" select="1"/> + + <xsl:param name="section.label.includes.component.label" select="1"/> + <xsl:param name="table.footnote.number.format" select="'1'"/> + +<!--################################################### + Programlistings + ################################################### --> + +<!-- Verbatim text formatting (programlistings) --> + <xsl:attribute-set name="monospace.verbatim.properties"> + <xsl:attribute name="font-size"> + <xsl:value-of select="$body.font.small * 1.0"/> + <xsl:text>pt</xsl:text> + </xsl:attribute> + </xsl:attribute-set> + + <xsl:attribute-set name="verbatim.properties"> + <xsl:attribute name="space-before.minimum">1em</xsl:attribute> + <xsl:attribute name="space-before.optimum">1em</xsl:attribute> + <xsl:attribute name="space-before.maximum">1em</xsl:attribute> + <xsl:attribute name="space-after.minimum">0.1em</xsl:attribute> + <xsl:attribute name="space-after.optimum">0.1em</xsl:attribute> + <xsl:attribute name="space-after.maximum">0.1em</xsl:attribute> + + <xsl:attribute name="border-color">#444444</xsl:attribute> + <xsl:attribute name="border-style">solid</xsl:attribute> + <xsl:attribute name="border-width">0.1pt</xsl:attribute> + <xsl:attribute name="padding-top">0.5em</xsl:attribute> + <xsl:attribute name="padding-left">0.5em</xsl:attribute> + <xsl:attribute name="padding-right">0.5em</xsl:attribute> + <xsl:attribute name="padding-bottom">0.5em</xsl:attribute> + <xsl:attribute name="margin-left">0.5em</xsl:attribute> + <xsl:attribute name="margin-right">0.5em</xsl:attribute> + <xsl:attribute name="keep-together.within-page">always</xsl:attribute> + </xsl:attribute-set> + + <!-- Shade (background) programlistings --> + <xsl:param name="shade.verbatim">1</xsl:param> + <xsl:attribute-set name="shade.verbatim.style"> + <xsl:attribute name="background-color">#F0F0F0</xsl:attribute> + </xsl:attribute-set> + + <xsl:attribute-set name="list.block.spacing"> + <xsl:attribute name="space-before.optimum">0.1em</xsl:attribute> + <xsl:attribute name="space-before.minimum">0.1em</xsl:attribute> + <xsl:attribute name="space-before.maximum">0.1em</xsl:attribute> + <xsl:attribute name="space-after.optimum">0.1em</xsl:attribute> + <xsl:attribute name="space-after.minimum">0.1em</xsl:attribute> + <xsl:attribute name="space-after.maximum">0.1em</xsl:attribute> + </xsl:attribute-set> + + <xsl:attribute-set name="example.properties"> + <xsl:attribute name="space-before.minimum">0.5em</xsl:attribute> + <xsl:attribute name="space-before.optimum">0.5em</xsl:attribute> + <xsl:attribute name="space-before.maximum">0.5em</xsl:attribute> + <xsl:attribute name="space-after.minimum">0.1em</xsl:attribute> + <xsl:attribute name="space-after.optimum">0.1em</xsl:attribute> + <xsl:attribute name="space-after.maximum">0.1em</xsl:attribute> + <xsl:attribute name="keep-together.within-column">always</xsl:attribute> + </xsl:attribute-set> + +<!--################################################### + Title information for Figures, Examples etc. + ################################################### --> + + <xsl:attribute-set name="formal.title.properties" use-attribute-sets="normal.para.spacing"> + <xsl:attribute name="font-weight">normal</xsl:attribute> + <xsl:attribute name="font-style">italic</xsl:attribute> + <xsl:attribute name="font-size"> + <xsl:value-of select="$body.font.master"/> + <xsl:text>pt</xsl:text> + </xsl:attribute> + <xsl:attribute name="hyphenate">false</xsl:attribute> + <xsl:attribute name="space-before.minimum">0.1em</xsl:attribute> + <xsl:attribute name="space-before.optimum">0.1em</xsl:attribute> + <xsl:attribute name="space-before.maximum">0.1em</xsl:attribute> + </xsl:attribute-set> + +<!--################################################### + Callouts + ################################################### --> + +<!-- don't use images for callouts --> + <xsl:param name="callout.graphics">0</xsl:param> + <xsl:param name="callout.unicode">1</xsl:param> + +<!-- Place callout marks at this column in annotated areas --> + <xsl:param name="callout.defaultcolumn">90</xsl:param> + +<!--################################################### + Misc + ################################################### --> + +<!-- Placement of titles --> + <xsl:param name="formal.title.placement"> + figure after + example after + equation before + table before + procedure before + </xsl:param> + +<!-- Format Variable Lists as Blocks (prevents horizontal overflow) --> + <xsl:param name="variablelist.as.blocks">1</xsl:param> + + <xsl:param name="body.start.indent">0pt</xsl:param> + +<!-- Show only Sections up to level 3 in the TOCs --> + <xsl:param name="toc.section.depth">3</xsl:param> + +<!-- Remove "Chapter" from the Chapter titles... --> + <xsl:param name="local.l10n.xml" select="document('')"/> + <l:i18n xmlns:l="http://docbook.sourceforge.net/xmlns/l10n/1.0"> + <l:l10n language="en"> + <l:context name="title-numbered"> + <l:template name="chapter" text="%n. %t"/> + <l:template name="section" text="%n %t"/> + </l:context> + <l:context name="title"> + <l:template name="example" text="Example %n %t"/> + </l:context> + </l:l10n> + </l:i18n> + +<!--################################################### + colored and hyphenated links + ################################################### --> + + <xsl:template match="ulink"> + <fo:basic-link external-destination="{@url}" + xsl:use-attribute-sets="xref.properties" + text-decoration="underline" + color="blue"> + <xsl:choose> + <xsl:when test="count(child::node())=0"> + <xsl:value-of select="@url"/> + </xsl:when> + <xsl:otherwise> + <xsl:apply-templates/> + </xsl:otherwise> + </xsl:choose> + </fo:basic-link> + </xsl:template> + + <xsl:template match="link"> + <fo:basic-link internal-destination="{@linkend}" + xsl:use-attribute-sets="xref.properties" + text-decoration="underline" + color="blue"> + <xsl:choose> + <xsl:when test="count(child::node())=0"> + <xsl:value-of select="@linkend"/> + </xsl:when> + <xsl:otherwise> + <xsl:apply-templates/> + </xsl:otherwise> + </xsl:choose> + </fo:basic-link> + </xsl:template> + </xsl:stylesheet> \ No newline at end of file diff --git a/querydsl-docs/src/main/styles/pdf/titlepage.xsl b/querydsl-docs/src/main/styles/pdf/titlepage.xsl index e2825243de..dc18e1e0de 100644 --- a/querydsl-docs/src/main/styles/pdf/titlepage.xsl +++ b/querydsl-docs/src/main/styles/pdf/titlepage.xsl @@ -1,101 +1,101 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<!-- - Licensed to the Apache Software Foundation (ASF) under one - or more contributor license agreements. See the NOTICE file - distributed with this work for additional information - regarding copyright ownership. The ASF licenses this file - to you 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. ---> - -<!DOCTYPE t:templates [ -<!ENTITY hsize0 "10pt"> -<!ENTITY hsize1 "12pt"> -<!ENTITY hsize2 "14.4pt"> -<!ENTITY hsize3 "17.28pt"> -<!ENTITY hsize4 "20.736pt"> -<!ENTITY hsize5 "24.8832pt"> -<!ENTITY hsize0space "7.5pt"> <!-- 0.75 * hsize0 --> -<!ENTITY hsize1space "9pt"> <!-- 0.75 * hsize1 --> -<!ENTITY hsize2space "10.8pt"> <!-- 0.75 * hsize2 --> -<!ENTITY hsize3space "12.96pt"> <!-- 0.75 * hsize3 --> -<!ENTITY hsize4space "15.552pt"> <!-- 0.75 * hsize4 --> -<!ENTITY hsize5space "18.6624pt"> <!-- 0.75 * hsize5 --> -]> -<t:templates xmlns:t="http://nwalsh.com/docbook/xsl/template/1.0" - xmlns:param="http://nwalsh.com/docbook/xsl/template/1.0/param" - xmlns:fo="http://www.w3.org/1999/XSL/Format" - xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> - - <t:titlepage t:element="book" t:wrapper="fo:block"> - <t:titlepage-content t:side="recto"> - <title - t:named-template="division.title" - param:node="ancestor-or-self::book[1]" - text-align="center" - font-size="&hsize5;" - space-before="&hsize5space;" - font-weight="bold" - font-family="{$title.fontset}"/> - <subtitle - text-align="center" - font-size="&hsize4;" - space-before="&hsize4space;" - font-family="{$title.fontset}"/> - - <!-- <corpauthor space-before="0.5em" - font-size="&hsize2;"/> - <authorgroup space-before="0.5em" - font-size="&hsize2;"/> - <author space-before="0.5em" - font-size="&hsize2;"/> --> - - <mediaobject space-before="2em" space-after="2em"/> - <releaseinfo space-before="5em" font-size="&hsize2;"/> - <copyright space-before="1.5em" - font-weight="normal" - font-size="8"/> - <legalnotice space-before="5em" - font-weight="normal" - font-style="italic" - font-size="8"/> - <othercredit space-before="2em" - font-weight="normal" - font-size="8"/> - <pubdate space-before="0.5em"/> - <revision space-before="0.5em"/> - <revhistory space-before="0.5em"/> - <abstract space-before="0.5em" - text-align="start" - margin-left="0.5in" - margin-right="0.5in" - font-family="{$body.fontset}"/> - </t:titlepage-content> - - <t:titlepage-content t:side="verso"> - </t:titlepage-content> - - <t:titlepage-separator> - </t:titlepage-separator> - - <t:titlepage-before t:side="recto"> - </t:titlepage-before> - - <t:titlepage-before t:side="verso"> - </t:titlepage-before> -</t:titlepage> - -<!-- ==================================================================== --> - -</t:templates> +<?xml version="1.0" encoding="UTF-8"?> + +<!-- + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you 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. +--> + +<!DOCTYPE t:templates [ +<!ENTITY hsize0 "10pt"> +<!ENTITY hsize1 "12pt"> +<!ENTITY hsize2 "14.4pt"> +<!ENTITY hsize3 "17.28pt"> +<!ENTITY hsize4 "20.736pt"> +<!ENTITY hsize5 "24.8832pt"> +<!ENTITY hsize0space "7.5pt"> <!-- 0.75 * hsize0 --> +<!ENTITY hsize1space "9pt"> <!-- 0.75 * hsize1 --> +<!ENTITY hsize2space "10.8pt"> <!-- 0.75 * hsize2 --> +<!ENTITY hsize3space "12.96pt"> <!-- 0.75 * hsize3 --> +<!ENTITY hsize4space "15.552pt"> <!-- 0.75 * hsize4 --> +<!ENTITY hsize5space "18.6624pt"> <!-- 0.75 * hsize5 --> +]> +<t:templates xmlns:t="http://nwalsh.com/docbook/xsl/template/1.0" + xmlns:param="http://nwalsh.com/docbook/xsl/template/1.0/param" + xmlns:fo="http://www.w3.org/1999/XSL/Format" + xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> + + <t:titlepage t:element="book" t:wrapper="fo:block"> + <t:titlepage-content t:side="recto"> + <title + t:named-template="division.title" + param:node="ancestor-or-self::book[1]" + text-align="center" + font-size="&hsize5;" + space-before="&hsize5space;" + font-weight="bold" + font-family="{$title.fontset}"/> + <subtitle + text-align="center" + font-size="&hsize4;" + space-before="&hsize4space;" + font-family="{$title.fontset}"/> + + <!-- <corpauthor space-before="0.5em" + font-size="&hsize2;"/> + <authorgroup space-before="0.5em" + font-size="&hsize2;"/> + <author space-before="0.5em" + font-size="&hsize2;"/> --> + + <mediaobject space-before="2em" space-after="2em"/> + <releaseinfo space-before="5em" font-size="&hsize2;"/> + <copyright space-before="1.5em" + font-weight="normal" + font-size="8"/> + <legalnotice space-before="5em" + font-weight="normal" + font-style="italic" + font-size="8"/> + <othercredit space-before="2em" + font-weight="normal" + font-size="8"/> + <pubdate space-before="0.5em"/> + <revision space-before="0.5em"/> + <revhistory space-before="0.5em"/> + <abstract space-before="0.5em" + text-align="start" + margin-left="0.5in" + margin-right="0.5in" + font-family="{$body.fontset}"/> + </t:titlepage-content> + + <t:titlepage-content t:side="verso"> + </t:titlepage-content> + + <t:titlepage-separator> + </t:titlepage-separator> + + <t:titlepage-before t:side="recto"> + </t:titlepage-before> + + <t:titlepage-before t:side="verso"> + </t:titlepage-before> +</t:titlepage> + +<!-- ==================================================================== --> + +</t:templates> diff --git a/querydsl-examples/pom.xml b/querydsl-examples/pom.xml new file mode 100644 index 0000000000..7178148d0e --- /dev/null +++ b/querydsl-examples/pom.xml @@ -0,0 +1,117 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>com.querydsl</groupId> + <artifactId>querydsl-root</artifactId> + <version>5.1.0</version> + <relativePath>../pom.xml</relativePath> + </parent> + + <groupId>com.querydsl</groupId> + <artifactId>querydsl-examples</artifactId> + <name>Querydsl - Examples</name> + <url>${project.homepage}</url> + <packaging>pom</packaging> + + <properties> + <checkstyle.skip>true</checkstyle.skip> + <enforcer.skip>true</enforcer.skip> + </properties> + + <modules> + <module>querydsl-example-sql-spring</module> + <module>querydsl-example-sql-guice</module> + <module>querydsl-example-jpa-guice</module> + <module>querydsl-example-kotlin-jpa</module> + <module>querydsl-example-kotlin-mongodb</module> + <module>querydsl-example-kotlin-codegen</module> + </modules> + + <build> + <plugins> + <plugin> + <artifactId>maven-eclipse-plugin</artifactId> + <version>2.10</version> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-enforcer-plugin</artifactId> + <version>1.4.1</version> + <executions> + <execution> + <id>enforce-banned-dependencies</id> + <phase>validate</phase> + <goals> + <goal>enforce</goal> + </goals> + <configuration> + <rules> + <bannedDependencies/> + </rules> + </configuration> + </execution> + </executions> + <dependencies> + <dependency> + <groupId>org.semver</groupId> + <artifactId>enforcer-rule</artifactId> + <version>0.9.33</version> + <exclusions> + <exclusion> + <groupId>org.ow2.asm</groupId> + <artifactId>asm</artifactId> + </exclusion> + <exclusion> + <groupId>org.ow2.asm</groupId> + <artifactId>asm-commons</artifactId> + </exclusion> + </exclusions> + </dependency> + <dependency> + <groupId>org.ow2.asm</groupId> + <artifactId>asm</artifactId> + <version>${asm.version}</version> + </dependency> + <dependency> + <groupId>org.ow2.asm</groupId> + <artifactId>asm-commons</artifactId> + <version>${asm.version}</version> + </dependency> + </dependencies> + </plugin> + </plugins> + </build> + + <dependencyManagement> + <dependencies> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + <version>${slf4j.version}</version> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-log4j12</artifactId> + <version>${slf4j.version}</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>log4j</groupId> + <artifactId>log4j</artifactId> + <version>1.2.17</version> + </dependency> + </dependencies> + </dependencyManagement> + + <dependencies> + <dependency> + <groupId>com.querydsl</groupId> + <artifactId>querydsl-core</artifactId> + <version>${project.version}</version> + <scope>test</scope> + <type>test-jar</type> + </dependency> + </dependencies> +</project> diff --git a/querydsl-examples/querydsl-example-jpa-guice/README.md b/querydsl-examples/querydsl-example-jpa-guice/README.md new file mode 100644 index 0000000000..56a7fe41e6 --- /dev/null +++ b/querydsl-examples/querydsl-example-jpa-guice/README.md @@ -0,0 +1,8 @@ +## Querydsl JPA Example + +Querydsl JPA Example is an example project that demonstrates some best practices on how to use Querydsl JPA in repositories. + +Querydsl combines the typesafety of a Criteria API with the syntax of JPQL into an attractive alternative. + +Guice is used as the DI layer to complement the already available Spring + Querydsl tutorials and examples. + diff --git a/querydsl-examples/querydsl-example-jpa-guice/pom.xml b/querydsl-examples/querydsl-example-jpa-guice/pom.xml new file mode 100644 index 0000000000..acc4b9d152 --- /dev/null +++ b/querydsl-examples/querydsl-example-jpa-guice/pom.xml @@ -0,0 +1,202 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>com.querydsl</groupId> + <artifactId>querydsl-examples</artifactId> + <version>5.1.0</version> + <relativePath>../</relativePath> + </parent> + + <groupId>com.querydsl</groupId> + <artifactId>querydsl-example-jpa-guice</artifactId> + <packaging>jar</packaging> + <name>Querydsl example - JPA Guice</name> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + <failIfNoTests>false</failIfNoTests> + + <guice.version>5.1.0</guice.version> + <h2.version>1.3.170</h2.version> + </properties> + + <dependencies> + + <!-- guice --> + <dependency> + <groupId>com.google.inject</groupId> + <artifactId>guice</artifactId> + <version>${guice.version}</version> + </dependency> + <dependency> + <groupId>com.google.inject.extensions</groupId> + <artifactId>guice-persist</artifactId> + <version>${guice.version}</version> + </dependency> + <dependency> + <groupId>javax.transaction</groupId> + <artifactId>jta</artifactId> + <version>1.1</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>javax.el</groupId> + <artifactId>javax.el-api</artifactId> + <version>3.0.0</version> + <scope>provided</scope> + </dependency> + + <!-- logging --> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-log4j12</artifactId> + </dependency> + <dependency> + <groupId>log4j</groupId> + <artifactId>log4j</artifactId> + </dependency> + + <!-- persistence --> + <dependency> + <groupId>org.hibernate</groupId> + <artifactId>hibernate-core</artifactId> + <version>${hibernate.version}</version> + <exclusions> + <exclusion> + <groupId>cglib</groupId> + <artifactId>cglib</artifactId> + </exclusion> + <exclusion> + <groupId>asm</groupId> + <artifactId>asm</artifactId> + </exclusion> + </exclusions> + </dependency> + <dependency> + <groupId>org.hibernate</groupId> + <artifactId>hibernate-ehcache</artifactId> + <version>${hibernate.version}</version> + </dependency> + <dependency> + <groupId>org.hibernate.validator</groupId> + <artifactId>hibernate-validator</artifactId> + <version>${hibernate.validator.version}</version> + <exclusions> + <exclusion> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + </exclusion> + </exclusions> + </dependency> + <dependency> + <groupId>org.hibernate</groupId> + <artifactId>hibernate-c3p0</artifactId> + <version>${hibernate.version}</version> + </dependency> + <dependency> + <groupId>com.querydsl</groupId> + <artifactId>querydsl-jpa</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>com.querydsl</groupId> + <artifactId>querydsl-apt</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>com.h2database</groupId> + <artifactId>h2</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>joda-time</groupId> + <artifactId>joda-time</artifactId> + <version>${jodatime.version}</version> + </dependency> + + <dependency> + <groupId>net.sf.ehcache</groupId> + <artifactId>ehcache-core</artifactId> + <version>2.6.11</version> + </dependency> + + <!-- TEST dependencies --> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>4.13.2</version> + <scope>test</scope> + </dependency> + </dependencies> + + <build> + <finalName>querydsl-example-jpa-guice</finalName> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <configuration> + <source>1.8</source> + <target>1.8</target> + </configuration> + </plugin> + <plugin> + <groupId>com.mysema.maven</groupId> + <artifactId>apt-maven-plugin</artifactId> + <version>1.0.9</version> + <executions> + <execution> + <goals> + <goal>process</goal> + </goals> + <configuration> + <outputDirectory>target/generated-sources/java</outputDirectory> + <processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> + + <pluginRepositories> + <pluginRepository> + <id>sonatype-oss-public</id> + <url>https://oss.sonatype.org/content/groups/public</url> + <releases> + <enabled>true</enabled> + </releases> + <snapshots> + <enabled>true</enabled> + </snapshots> + </pluginRepository> + </pluginRepositories> + + <profiles> + <profile> + <id>java-11</id> + <activation> + <jdk>[11,)</jdk> + </activation> + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <configuration> + <source>11</source> + <target>11</target> + </configuration> + </plugin> + </plugins> + </build> + </profile> + </profiles> + +</project> diff --git a/querydsl-examples/querydsl-example-jpa-guice/src/main/java/com/querydsl/example/jpa/guice/JpaInitializer.java b/querydsl-examples/querydsl-example-jpa-guice/src/main/java/com/querydsl/example/jpa/guice/JpaInitializer.java new file mode 100644 index 0000000000..eb3faca09c --- /dev/null +++ b/querydsl-examples/querydsl-example-jpa-guice/src/main/java/com/querydsl/example/jpa/guice/JpaInitializer.java @@ -0,0 +1,11 @@ +package com.querydsl.example.jpa.guice; + +import com.google.inject.Inject; +import com.google.inject.persist.PersistService; + +public class JpaInitializer { + @Inject + public JpaInitializer(PersistService service) { + service.start(); + } +} diff --git a/querydsl-examples/querydsl-example-jpa-guice/src/main/java/com/querydsl/example/jpa/guice/ServiceModule.java b/querydsl-examples/querydsl-example-jpa-guice/src/main/java/com/querydsl/example/jpa/guice/ServiceModule.java new file mode 100644 index 0000000000..988ab87bd1 --- /dev/null +++ b/querydsl-examples/querydsl-example-jpa-guice/src/main/java/com/querydsl/example/jpa/guice/ServiceModule.java @@ -0,0 +1,17 @@ +package com.querydsl.example.jpa.guice; + +import com.google.inject.AbstractModule; +import com.google.inject.Scopes; +import com.google.inject.persist.jpa.JpaPersistModule; +import com.querydsl.example.jpa.repository.TweetRepository; +import com.querydsl.example.jpa.repository.UserRepository; + +public class ServiceModule extends AbstractModule { + @Override + protected void configure() { + install(new JpaPersistModule("h2").properties(System.getProperties())); + bind(JpaInitializer.class).asEagerSingleton(); + bind(TweetRepository.class).in(Scopes.SINGLETON); + bind(UserRepository.class).in(Scopes.SINGLETON); + } +} diff --git a/querydsl-examples/querydsl-example-jpa-guice/src/main/java/com/querydsl/example/jpa/model/BaseEntity.java b/querydsl-examples/querydsl-example-jpa-guice/src/main/java/com/querydsl/example/jpa/model/BaseEntity.java new file mode 100644 index 0000000000..93696145b4 --- /dev/null +++ b/querydsl-examples/querydsl-example-jpa-guice/src/main/java/com/querydsl/example/jpa/model/BaseEntity.java @@ -0,0 +1,25 @@ +package com.querydsl.example.jpa.model; + +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.MappedSuperclass; + + +@MappedSuperclass +public abstract class BaseEntity implements Identifiable { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + + @Override + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + +} diff --git a/querydsl-examples/querydsl-example-jpa-guice/src/main/java/com/querydsl/example/jpa/model/Identifiable.java b/querydsl-examples/querydsl-example-jpa-guice/src/main/java/com/querydsl/example/jpa/model/Identifiable.java new file mode 100644 index 0000000000..09ac2666cb --- /dev/null +++ b/querydsl-examples/querydsl-example-jpa-guice/src/main/java/com/querydsl/example/jpa/model/Identifiable.java @@ -0,0 +1,5 @@ +package com.querydsl.example.jpa.model; + +public interface Identifiable { + Long getId(); +} diff --git a/querydsl-examples/querydsl-example-jpa-guice/src/main/java/com/querydsl/example/jpa/model/Location.java b/querydsl-examples/querydsl-example-jpa-guice/src/main/java/com/querydsl/example/jpa/model/Location.java new file mode 100644 index 0000000000..61b28b58e2 --- /dev/null +++ b/querydsl-examples/querydsl-example-jpa-guice/src/main/java/com/querydsl/example/jpa/model/Location.java @@ -0,0 +1,44 @@ +package com.querydsl.example.jpa.model; + +import org.hibernate.annotations.Cache; +import org.hibernate.annotations.CacheConcurrencyStrategy; + +import javax.persistence.Entity; +import javax.persistence.Table; +import javax.persistence.UniqueConstraint; + +@Entity +@Table(name = "location", + uniqueConstraints = @UniqueConstraint(columnNames = { "longitude", "latitude"})) +@Cache(usage = CacheConcurrencyStrategy.READ_WRITE) +public class Location extends BaseEntity { + + private Double longitude; + + private Double latitude; + + public Location() { + } + + public Location(Double longitude, Double latitude) { + this.longitude = longitude; + this.latitude = latitude; + } + + public Double getLatitude() { + return latitude; + } + + public void setLongitude(Double longitude) { + this.longitude = longitude; + } + + public void setLatitude(Double latitude) { + this.latitude = latitude; + } + + public Double getLongitude() { + return longitude; + } + +} diff --git a/querydsl-examples/querydsl-example-jpa-guice/src/main/java/com/querydsl/example/jpa/model/Tweet.java b/querydsl-examples/querydsl-example-jpa-guice/src/main/java/com/querydsl/example/jpa/model/Tweet.java new file mode 100644 index 0000000000..ad2dd88a29 --- /dev/null +++ b/querydsl-examples/querydsl-example-jpa-guice/src/main/java/com/querydsl/example/jpa/model/Tweet.java @@ -0,0 +1,63 @@ +package com.querydsl.example.jpa.model; + +import javax.persistence.*; +import java.util.ArrayList; +import java.util.List; + +@Entity +@Table(name = "tweet") +public class Tweet extends BaseEntity { + private String content; + + @ManyToOne(optional = false) + private User poster; + + @ManyToMany(fetch = FetchType.EAGER) + private List<User> mentions = new ArrayList<User>(); + + @ManyToOne + private Location location; + + public Tweet() { + } + + public Tweet(User poster, String content, List<User> mentions, + Location location) { + this.poster = poster; + this.content = content; + this.mentions = mentions; + this.location = location; + } + + public void setPoster(User poster) { + this.poster = poster; + } + + public void setMentions(List<User> mentions) { + this.mentions = mentions; + } + + public void setContent(String content) { + this.content = content; + } + + public User getPoster() { + return poster; + } + + public List<User> getMentions() { + return mentions; + } + + public String getContent() { + return content; + } + + public void setLocation(Location location) { + this.location = location; + } + + public Location getLocation() { + return location; + } +} diff --git a/querydsl-examples/querydsl-example-jpa-guice/src/main/java/com/querydsl/example/jpa/model/User.java b/querydsl-examples/querydsl-example-jpa-guice/src/main/java/com/querydsl/example/jpa/model/User.java new file mode 100644 index 0000000000..679ff2b39c --- /dev/null +++ b/querydsl-examples/querydsl-example-jpa-guice/src/main/java/com/querydsl/example/jpa/model/User.java @@ -0,0 +1,43 @@ +package com.querydsl.example.jpa.model; + +import javax.persistence.*; +import java.util.HashSet; +import java.util.Set; + +@Entity +@Table(name = "user") +public class User extends BaseEntity { + @Column(unique = true) + private String username; + + @OneToMany(fetch = FetchType.LAZY, mappedBy = "poster") + private Set<Tweet> tweets = new HashSet<Tweet>(); + + public User() { + } + + public User(Long id, String username) { + setId(id); + this.username = username; + } + + public User(String username) { + this.username = username; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public void setTweets(Set<Tweet> tweets) { + this.tweets = tweets; + } + + public Set<Tweet> getTweets() { + return tweets; + } +} diff --git a/querydsl-examples/querydsl-example-jpa-guice/src/main/java/com/querydsl/example/jpa/repository/AbstractRepository.java b/querydsl-examples/querydsl-example-jpa-guice/src/main/java/com/querydsl/example/jpa/repository/AbstractRepository.java new file mode 100644 index 0000000000..b96ecffff7 --- /dev/null +++ b/querydsl-examples/querydsl-example-jpa-guice/src/main/java/com/querydsl/example/jpa/repository/AbstractRepository.java @@ -0,0 +1,71 @@ +package com.querydsl.example.jpa.repository; + +import com.querydsl.core.types.EntityPath; +import com.querydsl.core.types.Expression; +import com.querydsl.example.jpa.model.Identifiable; +import com.querydsl.jpa.HQLTemplates; +import com.querydsl.jpa.hibernate.HibernateQuery; +import com.querydsl.jpa.impl.JPADeleteClause; +import com.querydsl.jpa.impl.JPAQuery; + +import javax.inject.Inject; +import javax.inject.Provider; +import javax.persistence.EntityManager; + +import org.hibernate.Session; + +public abstract class AbstractRepository<T extends Identifiable> implements Repository<T, Long> { + + @Inject + private Provider<EntityManager> em; + + protected <T> JPAQuery<T> selectFrom(EntityPath<T> entity) { + return select(entity).from(entity); + } + + protected <T> JPAQuery<T> select(Expression<T> select) { + return new JPAQuery<>(em.get(), HQLTemplates.DEFAULT).select(select); + } + + protected JPADeleteClause delete(EntityPath<?> entity) { + return new JPADeleteClause(em.get(), entity, HQLTemplates.DEFAULT); + } + + protected void detach(Object entity) { + em.get().detach(entity); + } + + protected <E> E find(Class<E> type, Long id) { + return em.get().find(type, id); + } + + protected void persist(Object entity) { + em.get().persist(entity); + } + + protected <E> E merge(E entity) { + return em.get().merge(entity); + } + + protected <E extends Identifiable> E persistOrMerge(E entity) { + if (entity.getId() != null) { + return merge(entity); + } + persist(entity); + return entity; + } + + protected void remove(Object entity) { + em.get().remove(entity); + } + + protected <T> HibernateQuery<T> selectFromHibernateQuery(EntityPath<T> entity) { + return selectHibernateQuery(entity).from(entity); + } + + protected <T> HibernateQuery<T> selectHibernateQuery(Expression<T> select) { + return new HibernateQuery<>(em.get().unwrap(Session.class)).select(select); + } + + +} diff --git a/querydsl-examples/querydsl-example-jpa-guice/src/main/java/com/querydsl/example/jpa/repository/Repository.java b/querydsl-examples/querydsl-example-jpa-guice/src/main/java/com/querydsl/example/jpa/repository/Repository.java new file mode 100644 index 0000000000..632748b6dd --- /dev/null +++ b/querydsl-examples/querydsl-example-jpa-guice/src/main/java/com/querydsl/example/jpa/repository/Repository.java @@ -0,0 +1,14 @@ +package com.querydsl.example.jpa.repository; + +import java.io.Serializable; + +public interface Repository<Entity, Id extends Serializable> { + /** + * Get the persisted instance with the given id + * + * @param id + * @return + */ + Entity findById(Id id); + +} diff --git a/querydsl-examples/querydsl-example-jpa-guice/src/main/java/com/querydsl/example/jpa/repository/TweetRepository.java b/querydsl-examples/querydsl-example-jpa-guice/src/main/java/com/querydsl/example/jpa/repository/TweetRepository.java new file mode 100644 index 0000000000..f2455bcebc --- /dev/null +++ b/querydsl-examples/querydsl-example-jpa-guice/src/main/java/com/querydsl/example/jpa/repository/TweetRepository.java @@ -0,0 +1,30 @@ +package com.querydsl.example.jpa.repository; + +import com.google.inject.persist.Transactional; +import com.querydsl.core.types.Predicate; +import com.querydsl.example.jpa.model.Tweet; + +import java.util.List; + +import static com.querydsl.example.jpa.model.QTweet.tweet; + +@Transactional +public class TweetRepository extends AbstractRepository<Tweet> { + + public Tweet save(Tweet tweet) { + return persistOrMerge(tweet); + } + + @Override + public Tweet findById(Long id) { + return find(Tweet.class, id); + } + + public List<Tweet> findAll(Predicate expr) { + return selectFrom(tweet).where(expr).fetch(); + } + + public List<Tweet> findAllWithHibernateQuery(Predicate expr) { + return selectFromHibernateQuery(tweet).where(expr).fetch(); + } +} diff --git a/querydsl-examples/querydsl-example-jpa-guice/src/main/java/com/querydsl/example/jpa/repository/UserRepository.java b/querydsl-examples/querydsl-example-jpa-guice/src/main/java/com/querydsl/example/jpa/repository/UserRepository.java new file mode 100644 index 0000000000..9ceda21436 --- /dev/null +++ b/querydsl-examples/querydsl-example-jpa-guice/src/main/java/com/querydsl/example/jpa/repository/UserRepository.java @@ -0,0 +1,30 @@ +package com.querydsl.example.jpa.repository; + +import com.google.inject.persist.Transactional; +import com.querydsl.core.types.Predicate; +import com.querydsl.example.jpa.model.User; + +import java.util.List; + +import static com.querydsl.example.jpa.model.QUser.user; + +@Transactional +public class UserRepository extends AbstractRepository<User> { + + @Override + public User findById(Long id) { + return find(User.class, id); + } + + public User save(User user) { + return persistOrMerge(user); + } + + public List<User> findAll(Predicate expr) { + return selectFrom(user).where(expr).fetch(); + } + + public List<User> all() { + return selectFrom(user).fetch(); + } +} diff --git a/querydsl-examples/querydsl-example-jpa-guice/src/main/resources/META-INF/persistence.xml b/querydsl-examples/querydsl-example-jpa-guice/src/main/resources/META-INF/persistence.xml new file mode 100644 index 0000000000..457ed1e7cb --- /dev/null +++ b/querydsl-examples/querydsl-example-jpa-guice/src/main/resources/META-INF/persistence.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="UTF-8"?> +<persistence xmlns="http://java.sun.com/xml/ns/persistence" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" + version="1.0"> + <persistence-unit name="h2" transaction-type="RESOURCE_LOCAL"> + <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider> + <properties> + <property name="hibernate.archive.autodetection" value="class" /> + <property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect" /> + <property name="hibernate.connection.driver_class" value="org.h2.Driver" /> + <property name="hibernate.connection.url" value="jdbc:h2:./target/h2-hibernate" /> + <property name="hibernate.connection.user" value="sa" /> + <property name="hibernate.show_sql" value="false" /> + <property name="hibernate.flushMode" value="FLUSH_AUTO" /> + <property name="hibernate.hbm2ddl.auto" value="create-drop" /> + <property name="hibernate.cache.region.factory_class" value="org.hibernate.cache.ehcache.EhCacheRegionFactory" /> + </properties> + </persistence-unit> +</persistence> \ No newline at end of file diff --git a/querydsl-examples/querydsl-example-jpa-guice/src/test/java/com/querydsl/example/jpa/guice/GuiceTestRunner.java b/querydsl-examples/querydsl-example-jpa-guice/src/test/java/com/querydsl/example/jpa/guice/GuiceTestRunner.java new file mode 100644 index 0000000000..ca1c152891 --- /dev/null +++ b/querydsl-examples/querydsl-example-jpa-guice/src/test/java/com/querydsl/example/jpa/guice/GuiceTestRunner.java @@ -0,0 +1,22 @@ +package com.querydsl.example.jpa.guice; + +import com.google.inject.Guice; +import com.google.inject.Injector; +import com.querydsl.example.jpa.guice.ServiceModule; +import org.junit.runners.BlockJUnit4ClassRunner; +import org.junit.runners.model.InitializationError; + +public class GuiceTestRunner extends BlockJUnit4ClassRunner { + + private static final Injector injector = Guice + .createInjector(new ServiceModule()); + + public GuiceTestRunner(Class<?> klass) throws InitializationError { + super(klass); + } + + @Override + protected Object createTest() throws Exception { + return injector.getInstance(getTestClass().getJavaClass()); + } +} diff --git a/querydsl-examples/querydsl-example-jpa-guice/src/test/java/com/querydsl/example/jpa/repository/AbstractPersistenceTest.java b/querydsl-examples/querydsl-example-jpa-guice/src/test/java/com/querydsl/example/jpa/repository/AbstractPersistenceTest.java new file mode 100644 index 0000000000..2125f7e060 --- /dev/null +++ b/querydsl-examples/querydsl-example-jpa-guice/src/test/java/com/querydsl/example/jpa/repository/AbstractPersistenceTest.java @@ -0,0 +1,57 @@ +package com.querydsl.example.jpa.repository; + +import com.google.inject.persist.Transactional; +import com.querydsl.example.jpa.guice.GuiceTestRunner; +import org.hibernate.Session; +import org.hibernate.jdbc.Work; +import org.junit.Before; +import org.junit.runner.RunWith; + +import javax.inject.Inject; +import javax.inject.Provider; +import javax.persistence.EntityManager; +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +@RunWith(GuiceTestRunner.class) +public abstract class AbstractPersistenceTest { + @Inject + private Provider<EntityManager> em; + + @Before + @Transactional + public void before() { + EntityManager entityManager = em.get(); + entityManager.getEntityManagerFactory().getCache().evictAll(); + Session session = entityManager.unwrap(Session.class); + session.doWork(new Work() { + @Override + public void execute(Connection connection) + throws SQLException { + List<String> tables = new ArrayList<String>(); + DatabaseMetaData md = connection.getMetaData(); + ResultSet rs = md.getTables(null, null, null, new String[] {"TABLE"}); + try { + while (rs.next()) { + tables.add(rs.getString("TABLE_NAME")); + } + } finally { + rs.close(); + } + + try (java.sql.Statement stmt = connection.createStatement()) { + stmt.execute("SET REFERENTIAL_INTEGRITY FALSE"); + for (String table : tables) { + stmt.execute("TRUNCATE TABLE " + table); + } + stmt.execute("SET REFERENTIAL_INTEGRITY TRUE"); + } + + } + }); + } +} diff --git a/querydsl-examples/querydsl-example-jpa-guice/src/test/java/com/querydsl/example/jpa/repository/TweetRepositoryTest.java b/querydsl-examples/querydsl-example-jpa-guice/src/test/java/com/querydsl/example/jpa/repository/TweetRepositoryTest.java new file mode 100644 index 0000000000..18ed700fc3 --- /dev/null +++ b/querydsl-examples/querydsl-example-jpa-guice/src/test/java/com/querydsl/example/jpa/repository/TweetRepositoryTest.java @@ -0,0 +1,100 @@ +package com.querydsl.example.jpa.repository; + +import com.querydsl.example.jpa.model.Tweet; +import com.querydsl.example.jpa.model.User; +import org.junit.Test; + +import javax.inject.Inject; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import static com.querydsl.example.jpa.model.QTweet.tweet; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class TweetRepositoryTest extends AbstractPersistenceTest { + @Inject + private TweetRepository repository; + + @Inject + private UserRepository userRepository; + + @Test + public void save_and_find_by_id() { + User poster = new User("dr_frank"); + userRepository.save(poster); + + String content = "I am alive! #YOLO"; + Tweet tweet = new Tweet(poster, content, + Collections.<User>emptyList(), null); + repository.save(tweet); + assertEquals(content, repository.findById(tweet.getId()).getContent()); + } + + @Test + public void find_list_by_predicate() { + User poster = new User("dr_frank"); + userRepository.save(poster); + + repository.save(new Tweet(poster, "It is a alive! #YOLO", Collections.<User>emptyList(), null)); + repository.save(new Tweet(poster, "Oh the humanity!", Collections.<User>emptyList(), null)); + repository.save(new Tweet(poster, "#EpicFail", Collections.<User>emptyList(), null)); + assertEquals(1, repository.findAll(tweet.content.contains("#YOLO")).size()); + } + + @Test + public void find_list_by_predicate_with_hibernate() { + User poster = new User("dr_frank"); + userRepository.save(poster); + + repository.save(new Tweet(poster, "It is a alive! #YOLO", Collections.<User>emptyList(), null)); + repository.save(new Tweet(poster, "Oh the humanity!", Collections.<User>emptyList(), null)); + repository.save(new Tweet(poster, "#EpicFail", Collections.<User>emptyList(), null)); + assertEquals(1, repository.findAllWithHibernateQuery(tweet.content.contains("#YOLO")).size()); + } + + + @Test + public void find_list_by_complex_predicate() { + List<String> usernames = Arrays.asList("dr_frank", "mike", "maggie", "liza"); + List<User> users = new ArrayList<>(); + for (String username : usernames) { + users.add(userRepository.save(new User(username))); + } + User poster = new User("duplo"); + userRepository.save(poster); + for (int i = 0; i < 100; i++) { + repository.save(new Tweet(poster, "spamming @dr_frank " + i, users.subList(0, 1), null)); + } + assertTrue(repository.findAll(tweet.mentions.contains(users.get(1))).isEmpty()); + + assertEquals(100, repository.findAll(tweet.mentions.contains(users.get(0))).size()); + + assertTrue(repository.findAll(tweet.mentions.any().username.eq("duplo")).isEmpty()); + + assertEquals(100, repository.findAll(tweet.mentions.any().username.eq("dr_frank")).size()); + } + + @Test + public void find_list_by_complex_predicate_hibernate() { + List<String> usernames = Arrays.asList("dr_frank", "mike", "maggie", "liza"); + List<User> users = new ArrayList<>(); + for (String username : usernames) { + users.add(userRepository.save(new User(username))); + } + User poster = new User("duplo"); + userRepository.save(poster); + for (int i = 0; i < 100; i++) { + repository.save(new Tweet(poster, "spamming @dr_frank " + i, users.subList(0, 1), null)); + } + assertTrue(repository.findAllWithHibernateQuery(tweet.mentions.contains(users.get(1))).isEmpty()); + + assertEquals(100, repository.findAllWithHibernateQuery(tweet.mentions.contains(users.get(0))).size()); + + assertTrue(repository.findAllWithHibernateQuery(tweet.mentions.any().username.eq("duplo")).isEmpty()); + + assertEquals(100, repository.findAllWithHibernateQuery(tweet.mentions.any().username.eq("dr_frank")).size()); + } +} diff --git a/querydsl-examples/querydsl-example-jpa-guice/src/test/java/com/querydsl/example/jpa/repository/UserRepositoryTest.java b/querydsl-examples/querydsl-example-jpa-guice/src/test/java/com/querydsl/example/jpa/repository/UserRepositoryTest.java new file mode 100644 index 0000000000..27faeefe90 --- /dev/null +++ b/querydsl-examples/querydsl-example-jpa-guice/src/test/java/com/querydsl/example/jpa/repository/UserRepositoryTest.java @@ -0,0 +1,29 @@ +package com.querydsl.example.jpa.repository; + +import com.querydsl.example.jpa.model.User; +import com.querydsl.example.jpa.repository.UserRepository; +import org.junit.Test; + +import javax.inject.Inject; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class UserRepositoryTest extends AbstractPersistenceTest { + @Inject + private UserRepository repository; + + @Test + public void save_and_get_by_id() { + String username = "jackie"; + User user = new User(username); + repository.save(user); + assertEquals(username, repository.findById(user.getId()).getUsername()); + } + + @Test + public void get_all() { + repository.save(new User("jimmy")); + assertTrue(repository.all().size() == 1); + } +} diff --git a/querydsl-examples/querydsl-example-kotlin-codegen/pom.xml b/querydsl-examples/querydsl-example-kotlin-codegen/pom.xml new file mode 100644 index 0000000000..81d35dc4c0 --- /dev/null +++ b/querydsl-examples/querydsl-example-kotlin-codegen/pom.xml @@ -0,0 +1,109 @@ +<?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"> + <parent> + <artifactId>querydsl-examples</artifactId> + <groupId>com.querydsl</groupId> + <version>5.1.0</version> + </parent> + <modelVersion>4.0.0</modelVersion> + <artifactId>querydsl-example-kotlin-codegen</artifactId> + <name>Querydsl example - Kotlin Codegen</name> + + <dependencies> + <dependency> + <groupId>jakarta.persistence</groupId> + <artifactId>jakarta.persistence-api</artifactId> + <version>2.2.3</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>com.querydsl</groupId> + <artifactId>querydsl-jpa</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.jetbrains.kotlin</groupId> + <artifactId>kotlin-stdlib-jdk8</artifactId> + <version>${kotlin.version}</version> + </dependency> + <dependency> + <groupId>org.jetbrains.kotlin</groupId> + <artifactId>kotlin-test-junit</artifactId> + <version>${kotlin.version}</version> + <scope>test</scope> + </dependency> + </dependencies> + + <build> + <sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory> + <testSourceDirectory>${project.basedir}/src/test/kotlin</testSourceDirectory> + <plugins> + <plugin> + <groupId>org.jetbrains.kotlin</groupId> + <artifactId>kotlin-maven-plugin</artifactId> + <version>${kotlin.version}</version> + <configuration> + <compilerPlugins> + <plugin>jpa</plugin> + </compilerPlugins> + <annotationProcessorPaths> + <annotationProcessorPath> + <groupId>com.querydsl</groupId> + <artifactId>querydsl-kotlin-codegen</artifactId> + <version>${project.version}</version> + </annotationProcessorPath> + <annotationProcessorPath> + <groupId>com.querydsl</groupId> + <artifactId>querydsl-apt</artifactId> + <version>${project.version}</version> + <classifier>jpa</classifier> + </annotationProcessorPath> + </annotationProcessorPaths> + <jvmTarget>1.8</jvmTarget> + </configuration> + <dependencies> + <dependency> + <groupId>org.jetbrains.kotlin</groupId> + <artifactId>kotlin-maven-allopen</artifactId> + <version>${kotlin.version}</version> + </dependency> + <dependency> + <groupId>org.jetbrains.kotlin</groupId> + <artifactId>kotlin-maven-noarg</artifactId> + <version>${kotlin.version}</version> + </dependency> + </dependencies> + <executions> + <execution> + <id>kapt</id> + <goals> + <goal>kapt</goal> + </goals> + </execution> + <execution> + <id>compile</id> + <phase>compile</phase> + <goals> + <goal>compile</goal> + </goals> + </execution> + <execution> + <id>test-kapt</id> + <goals> + <goal>test-kapt</goal> + </goals> + </execution> + <execution> + <id>test-compile</id> + <phase>test-compile</phase> + <goals> + <goal>test-compile</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> +</project> diff --git a/querydsl-examples/querydsl-example-kotlin-codegen/src/main/kotlin/com/querydsl/examples/kotlin/entity/ExampleEntity.kt b/querydsl-examples/querydsl-example-kotlin-codegen/src/main/kotlin/com/querydsl/examples/kotlin/entity/ExampleEntity.kt new file mode 100644 index 0000000000..bbda297056 --- /dev/null +++ b/querydsl-examples/querydsl-example-kotlin-codegen/src/main/kotlin/com/querydsl/examples/kotlin/entity/ExampleEntity.kt @@ -0,0 +1,36 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team). + * + * 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. + */ + +package com.querydsl.examples.kotlin.entity + +import javax.persistence.* + +@Entity +data class ExampleEntity( + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + val id: Int, + + @Column + val name: String, + + @OneToMany(mappedBy = "parent") + val children: List<ExampleEntity>? = null, + + @ManyToOne + val parent: ExampleEntity? = null +) { +} \ No newline at end of file diff --git a/querydsl-examples/querydsl-example-kotlin-codegen/src/test/kotlin/com/querydsl/examples/kotlin/ExampleEntityTest.kt b/querydsl-examples/querydsl-example-kotlin-codegen/src/test/kotlin/com/querydsl/examples/kotlin/ExampleEntityTest.kt new file mode 100644 index 0000000000..09e4807d9a --- /dev/null +++ b/querydsl-examples/querydsl-example-kotlin-codegen/src/test/kotlin/com/querydsl/examples/kotlin/ExampleEntityTest.kt @@ -0,0 +1,37 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team). + * + * 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. + */ + +package com.querydsl.examples.kotlin + +import com.querydsl.examples.kotlin.entity.ExampleEntity +import com.querydsl.examples.kotlin.entity.QExampleEntity +import com.querydsl.examples.kotlin.entity.QExampleEntity.Companion.exampleEntity +import com.querydsl.jpa.impl.JPAQuery +import org.junit.Test + +class ExampleEntityTest { + + @Test + fun basicMetamodelExpression() { + val child : QExampleEntity = QExampleEntity("child") + + JPAQuery<ExampleEntity>() + .from(exampleEntity) + .innerJoin(exampleEntity.children, child) + .select(exampleEntity.name, child.name) + } + +} \ No newline at end of file diff --git a/querydsl-examples/querydsl-example-kotlin-jpa/pom.xml b/querydsl-examples/querydsl-example-kotlin-jpa/pom.xml new file mode 100644 index 0000000000..d69d2b0cdd --- /dev/null +++ b/querydsl-examples/querydsl-example-kotlin-jpa/pom.xml @@ -0,0 +1,128 @@ +<?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"> + <parent> + <artifactId>querydsl-examples</artifactId> + <groupId>com.querydsl</groupId> + <version>5.1.0</version> + </parent> + <modelVersion>4.0.0</modelVersion> + <artifactId>querydsl-example-kotlin</artifactId> + <name>Querydsl example - Kotlin JPA</name> + + <dependencies> + <dependency> + <groupId>jakarta.persistence</groupId> + <artifactId>jakarta.persistence-api</artifactId> + <version>2.2.3</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>com.querydsl</groupId> + <artifactId>querydsl-jpa</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.jetbrains.kotlin</groupId> + <artifactId>kotlin-stdlib-jdk8</artifactId> + <version>${kotlin.version}</version> + </dependency> + <dependency> + <groupId>org.jetbrains.kotlin</groupId> + <artifactId>kotlin-test-junit</artifactId> + <version>${kotlin.version}</version> + <scope>test</scope> + </dependency> + </dependencies> + + <build> + <sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory> + <testSourceDirectory>${project.basedir}/src/test/kotlin</testSourceDirectory> + <plugins> + <plugin> + <groupId>org.jetbrains.kotlin</groupId> + <artifactId>kotlin-maven-plugin</artifactId> + <version>${kotlin.version}</version> + <configuration> + <compilerPlugins> + <plugin>jpa</plugin> + </compilerPlugins> + <annotationProcessorPaths> + <annotationProcessorPath> + <groupId>com.querydsl</groupId> + <artifactId>querydsl-apt</artifactId> + <version>${project.version}</version> + <classifier>jpa</classifier> + </annotationProcessorPath> + </annotationProcessorPaths> + <jvmTarget>1.8</jvmTarget> + </configuration> + <dependencies> + <dependency> + <groupId>org.jetbrains.kotlin</groupId> + <artifactId>kotlin-maven-allopen</artifactId> + <version>${kotlin.version}</version> + </dependency> + <dependency> + <groupId>org.jetbrains.kotlin</groupId> + <artifactId>kotlin-maven-noarg</artifactId> + <version>${kotlin.version}</version> + </dependency> + </dependencies> + <executions> + <execution> + <id>kapt</id> + <goals> + <goal>kapt</goal> + </goals> + <configuration> + <sourceDirs> + <sourceDir>src/main/kotlin</sourceDir> + <sourceDir>src/main/java</sourceDir> + </sourceDirs> + </configuration> + </execution> + <execution> + <id>compile</id> + <phase>process-sources</phase> + <goals> + <goal>compile</goal> + </goals> + <configuration> + <sourceDirs> + <sourceDir>src/main/kotlin</sourceDir> + <sourceDir>src/main/java</sourceDir> + </sourceDirs> + </configuration> + </execution> + <execution> + <id>test-kapt</id> + <goals> + <goal>test-kapt</goal> + </goals> + <configuration> + <sourceDirs> + <sourceDir>src/test/kotlin</sourceDir> + <sourceDir>src/test/java</sourceDir> + </sourceDirs> + </configuration> + </execution> + <execution> + <id>test-compile</id> + <goals> + <goal>test-compile</goal> + </goals> + <configuration> + <sourceDirs> + <sourceDir>src/test/kotlin</sourceDir> + <sourceDir>src/test/java</sourceDir> + <sourceDir>target/generated-sources/kapt/test</sourceDir> + </sourceDirs> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> +</project> diff --git a/querydsl-examples/querydsl-example-kotlin-jpa/src/main/kotlin/com/querydsl/examples/kotlin/entity/ExampleEntity.kt b/querydsl-examples/querydsl-example-kotlin-jpa/src/main/kotlin/com/querydsl/examples/kotlin/entity/ExampleEntity.kt new file mode 100644 index 0000000000..bbda297056 --- /dev/null +++ b/querydsl-examples/querydsl-example-kotlin-jpa/src/main/kotlin/com/querydsl/examples/kotlin/entity/ExampleEntity.kt @@ -0,0 +1,36 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team). + * + * 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. + */ + +package com.querydsl.examples.kotlin.entity + +import javax.persistence.* + +@Entity +data class ExampleEntity( + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + val id: Int, + + @Column + val name: String, + + @OneToMany(mappedBy = "parent") + val children: List<ExampleEntity>? = null, + + @ManyToOne + val parent: ExampleEntity? = null +) { +} \ No newline at end of file diff --git a/querydsl-examples/querydsl-example-kotlin-jpa/src/test/kotlin/com/querydsl/examples/kotlin/ExampleEntityTest.kt b/querydsl-examples/querydsl-example-kotlin-jpa/src/test/kotlin/com/querydsl/examples/kotlin/ExampleEntityTest.kt new file mode 100644 index 0000000000..dd8b5425a7 --- /dev/null +++ b/querydsl-examples/querydsl-example-kotlin-jpa/src/test/kotlin/com/querydsl/examples/kotlin/ExampleEntityTest.kt @@ -0,0 +1,37 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team). + * + * 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. + */ + +package com.querydsl.examples.kotlin + +import com.querydsl.examples.kotlin.entity.ExampleEntity +import com.querydsl.examples.kotlin.entity.QExampleEntity +import com.querydsl.examples.kotlin.entity.QExampleEntity.exampleEntity +import com.querydsl.jpa.impl.JPAQuery +import org.junit.Test + +class ExampleEntityTest { + + @Test + fun basicMetamodelExpression() { + val child : QExampleEntity = QExampleEntity("child") + + JPAQuery<ExampleEntity>() + .from(exampleEntity) + .innerJoin(exampleEntity.children, child) + .select(exampleEntity.name, child.name) + } + +} \ No newline at end of file diff --git a/querydsl-examples/querydsl-example-kotlin-mongodb/pom.xml b/querydsl-examples/querydsl-example-kotlin-mongodb/pom.xml new file mode 100644 index 0000000000..e3888375ac --- /dev/null +++ b/querydsl-examples/querydsl-example-kotlin-mongodb/pom.xml @@ -0,0 +1,152 @@ +<?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"> + <parent> + <artifactId>querydsl-examples</artifactId> + <groupId>com.querydsl</groupId> + <version>5.1.0</version> + </parent> + <modelVersion>4.0.0</modelVersion> + <artifactId>querydsl-example-kotlin-mongodb</artifactId> + <name>Querydsl example - Kotlin MongoDB</name> + + <dependencyManagement> + <dependencies> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-parent</artifactId> + <version>2.6.7</version> + <type>pom</type> + <scope>import</scope> + </dependency> + </dependencies> + </dependencyManagement> + + <dependencies> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-data-mongodb</artifactId> + </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-test</artifactId> + <scope>test</scope> + <exclusions> + <exclusion> + <groupId>org.junit.vintage</groupId> + <artifactId>junit-vintage-engine</artifactId> + </exclusion> + </exclusions> + </dependency> + <dependency> + <groupId>com.querydsl</groupId> + <artifactId>querydsl-mongodb</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.jetbrains.kotlin</groupId> + <artifactId>kotlin-stdlib-jdk8</artifactId> + <version>${kotlin.version}</version> + </dependency> + <dependency> + <groupId>org.jetbrains.kotlin</groupId> + <artifactId>kotlin-test-junit</artifactId> + <version>${kotlin.version}</version> + <scope>test</scope> + </dependency> + </dependencies> + + <build> + <sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory> + <testSourceDirectory>${project.basedir}/src/test/kotlin</testSourceDirectory> + <plugins> + <plugin> + <groupId>org.jetbrains.kotlin</groupId> + <artifactId>kotlin-maven-plugin</artifactId> + <version>${kotlin.version}</version> + <configuration> + <annotationProcessorPaths> + <annotationProcessorPath> + <groupId>com.querydsl</groupId> + <artifactId>querydsl-apt</artifactId> + <version>${project.version}</version> + </annotationProcessorPath> + </annotationProcessorPaths> + <annotationProcessors> + <annotationProcessor>org.springframework.data.mongodb.repository.support.MongoAnnotationProcessor</annotationProcessor> + </annotationProcessors> + <jvmTarget>1.8</jvmTarget> + </configuration> + <dependencies> + <dependency> + <groupId>org.jetbrains.kotlin</groupId> + <artifactId>kotlin-maven-allopen</artifactId> + <version>${kotlin.version}</version> + </dependency> + <dependency> + <groupId>org.jetbrains.kotlin</groupId> + <artifactId>kotlin-maven-noarg</artifactId> + <version>${kotlin.version}</version> + </dependency> + </dependencies> + <executions> + <execution> + <id>kapt</id> + <goals> + <goal>kapt</goal> + </goals> + <configuration> + <sourceDirs> + <sourceDir>src/main/kotlin</sourceDir> + <sourceDir>src/main/java</sourceDir> + </sourceDirs> + </configuration> + </execution> + <execution> + <id>compile</id> + <phase>process-sources</phase> + <goals> + <goal>compile</goal> + </goals> + <configuration> + <sourceDirs> + <sourceDir>src/main/kotlin</sourceDir> + <sourceDir>src/main/java</sourceDir> + </sourceDirs> + </configuration> + </execution> + <execution> + <id>test-kapt</id> + <goals> + <goal>test-kapt</goal> + </goals> + <configuration> + <sourceDirs> + <sourceDir>src/test/kotlin</sourceDir> + <sourceDir>src/test/java</sourceDir> + </sourceDirs> + </configuration> + </execution> + <execution> + <id>test-compile</id> + <goals> + <goal>test-compile</goal> + </goals> + <configuration> + <sourceDirs> + <sourceDir>src/test/kotlin</sourceDir> + <sourceDir>src/test/java</sourceDir> + <sourceDir>target/generated-sources/kapt/test</sourceDir> + </sourceDirs> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-maven-plugin</artifactId> + </plugin> + </plugins> + </build> +</project> \ No newline at end of file diff --git a/querydsl-examples/querydsl-example-kotlin-mongodb/src/main/kotlin/com/querydsl/examples/kotlin/entity/ExampleEntity.kt b/querydsl-examples/querydsl-example-kotlin-mongodb/src/main/kotlin/com/querydsl/examples/kotlin/entity/ExampleEntity.kt new file mode 100644 index 0000000000..7b79f65f20 --- /dev/null +++ b/querydsl-examples/querydsl-example-kotlin-mongodb/src/main/kotlin/com/querydsl/examples/kotlin/entity/ExampleEntity.kt @@ -0,0 +1,33 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team). + * + * 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. + */ + +package com.querydsl.examples.kotlin.entity + +import com.querydsl.core.annotations.QueryEntity +import org.springframework.data.annotation.Id +import org.springframework.data.mongodb.core.mapping.Document + +@Document +@QueryEntity +data class ExampleEntity( + @Id + val id: Int, + + val name: String, + + val age : Int +) { +} \ No newline at end of file diff --git a/querydsl-examples/querydsl-example-kotlin-mongodb/src/main/kotlin/com/querydsl/examples/kotlin/repository/ExampleEntityRespository.kt b/querydsl-examples/querydsl-example-kotlin-mongodb/src/main/kotlin/com/querydsl/examples/kotlin/repository/ExampleEntityRespository.kt new file mode 100644 index 0000000000..fc3bee88a3 --- /dev/null +++ b/querydsl-examples/querydsl-example-kotlin-mongodb/src/main/kotlin/com/querydsl/examples/kotlin/repository/ExampleEntityRespository.kt @@ -0,0 +1,24 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team). + * + * 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. + */ + +package com.querydsl.examples.kotlin.repository + +import com.querydsl.examples.kotlin.entity.ExampleEntity +import org.springframework.data.mongodb.repository.MongoRepository +import org.springframework.data.querydsl.QuerydslPredicateExecutor + +interface ExampleEntityRespository : MongoRepository<ExampleEntity, String>, QuerydslPredicateExecutor<ExampleEntity> { +} \ No newline at end of file diff --git a/querydsl-examples/querydsl-example-kotlin-mongodb/src/main/kotlin/com/querydsl/examples/kotlin/repository/ExampleUse.kt b/querydsl-examples/querydsl-example-kotlin-mongodb/src/main/kotlin/com/querydsl/examples/kotlin/repository/ExampleUse.kt new file mode 100644 index 0000000000..c5cd683525 --- /dev/null +++ b/querydsl-examples/querydsl-example-kotlin-mongodb/src/main/kotlin/com/querydsl/examples/kotlin/repository/ExampleUse.kt @@ -0,0 +1,27 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team). + * + * 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. + */ + +package com.querydsl.examples.kotlin.repository + +import com.querydsl.examples.kotlin.entity.QExampleEntity + +class ExampleUse { + + fun test() { + val qExampleEntity = QExampleEntity("test"); + } + +} \ No newline at end of file diff --git a/querydsl-examples/querydsl-example-kotlin-mongodb/src/test/kotlin/com/querydsl/examples/kotlin/ExampleEntityTest.kt b/querydsl-examples/querydsl-example-kotlin-mongodb/src/test/kotlin/com/querydsl/examples/kotlin/ExampleEntityTest.kt new file mode 100644 index 0000000000..2ea4c8d7a4 --- /dev/null +++ b/querydsl-examples/querydsl-example-kotlin-mongodb/src/test/kotlin/com/querydsl/examples/kotlin/ExampleEntityTest.kt @@ -0,0 +1,30 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team). + * + * 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. + */ + +package com.querydsl.examples.kotlin + +import com.querydsl.examples.kotlin.entity.QExampleEntity +import org.junit.Test + +class ExampleEntityTest { + + @Test + fun basicMetamodelExpression() { + val example : QExampleEntity = QExampleEntity("example") + val predicate = example.name.eq("Eric") + } + +} \ No newline at end of file diff --git a/querydsl-examples/querydsl-example-sql-guice/README.md b/querydsl-examples/querydsl-example-sql-guice/README.md new file mode 100644 index 0000000000..14fd1c17e1 --- /dev/null +++ b/querydsl-examples/querydsl-example-sql-guice/README.md @@ -0,0 +1,7 @@ +## Querydsl SQL Example + +Querydsl SQL Example is an example project that demonstrates some best practices on how to use Querydsl SQL in repositories. + +Compared to direct JDBC usage Querydsl SQL is typesafe, closer to SQL and abstracts over SQL dialect specific differences. + +Guice is used as the DI layer to complement the already available Spring + Querydsl tutorials and examples. diff --git a/querydsl-examples/querydsl-example-sql-guice/pom.xml b/querydsl-examples/querydsl-example-sql-guice/pom.xml new file mode 100644 index 0000000000..852f831f40 --- /dev/null +++ b/querydsl-examples/querydsl-example-sql-guice/pom.xml @@ -0,0 +1,140 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>com.querydsl</groupId> + <artifactId>querydsl-examples</artifactId> + <version>5.1.0</version> + <relativePath>../</relativePath> + </parent> + + <groupId>com.querydsl</groupId> + <artifactId>querydsl-example-sql-guice</artifactId> + <packaging>jar</packaging> + <name>Querydsl example - SQL Guice</name> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + <failIfNoTests>false</failIfNoTests> + <guice.version>5.1.0</guice.version> + <h2.version>1.4.186</h2.version> + </properties> + + <dependencies> + + <!-- guice --> + <dependency> + <groupId>com.google.inject</groupId> + <artifactId>guice</artifactId> + <version>${guice.version}</version> + </dependency> + + <!-- logging --> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-log4j12</artifactId> + </dependency> + <dependency> + <groupId>log4j</groupId> + <artifactId>log4j</artifactId> + </dependency> + + <!-- persistence --> + <dependency> + <groupId>com.querydsl</groupId> + <artifactId>querydsl-sql</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>com.h2database</groupId> + <artifactId>h2</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>c3p0</groupId> + <artifactId>c3p0</artifactId> + <version>0.9.1.2</version> + </dependency> + <dependency> + <groupId>joda-time</groupId> + <artifactId>joda-time</artifactId> + <version>${jodatime.version}</version> + </dependency> + + <!-- TEST dependencies --> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>4.13.2</version> + <scope>test</scope> + </dependency> + </dependencies> + + <build> + <finalName>querydsl-example-sql-guice</finalName> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <configuration> + <source>1.8</source> + <target>1.8</target> + </configuration> + </plugin> + + <plugin> + <groupId>com.querydsl</groupId> + <artifactId>querydsl-maven-plugin</artifactId> + <version>${project.version}</version> + <executions> + <execution> + <goals> + <goal>export</goal> + </goals> + </execution> + </executions> + <configuration> + <jdbcDriver>org.h2.Driver</jdbcDriver> + <jdbcUrl>jdbc:h2:mem:;INIT=runscript from 'file:${project.baseUri}/src/main/sql/001_schema.sql'</jdbcUrl> + <jdbcUser>sa</jdbcUser> + <packageName>com.querydsl.example.sql.model</packageName> + <targetFolder>${project.basedir}/target/generated-sources/java</targetFolder> + <exportBeans>true</exportBeans> + </configuration> + <dependencies> + <dependency> + <groupId>com.h2database</groupId> + <artifactId>h2</artifactId> + <version>${h2.version}</version> + </dependency> + </dependencies> + </plugin> + + </plugins> + </build> + <profiles> + <profile> + <id>java-11</id> + <activation> + <jdk>[11,)</jdk> + </activation> + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <configuration> + <source>11</source> + <target>11</target> + </configuration> + </plugin> + </plugins> + </build> + </profile> + </profiles> +</project> diff --git a/querydsl-examples/querydsl-example-sql-guice/src/main/java/com/querydsl/example/sql/guice/ConnectionContext.java b/querydsl-examples/querydsl-example-sql-guice/src/main/java/com/querydsl/example/sql/guice/ConnectionContext.java new file mode 100644 index 0000000000..7cf5040582 --- /dev/null +++ b/querydsl-examples/querydsl-example-sql-guice/src/main/java/com/querydsl/example/sql/guice/ConnectionContext.java @@ -0,0 +1,40 @@ +package com.querydsl.example.sql.guice; + +import javax.inject.Inject; +import javax.sql.DataSource; +import java.sql.Connection; +import java.sql.SQLException; + +public class ConnectionContext { + + private final DataSource dataSource; + + private final ThreadLocal<Connection> connectionHolder = new ThreadLocal<Connection>(); + + @Inject + public ConnectionContext(DataSource dataSource) { + this.dataSource = dataSource; + } + + public Connection getConnection(boolean create) { + Connection connection = connectionHolder.get(); + if (!create || connection != null) { + return connection; + } + try { + connection = dataSource.getConnection(); + } catch (SQLException e) { + throw new RuntimeException(e); + } + connectionHolder.set(connection); + return connection; + } + + public Connection getConnection() { + return connectionHolder.get(); + } + + public void removeConnection() { + connectionHolder.remove(); + } +} diff --git a/querydsl-examples/querydsl-example-sql-guice/src/main/java/com/querydsl/example/sql/guice/ServiceModule.java b/querydsl-examples/querydsl-example-sql-guice/src/main/java/com/querydsl/example/sql/guice/ServiceModule.java new file mode 100644 index 0000000000..eb705ce0c6 --- /dev/null +++ b/querydsl-examples/querydsl-example-sql-guice/src/main/java/com/querydsl/example/sql/guice/ServiceModule.java @@ -0,0 +1,67 @@ +package com.querydsl.example.sql.guice; + +import com.google.inject.AbstractModule; +import com.google.inject.Provides; +import com.google.inject.Scopes; +import com.google.inject.matcher.Matchers; +import com.google.inject.name.Names; +import com.mchange.v2.c3p0.DataSources; +import com.querydsl.example.sql.repository.TweetRepository; +import com.querydsl.example.sql.repository.UserRepository; +import com.querydsl.sql.Configuration; +import com.querydsl.sql.H2Templates; + +import javax.inject.Named; +import javax.inject.Singleton; +import javax.sql.DataSource; +import java.io.IOException; +import java.sql.SQLException; +import java.util.Map.Entry; +import java.util.Properties; + +public class ServiceModule extends AbstractModule { + @Override + protected void configure() { + Properties properties = new Properties(); + try { + properties.load(getClass().getResourceAsStream("/jdbc.properties")); + } catch (IOException e) { + throw new RuntimeException(e); + } + for (Entry<Object, Object> entry : properties.entrySet()) { + bind(String.class).annotatedWith(Names.named((String)entry.getKey())) + .toInstance((String) entry.getValue()); + } + + bind(ConnectionContext.class).in(Scopes.SINGLETON); + bind(TweetRepository.class).in(Scopes.SINGLETON); + bind(UserRepository.class).in(Scopes.SINGLETON); + + TransactionInterceptor interceptor = new TransactionInterceptor(); + requestInjection(interceptor); + bindInterceptor(Matchers.any(), Matchers.annotatedWith(Transactional.class), interceptor); + } + + @Provides + @Singleton + public Configuration configuration() { + return new Configuration(new H2Templates()); + } + + @Provides + @Singleton + public DataSource dataSource(@Named("jdbc.user") String user, + @Named("jdbc.password") String password, + @Named("jdbc.url") String url, + @Named("jdbc.driver") String driver) { + try { + Class.forName(driver); + return DataSources.pooledDataSource(DataSources.unpooledDataSource( + url, user, password)); + + } catch (SQLException | ClassNotFoundException e) { + throw new RuntimeException(e); + } + } + +} diff --git a/querydsl-examples/querydsl-example-sql-guice/src/main/java/com/querydsl/example/sql/guice/TransactionInterceptor.java b/querydsl-examples/querydsl-example-sql-guice/src/main/java/com/querydsl/example/sql/guice/TransactionInterceptor.java new file mode 100644 index 0000000000..32c235e0fa --- /dev/null +++ b/querydsl-examples/querydsl-example-sql-guice/src/main/java/com/querydsl/example/sql/guice/TransactionInterceptor.java @@ -0,0 +1,35 @@ +package com.querydsl.example.sql.guice; + +import org.aopalliance.intercept.MethodInterceptor; +import org.aopalliance.intercept.MethodInvocation; + +import javax.inject.Inject; +import java.lang.reflect.Method; +import java.sql.Connection; + +public class TransactionInterceptor implements MethodInterceptor { + @Inject + private ConnectionContext context; + + @Override + public Object invoke(MethodInvocation invocation) throws Throwable { + Method method = invocation.getMethod(); + Transactional annotation = method.getAnnotation(Transactional.class); + if (annotation == null || context.getConnection() != null) { + return invocation.proceed(); + } + Connection connection = context.getConnection(true); + connection.setAutoCommit(false); + try { + Object rv = invocation.proceed(); + connection.commit(); + return rv; + } catch (Exception e) { + connection.rollback(); + throw e; + } finally { + connection.close(); + context.removeConnection(); + } + } +} diff --git a/querydsl-examples/querydsl-example-sql-guice/src/main/java/com/querydsl/example/sql/guice/Transactional.java b/querydsl-examples/querydsl-example-sql-guice/src/main/java/com/querydsl/example/sql/guice/Transactional.java new file mode 100644 index 0000000000..db379ed9a3 --- /dev/null +++ b/querydsl-examples/querydsl-example-sql-guice/src/main/java/com/querydsl/example/sql/guice/Transactional.java @@ -0,0 +1,11 @@ +package com.querydsl.example.sql.guice; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface Transactional { +} diff --git a/querydsl-examples/querydsl-example-sql-guice/src/main/java/com/querydsl/example/sql/repository/AbstractRepository.java b/querydsl-examples/querydsl-example-sql-guice/src/main/java/com/querydsl/example/sql/repository/AbstractRepository.java new file mode 100644 index 0000000000..3fbbc40fe3 --- /dev/null +++ b/querydsl-examples/querydsl-example-sql-guice/src/main/java/com/querydsl/example/sql/repository/AbstractRepository.java @@ -0,0 +1,49 @@ +package com.querydsl.example.sql.repository; + +import com.querydsl.example.sql.guice.ConnectionContext; +import com.querydsl.core.types.Expression; +import com.querydsl.sql.Configuration; +import com.querydsl.sql.RelationalPath; +import com.querydsl.sql.SQLQuery; +import com.querydsl.sql.dml.SQLDeleteClause; +import com.querydsl.sql.dml.SQLInsertClause; +import com.querydsl.sql.dml.SQLUpdateClause; + +import javax.inject.Inject; +import javax.sql.DataSource; +import java.sql.Connection; + +public abstract class AbstractRepository { + @Inject + private Configuration configuration; + + @Inject + private ConnectionContext context; + + @Inject + private DataSource datasource; + + private Connection getConnection() { + return context.getConnection(); + } + + protected <T> SQLQuery<T> selectFrom(RelationalPath<T> entity) { + return select(entity).from(entity); + } + + protected <T> SQLQuery<T> select(Expression<T> entity) { + return new SQLQuery<Void>(getConnection(), configuration).select(entity); + } + + protected SQLInsertClause insert(RelationalPath<?> path) { + return new SQLInsertClause(getConnection(), configuration, path); + } + + protected SQLUpdateClause update(RelationalPath<?> path) { + return new SQLUpdateClause(getConnection(), configuration, path); + } + + protected SQLDeleteClause delete(RelationalPath<?> path) { + return new SQLDeleteClause(getConnection(), configuration, path); + } +} diff --git a/querydsl-examples/querydsl-example-sql-guice/src/main/java/com/querydsl/example/sql/repository/TweetRepository.java b/querydsl-examples/querydsl-example-sql-guice/src/main/java/com/querydsl/example/sql/repository/TweetRepository.java new file mode 100644 index 0000000000..3e9f0575c7 --- /dev/null +++ b/querydsl-examples/querydsl-example-sql-guice/src/main/java/com/querydsl/example/sql/repository/TweetRepository.java @@ -0,0 +1,74 @@ +package com.querydsl.example.sql.repository; + +import com.querydsl.core.types.Predicate; +import com.querydsl.example.sql.guice.Transactional; +import com.querydsl.example.sql.model.Tweet; +import com.querydsl.example.sql.model.TweetUser; +import com.querydsl.sql.dml.SQLInsertClause; + +import java.util.List; + +import static com.querydsl.example.sql.model.QLocation.location; +import static com.querydsl.example.sql.model.QTweet.tweet; +import static com.querydsl.example.sql.model.QTweetUser.tweetUser; +import static com.querydsl.example.sql.model.QUser.user; + +public class TweetRepository extends AbstractRepository { + @Transactional + public Long save(Tweet entity) { + if (entity.getId() != null) { + update(tweet).populate(entity).execute(); + return entity.getId(); + } + return insert(tweet).populate(entity) + .executeWithKey(user.id); + } + + @Transactional + public Long save(Tweet tweet, Long... mentions) { + Long tweetId = save(tweet); + SQLInsertClause insert = insert(tweetUser); + for (Long mentionsId : mentions) { + TweetUser tu = new TweetUser(); + tu.setTweetId(tweetId); + tu.setMentionsId(mentionsId); + insert.populate(tu).addBatch(); + } + insert.execute(); + return tweetId; + } + + @Transactional + public Tweet findById(Long id) { + return selectFrom(tweet).where(tweet.id.eq(id)).fetchOne(); + } + + @Transactional + public List<Tweet> findOfUser(String username) { + return select(tweet).from(user) + .innerJoin(tweet).on(tweet.posterId.eq(user.id)) + .fetch(); + } + + @Transactional + public List<Tweet> findWithMentioned(Long userId) { + return selectFrom(tweet) + .innerJoin(tweetUser).on(tweet.id.eq(tweetUser.tweetId)) + .where(tweetUser.mentionsId.eq(userId)) + .fetch(); + } + + @Transactional + public List<Tweet> findOfArea(double[] pointA, double[] pointB) { + return selectFrom(tweet) + .innerJoin(location).on(tweet.locationId.eq(location.id)) + .where(location.longitude.between(pointA[0], pointB[0]), + location.latitude.between(pointA[1], pointB[1])) + .fetch(); + } + + @Transactional + public List<Tweet> findAll(Predicate expr) { + return selectFrom(tweet).where(expr).fetch(); + } +} diff --git a/querydsl-examples/querydsl-example-sql-guice/src/main/java/com/querydsl/example/sql/repository/UserInfo.java b/querydsl-examples/querydsl-example-sql-guice/src/main/java/com/querydsl/example/sql/repository/UserInfo.java new file mode 100644 index 0000000000..a0c4340119 --- /dev/null +++ b/querydsl-examples/querydsl-example-sql-guice/src/main/java/com/querydsl/example/sql/repository/UserInfo.java @@ -0,0 +1,22 @@ +package com.querydsl.example.sql.repository; + +public class UserInfo { + + private final String username; + + private final long tweets; + + public UserInfo(String username, long tweets) { + this.username = username; + this.tweets = tweets; + } + + public String getUsername() { + return username; + } + + public long getTweets() { + return tweets; + } + +} diff --git a/querydsl-examples/querydsl-example-sql-guice/src/main/java/com/querydsl/example/sql/repository/UserRepository.java b/querydsl-examples/querydsl-example-sql-guice/src/main/java/com/querydsl/example/sql/repository/UserRepository.java new file mode 100644 index 0000000000..1afa107054 --- /dev/null +++ b/querydsl-examples/querydsl-example-sql-guice/src/main/java/com/querydsl/example/sql/repository/UserRepository.java @@ -0,0 +1,47 @@ +package com.querydsl.example.sql.repository; + +import com.querydsl.core.types.Predicate; +import com.querydsl.core.types.Projections; +import com.querydsl.example.sql.guice.Transactional; +import com.querydsl.example.sql.model.User; + +import java.util.List; + +import static com.querydsl.example.sql.model.QTweet.tweet; +import static com.querydsl.example.sql.model.QUser.user; + +public class UserRepository extends AbstractRepository { + @Transactional + public User findById(Long id) { + return selectFrom(user).where(user.id.eq(id)).fetchOne(); + } + + @Transactional + public Long save(User entity) { + if (entity.getId() != null) { + update(user).populate(entity).execute(); + return entity.getId(); + } + return insert(user).populate(entity) + .executeWithKey(user.id); + } + + @Transactional + public List<UserInfo> allWithTweetCount() { + return select(Projections.constructor(UserInfo.class, user.username, tweet.id.count())).from(user) + .leftJoin(tweet).on(user.id.eq(tweet.posterId)) + .groupBy(user.username) + .fetch(); + } + + @Transactional + public List<User> findAll(Predicate expr) { + return selectFrom(user).where(expr).fetch(); + } + + @Transactional + public List<User> all() { + return selectFrom(user).fetch(); + } + +} diff --git a/querydsl-examples/querydsl-example-sql-guice/src/main/resources/jdbc.properties b/querydsl-examples/querydsl-example-sql-guice/src/main/resources/jdbc.properties new file mode 100644 index 0000000000..8e1552f3ee --- /dev/null +++ b/querydsl-examples/querydsl-example-sql-guice/src/main/resources/jdbc.properties @@ -0,0 +1,4 @@ +jdbc.url=jdbc:h2:mem:testdb;INIT=runscript from 'src/main/sql/001_schema.sql' +jdbc.user=sa +jdbc.password= +jdbc.driver=org.h2.Driver \ No newline at end of file diff --git a/querydsl-examples/querydsl-example-sql-guice/src/main/sql/001_schema.sql b/querydsl-examples/querydsl-example-sql-guice/src/main/sql/001_schema.sql new file mode 100644 index 0000000000..a8532d58ac --- /dev/null +++ b/querydsl-examples/querydsl-example-sql-guice/src/main/sql/001_schema.sql @@ -0,0 +1,29 @@ +create schema if not exists PUBLIC; + +create table if not exists LOCATION +( + ID BIGINT auto_increment primary key, + LATITUDE DOUBLE, + LONGITUDE DOUBLE, +); + +create table if not exists USER +( + ID BIGINT auto_increment primary key, + USERNAME VARCHAR(255) +); + +create table if not exists TWEET +( + ID BIGINT auto_increment primary key, + CONTENT VARCHAR(255), + LOCATION_ID BIGINT, + POSTER_ID BIGINT not null, +); + +create table if not exists TWEET_USER +( + TWEET_ID BIGINT not null, + MENTIONS_ID BIGINT not null, +); + diff --git a/querydsl-examples/querydsl-example-sql-guice/src/test/java/com/querydsl/example/sql/guice/ConnectionContextTest.java b/querydsl-examples/querydsl-example-sql-guice/src/test/java/com/querydsl/example/sql/guice/ConnectionContextTest.java new file mode 100644 index 0000000000..44b7b94ce2 --- /dev/null +++ b/querydsl-examples/querydsl-example-sql-guice/src/test/java/com/querydsl/example/sql/guice/ConnectionContextTest.java @@ -0,0 +1,28 @@ +package com.querydsl.example.sql.guice; + +import com.google.inject.Inject; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +@RunWith(GuiceTestRunner.class) +public class ConnectionContextTest { + + @Inject + private ConnectionContext context; + + @After + public void tearDown() { + context.removeConnection(); + } + + @Test + public void get_connection() { + assertNotNull(context.getConnection(true)); + assertNotNull(context.getConnection()); + context.removeConnection(); + assertNull(context.getConnection()); + } +} diff --git a/querydsl-examples/querydsl-example-sql-guice/src/test/java/com/querydsl/example/sql/guice/GuiceTestRunner.java b/querydsl-examples/querydsl-example-sql-guice/src/test/java/com/querydsl/example/sql/guice/GuiceTestRunner.java new file mode 100644 index 0000000000..ee49f18d63 --- /dev/null +++ b/querydsl-examples/querydsl-example-sql-guice/src/test/java/com/querydsl/example/sql/guice/GuiceTestRunner.java @@ -0,0 +1,21 @@ +package com.querydsl.example.sql.guice; + +import com.google.inject.Guice; +import com.google.inject.Injector; +import org.junit.runners.BlockJUnit4ClassRunner; +import org.junit.runners.model.InitializationError; + +public class GuiceTestRunner extends BlockJUnit4ClassRunner { + + private static final Injector injector = Guice + .createInjector(new ServiceModule()); + + public GuiceTestRunner(Class<?> klass) throws InitializationError { + super(klass); + } + + @Override + protected Object createTest() throws Exception { + return injector.getInstance(getTestClass().getJavaClass()); + } +} diff --git a/querydsl-examples/querydsl-example-sql-guice/src/test/java/com/querydsl/example/sql/repository/AbstractPersistenceTest.java b/querydsl-examples/querydsl-example-sql-guice/src/test/java/com/querydsl/example/sql/repository/AbstractPersistenceTest.java new file mode 100644 index 0000000000..4697aca209 --- /dev/null +++ b/querydsl-examples/querydsl-example-sql-guice/src/test/java/com/querydsl/example/sql/repository/AbstractPersistenceTest.java @@ -0,0 +1,52 @@ +package com.querydsl.example.sql.repository; + +import com.querydsl.example.sql.guice.GuiceTestRunner; +import com.querydsl.example.sql.guice.Transactional; +import org.junit.Before; +import org.junit.runner.RunWith; + +import javax.inject.Inject; +import javax.sql.DataSource; +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +@RunWith(GuiceTestRunner.class) +public abstract class AbstractPersistenceTest { + @Inject + private DataSource dataSource; + + @Before + @Transactional + public void before() { + try (Connection connection = dataSource.getConnection()) { + List<String> tables = new ArrayList<String>(); + DatabaseMetaData md = connection.getMetaData(); + ResultSet rs = md.getTables(null, null, null, + new String[] { "TABLE" }); + try { + while (rs.next()) { + tables.add(rs.getString("TABLE_NAME")); + } + } finally { + rs.close(); + } + + java.sql.Statement stmt = connection.createStatement(); + try { + stmt.execute("SET REFERENTIAL_INTEGRITY FALSE"); + for (String table : tables) { + stmt.execute("TRUNCATE TABLE " + table); + } + stmt.execute("SET REFERENTIAL_INTEGRITY TRUE"); + } finally { + stmt.close(); + } + } catch (SQLException e) { + throw new RuntimeException(e); + } + } +} diff --git a/querydsl-examples/querydsl-example-sql-guice/src/test/java/com/querydsl/example/sql/repository/TweetRepositoryTest.java b/querydsl-examples/querydsl-example-sql-guice/src/test/java/com/querydsl/example/sql/repository/TweetRepositoryTest.java new file mode 100644 index 0000000000..9115c028ad --- /dev/null +++ b/querydsl-examples/querydsl-example-sql-guice/src/test/java/com/querydsl/example/sql/repository/TweetRepositoryTest.java @@ -0,0 +1,86 @@ +package com.querydsl.example.sql.repository; + +import com.querydsl.example.sql.model.Tweet; +import com.querydsl.example.sql.model.User; +import org.junit.Before; +import org.junit.Test; + +import javax.inject.Inject; + +import static com.querydsl.example.sql.model.QTweet.tweet; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; + +public class TweetRepositoryTest extends AbstractPersistenceTest { + @Inject + private TweetRepository repository; + + @Inject + private UserRepository userRepository; + + private Long posterId; + + @Before + public void setUp() { + User poster = new User(); + poster.setUsername("dr_frank"); + posterId = userRepository.save(poster); + } + + @Test + public void save_and_find_by_id() { + String content = "I am alive! #YOLO"; + Tweet tweet = new Tweet(); + tweet.setContent(content); + tweet.setPosterId(posterId); + Long id = repository.save(tweet); + assertEquals(content, repository.findById(id).getContent()); + } + + @Test + public void save_and_find_by_username() { + String content = "I am alive! #YOLO"; + Tweet tweet = new Tweet(); + tweet.setContent(content); + tweet.setPosterId(posterId); + repository.save(tweet); + + assertFalse(repository.findOfUser("dr_frank").isEmpty()); + } + + @Test + public void save_with_mentions() { + User other = new User(); + other.setUsername("dexter"); + Long otherId = userRepository.save(other); + + String content = "I am alive! #YOLO"; + Tweet tweet = new Tweet(); + tweet.setContent(content); + tweet.setPosterId(posterId); + Long tweetId = repository.save(tweet, otherId); + + assertEquals(tweetId, repository.findWithMentioned(otherId).get(0).getId()); + } + + @Test + public void find_list_by_predicate() { + Tweet tw1 = new Tweet(); + tw1.setPosterId(posterId); + tw1.setContent("It is a alive! #YOLO"); + repository.save(tw1); + + Tweet tw2 = new Tweet(); + tw2.setPosterId(posterId); + tw2.setContent("Oh the humanity!"); + repository.save(tw2); + + Tweet tw3 = new Tweet(); + tw3.setPosterId(posterId); + tw3.setContent("#EpicFail"); + repository.save(tw3); + + assertEquals(1, repository.findAll(tweet.content.contains("#YOLO")).size()); + } + +} diff --git a/querydsl-examples/querydsl-example-sql-guice/src/test/java/com/querydsl/example/sql/repository/UserRepositoryTest.java b/querydsl-examples/querydsl-example-sql-guice/src/test/java/com/querydsl/example/sql/repository/UserRepositoryTest.java new file mode 100644 index 0000000000..4f2848da0b --- /dev/null +++ b/querydsl-examples/querydsl-example-sql-guice/src/test/java/com/querydsl/example/sql/repository/UserRepositoryTest.java @@ -0,0 +1,53 @@ +package com.querydsl.example.sql.repository; + +import com.querydsl.example.sql.model.Tweet; +import com.querydsl.example.sql.model.User; +import org.junit.Test; + +import javax.inject.Inject; +import java.util.List; + +import static org.junit.Assert.*; + +public class UserRepositoryTest extends AbstractPersistenceTest { + @Inject + private UserRepository repository; + + @Inject + private TweetRepository tweetRepository; + + @Test + public void save_and_get_by_id() { + String username = "jackie"; + User user = new User(); + user.setUsername(username); + Long id = repository.save(user); + assertEquals(username, repository.findById(id).getUsername()); + } + + @Test + public void get_all() { + User user = new User(); + user.setUsername("jimmy"); + repository.save(user); + assertTrue(repository.all().size() == 1); + } + + @Test + public void get_all_with_tweet_count() { + User user = new User(); + user.setUsername("jimmy"); + Long posterId = repository.save(user); + + Tweet tw3 = new Tweet(); + tw3.setPosterId(posterId); + tw3.setContent("#EpicFail"); + tweetRepository.save(tw3); + + List<UserInfo> infos = repository.allWithTweetCount(); + assertFalse(infos.isEmpty()); + for (UserInfo info : infos) { + assertNotNull(info.getUsername()); + } + } +} diff --git a/querydsl-examples/querydsl-example-sql-spring/README.md b/querydsl-examples/querydsl-example-sql-spring/README.md new file mode 100644 index 0000000000..253ce96e19 --- /dev/null +++ b/querydsl-examples/querydsl-example-sql-spring/README.md @@ -0,0 +1,7 @@ +## Querydsl Customer DAO + +Querydsl Customer DAO is an example project that demonstrates some best practices on how to use Querydsl SQL on the DAO level in Spring projects. + +Compared to direct JDBC usage Querydsl SQL is typesafe, closer to SQL and abstracts over SQL dialect specific differences. + +This example project presents a version of Querydsl SQL usage where no generated bean types are used, but external DTO types are populated from queries. diff --git a/querydsl-examples/querydsl-example-sql-spring/pom.xml b/querydsl-examples/querydsl-example-sql-spring/pom.xml new file mode 100644 index 0000000000..aa25e707dc --- /dev/null +++ b/querydsl-examples/querydsl-example-sql-spring/pom.xml @@ -0,0 +1,207 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>com.querydsl</groupId> + <artifactId>querydsl-examples</artifactId> + <version>5.1.0</version> + <relativePath>../pom.xml</relativePath> + </parent> + + <groupId>com.querydsl</groupId> + <artifactId>querydsl-example-sql-spring</artifactId> + <packaging>jar</packaging> + <name>Querydsl example - SQL Spring</name> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + <spring.version>5.3.19</spring.version> + <h2.version>1.3.170</h2.version> + </properties> + + <dependencies> + + <!-- spring --> + + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-context</artifactId> + <version>${spring.version}</version> + </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-aop</artifactId> + <version>${spring.version}</version> + </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-jdbc</artifactId> + <version>${spring.version}</version> + </dependency> + + <dependency> + <groupId>javax.inject</groupId> + <artifactId>javax.inject</artifactId> + <version>1</version> + </dependency> + <dependency> + <groupId>org.projectlombok</groupId> + <artifactId>lombok</artifactId> + <version>1.18.30</version> + <scope>provided</scope> + </dependency> + + <!-- persistence --> + <dependency> + <groupId>com.querydsl</groupId> + <artifactId>querydsl-sql</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>com.querydsl</groupId> + <artifactId>querydsl-sql-spring</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>com.h2database</groupId> + <artifactId>h2</artifactId> + </dependency> + <dependency> + <groupId>com.zaxxer</groupId> + <artifactId>HikariCP</artifactId> + <version>5.1.0</version> + </dependency> + <dependency> + <groupId>joda-time</groupId> + <artifactId>joda-time</artifactId> + <version>${jodatime.version}</version> + </dependency> + + <!-- logging --> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-log4j12</artifactId> + </dependency> + <dependency> + <groupId>log4j</groupId> + <artifactId>log4j</artifactId> + </dependency> + + <!-- TEST dependencies --> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>4.13.2</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-test</artifactId> + <version>${spring.version}</version> + <scope>test</scope> + </dependency> + </dependencies> + + <build> + <finalName>querydsl-example-sql-spring</finalName> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <configuration> + <source>1.8</source> + <target>1.8</target> + </configuration> + </plugin> + + <plugin> + <groupId>com.querydsl</groupId> + <artifactId>querydsl-maven-plugin</artifactId> + <version>${project.version}</version> + <executions> + <execution> + <goals> + <goal>export</goal> + </goals> + </execution> + </executions> + <configuration> + <jdbcDriver>org.h2.Driver</jdbcDriver> + <jdbcUrl>jdbc:h2:mem:;INIT=runscript from 'file:${project.baseUri}/src/main/resources/sql/001_schema.sql'</jdbcUrl> + <jdbcUser>sa</jdbcUser> + <customTypes> + <customType>com.querydsl.sql.types.DateTimeType</customType> + <customType>com.querydsl.sql.types.LocalDateType</customType> + </customTypes> + <packageName>com.querydsl.example.sql</packageName> + <targetFolder>${project.basedir}/target/generated-sources/java</targetFolder> + </configuration> + <dependencies> + <dependency> + <groupId>com.h2database</groupId> + <artifactId>h2</artifactId> + <version>${h2.version}</version> + </dependency> + <dependency> + <groupId>joda-time</groupId> + <artifactId>joda-time</artifactId> + <version>${jodatime.version}</version> + </dependency> + </dependencies> + </plugin> + </plugins> + </build> + + <pluginRepositories> + <pluginRepository> + <id>sonatype-oss-public</id> + <url>https://oss.sonatype.org/content/groups/public</url> + <releases> + <enabled>true</enabled> + </releases> + <snapshots> + <enabled>true</enabled> + </snapshots> + </pluginRepository> + </pluginRepositories> + + <profiles> + <profile> + <id>java-11</id> + <activation> + <jdk>[11,)</jdk> + </activation> + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <configuration> + <source>11</source> + <target>11</target> + </configuration> + </plugin> + </plugins> + </build> + </profile> + <profile> + <id>java-8</id> + <activation> + <jdk>1.8</jdk> + </activation> + <dependencies> + <dependency> + <groupId>com.zaxxer</groupId> + <artifactId>HikariCP</artifactId> + <version>4.0.3</version> + </dependency> + </dependencies> + </profile> + </profiles> + +</project> diff --git a/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/config/AppConfiguration.java b/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/config/AppConfiguration.java new file mode 100644 index 0000000000..6f4f74ae4c --- /dev/null +++ b/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/config/AppConfiguration.java @@ -0,0 +1,44 @@ +package com.querydsl.example.config; + +import com.querydsl.example.dao.*; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.core.env.Environment; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +import javax.inject.Inject; + +@Configuration +@EnableTransactionManagement +@Import(JdbcConfiguration.class) +public class AppConfiguration { + + @Inject Environment env; + + @Bean + public CustomerDao customerDao() { + return new CustomerDaoImpl(); + } + + @Bean + public OrderDao orderDao() { + return new OrderDaoImpl(); + } + + @Bean + public PersonDao personDao() { + return new PersonDaoImpl(); + } + + @Bean + public ProductDao productDao() { + return new ProductDaoImpl(); + } + + @Bean + public SupplierDao supplierDao() { + return new SupplierDaoImpl(); + } + +} diff --git a/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/config/JdbcConfiguration.java b/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/config/JdbcConfiguration.java new file mode 100644 index 0000000000..3fce31ce94 --- /dev/null +++ b/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/config/JdbcConfiguration.java @@ -0,0 +1,58 @@ +package com.querydsl.example.config; + +import com.querydsl.sql.H2Templates; +import com.querydsl.sql.SQLQueryFactory; +import com.querydsl.sql.SQLTemplates; +import com.querydsl.sql.spring.SpringConnectionProvider; +import com.querydsl.sql.spring.SpringExceptionTranslator; +import com.querydsl.sql.types.DateTimeType; +import com.querydsl.sql.types.LocalDateType; +import com.zaxxer.hikari.HikariDataSource; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.PropertySource; +import org.springframework.core.env.Environment; +import org.springframework.jdbc.datasource.DataSourceTransactionManager; +import org.springframework.transaction.PlatformTransactionManager; + +import javax.inject.Inject; +import javax.sql.DataSource; + +@Configuration +@PropertySource({"classpath:jdbc.properties"}) +public class JdbcConfiguration { + + @Inject Environment env; + + @Bean + public DataSource dataSource() { + HikariDataSource dataSource = new HikariDataSource(); + dataSource.setDriverClassName(env.getRequiredProperty("jdbc.driver")); + dataSource.setJdbcUrl(env.getRequiredProperty("jdbc.url")); + dataSource.setUsername(env.getRequiredProperty("jdbc.user")); + dataSource.setPassword(env.getRequiredProperty("jdbc.password")); + return dataSource; + } + + @Bean + public PlatformTransactionManager transactionManager() { + return new DataSourceTransactionManager(dataSource()); + } + + @Bean + public com.querydsl.sql.Configuration querydslConfiguration() { + SQLTemplates templates = H2Templates.builder().build(); + com.querydsl.sql.Configuration configuration = new com.querydsl.sql.Configuration(templates); + configuration.setExceptionTranslator(new SpringExceptionTranslator()); + configuration.register(new DateTimeType()); + configuration.register(new LocalDateType()); + return configuration; + } + + @Bean + public SQLQueryFactory queryFactory() { + SpringConnectionProvider provider = new SpringConnectionProvider(dataSource()); + return new SQLQueryFactory(querydslConfiguration(), provider); + } + +} diff --git a/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/dao/CustomerDao.java b/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/dao/CustomerDao.java new file mode 100644 index 0000000000..fc7befd07d --- /dev/null +++ b/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/dao/CustomerDao.java @@ -0,0 +1,20 @@ +package com.querydsl.example.dao; + +import com.querydsl.core.types.Predicate; +import com.querydsl.example.dto.Customer; + +import java.util.List; + +public interface CustomerDao { + + Customer findById(long id); + + List<Customer> findAll(Predicate... where); + + Customer save(Customer c); + + long count(); + + void delete(Customer p); + +} diff --git a/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/dao/CustomerDaoImpl.java b/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/dao/CustomerDaoImpl.java new file mode 100644 index 0000000000..5cec247126 --- /dev/null +++ b/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/dao/CustomerDaoImpl.java @@ -0,0 +1,114 @@ +package com.querydsl.example.dao; + +import com.querydsl.core.group.GroupBy; +import com.querydsl.core.types.Predicate; +import com.querydsl.core.types.QBean; +import com.querydsl.example.dto.Address; +import com.querydsl.example.dto.Customer; +import com.querydsl.example.dto.CustomerAddress; +import com.querydsl.example.dto.Person; +import com.querydsl.sql.SQLQueryFactory; +import com.querydsl.sql.dml.SQLInsertClause; +import org.springframework.transaction.annotation.Transactional; + +import javax.inject.Inject; +import java.util.List; + +import static com.querydsl.core.types.Projections.bean; +import static com.querydsl.example.sql.QAddress.address; +import static com.querydsl.example.sql.QCustomer.customer; +import static com.querydsl.example.sql.QCustomerAddress.customerAddress; +import static com.querydsl.example.sql.QPerson.person; + +@Transactional +public class CustomerDaoImpl implements CustomerDao { + + @Inject + SQLQueryFactory queryFactory; + + final QBean<CustomerAddress> customerAddressBean = bean(CustomerAddress.class, + customerAddress.addressTypeCode, customerAddress.fromDate, customerAddress.toDate, + bean(Address.class, address.all()).as("address")); + + final QBean<Customer> customerBean = bean(Customer.class, + customer.id, customer.name, + bean(Person.class, person.all()).as("contactPerson"), + GroupBy.set(customerAddressBean).as("addresses")); + + @Override + public Customer findById(long id) { + List<Customer> customers = findAll(customer.id.eq(id)); + return customers.isEmpty() ? null : customers.get(0); + } + + @Override + public List<Customer> findAll(Predicate... where) { + return queryFactory.from(customer) + .leftJoin(customer.contactPersonFk, person) + .leftJoin(customer._customer3Fk, customerAddress) + .leftJoin(customerAddress.addressFk, address) + .where(where) + .transform(GroupBy.groupBy(customer.id).list(customerBean)); + } + + @Override + public Customer save(Customer c) { + Long id = c.getId(); + + if (id == null) { + id = queryFactory.insert(customer) + .set(customer.name, c.getName()) + .set(customer.contactPersonId, c.getContactPerson().getId()) + .executeWithKey(customer.id); + c.setId(id); + } else { + queryFactory.update(customer) + .set(customer.name, c.getName()) + .set(customer.contactPersonId, c.getContactPerson().getId()) + .where(customer.id.eq(c.getId())) + .execute(); + + // delete address rows + queryFactory.delete(customerAddress) + .where(customerAddress.customerId.eq(id)) + .execute(); + } + + SQLInsertClause insert = queryFactory.insert(customerAddress); + for (CustomerAddress ca : c.getAddresses()) { + if (ca.getAddress().getId() == null) { + ca.getAddress().setId(queryFactory.insert(address) + .populate(ca.getAddress()) + .executeWithKey(address.id)); + } + insert.set(customerAddress.customerId, id) + .set(customerAddress.addressId, ca.getAddress().getId()) + .set(customerAddress.addressTypeCode, ca.getAddressTypeCode()) + .set(customerAddress.fromDate, ca.getFromDate()) + .set(customerAddress.toDate, ca.getToDate()) + .addBatch(); + } + insert.execute(); + + c.setId(id); + return c; + } + + @Override + public long count() { + return queryFactory.from(customer).fetchCount(); + } + + @Override + public void delete(Customer c) { + // TODO use combined delete clause + queryFactory.delete(customerAddress) + .where(customerAddress.customerId.eq(c.getId())) + .execute(); + + queryFactory.delete(customer) + .where(customer.id.eq(c.getId())) + .execute(); + } + +} diff --git a/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/dao/OrderDao.java b/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/dao/OrderDao.java new file mode 100644 index 0000000000..6409175a4e --- /dev/null +++ b/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/dao/OrderDao.java @@ -0,0 +1,20 @@ +package com.querydsl.example.dao; + +import com.querydsl.core.types.Predicate; +import com.querydsl.example.dto.Order; + +import java.util.List; + +public interface OrderDao { + + Order findById(long id); + + List<Order> findAll(Predicate... where); + + Order save(Order order); + + long count(); + + void delete(Order p); + +} diff --git a/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/dao/OrderDaoImpl.java b/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/dao/OrderDaoImpl.java new file mode 100644 index 0000000000..24c061aea4 --- /dev/null +++ b/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/dao/OrderDaoImpl.java @@ -0,0 +1,108 @@ +package com.querydsl.example.dao; + +import com.querydsl.core.dml.StoreClause; +import com.querydsl.core.group.GroupBy; +import com.querydsl.core.types.Predicate; +import com.querydsl.core.types.QBean; +import com.querydsl.example.dto.CustomerPaymentMethod; +import com.querydsl.example.dto.Order; +import com.querydsl.example.dto.OrderProduct; +import com.querydsl.sql.SQLQueryFactory; +import com.querydsl.sql.dml.SQLInsertClause; +import org.springframework.transaction.annotation.Transactional; + +import javax.inject.Inject; +import java.util.List; + +import static com.querydsl.core.types.Projections.bean; +import static com.querydsl.example.sql.QCustomerOrder.customerOrder; +import static com.querydsl.example.sql.QCustomerOrderProduct.customerOrderProduct; +import static com.querydsl.example.sql.QCustomerPaymentMethod.customerPaymentMethod; + +@Transactional +public class OrderDaoImpl implements OrderDao { + + @Inject + SQLQueryFactory queryFactory; + + final QBean<OrderProduct> orderProductBean = bean(OrderProduct.class, + customerOrderProduct.productId, customerOrderProduct.comments, customerOrderProduct.quantity); + + final QBean<Order> orderBean = bean(Order.class, + customerOrder.id, customerOrder.orderPlacedDate, customerOrder.orderPaidDate, + customerOrder.orderStatus, customerOrder.totalOrderPrice, + bean(CustomerPaymentMethod.class, customerPaymentMethod.all()).as("customerPaymentMethod"), + GroupBy.set(orderProductBean).as("orderProducts")); + + @Override + public Order findById(long id) { + List<Order> orders = findAll(customerOrder.id.eq(id)); + return orders.isEmpty() ? null : orders.get(0); + } + + @Override + public List<Order> findAll(Predicate... where) { + return queryFactory.from(customerOrder) + .leftJoin(customerOrder.paymentMethodFk, customerPaymentMethod) + .leftJoin(customerOrder._orderFk, customerOrderProduct) + .where(where) + .transform(GroupBy.groupBy(customerOrder.id).list(orderBean)); + } + + private <T extends StoreClause<T>> T populate(T dml, Order o) { + return dml.set(customerOrder.customerPaymentMethodId, o.getCustomerPaymentMethod().getId()) + .set(customerOrder.orderPlacedDate, o.getOrderPlacedDate()) + .set(customerOrder.totalOrderPrice, o.getTotalOrderPrice()); + } + + @Override + public Order save(Order o) { + Long id = o.getId(); + + if (id == null) { + id = populate(queryFactory.insert(customerOrder), o) + .executeWithKey(customerOrder.id); + o.setId(id); + } else { + populate(queryFactory.update(customerOrder), o) + .where(customerOrder.id.eq(id)) + .execute(); + + // delete orderproduct rows + queryFactory.delete(customerOrderProduct) + .where(customerOrderProduct.orderId.eq(id)) + .execute(); + } + + SQLInsertClause insert = queryFactory.insert(customerOrderProduct); + for (OrderProduct op : o.getOrderProducts()) { + insert.set(customerOrderProduct.orderId, id) + .set(customerOrderProduct.comments, op.getComments()) + .set(customerOrderProduct.productId, op.getProductId()) + .set(customerOrderProduct.quantity, op.getQuantity()) + .addBatch(); + } + insert.execute(); + + o.setId(id); + return o; + } + + @Override + public long count() { + return queryFactory.from(customerOrder).fetchCount(); + } + + @Override + public void delete(Order o) { + // TODO use combined delete clause + queryFactory.delete(customerOrderProduct) + .where(customerOrderProduct.orderId.eq(o.getId())) + .execute(); + + queryFactory.delete(customerOrder) + .where(customerOrder.id.eq(o.getId())) + .execute(); + } + +} diff --git a/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/dao/PersonDao.java b/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/dao/PersonDao.java new file mode 100644 index 0000000000..ce61ba4a6a --- /dev/null +++ b/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/dao/PersonDao.java @@ -0,0 +1,20 @@ +package com.querydsl.example.dao; + +import com.querydsl.core.types.Predicate; +import com.querydsl.example.dto.Person; + +import java.util.List; + +public interface PersonDao { + + Person findById(long id); + + List<Person> findAll(Predicate... where); + + Person save(Person p); + + long count(); + + void delete(Person p); + +} diff --git a/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/dao/PersonDaoImpl.java b/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/dao/PersonDaoImpl.java new file mode 100644 index 0000000000..48b5366a41 --- /dev/null +++ b/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/dao/PersonDaoImpl.java @@ -0,0 +1,69 @@ +package com.querydsl.example.dao; + +import com.querydsl.core.types.Predicate; +import com.querydsl.core.types.QBean; +import com.querydsl.example.dto.Person; +import com.querydsl.sql.SQLQueryFactory; +import org.springframework.transaction.annotation.Transactional; + +import javax.inject.Inject; +import java.util.List; + +import static com.querydsl.core.types.Projections.bean; +import static com.querydsl.example.sql.QPerson.person; + +@Transactional +public class PersonDaoImpl implements PersonDao { + + @Inject + SQLQueryFactory queryFactory; + + final QBean<Person> personBean = bean(Person.class, person.all()); + + @Override + public Person findById(long id) { + return queryFactory.select(personBean) + .from(person) + .where(person.id.eq(id)) + .fetchOne(); + } + + @Override + public List<Person> findAll(Predicate... where) { + return queryFactory.select(personBean) + .from(person) + .where(where) + .fetch(); + } + + @Override + public Person save(Person p) { + Long id = p.getId(); + + if (id == null) { + id = queryFactory.insert(person) + .populate(p) + .executeWithKey(person.id); + p.setId(id); + } else { + queryFactory.update(person) + .populate(p) + .where(person.id.eq(id)).execute(); + } + + return p; + } + + @Override + public long count() { + return queryFactory.from(person).fetchCount(); + } + + @Override + public void delete(Person p) { + queryFactory.delete(person) + .where(person.id.eq(p.getId())) + .execute(); + } + +} diff --git a/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/dao/ProductDao.java b/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/dao/ProductDao.java new file mode 100644 index 0000000000..cbd891d13f --- /dev/null +++ b/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/dao/ProductDao.java @@ -0,0 +1,20 @@ +package com.querydsl.example.dao; + +import com.querydsl.core.types.Predicate; +import com.querydsl.example.dto.Product; + +import java.util.List; + +public interface ProductDao { + + Product findById(long id); + + List<Product> findAll(Predicate... where); + + Product save(Product p); + + long count(); + + void delete(Product p); + +} diff --git a/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/dao/ProductDaoImpl.java b/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/dao/ProductDaoImpl.java new file mode 100644 index 0000000000..691162cb87 --- /dev/null +++ b/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/dao/ProductDaoImpl.java @@ -0,0 +1,107 @@ +package com.querydsl.example.dao; + +import com.querydsl.core.dml.StoreClause; +import com.querydsl.core.group.GroupBy; +import com.querydsl.core.types.Predicate; +import com.querydsl.core.types.QBean; +import com.querydsl.example.dto.Product; +import com.querydsl.example.dto.ProductL10n; +import com.querydsl.example.dto.Supplier; +import com.querydsl.sql.SQLQueryFactory; +import com.querydsl.sql.dml.SQLInsertClause; +import org.springframework.transaction.annotation.Transactional; + +import javax.inject.Inject; +import java.util.List; + +import static com.querydsl.core.types.Projections.bean; +import static com.querydsl.example.sql.QProduct.product; +import static com.querydsl.example.sql.QProductL10n.productL10n; +import static com.querydsl.example.sql.QSupplier.supplier; + +@Transactional +public class ProductDaoImpl implements ProductDao { + + @Inject + SQLQueryFactory queryFactory; + + final QBean<ProductL10n> productL10nBean = bean(ProductL10n.class, + productL10n.description, productL10n.lang, productL10n.name); + + final QBean<Product> productBean = bean(Product.class, + product.id, product.name, product.otherProductDetails, product.price, + bean(Supplier.class, supplier.all()).as("supplier"), + GroupBy.set(productL10nBean).as("localizations")); + + @Override + public Product findById(long id) { + List<Product> persons = findAll(product.id.eq(id)); + return persons.isEmpty() ? null : persons.get(0); + } + + @Override + public List<Product> findAll(Predicate... where) { + return queryFactory.from(product) + .innerJoin(product.supplierFk, supplier) + .innerJoin(product._productFk, productL10n) + .where(where) + .transform(GroupBy.groupBy(product.id).list(productBean)); + } + + private <T extends StoreClause<T>> T populate(T dml, Product p) { + return dml.set(product.name, p.getName()) + .set(product.otherProductDetails, p.getOtherProductDetails()) + .set(product.price, p.getPrice()) + .set(product.supplierId, p.getSupplier().getId()); + } + + @Override + public Product save(Product p) { + Long id = p.getId(); + + if (id == null) { + id = populate(queryFactory.insert(product), p) + .executeWithKey(product.id); + p.setId(id); + } else { + populate(queryFactory.update(product), p) + .where(product.id.eq(id)) + .execute(); + + // delete l10n rows + queryFactory.delete(productL10n) + .where(productL10n.productId.eq(id)) + .execute(); + } + + SQLInsertClause insert = queryFactory.insert(productL10n); + for (ProductL10n l10n : p.getLocalizations()) { + insert.set(productL10n.productId, id) + .set(productL10n.description, l10n.getDescription()) + .set(productL10n.lang, l10n.getLang()) + .set(productL10n.name, l10n.getName()) + .addBatch(); + } + insert.execute(); + + return p; + } + + @Override + public long count() { + return queryFactory.from(product).fetchCount(); + } + + @Override + public void delete(Product p) { + // TODO use combined delete clause + queryFactory.delete(productL10n) + .where(productL10n.productId.eq(p.getId())) + .execute(); + + queryFactory.delete(product) + .where(product.id.eq(p.getId())) + .execute(); + } + +} diff --git a/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/dao/SupplierDao.java b/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/dao/SupplierDao.java new file mode 100644 index 0000000000..e8558702e5 --- /dev/null +++ b/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/dao/SupplierDao.java @@ -0,0 +1,20 @@ +package com.querydsl.example.dao; + +import com.querydsl.core.types.Predicate; +import com.querydsl.example.dto.Supplier; + +import java.util.List; + +public interface SupplierDao { + + Supplier findById(long id); + + List<Supplier> findAll(Predicate... where); + + Supplier save(Supplier s); + + long count(); + + void delete(Supplier s); + +} diff --git a/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/dao/SupplierDaoImpl.java b/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/dao/SupplierDaoImpl.java new file mode 100644 index 0000000000..f50e89c843 --- /dev/null +++ b/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/dao/SupplierDaoImpl.java @@ -0,0 +1,68 @@ +package com.querydsl.example.dao; + +import com.querydsl.core.types.Predicate; +import com.querydsl.core.types.QBean; +import com.querydsl.example.dto.Supplier; +import com.querydsl.sql.SQLQueryFactory; +import org.springframework.transaction.annotation.Transactional; + +import javax.inject.Inject; +import java.util.List; + +import static com.querydsl.core.types.Projections.bean; +import static com.querydsl.example.sql.QSupplier.supplier; + +@Transactional +public class SupplierDaoImpl implements SupplierDao { + + @Inject + SQLQueryFactory queryFactory; + + final QBean<Supplier> supplierBean = bean(Supplier.class, supplier.all()); + + @Override + public Supplier findById(long id) { + List<Supplier> suppliers = findAll(supplier.id.eq(id)); + return suppliers.isEmpty() ? null : suppliers.get(0); + } + + @Override + public List<Supplier> findAll(Predicate... where) { + return queryFactory.select(supplierBean) + .from(supplier) + .where(where) + .fetch(); + } + + @Override + public Supplier save(Supplier s) { + if (s.getId() == null) { + Long id = queryFactory.insert(supplier) + .set(supplier.code, s.getCode()) + .set(supplier.name, s.getName()) + .executeWithKey(supplier.id); + s.setId(id); + } else { + queryFactory.update(supplier) + .set(supplier.code, s.getCode()) + .set(supplier.name, s.getName()) + .where(supplier.id.eq(s.getId())) + .execute(); + } + + return s; + } + + @Override + public long count() { + return queryFactory.from(supplier).fetchCount(); + } + + @Override + public void delete(Supplier s) { + queryFactory.delete(supplier) + .where(supplier.id.eq(s.getId())) + .execute(); + } + +} diff --git a/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/dto/Address.java b/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/dto/Address.java new file mode 100644 index 0000000000..73d217af82 --- /dev/null +++ b/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/dto/Address.java @@ -0,0 +1,15 @@ +package com.querydsl.example.dto; + +import lombok.Data; + +@Data +public class Address { + + private Long id; + + private String street, zip, town, state, country; + + private String otherDetails; + +} + diff --git a/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/dto/Customer.java b/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/dto/Customer.java new file mode 100644 index 0000000000..9e28838519 --- /dev/null +++ b/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/dto/Customer.java @@ -0,0 +1,19 @@ +package com.querydsl.example.dto; + +import lombok.Data; + +import java.util.Set; + +@Data +public class Customer { + + private Long id; + + private Person contactPerson; + + private String name; + + private Set<CustomerAddress> addresses; + +} + diff --git a/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/dto/CustomerAddress.java b/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/dto/CustomerAddress.java new file mode 100644 index 0000000000..e78b9f268a --- /dev/null +++ b/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/dto/CustomerAddress.java @@ -0,0 +1,16 @@ +package com.querydsl.example.dto; + +import lombok.Data; +import org.joda.time.LocalDate; + +@Data +public class CustomerAddress { + + private Address address; + + private String addressTypeCode; + + private LocalDate fromDate, toDate; + +} + diff --git a/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/dto/CustomerPaymentMethod.java b/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/dto/CustomerPaymentMethod.java new file mode 100644 index 0000000000..cb422dda58 --- /dev/null +++ b/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/dto/CustomerPaymentMethod.java @@ -0,0 +1,18 @@ +package com.querydsl.example.dto; + +import lombok.Data; +import org.joda.time.LocalDate; + +@Data +public class CustomerPaymentMethod { + + private Long id; + + private Long customerId; + + private String cardNumber, otherDetails, paymentMethodCode; + + private LocalDate fromDate, toDate; + +} + diff --git a/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/dto/Order.java b/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/dto/Order.java new file mode 100644 index 0000000000..88e02e48c4 --- /dev/null +++ b/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/dto/Order.java @@ -0,0 +1,24 @@ +package com.querydsl.example.dto; + +import lombok.Data; +import org.joda.time.LocalDate; + +import java.util.Set; + +@Data +public class Order { + + private Long id; + + private CustomerPaymentMethod customerPaymentMethod; + + private LocalDate orderPlacedDate, orderPaidDate; + + private String orderStatus; + + private Double totalOrderPrice; + + private Set<OrderProduct> orderProducts; + +} + diff --git a/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/dto/OrderDelivery.java b/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/dto/OrderDelivery.java new file mode 100644 index 0000000000..06085992b0 --- /dev/null +++ b/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/dto/OrderDelivery.java @@ -0,0 +1,14 @@ +package com.querydsl.example.dto; + +import lombok.Data; +import org.joda.time.LocalDate; + +@Data +public class OrderDelivery { + + private String deliveryStatusCode; + + private LocalDate reportedDate; + +} + diff --git a/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/dto/OrderProduct.java b/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/dto/OrderProduct.java new file mode 100644 index 0000000000..91613982c5 --- /dev/null +++ b/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/dto/OrderProduct.java @@ -0,0 +1,15 @@ +package com.querydsl.example.dto; + +import lombok.Data; + +@Data +public class OrderProduct { + + private Long productId; + + private String comments; + + private Integer quantity; + +} + diff --git a/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/dto/Person.java b/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/dto/Person.java new file mode 100644 index 0000000000..6cb63d65a6 --- /dev/null +++ b/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/dto/Person.java @@ -0,0 +1,13 @@ +package com.querydsl.example.dto; + +import lombok.Data; + +@Data +public class Person { + + private Long id; + + private String firstName, lastName, email, phone; + +} + diff --git a/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/dto/Product.java b/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/dto/Product.java new file mode 100644 index 0000000000..def999e782 --- /dev/null +++ b/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/dto/Product.java @@ -0,0 +1,22 @@ +package com.querydsl.example.dto; + +import lombok.Data; + +import java.util.Set; + +@Data +public class Product { + + private Long id; + + private String name; + + private String otherProductDetails; + + private Double price; + + private Supplier supplier; + + private Set<ProductL10n> localizations; +} + diff --git a/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/dto/ProductL10n.java b/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/dto/ProductL10n.java new file mode 100644 index 0000000000..1a749c7bf1 --- /dev/null +++ b/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/dto/ProductL10n.java @@ -0,0 +1,15 @@ +package com.querydsl.example.dto; + +import lombok.Data; + +@Data +public class ProductL10n { + + private String description; + + private String lang; + + private String name; + +} + diff --git a/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/dto/Supplier.java b/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/dto/Supplier.java new file mode 100644 index 0000000000..322fcf34d8 --- /dev/null +++ b/querydsl-examples/querydsl-example-sql-spring/src/main/java/com/querydsl/example/dto/Supplier.java @@ -0,0 +1,15 @@ +package com.querydsl.example.dto; + +import lombok.Data; + +@Data +public class Supplier { + + private Long id; + + private String code; + + private String name; + +} + diff --git a/querydsl-examples/querydsl-example-sql-spring/src/main/resources/sql/001_schema.sql b/querydsl-examples/querydsl-example-sql-spring/src/main/resources/sql/001_schema.sql new file mode 100644 index 0000000000..20e9e02bf8 --- /dev/null +++ b/querydsl-examples/querydsl-example-sql-spring/src/main/resources/sql/001_schema.sql @@ -0,0 +1,104 @@ +create table supplier ( + id serial primary key, + code varchar(255), + name varchar(255) +); + +create table product ( + id serial primary key, + supplier_id long, + name varchar(64), + price double, + other_product_details varchar(64), + + constraint supplier_fk foreign key (supplier_id) references supplier(id) +); + +create table product_l10n ( + product_id long, + lang varchar(5), + name varchar(128), + description varchar(255), + + constraint product_fk foreign key (product_id) references product(id) +); + +create table person ( + id serial primary key, + first_name varchar(64), + last_name varchar(64), + phone varchar(64), + email varchar(64) +); + +create table customer ( + id serial primary key, + name varchar(64), + contact_person_id long, + + constraint contact_person_fk foreign key (contact_person_id) references person(id) +); + +create table customer_payment_method ( + id serial primary key, + customer_id long, + payment_method_code varchar(12), + card_number varchar(24), + from_date date, + to_date date, + other_details varchar(128), + + constraint customer_fk foreign key (customer_id) references customer(id) +); + +create table customer_order ( + id serial primary key, + customer_id long, + customer_payment_method_id long, + order_status varchar(12), + order_placed_date date, + order_paid_date date, + total_order_price double, + + constraint customer2_fk foreign key (customer_id) references customer(id), + constraint payment_method_fk foreign key (customer_payment_method_id) references customer_payment_method(id) +); + +create table customer_order_product ( + order_id long, + product_id long, + quantity int, + comments varchar(12), + + constraint order_fk foreign key (order_id) references customer_order(id), + constraint product2_fk foreign key (product_id) references product(id) +); + +create table customer_order_delivery ( + order_id long, + reported_date date, + delivery_status_code varchar(12), + + constraint order2_fk foreign key (order_id) references customer_order(id) +); + +create table address ( + id serial primary key, + street varchar(64), + zip varchar(64), + town varchar(64), + state varchar(64), + country varchar(3), + other_details varchar(64) +); + +create table customer_address ( + customer_id long, + address_id long, + from_date date, + to_date date, + address_type_code varchar(12), + + constraint customer3_fk foreign key (customer_id) references customer(id), + constraint address_fk foreign key (address_id) references address(id) +); diff --git a/querydsl-examples/querydsl-example-sql-spring/src/main/resources/sql/drop_all.sql b/querydsl-examples/querydsl-example-sql-spring/src/main/resources/sql/drop_all.sql new file mode 100644 index 0000000000..56025e8f23 --- /dev/null +++ b/querydsl-examples/querydsl-example-sql-spring/src/main/resources/sql/drop_all.sql @@ -0,0 +1 @@ +drop all objects; \ No newline at end of file diff --git a/querydsl-examples/querydsl-example-sql-spring/src/test/java/com/querydsl/example/config/TestConfiguration.java b/querydsl-examples/querydsl-example-sql-spring/src/test/java/com/querydsl/example/config/TestConfiguration.java new file mode 100644 index 0000000000..0936821f4b --- /dev/null +++ b/querydsl-examples/querydsl-example-sql-spring/src/test/java/com/querydsl/example/config/TestConfiguration.java @@ -0,0 +1,18 @@ +package com.querydsl.example.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +@Configuration +@Import(AppConfiguration.class) +@EnableTransactionManagement +public class TestConfiguration { + + @Bean + public TestDataService testDataService() { + return new TestDataServiceImpl(); + } + +} diff --git a/querydsl-examples/querydsl-example-sql-spring/src/test/java/com/querydsl/example/config/TestDataService.java b/querydsl-examples/querydsl-example-sql-spring/src/test/java/com/querydsl/example/config/TestDataService.java new file mode 100644 index 0000000000..8f8ba98bcb --- /dev/null +++ b/querydsl-examples/querydsl-example-sql-spring/src/test/java/com/querydsl/example/config/TestDataService.java @@ -0,0 +1,9 @@ +package com.querydsl.example.config; + +public interface TestDataService { + + void addTestData(); + + void cleanTestData(); + +} diff --git a/querydsl-examples/querydsl-example-sql-spring/src/test/java/com/querydsl/example/config/TestDataServiceImpl.java b/querydsl-examples/querydsl-example-sql-spring/src/test/java/com/querydsl/example/config/TestDataServiceImpl.java new file mode 100644 index 0000000000..deafe5f750 --- /dev/null +++ b/querydsl-examples/querydsl-example-sql-spring/src/test/java/com/querydsl/example/config/TestDataServiceImpl.java @@ -0,0 +1,136 @@ +package com.querydsl.example.config; + +import com.querydsl.example.dao.*; +import com.querydsl.example.dto.*; +import org.joda.time.LocalDate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.io.ClassPathResource; +import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; +import org.springframework.transaction.annotation.Transactional; + +import javax.sql.DataSource; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; + +@Transactional +public class TestDataServiceImpl implements TestDataService { + + @Autowired DataSource dataSource; + + @Autowired CustomerDao customerDao; + @Autowired OrderDao orderDao; + @Autowired PersonDao personDao; + @Autowired ProductDao productDao; + @Autowired SupplierDao supplierDao; + + @Override + public void addTestData() { + // suppliers + Supplier supplier = new Supplier(); + supplier.setCode("acme"); + supplier.setName("ACME"); + supplierDao.save(supplier); + + Supplier supplier2 = new Supplier(); + supplier2.setCode("bigs"); + supplier2.setName("BigS"); + supplierDao.save(supplier2); + + // products + Product product = new Product(); + product.setName("Screwdriver"); + product.setPrice(12.0); + product.setSupplier(supplier); + + ProductL10n l10nEn = new ProductL10n(); + l10nEn.setLang("en"); + l10nEn.setName("Screwdriver"); + + ProductL10n l10nDe = new ProductL10n(); + l10nDe.setLang("de"); + l10nDe.setName("Schraubenzieher"); + + product.setLocalizations(new HashSet<ProductL10n>(Arrays.asList(l10nEn, l10nDe))); + productDao.save(product); + + Product product2 = new Product(); + product2.setName("Hammer"); + product2.setPrice(5.0); + product2.setSupplier(supplier2); + + l10nEn = new ProductL10n(); + l10nEn.setLang("en"); + l10nEn.setName("Hammer"); + + product2.setLocalizations(Collections.singleton(l10nEn)); + productDao.save(product2); + + // persons + Person person = new Person(); + person.setFirstName("John"); + person.setLastName("Doe"); + person.setEmail("john.doe@aexample.com"); + personDao.save(person); + + Person person2 = new Person(); + person2.setFirstName("Mary"); + person2.setLastName("Blue"); + person2.setEmail("mary.blue@example.com"); + personDao.save(person2); + + // customers + Address address = new Address(); + address.setStreet("Mainstreet 1"); + address.setZip("00100"); + address.setTown("Helsinki"); + address.setCountry("FI"); + + CustomerAddress customerAddress = new CustomerAddress(); + customerAddress.setAddress(address); + customerAddress.setAddressTypeCode("office"); + customerAddress.setFromDate(new LocalDate()); + + Customer customer = new Customer(); + customer.setAddresses(Collections.singleton(customerAddress)); + customer.setContactPerson(person); + customer.setName("SmallS"); + customerDao.save(customer); + + Customer customer2 = new Customer(); + customer2.setAddresses(Collections.<CustomerAddress>emptySet()); + customer2.setContactPerson(person); + customer2.setName("MediumM"); + customerDao.save(customer2); + + // orders + OrderProduct orderProduct = new OrderProduct(); + orderProduct.setComments("my comments"); + orderProduct.setProductId(product.getId()); + orderProduct.setQuantity(4); + + CustomerPaymentMethod paymentMethod = new CustomerPaymentMethod(); + paymentMethod.setCardNumber("11111111111"); + paymentMethod.setCustomerId(customer.getId()); + paymentMethod.setFromDate(new LocalDate()); + paymentMethod.setPaymentMethodCode("abc"); + + Order order = new Order(); + order.setCustomerPaymentMethod(paymentMethod); + order.setOrderPlacedDate(new LocalDate()); + order.setOrderProducts(Collections.singleton(orderProduct)); + order.setTotalOrderPrice(13124.00); + orderDao.save(order); + } + + @Override + public void cleanTestData() { + ResourceDatabasePopulator populator = new ResourceDatabasePopulator(); + populator.addScripts( + new ClassPathResource("sql/drop_all.sql"), + new ClassPathResource("sql/001_schema.sql") + ); + populator.execute(dataSource); + } + +} diff --git a/querydsl-examples/querydsl-example-sql-spring/src/test/java/com/querydsl/example/dao/AbstractDaoTest.java b/querydsl-examples/querydsl-example-sql-spring/src/test/java/com/querydsl/example/dao/AbstractDaoTest.java new file mode 100644 index 0000000000..46414ef5c9 --- /dev/null +++ b/querydsl-examples/querydsl-example-sql-spring/src/test/java/com/querydsl/example/dao/AbstractDaoTest.java @@ -0,0 +1,27 @@ +package com.querydsl.example.dao; + +import com.querydsl.example.config.TestConfiguration; +import com.querydsl.example.config.TestDataService; +import org.junit.Before; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.annotation.Rollback; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.transaction.annotation.Transactional; + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration(classes = {TestConfiguration.class}) +@Rollback +@Transactional +public abstract class AbstractDaoTest { + + @Autowired + TestDataService testDataService; + + @Before + public void setUp() { + testDataService.cleanTestData(); + testDataService.addTestData(); + } +} diff --git a/querydsl-examples/querydsl-example-sql-spring/src/test/java/com/querydsl/example/dao/CustomerDaoTest.java b/querydsl-examples/querydsl-example-sql-spring/src/test/java/com/querydsl/example/dao/CustomerDaoTest.java new file mode 100644 index 0000000000..bcab6f4419 --- /dev/null +++ b/querydsl-examples/querydsl-example-sql-spring/src/test/java/com/querydsl/example/dao/CustomerDaoTest.java @@ -0,0 +1,40 @@ +package com.querydsl.example.dao; + +import com.querydsl.example.dto.Customer; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.List; + +import static org.junit.Assert.*; + +public class CustomerDaoTest extends AbstractDaoTest { + + @Autowired + CustomerDao customerDao; + + @Test + public void findAll() { + List<Customer> customers = customerDao.findAll(); + assertFalse(customers.isEmpty()); + } + + @Test + public void findById() { + assertNotNull(customerDao.findById(1)); + } + + @Test + public void update() { + Customer customer = customerDao.findById(1); + customerDao.save(customer); + } + + @Test + public void delete() { + Customer customer = customerDao.findById(1); + customerDao.delete(customer); + assertNull(customerDao.findById(1)); + } + +} diff --git a/querydsl-examples/querydsl-example-sql-spring/src/test/java/com/querydsl/example/dao/OrderDaoTest.java b/querydsl-examples/querydsl-example-sql-spring/src/test/java/com/querydsl/example/dao/OrderDaoTest.java new file mode 100644 index 0000000000..37ee31c841 --- /dev/null +++ b/querydsl-examples/querydsl-example-sql-spring/src/test/java/com/querydsl/example/dao/OrderDaoTest.java @@ -0,0 +1,53 @@ +package com.querydsl.example.dao; + +import com.querydsl.example.dto.CustomerPaymentMethod; +import com.querydsl.example.dto.Order; +import com.querydsl.example.dto.OrderProduct; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.Collections; +import java.util.List; + +import static org.junit.Assert.*; + +public class OrderDaoTest extends AbstractDaoTest { + + @Autowired + OrderDao orderDao; + + @Test + public void findAll() { + List<Order> orders = orderDao.findAll(); + assertFalse(orders.isEmpty()); + } + + @Test + public void findById() { + assertNotNull(orderDao.findById(1)); + } + + @Test + public void update() { + Order order = orderDao.findById(1); + orderDao.save(order); + } + + @Test + public void delete() { + OrderProduct orderProduct = new OrderProduct(); + orderProduct.setProductId(1L); + orderProduct.setQuantity(1); + + // FIXME + CustomerPaymentMethod paymentMethod = new CustomerPaymentMethod(); + + Order order = new Order(); + order.setCustomerPaymentMethod(paymentMethod); + order.setOrderProducts(Collections.singleton(orderProduct)); + orderDao.save(order); + assertNotNull(order.getId()); + orderDao.delete(order); + assertNull(orderDao.findById(order.getId())); + } +} diff --git a/querydsl-examples/querydsl-example-sql-spring/src/test/java/com/querydsl/example/dao/PersonDaoTest.java b/querydsl-examples/querydsl-example-sql-spring/src/test/java/com/querydsl/example/dao/PersonDaoTest.java new file mode 100644 index 0000000000..920b30ea0d --- /dev/null +++ b/querydsl-examples/querydsl-example-sql-spring/src/test/java/com/querydsl/example/dao/PersonDaoTest.java @@ -0,0 +1,43 @@ +package com.querydsl.example.dao; + +import com.querydsl.example.dto.Person; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.List; + +import static org.junit.Assert.*; + +public class PersonDaoTest extends AbstractDaoTest { + + @Autowired + PersonDao personDao; + + @Test + public void findAll() { + List<Person> persons = personDao.findAll(); + assertFalse(persons.isEmpty()); + } + + @Test + public void findById() { + assertNotNull(personDao.findById(1)); + } + + @Test + public void update() { + Person person = personDao.findById(1); + personDao.save(person); + } + + @Test + public void delete() { + Person person = new Person(); + person.setEmail("john@acme.com"); + personDao.save(person); + assertNotNull(person.getId()); + personDao.delete(person); + assertNull(personDao.findById(person.getId())); + } + +} diff --git a/querydsl-examples/querydsl-example-sql-spring/src/test/java/com/querydsl/example/dao/ProductDaoTest.java b/querydsl-examples/querydsl-example-sql-spring/src/test/java/com/querydsl/example/dao/ProductDaoTest.java new file mode 100644 index 0000000000..79d062de93 --- /dev/null +++ b/querydsl-examples/querydsl-example-sql-spring/src/test/java/com/querydsl/example/dao/ProductDaoTest.java @@ -0,0 +1,49 @@ +package com.querydsl.example.dao; + +import com.querydsl.example.dto.Product; +import com.querydsl.example.dto.ProductL10n; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.Collections; +import java.util.List; + +import static org.junit.Assert.*; + +public class ProductDaoTest extends AbstractDaoTest { + + @Autowired + SupplierDao supplierDao; + + @Autowired ProductDao productDao; + + @Test + public void findAll() { + List<Product> products = productDao.findAll(); + assertFalse(products.isEmpty()); + } + + @Test + public void findById() { + assertNotNull(productDao.findById(1)); + } + + @Test + public void update() { + Product product = productDao.findById(1); + productDao.save(product); + } + + @Test + public void delete() { + Product product = new Product(); + product.setSupplier(supplierDao.findById(1)); + product.setName("ProductX"); + product.setLocalizations(Collections.singleton(new ProductL10n())); + productDao.save(product); + assertNotNull(productDao.findById(product.getId())); + productDao.delete(product); + assertNull(productDao.findById(product.getId())); + } + +} diff --git a/querydsl-examples/querydsl-example-sql-spring/src/test/java/com/querydsl/example/dao/SupplierDaoTest.java b/querydsl-examples/querydsl-example-sql-spring/src/test/java/com/querydsl/example/dao/SupplierDaoTest.java new file mode 100644 index 0000000000..12782ff7af --- /dev/null +++ b/querydsl-examples/querydsl-example-sql-spring/src/test/java/com/querydsl/example/dao/SupplierDaoTest.java @@ -0,0 +1,42 @@ +package com.querydsl.example.dao; + +import com.querydsl.example.dto.Supplier; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.List; + +import static org.junit.Assert.*; + +public class SupplierDaoTest extends AbstractDaoTest { + + @Autowired + SupplierDao supplierDao; + + @Test + public void findAll() { + List<Supplier> suppliers = supplierDao.findAll(); + assertFalse(suppliers.isEmpty()); + } + + @Test + public void findById() { + assertNotNull(supplierDao.findById(1)); + } + + @Test + public void update() { + Supplier supplier = supplierDao.findById(1); + supplierDao.save(supplier); + } + + @Test + public void delete() { + Supplier supplier = new Supplier(); + supplierDao.save(supplier); + assertNotNull(supplier.getId()); + supplierDao.delete(supplier); + assertNull(supplierDao.findById(supplier.getId())); + } + +} diff --git a/querydsl-examples/querydsl-example-sql-spring/src/test/resources/jdbc.properties b/querydsl-examples/querydsl-example-sql-spring/src/test/resources/jdbc.properties new file mode 100644 index 0000000000..4f8e43b32b --- /dev/null +++ b/querydsl-examples/querydsl-example-sql-spring/src/test/resources/jdbc.properties @@ -0,0 +1,4 @@ +jdbc.driver=org.h2.Driver +jdbc.url=jdbc:h2:mem:example' +jdbc.user=sa +jdbc.password= \ No newline at end of file diff --git a/querydsl-guava/pom.xml b/querydsl-guava/pom.xml new file mode 100644 index 0000000000..82f3a83824 --- /dev/null +++ b/querydsl-guava/pom.xml @@ -0,0 +1,71 @@ +<?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"> + <parent> + <artifactId>querydsl-root</artifactId> + <groupId>com.querydsl</groupId> + <version>5.1.0</version> + </parent> + <modelVersion>4.0.0</modelVersion> + + <artifactId>querydsl-guava</artifactId> + <name>Querydsl - Guava Group By utilities</name> + <description>Utilities for creating group by factory expressions for Guava collection types</description> + + <properties> + <maven.compiler.source>8</maven.compiler.source> + <maven.compiler.target>8</maven.compiler.target> + </properties> + + <dependencies> + <dependency> + <groupId>com.querydsl</groupId> + <artifactId>querydsl-core</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>com.google.guava</groupId> + <artifactId>guava</artifactId> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-jar-plugin</artifactId> + <executions> + <execution> + <id>test-jar</id> + <goals> + <goal>test-jar</goal> + </goals> + </execution> + </executions> + <configuration> + <archive> + <manifestEntries> + <Automatic-Module-Name>com.querydsl.core.group.guava</Automatic-Module-Name> + </manifestEntries> + </archive> + </configuration> + </plugin> + <plugin> + <artifactId>maven-source-plugin</artifactId> + <executions> + <execution> + <phase>package</phase> + <goals> + <goal>test-jar</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> +</project> \ No newline at end of file diff --git a/querydsl-guava/src/main/java/com/querydsl/core/group/guava/GMultimap.java b/querydsl-guava/src/main/java/com/querydsl/core/group/guava/GMultimap.java new file mode 100644 index 0000000000..5e6cdc2270 --- /dev/null +++ b/querydsl-guava/src/main/java/com/querydsl/core/group/guava/GMultimap.java @@ -0,0 +1,155 @@ +/* + * Copyright 2020, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.core.group.guava; + +import com.google.common.collect.LinkedHashMultimap; +import com.google.common.collect.Multimap; +import com.google.common.collect.SortedSetMultimap; +import com.google.common.collect.TreeMultimap; +import com.mysema.commons.lang.Pair; +import com.querydsl.core.group.AbstractGroupExpression; +import com.querydsl.core.group.GroupCollector; +import com.querydsl.core.group.GroupExpression; +import com.querydsl.core.group.QPair; + +import java.util.Comparator; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; + +abstract class GMultimap<K, V, M extends Multimap<K,V>> extends AbstractGroupExpression<Pair<K, V>, M> { + + private static final long serialVersionUID = 7106389414200843920L; + + GMultimap(QPair<K,V> qpair) { + super(Multimap.class, qpair); + } + + protected abstract M createMap(); + + public static <T, U> GMultimap<T, U, Multimap<T,U>> createLinked(QPair<T, U> expr) { + return new GMultimap<T, U, Multimap<T, U>>(expr) { + @Override + protected Multimap<T, U> createMap() { + return LinkedHashMultimap.create(); + } + }; + } + + public static <T extends Comparable<? super T>, U extends Comparable<? super U>> GMultimap<T, U, SortedSetMultimap<T, U>> createSorted(QPair<T, U> expr) { + return new GMultimap<T, U, SortedSetMultimap<T, U>>(expr) { + @Override + protected SortedSetMultimap<T, U> createMap() { + return TreeMultimap.create(); + } + }; + } + + public static <T, U> GMultimap<T, U, SortedSetMultimap<T, U>> createSorted(QPair<T, U> expr, final Comparator<? super T> comparator, final Comparator<? super U> comparator2) { + return new GMultimap<T, U, SortedSetMultimap<T, U>>(expr) { + @Override + protected SortedSetMultimap<T, U> createMap() { + return TreeMultimap.create(comparator, comparator2); + } + }; + } + + @Override + public GroupCollector<Pair<K,V>, M> createGroupCollector() { + return new GroupCollector<Pair<K,V>, M>() { + + private final M map = createMap(); + + @Override + public void add(Pair<K,V> pair) { + map.put(pair.getFirst(), pair.getSecond()); + } + + @Override + public M get() { + return map; + } + + }; + } + + static class Mixin<K, V, T, U, R extends Multimap<? super T, ? super U>> extends AbstractGroupExpression<Pair<K, V>, R> { + + private static final long serialVersionUID = 1939989270493531116L; + + private class GroupCollectorImpl implements GroupCollector<Pair<K, V>, R> { + + private final GroupCollector<Pair<T, U>, R> groupCollector; + + private final Map<K, GroupCollector<K, T>> keyCollectors = new LinkedHashMap<K, GroupCollector<K, T>>(); + + private final Map<GroupCollector<K, T>, GroupCollector<V, U>> valueCollectors = new HashMap<GroupCollector<K, T>, GroupCollector<V, U>>(); + + GroupCollectorImpl() { + this.groupCollector = mixin.createGroupCollector(); + } + + @Override + public void add(Pair<K, V> pair) { + K first = pair.getFirst(); + GroupCollector<K, T> keyCollector = keyCollectors.get(first); + if (keyCollector == null) { + keyCollector = keyExpression.createGroupCollector(); + keyCollectors.put(first, keyCollector); + } + keyCollector.add(first); + GroupCollector<V, U> valueCollector = valueCollectors.get(keyCollector); + if (valueCollector == null) { + valueCollector = valueExpression.createGroupCollector(); + valueCollectors.put(keyCollector, valueCollector); + } + V second = pair.getSecond(); + valueCollector.add(second); + } + + @Override + public R get() { + for (GroupCollector<K, T> keyCollector : keyCollectors.values()) { + T key = keyCollector.get(); + GroupCollector<V, U> valueCollector = valueCollectors.remove(keyCollector); + U value = valueCollector.get(); + groupCollector.add(Pair.of(key, value)); + } + keyCollectors.clear(); + return groupCollector.get(); + } + + } + + private final GroupExpression<Pair<T, U>, R> mixin; + + private final GroupExpression<K, T> keyExpression; + private final GroupExpression<V, U> valueExpression; + + @SuppressWarnings({ "rawtypes", "unchecked" }) + Mixin(GroupExpression<K, T> keyExpression, GroupExpression<V, U> valueExpression, AbstractGroupExpression<Pair<T, U>, R> mixin) { + super((Class) mixin.getType(), QPair.create(keyExpression.getExpression(), valueExpression.getExpression())); + this.keyExpression = keyExpression; + this.valueExpression = valueExpression; + this.mixin = mixin; + } + + @Override + public GroupCollector<Pair<K, V>, R> createGroupCollector() { + return new GroupCollectorImpl(); + } + + } + +} \ No newline at end of file diff --git a/querydsl-guava/src/main/java/com/querydsl/core/group/guava/GOne.java b/querydsl-guava/src/main/java/com/querydsl/core/group/guava/GOne.java new file mode 100644 index 0000000000..91c3cc5b68 --- /dev/null +++ b/querydsl-guava/src/main/java/com/querydsl/core/group/guava/GOne.java @@ -0,0 +1,50 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.core.group.guava; + +import com.querydsl.core.group.AbstractGroupExpression; +import com.querydsl.core.group.GroupCollector; +import com.querydsl.core.types.Expression; + +class GOne<T> extends AbstractGroupExpression<T, T> { + + private static final long serialVersionUID = 3518868612387641383L; + + @SuppressWarnings("unchecked") + GOne(Expression<T> expr) { + super((Class) expr.getType(), expr); + } + + @Override + public GroupCollector<T,T> createGroupCollector() { + return new GroupCollector<T,T>() { + private boolean first = true; + + private T val; + + @Override + public void add(T o) { + if (first) { + val = o; + first = false; + } + } + + @Override + public T get() { + return val; + } + }; + } +} \ No newline at end of file diff --git a/querydsl-guava/src/main/java/com/querydsl/core/group/guava/GTable.java b/querydsl-guava/src/main/java/com/querydsl/core/group/guava/GTable.java new file mode 100644 index 0000000000..30e42c3c30 --- /dev/null +++ b/querydsl-guava/src/main/java/com/querydsl/core/group/guava/GTable.java @@ -0,0 +1,165 @@ +/* + * Copyright 2020, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.core.group.guava; + +import com.google.common.collect.HashBasedTable; +import com.google.common.collect.Table; +import com.google.common.collect.TreeBasedTable; +import com.mysema.commons.lang.Pair; +import com.querydsl.core.group.AbstractGroupExpression; +import com.querydsl.core.group.GroupCollector; +import com.querydsl.core.group.GroupExpression; +import com.querydsl.core.group.QPair; + +import java.util.Comparator; +import java.util.HashMap; +import java.util.Map; + +abstract class GTable<R, C, V, M extends Table<R, C, V>> extends AbstractGroupExpression<Pair<Pair<R, C>, V>, M> { + + private static final long serialVersionUID = 7106389414200843920L; + + GTable(QPair<Pair<R,C>, V> qpair) { + super(Table.class, qpair); + } + + protected abstract M createTable(); + + public static <T, U, W> GTable<T, U, W, Table<T, U, W>> create(QPair<Pair<T, U>, W> expr) { + return new GTable<T, U, W, Table<T, U, W>>(expr) { + @Override + protected Table<T, U, W> createTable() { + return HashBasedTable.create(); + } + }; + } + + public static <T extends Comparable<? super T>, U extends Comparable<? super U>, W> GTable<T, U, W, TreeBasedTable<T, U, W>> createSorted(QPair<Pair<T, U>, W> expr) { + return new GTable<T, U, W, TreeBasedTable<T, U, W>>(expr) { + @Override + protected TreeBasedTable<T, U, W> createTable() { + return TreeBasedTable.create(); + } + }; + } + + public static <T, U, W> GTable<T, U, W, TreeBasedTable<T, U, W>> createSorted(QPair<Pair<T, U>, W> expr, final Comparator<? super T> rowComparator, final Comparator<? super U> columnComparator) { + return new GTable<T, U, W, TreeBasedTable<T, U, W>>(expr) { + @Override + protected TreeBasedTable<T, U, W> createTable() { + return TreeBasedTable.create(rowComparator, columnComparator); + } + }; + } + + @Override + public GroupCollector<Pair<Pair<R, C>, V>, M> createGroupCollector() { + return new GroupCollector<Pair<Pair<R, C>, V>, M>() { + + private final M table = createTable(); + + @Override + public void add(Pair<Pair<R, C>, V> pair) { + table.put(pair.getFirst().getFirst(), pair.getFirst().getSecond(), pair.getSecond()); + } + + @Override + public M get() { + return table; + } + + }; + } + + static class Mixin<R, C, V, T, U, W, RES extends Table<? super T, ? super U, ? super W>> extends AbstractGroupExpression<Pair<Pair<R, C>, V>, RES> { + + private static final long serialVersionUID = 1939989270493531116L; + + private class GroupCollectorImpl implements GroupCollector<Pair<Pair<R, C>, V>, RES> { + + private final GroupCollector<Pair<Pair<T, U>, W>, RES> groupCollector; + + private final Table<R, C, GroupCollector<R, T>> rowCollectors = HashBasedTable.create(); + private final Map<GroupCollector<R, T>, GroupCollector<C, U>> columnCollectors = new HashMap<GroupCollector<R, T>, GroupCollector<C, U>>(); + private final Map<GroupCollector<C, U>, GroupCollector<V, W>> valueCollectors = new HashMap<GroupCollector<C, U>, GroupCollector<V, W>>(); + + GroupCollectorImpl() { + this.groupCollector = mixin.createGroupCollector(); + } + + @Override + public void add(Pair<Pair<R, C>, V> pair) { + Pair<R, C> first = pair.getFirst(); + R rowKey = first.getFirst(); + C columnKey = first.getSecond(); + + GroupCollector<R, T> rowCollector = rowCollectors.get(rowKey, columnKey); + if (rowCollector == null) { + rowCollector = rowExpression.createGroupCollector(); + rowCollectors.put(rowKey, columnKey, rowCollector); + } + rowCollector.add(rowKey); + + GroupCollector<C, U> columnCollector = columnCollectors.get(rowCollector); + if (columnCollector == null) { + columnCollector = columnExpression.createGroupCollector(); + columnCollectors.put(rowCollector, columnCollector); + } + columnCollector.add(columnKey); + + GroupCollector<V, W> valueCollector = valueCollectors.get(columnCollector); + if (valueCollector == null) { + valueCollector = valueExpression.createGroupCollector(); + valueCollectors.put(columnCollector, valueCollector); + } + V second = pair.getSecond(); + valueCollector.add(second); + } + + @Override + public RES get() { + for (GroupCollector<R, T> rowCollector : rowCollectors.values()) { + T rowKey = rowCollector.get(); + GroupCollector<C, U> columnCollector = columnCollectors.get(rowCollector); + U columnKey = columnCollector.get(); + GroupCollector<V, W> valueCollector = valueCollectors.get(columnCollector); + W value = valueCollector.get(); + groupCollector.add(Pair.of(Pair.of(rowKey, columnKey), value)); + } + return groupCollector.get(); + } + + } + + private final GroupExpression<Pair<Pair<T, U>, W>, RES> mixin; + private final GroupExpression<R, T> rowExpression; + private final GroupExpression<C, U> columnExpression; + private final GroupExpression<V, W> valueExpression; + + @SuppressWarnings({ "rawtypes", "unchecked" }) + Mixin(GroupExpression<R, T> rowExpression, GroupExpression<C, U> columnExpression, GroupExpression<V, W> valueExpression, AbstractGroupExpression<Pair<Pair<T, U>, W>, RES> mixin) { + super((Class) mixin.getType(), QPair.create(QPair.create(rowExpression.getExpression(), columnExpression.getExpression()), valueExpression.getExpression())); + this.rowExpression = rowExpression; + this.columnExpression = columnExpression; + this.valueExpression = valueExpression; + this.mixin = mixin; + } + + @Override + public GroupCollector<Pair<Pair<R, C>, V>, RES> createGroupCollector() { + return new GroupCollectorImpl(); + } + } + +} \ No newline at end of file diff --git a/querydsl-guava/src/main/java/com/querydsl/core/group/guava/GroupByMultimap.java b/querydsl-guava/src/main/java/com/querydsl/core/group/guava/GroupByMultimap.java new file mode 100644 index 0000000000..67593459b9 --- /dev/null +++ b/querydsl-guava/src/main/java/com/querydsl/core/group/guava/GroupByMultimap.java @@ -0,0 +1,82 @@ +/* + * Copyright 2020, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.core.group.guava; + +import com.google.common.collect.LinkedHashMultimap; +import com.google.common.collect.Multimap; +import com.mysema.commons.lang.CloseableIterator; +import com.querydsl.core.FetchableQuery; +import com.querydsl.core.Tuple; +import com.querydsl.core.group.AbstractGroupByTransformer; +import com.querydsl.core.group.Group; +import com.querydsl.core.group.GroupExpression; +import com.querydsl.core.group.GroupImpl; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.FactoryExpression; +import com.querydsl.core.types.FactoryExpressionUtils; +import com.querydsl.core.types.Projections; + +/** + * Provides aggregated results as a map + * + * @author Jan-Willem Gmelig Meyling + * + * @param <K> multi map key type + * @param <V> multi map value type + * @param <R> multi map type + */ +public class GroupByMultimap<K, V, R extends Multimap<K,V>> extends AbstractGroupByTransformer<K, R> { + + GroupByMultimap(Expression<K> key, Expression<?>... expressions) { + super(key, expressions); + } + + @Override + public R transform(FetchableQuery<?,?> query) { + Multimap<K, Group> groups = LinkedHashMultimap.create(); + + // create groups + FactoryExpression<Tuple> expr = FactoryExpressionUtils.wrap(Projections.tuple(expressions)); + boolean hasGroups = false; + for (Expression<?> e : expr.getArgs()) { + hasGroups |= e instanceof GroupExpression; + } + if (hasGroups) { + expr = withoutGroupExpressions(expr); + } + CloseableIterator<Tuple> iter = query.select(expr).iterate(); + try { + while (iter.hasNext()) { + @SuppressWarnings("unchecked") //This type is mandated by the key type + K[] row = (K[]) iter.next().toArray(); + K groupId = row[0]; + GroupImpl group = new GroupImpl(groupExpressions, maps); + groups.put(groupId, group); + group.add(row); + } + } finally { + iter.close(); + } + + // transform groups + return transform(groups); + + } + + @SuppressWarnings("unchecked") + protected R transform(Multimap<K, Group> groups) { + return (R) groups; + } + +} diff --git a/querydsl-guava/src/main/java/com/querydsl/core/group/guava/GroupByTable.java b/querydsl-guava/src/main/java/com/querydsl/core/group/guava/GroupByTable.java new file mode 100644 index 0000000000..5d6432e59f --- /dev/null +++ b/querydsl-guava/src/main/java/com/querydsl/core/group/guava/GroupByTable.java @@ -0,0 +1,89 @@ +/* + * Copyright 2020, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.core.group.guava; + +import com.google.common.collect.HashBasedTable; +import com.google.common.collect.Table; +import com.mysema.commons.lang.CloseableIterator; +import com.querydsl.core.FetchableQuery; +import com.querydsl.core.Tuple; +import com.querydsl.core.group.AbstractGroupByTransformer; +import com.querydsl.core.group.Group; +import com.querydsl.core.group.GroupExpression; +import com.querydsl.core.group.GroupImpl; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.FactoryExpression; +import com.querydsl.core.types.FactoryExpressionUtils; +import com.querydsl.core.types.Projections; +import com.querydsl.core.util.ArrayUtils; + +/** + * Provides aggregated results as a table + * + * @author Jan-Willem Gmelig Meyling + * + * @param <R> row type + * @param <C> column type + * @param <V> value type + * @param <RES> table type + */ +public class GroupByTable<R, C, V, RES extends Table<R, C, V>> extends AbstractGroupByTransformer<R, RES> { + + GroupByTable(Expression<R> rowKey, Expression<C> columnKey, Expression<?>... expressions) { + super(rowKey, ArrayUtils.combine(Expression.class, columnKey, expressions)); + } + + @Override + public RES transform(FetchableQuery<?,?> query) { + // TODO Table<Object, Object, Group> after support for it in https://github.com/querydsl/querydsl/issues/2644 + Table<R, Object, Group> groups = HashBasedTable.create(); + + // create groups + FactoryExpression<Tuple> expr = FactoryExpressionUtils.wrap(Projections.tuple(expressions)); + boolean hasGroups = false; + for (Expression<?> e : expr.getArgs()) { + hasGroups |= e instanceof GroupExpression; + } + if (hasGroups) { + expr = withoutGroupExpressions(expr); + } + CloseableIterator<Tuple> iter = query.select(expr).iterate(); + try { + while (iter.hasNext()) { + @SuppressWarnings("unchecked") //This type is mandated by the key type + Object[] row = iter.next().toArray(); + R groupId = (R) row[0]; + Object rowId = row[1]; + GroupImpl group = (GroupImpl) groups.get(groupId, rowId); + if (group == null) { + group = new GroupImpl(groupExpressions, maps); + groups.put(groupId, rowId, group); + } + group.add(row); + } + } finally { + iter.close(); + } + + // transform groups + return transform(groups); + + } + + @SuppressWarnings("unchecked") + protected RES transform(Table<R, ?, Group> groups) { + return (RES) groups; + } + +} diff --git a/querydsl-guava/src/main/java/com/querydsl/core/group/guava/GuavaGroupBy.java b/querydsl-guava/src/main/java/com/querydsl/core/group/guava/GuavaGroupBy.java new file mode 100644 index 0000000000..e7970d0c0f --- /dev/null +++ b/querydsl-guava/src/main/java/com/querydsl/core/group/guava/GuavaGroupBy.java @@ -0,0 +1,455 @@ +/* + * Copyright 2020, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.core.group.guava; + +import com.google.common.collect.Multimap; +import com.google.common.collect.SortedSetMultimap; +import com.google.common.collect.Table; +import com.google.common.collect.TreeBasedTable; +import com.mysema.commons.lang.Pair; +import com.querydsl.core.ResultTransformer; +import com.querydsl.core.group.AbstractGroupExpression; +import com.querydsl.core.group.GroupBy; +import com.querydsl.core.group.GroupExpression; +import com.querydsl.core.group.QPair; +import com.querydsl.core.types.Expression; + +import java.util.Comparator; + +/** + * {@code GuavaGroupBy} extends {@code GroupBy} with factory methods for creating {@link ResultTransformer} and {@link + * GroupExpression} instances for Guava Collection types. + * + * @author Jan-Willem Gmelig Meyling + */ +public final class GuavaGroupBy extends GroupBy { + + /** + * Create a new GroupByBuilder for the given key expression + * + * @param key key for aggregation + * @return builder for further specification + */ + public static <K> GuavaGroupByBuilder<K> groupBy(Expression<K> key) { + return new GuavaGroupByBuilder<K>(key); + } + + /** + * Create a new aggregating map expression using a backing LinkedHashMap + * + * @param key key for the map entries + * @param value value for the map entries + * @return wrapper expression + */ + public static <K, V> AbstractGroupExpression<Pair<K, V>, Multimap<K, V>> multimap(Expression<K> key, + Expression<V> value) { + return GMultimap.createLinked(QPair.create(key, value)); + } + + /** + * Create a new aggregating map expression using a backing LinkedHashMap + * + * @param key key for the map entries + * @param value value for the map entries + * @return wrapper expression + */ + public static <K, V, T> AbstractGroupExpression<Pair<K, V>, Multimap<T, V>> multimap(GroupExpression<K, T> key, + Expression<V> value) { + return multimap(key, new GOne<V>(value)); + } + + /** + * Create a new aggregating map expression using a backing LinkedHashMap + * + * @param key key for the map entries + * @param value value for the map entries + * @return wrapper expression + */ + public static <K, V, U> AbstractGroupExpression<Pair<K, V>, Multimap<K, U>> multimap(Expression<K> key, + GroupExpression<V, U> value) { + return multimap(new GOne<K>(key), value); + } + + /** + * Create a new aggregating map expression using a backing LinkedHashMap + * + * @param key key for the map entries + * @param value value for the map entries + * @return wrapper expression + */ + public static <K, V, T, U> AbstractGroupExpression<Pair<K, V>, Multimap<T, U>> multimap(GroupExpression<K, T> key, + GroupExpression<V, U> value) { + return new GMultimap.Mixin<K, V, T, U, Multimap<T, U>>(key, value, GMultimap.createLinked(QPair.create(key, value))); + } + + /** + * Create a new aggregating map expression using a backing TreeMap + * + * @param key key for the map entries + * @param value value for the map entries + * @return wrapper expression + */ + public static <K extends Comparable<? super K>, V extends Comparable<? super V>> AbstractGroupExpression<Pair<K, V>, SortedSetMultimap<K, V>> sortedSetMultimap(Expression<K> key, + Expression<V> value) { + return GMultimap.createSorted(QPair.create(key, value)); + } + + /** + * Create a new aggregating map expression using a backing TreeMap + * + * @param key key for the map entries + * @param value value for the map entries + * @return wrapper expression + */ + public static <K, V, T extends Comparable<? super T>> AbstractGroupExpression<Pair<K, V>, SortedSetMultimap<T, V>> sortedSetMultimap(GroupExpression<K, T> key, + Expression<V> value) { + return sortedSetMultimap(key, (GroupExpression) new GOne<V>(value)); + } + + /** + * Create a new aggregating map expression using a backing TreeMap + * + * @param key key for the map entries + * @param value value for the map entries + * @return wrapper expression + */ + public static <K extends Comparable<? super K>, V, U> AbstractGroupExpression<Pair<K, V>, SortedSetMultimap<K, U>> sortedSetMultimap(Expression<K> key, + GroupExpression<V, U> value) { + return sortedSetMultimap(new GOne<K>(key), (GroupExpression) value); + } + + /** + * Create a new aggregating map expression using a backing TreeMap + * + * @param key key for the map entries + * @param value value for the map entries + * @return wrapper expression + */ + public static <K, V, T extends Comparable<? super T>, U extends Comparable<? super U>> AbstractGroupExpression<Pair<K, V>, SortedSetMultimap<T, U>> sortedSetMultimap(GroupExpression<K, T> key, + GroupExpression<V, U> value) { + return new GMultimap.Mixin<K, V, T, U, SortedSetMultimap<T, U>>(key, value, GMultimap.createSorted(QPair.create(key, value))); + } + + /** + * Create a new aggregating map expression using a backing TreeMap using the given comparator + * + * @param key key for the map entries + * @param value value for the map entries + * @param keyComparator comparator for the created TreeMap instances + * @param valueComparator comparator for the created TreeMap instances + * @return wrapper expression + */ + public static <K, V> AbstractGroupExpression<Pair<K, V>, SortedSetMultimap<K, V>> sortedSetMultimap(Expression<K> key, + Expression<V> value, + Comparator<? super K> keyComparator, + Comparator<? super V> valueComparator) { + return GMultimap.createSorted(QPair.create(key, value), keyComparator, valueComparator); + } + + /** + * Create a new aggregating map expression using a backing TreeMap using the given comparator + * + * @param key key for the map entries + * @param value value for the map entries + * @param comparator comparator for the created TreeMap instances + * @param valueComparator comparator for the created TreeMap instances + * @return wrapper expression + */ + public static <K, V, T> AbstractGroupExpression<Pair<K, V>, SortedSetMultimap<T, V>> sortedSetMultimap(GroupExpression<K, T> key, + Expression<V> value, + Comparator<? super T> comparator, + Comparator<? super V> valueComparator) { + return sortedSetMultimap(key, new GOne<V>(value), comparator, valueComparator); + } + + /** + * Create a new aggregating map expression using a backing TreeMap using the given comparator + * + * @param key key for the map entries + * @param value value for the map entries + * @param keyComparator comparator for the created TreeMap instances + * @param valueComparator comparator for the created TreeMap instances + * @return wrapper expression + */ + public static <K, V, U> AbstractGroupExpression<Pair<K, V>, SortedSetMultimap<K, U>> sortedSetMultimap(Expression<K> key, + GroupExpression<V, U> value, + Comparator<? super K> keyComparator, + Comparator<? super U> valueComparator) { + return sortedSetMultimap(new GOne<K>(key), value, keyComparator, valueComparator); + } + + /** + * Create a new aggregating map expression using a backing TreeMap using the given comparator + * + * @param key key for the map entries + * @param value value for the map entries + * @param keyComparator comparator for the created TreeMap instances + * @param valueComparator comparator for the created TreeMap instances + * @return wrapper expression + */ + public static <K, V, T, U> AbstractGroupExpression<Pair<K, V>, SortedSetMultimap<T, U>> sortedSetMultimap(GroupExpression<K, T> key, + GroupExpression<V, U> value, + Comparator<? super T> keyComparator, + Comparator<? super U> valueComparator) { + return new GMultimap.Mixin<K, V, T, U, SortedSetMultimap<T, U>>(key, value, GMultimap.createSorted(QPair.create(key, value), keyComparator, valueComparator)); + } + + /** + * Create a new aggregating map expression using a backing LinkedHashMap + * + * @param row row for the table entries + * @param column column for the table entries + * @param value value for the table entries + * @return wrapper expression + */ + public static <R, C, V> AbstractGroupExpression<Pair<Pair<R, C>, V>, Table<R, C, V>> table(Expression<R> row, + Expression<C> column, + Expression<V> value) { + return GTable.create(QPair.create(QPair.create(row, column), value)); + } + + /** + * Create a new aggregating map expression using a backing LinkedHashMap + * + * @param row row for the table entries + * @param column column for the table entries + * @param value value for the table entries + * @return wrapper expression + */ + public static <R, C, V, W> AbstractGroupExpression<Pair<Pair<R, C>, V>, Table<W, C, V>> table(GroupExpression<R, W> row, + Expression<C> column, + Expression<V> value) { + return table(row, new GOne<C>(column), new GOne<V>(value)); + } + + /** + * Create a new aggregating map expression using a backing LinkedHashMap + * + * @param row row for the table entries + * @param column column for the table entries + * @param value value for the table entries + * @return wrapper expression + */ + public static <R, C, V, W, X> AbstractGroupExpression<Pair<Pair<R, C>, V>, Table<W, X, V>> table(GroupExpression<R, W> row, + GroupExpression<C, X> column, + Expression<V> value) { + return table(row, column, new GOne<V>(value)); + } + + /** + * Create a new aggregating map expression using a backing LinkedHashMap + * + * @param row row for the table entries + * @param column column for the table entries + * @param value value for the table entries + * @return wrapper expression + */ + public static <R, C, V, W> AbstractGroupExpression<Pair<Pair<R, C>, V>, Table<R, W, V>> table(Expression<R> row, + GroupExpression<C, W> column, + Expression<V> value) { + return table(new GOne<R>(row), column, new GOne<V>(value)); + } + + /** + * Create a new aggregating map expression using a backing LinkedHashMap + * + * @param row row for the table entries + * @param column column for the table entries + * @param value value for the table entries + * @return wrapper expression + */ + public static <R, C, V, W, X> AbstractGroupExpression<Pair<Pair<R, C>, V>, Table<R, X, W>> table(Expression<R> row, + GroupExpression<C, X> column, + GroupExpression<V, W> value) { + return table(new GOne<R>(row), column, value); + } + + /** + * Create a new aggregating map expression using a backing LinkedHashMap + * + * @param row row for the table entries + * @param column column for the table entries + * @param value value for the table entries + * @return wrapper expression + */ + public static <R, C, V, W, X> AbstractGroupExpression<Pair<Pair<R, C>, V>, Table<X, C, W>> table(GroupExpression<R, X> row, + Expression<C> column, + GroupExpression<V, W> value) { + return table(row, new GOne<C>(column), value); + } + + /** + * Create a new aggregating map expression using a backing LinkedHashMap + * + * @param row row for the table entries + * @param column column for the table entries + * @param value value for the table entries + * @return wrapper expression + */ + public static <R, C, V, W> AbstractGroupExpression<Pair<Pair<R, C>, V>, Table<R, C, W>> table(Expression<R> row, + Expression<C> column, + GroupExpression<V, W> value) { + return table(new GOne<R>(row), new GOne<C>(column), value); + } + + + /** + * Create a new aggregating map expression using a backing LinkedHashMap + * + * @param row row for the table entries + * @param column column for the table entries + * @param value value for the table entries + * @return wrapper expression + */ + public static <R, C, V, T, U, W> AbstractGroupExpression<Pair<Pair<R, C>, V>, Table<T, U, W>> table(GroupExpression<R, T> row, + GroupExpression<C, U> column, + GroupExpression<V, W> value) { + return new GTable.Mixin<R, C, V, T, U, W, Table<T, U, W>>( + row, column, value, GTable.create(QPair.create(QPair.create(row, column), value))); + } + + /** + * Create a new aggregating map expression using a backing LinkedHashMap + * + * @param row row for the table entries + * @param column column for the table entries + * @param value value for the table entries + * @return wrapper expression + */ + public static <R, C, V> AbstractGroupExpression<Pair<Pair<R, C>, V>, TreeBasedTable<R, C, V>> sortedTable(Expression<R> row, + Expression<C> column, + Expression<V> value, + Comparator<? super R> rowComparator, + Comparator<? super C> columnComparator) { + return GTable.createSorted(QPair.create(QPair.create(row, column), value), rowComparator, columnComparator); + } + + /** + * Create a new aggregating map expression using a backing LinkedHashMap + * + * @param row row for the table entries + * @param column column for the table entries + * @param value value for the table entries + * @return wrapper expression + */ + public static <R, C, V, W> AbstractGroupExpression<Pair<Pair<R, C>, V>, TreeBasedTable<W, C, V>> sortedTable(GroupExpression<R, W> row, + Expression<C> column, + Expression<V> value, + Comparator<? super W> rowComparator, + Comparator<? super C> columnComparator) { + return GuavaGroupBy.<R, C, V, W, C, V>sortedTable(row, new GOne<C>(column), new GOne<V>(value), rowComparator, columnComparator); + } + + /** + * Create a new aggregating map expression using a backing LinkedHashMap + * + * @param row row for the table entries + * @param column column for the table entries + * @param value value for the table entries + * @return wrapper expression + */ + public static <R, C, V, W, X> AbstractGroupExpression<Pair<Pair<R, C>, V>, TreeBasedTable<W, X, V>> sortedTable(GroupExpression<R, W> row, + GroupExpression<C, X> column, + Expression<V> value, + Comparator<? super W> rowComparator, + Comparator<? super X> columnComparator) { + return GuavaGroupBy.<R, C, V, W, X, V> sortedTable(row, column, new GOne<V>(value), rowComparator, columnComparator); + } + + /** + * Create a new aggregating map expression using a backing LinkedHashMap + * + * @param row row for the table entries + * @param column column for the table entries + * @param value value for the table entries + * @return wrapper expression + */ + public static <R, C, V, W> AbstractGroupExpression<Pair<Pair<R, C>, V>, TreeBasedTable<R, W, V>> sortedTable(Expression<R> row, + GroupExpression<C, W> column, + Expression<V> value, + Comparator<? super R> rowComparator, + Comparator<? super W> columnComparator) { + return GuavaGroupBy.<R, C, V, R, W, V>sortedTable(new GOne<R>(row), column, new GOne<V>(value), rowComparator, columnComparator); + } + + /** + * Create a new aggregating map expression using a backing LinkedHashMap + * + * @param row row for the table entries + * @param column column for the table entries + * @param value value for the table entries + * @return wrapper expression + */ + public static <R, C, V, W, X> AbstractGroupExpression<Pair<Pair<R, C>, V>, TreeBasedTable<R, X, W>> sortedTable(Expression<R> row, + GroupExpression<C, X> column, + GroupExpression<V, W> value, + Comparator<? super R> rowComparator, + Comparator<? super X> columnComparator) { + return GuavaGroupBy.<R, C, V, R, X, W>sortedTable(new GOne<R>(row), column, value, rowComparator, columnComparator); + } + + /** + * Create a new aggregating map expression using a backing LinkedHashMap + * + * @param row row for the table entries + * @param column column for the table entries + * @param value value for the table entries + * @return wrapper expression + */ + public static <R, C, V, W, X> AbstractGroupExpression<Pair<Pair<R, C>, V>, TreeBasedTable<X, C, W>> sortedTable(GroupExpression<R, X> row, + Expression<C> column, + GroupExpression<V, W> value, + Comparator<? super X> rowComparator, + Comparator<? super C> columnComparator) { + return sortedTable(row, new GOne<C>(column), value, rowComparator, columnComparator); + } + + /** + * Create a new aggregating map expression using a backing LinkedHashMap + * + * @param row row for the table entries + * @param column column for the table entries + * @param value value for the table entries + * @return wrapper expression + */ + public static <R, C, V, W> AbstractGroupExpression<Pair<Pair<R, C>, V>, TreeBasedTable<R, C, W>> sortedTable(Expression<R> row, + Expression<C> column, + GroupExpression<V, W> value, + Comparator<? super R> rowComparator, + Comparator<? super C> columnComparator) { + return GuavaGroupBy.<R, C, V, R, C, W>sortedTable(new GOne<R>(row), new GOne<C>(column), value, rowComparator, columnComparator); + } + + + /** + * Create a new aggregating map expression using a backing LinkedHashMap + * + * @param row row for the table entries + * @param column column for the table entries + * @param value value for the table entries + * @return wrapper expression + */ + public static <R, C, V, T, U, W> AbstractGroupExpression<Pair<Pair<R, C>, V>, TreeBasedTable<T, U, W>> sortedTable(GroupExpression<R, T> row, + GroupExpression<C, U> column, + GroupExpression<V, W> value, + Comparator<? super T> rowComparator, + Comparator<? super U> columnComparator) { + return new GTable.Mixin<R, C, V, T, U, W, TreeBasedTable<T, U, W>>( + row, column, value, GTable.createSorted(QPair.create(QPair.create(row, column), value), rowComparator, columnComparator)); + } + + private GuavaGroupBy() { + } + +} diff --git a/querydsl-guava/src/main/java/com/querydsl/core/group/guava/GuavaGroupByBuilder.java b/querydsl-guava/src/main/java/com/querydsl/core/group/guava/GuavaGroupByBuilder.java new file mode 100644 index 0000000000..c27aa11d39 --- /dev/null +++ b/querydsl-guava/src/main/java/com/querydsl/core/group/guava/GuavaGroupByBuilder.java @@ -0,0 +1,202 @@ +/* + * Copyright 2020, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.core.group.guava; + +import com.google.common.collect.HashBasedTable; +import com.google.common.collect.LinkedHashMultimap; +import com.google.common.collect.Multimap; +import com.google.common.collect.Table; +import com.google.common.collect.Table.Cell; +import com.google.common.collect.TreeBasedTable; +import com.google.common.collect.TreeMultimap; +import com.querydsl.core.ResultTransformer; +import com.querydsl.core.group.Group; +import com.querydsl.core.group.GroupByBuilder; +import com.querydsl.core.types.Expression; + +import java.util.Comparator; +import java.util.Map; + +/** + * {@code GroupByBuilder} is a fluent builder for GroupBy transformer instances. This class is not to be used directly, + * but via {@link GuavaGroupBy}. + * + * @param <K> + * @author Jan-Willem Gmelig Melying + */ +public class GuavaGroupByBuilder<K> extends GroupByBuilder<K> { + + /** + * Create a new GroupByBuilder for the given key expression + * + * @param key key for aggregating + */ + public GuavaGroupByBuilder(Expression<K> key) { + super(key); + } + + /** + * Get the results as multi map + * + * @param expression value expression + * @param <V> Value type + * @return new result transformer + */ + public <V> ResultTransformer<Multimap<K, V>> asMultimap(Expression<V> expression) { + final Expression<V> lookup = getLookup(expression); + return new GroupByMultimap<K, V, Multimap<K, V>>(key, expression) { + @Override + protected Multimap<K, V> transform(Multimap<K, Group> groups) { + Multimap<K, V> results = LinkedHashMultimap.create(); + for (Map.Entry<K, Group> entry : groups.entries()) { + results.put(entry.getKey(), entry.getValue().getOne(lookup)); + } + return results; + } + }; + } + + /** + * Get the results as multi map + * + * @param expression value expression + * @param <V> Value type + * @return new result transformer + */ + public <V extends Comparable<? super V>> ResultTransformer<TreeMultimap<K, V>> asSortedSetMultimap(Expression<V> expression) { + final Expression<V> lookup = getLookup(expression); + return new GroupByMultimap<K, V, TreeMultimap<K, V>>(key, expression) { + @Override + protected TreeMultimap<K, V> transform(Multimap<K, Group> groups) { + TreeMultimap<K, V> results = (TreeMultimap) TreeMultimap.create(); + for (Map.Entry<K, Group> entry : groups.entries()) { + results.put(entry.getKey(), entry.getValue().getOne(lookup)); + } + return results; + } + }; + } + + /** + * Get the results as multi map + * + * @param expression value expression + * @param comparator key comparator + * @param valueComparator value comparator + * @param <V> Value type + * @return new result transformer + */ + public <V> ResultTransformer<TreeMultimap<K, V>> asSortedSetMultimap(Expression<V> expression, + final Comparator<? super K> comparator, + final Comparator<? super V> valueComparator) { + final Expression<V> lookup = getLookup(expression); + return new GroupByMultimap<K, V, TreeMultimap<K, V>>(key, expression) { + @Override + protected TreeMultimap<K, V> transform(Multimap<K, Group> groups) { + TreeMultimap<K, V> results = TreeMultimap.create(comparator, valueComparator); + for (Map.Entry<K, Group> entry : groups.entries()) { + results.put(entry.getKey(), entry.getValue().getOne(lookup)); + } + return results; + } + }; + } + + /** + * Get the results as sorted table + * + * @param column column expression + * @param expression value expression + * @param <C> Column type + * @param <V> Value type + * @return new result transformer + */ + public <C, V> ResultTransformer<Table<K, C, V>> asTable(final Expression<C> column, final Expression<V> expression) { + final Expression<C> columnKeyLookup = getLookup(column); + final Expression<V> lookup = getLookup(expression); + return new GroupByTable<K, C, V, Table<K, C, V>>(key, column, expression) { + @Override + protected Table<K, C, V> transform(Table<K, ?, Group> groups) { + Table<K, C, V> results = HashBasedTable.create(); + for (Cell<K, ?, Group> cell : groups.cellSet()) { + K rowKey = cell.getRowKey(); + C columnKey = cell.getValue().getOne(columnKeyLookup); + V value = cell.getValue().getOne(lookup); + results.put(rowKey, columnKey, value); + } + return results; + } + }; + } + + /** + * Get the results as sorted table + * + * @param column column expression + * @param expression value expression + * @param <C> Column type + * @param <V> Value type + * @return new result transformer + */ + public <C extends Comparable<? super C>, V> ResultTransformer<TreeBasedTable<K, C, V>> asSortedTable(final Expression<C> column, final Expression<V> expression) { + final Expression<C> columnKeyLookup = getLookup(column); + final Expression<V> lookup = getLookup(expression); + return new GroupByTable<K, C, V, TreeBasedTable<K, C, V>>(key, column, expression) { + @Override + protected TreeBasedTable<K, C, V> transform(Table<K, ?, Group> groups) { + TreeBasedTable<K, C, V> results = (TreeBasedTable) TreeBasedTable.create(); + for (Cell<K, ?, Group> cell : groups.cellSet()) { + K rowKey = cell.getRowKey(); + C columnKey = cell.getValue().getOne(columnKeyLookup); + V value = cell.getValue().getOne(lookup); + results.put(rowKey, columnKey, value); + } + return results; + } + }; + } + + /** + * Get the results as sorted table + * + * @param column column expression + * @param expression value expression + * @param rowComparator row comparator + * @param columnComparator column comparator + * @param <C> Column type + * @param <V> Value type + * @return new result transformer + */ + public <C, V> ResultTransformer<TreeBasedTable<K, C, V>> asSortedTable(final Expression<C> column, + final Expression<V> expression, + final Comparator<? super K> rowComparator, + final Comparator<? super C> columnComparator) { + final Expression<C> columnKeyLookup = getLookup(column); + final Expression<V> lookup = getLookup(expression); + return new GroupByTable<K, C, V, TreeBasedTable<K, C, V>>(key, column, expression) { + @Override + protected TreeBasedTable<K, C, V> transform(Table<K, ?, Group> groups) { + TreeBasedTable<K, C, V> results = TreeBasedTable.create(rowComparator, columnComparator); + for (Cell<K, ?, Group> cell : groups.cellSet()) { + K rowKey = cell.getRowKey(); + C columnKey = cell.getValue().getOne(columnKeyLookup); + V value = cell.getValue().getOne(lookup); + results.put(rowKey, columnKey, value); + } + return results; + } + }; + } + +} diff --git a/querydsl-guava/src/main/java/com/querydsl/core/group/guava/package-info.java b/querydsl-guava/src/main/java/com/querydsl/core/group/guava/package-info.java new file mode 100644 index 0000000000..40524882e2 --- /dev/null +++ b/querydsl-guava/src/main/java/com/querydsl/core/group/guava/package-info.java @@ -0,0 +1,19 @@ +/* + * Copyright 2020, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ + +/** + * Utilities for creating group by factory expressions for Guava collection types + */ +package com.querydsl.core.group.guava; + diff --git a/querydsl-hibernate-search/pom.xml b/querydsl-hibernate-search/pom.xml index 1680faea40..f9f9373c88 100644 --- a/querydsl-hibernate-search/pom.xml +++ b/querydsl-hibernate-search/pom.xml @@ -1,15 +1,15 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0" encoding="UTF-8"?> <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <modelVersion>4.0.0</modelVersion> <parent> - <groupId>com.mysema.querydsl</groupId> + <groupId>com.querydsl</groupId> <artifactId>querydsl-root</artifactId> - <version>3.4.1.BUILD-SNAPSHOT</version> - <relativePath>../querydsl-root/pom.xml</relativePath> + <version>5.1.0</version> + <relativePath>../pom.xml</relativePath> </parent> - <groupId>com.mysema.querydsl</groupId> + <groupId>com.querydsl</groupId> <artifactId>querydsl-hibernate-search</artifactId> <name>Querydsl - Hibernate Search support</name> <description>Hibernate Search support for querydsl</description> @@ -23,16 +23,36 @@ </scm> <properties> - <hibernate.version>4.1.7.Final</hibernate.version> - <hibernate.validator.version>4.3.0.Final</hibernate.validator.version> - <hibernate.search.version>4.2.0.Final</hibernate.search.version> - <lucene.version>3.6.2</lucene.version> + <hibernate.version>5.5.3.Final</hibernate.version> + <hibernate.validator.version>7.0.4.Final</hibernate.validator.version> + <hibernate.search.version>5.11.10.Final</hibernate.search.version> + <lucene.version>5.5.5</lucene.version> + <osgi.import.package> + org.apache.lucene.*;version="[3.6,4)", + org.hibernate.*;version="[4,5)", + ${osgi.import.package.root} + </osgi.import.package> </properties> + + <dependencyManagement> + <dependencies> + <dependency> + <groupId>org.apache.lucene</groupId> + <artifactId>lucene-core</artifactId> + <version>${lucene.version}</version> + </dependency> + <dependency> + <groupId>org.hibernate.common</groupId> + <artifactId>hibernate-commons-annotations</artifactId> + <version>5.1.2.Final</version> + </dependency> + </dependencies> + </dependencyManagement> <dependencies> <dependency> - <groupId>com.mysema.querydsl</groupId> - <artifactId>querydsl-lucene3</artifactId> + <groupId>com.querydsl</groupId> + <artifactId>querydsl-lucene5</artifactId> <version>${project.version}</version> </dependency> @@ -50,27 +70,31 @@ <groupId>asm</groupId> <artifactId>asm</artifactId> </exclusion> + <exclusion> + <artifactId>jboss-logging</artifactId> + <groupId>org.jboss.logging</groupId> + </exclusion> </exclusions> <scope>provided</scope> </dependency> <dependency> - <groupId>org.hibernate</groupId> + <groupId>org.hibernate.validator</groupId> <artifactId>hibernate-validator</artifactId> <version>${hibernate.validator.version}</version> <scope>provided</scope> - <exclusions> + <exclusions> <exclusion> - <groupId>org.slf4j</groupId> - <artifactId>slf4j-api</artifactId> + <artifactId>jboss-logging</artifactId> + <groupId>org.jboss.logging</groupId> </exclusion> - </exclusions> + </exclusions> </dependency> <dependency> - <groupId>org.hibernate.javax.persistence</groupId> - <artifactId>hibernate-jpa-2.0-api</artifactId> - <version>1.0.0.Final</version> - <scope>compile</scope> + <groupId>jakarta.persistence</groupId> + <artifactId>jakarta.persistence-api</artifactId> + <version>2.2.3</version> + <scope>provided</scope> </dependency> <dependency> @@ -81,7 +105,7 @@ </dependency> <dependency> <groupId>org.hibernate</groupId> - <artifactId>hibernate-search</artifactId> + <artifactId>hibernate-search-orm</artifactId> <version>${hibernate.search.version}</version> <scope>provided</scope> <exclusions> @@ -89,12 +113,20 @@ <groupId>hsqldb</groupId> <artifactId>hsqldb</artifactId> </exclusion> + <exclusion> + <artifactId>hibernate-core</artifactId> + <groupId>org.hibernate</groupId> + </exclusion> + <exclusion> + <artifactId>slf4j-api</artifactId> + <groupId>org.slf4j</groupId> + </exclusion> </exclusions> </dependency> <dependency> <groupId>javassist</groupId> <artifactId>javassist</artifactId> - <version>3.6.0.GA</version> + <version>3.12.1.GA</version> <scope>provided</scope> </dependency> @@ -105,22 +137,51 @@ <version>${derby.version}</version> <scope>test</scope> </dependency> + <dependency> + <groupId>org.apache.derby</groupId> + <artifactId>derbytools</artifactId> + <version>${derby.version}</version> + <scope>test</scope> + </dependency> <dependency> - <groupId>com.mysema.querydsl</groupId> + <groupId>com.querydsl</groupId> <artifactId>querydsl-core</artifactId> <version>${project.version}</version> <scope>test</scope> <type>test-jar</type> - </dependency> - + </dependency> + + <dependency> + <groupId>javax.xml.bind</groupId> + <artifactId>jaxb-api</artifactId> + <version>2.3.1</version> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>javax.validation</groupId> + <artifactId>validation-api</artifactId> + <scope>test</scope> + </dependency> </dependencies> <build> <plugins> <plugin> - <groupId>com.springsource.bundlor</groupId> - <artifactId>com.springsource.bundlor.maven</artifactId> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-jar-plugin</artifactId> + <configuration> + <archive> + <manifestEntries> + <Automatic-Module-Name>com.querydsl.hibernate.search</Automatic-Module-Name> + </manifestEntries> + </archive> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> @@ -138,4 +199,4 @@ </build> -</project> +</project> diff --git a/querydsl-hibernate-search/src/main/java/com/mysema/query/hibernate/search/SearchQuery.java b/querydsl-hibernate-search/src/main/java/com/mysema/query/hibernate/search/SearchQuery.java deleted file mode 100644 index cefc01df49..0000000000 --- a/querydsl-hibernate-search/src/main/java/com/mysema/query/hibernate/search/SearchQuery.java +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.hibernate.search; - -import java.util.List; - -import org.apache.lucene.search.MatchAllDocsQuery; -import org.hibernate.Session; -import org.hibernate.search.FullTextQuery; -import org.hibernate.search.FullTextSession; -import org.hibernate.search.Search; - -import com.mysema.commons.lang.CloseableIterator; -import com.mysema.commons.lang.IteratorAdapter; -import com.mysema.query.NonUniqueResultException; -import com.mysema.query.QueryMetadata; -import com.mysema.query.QueryModifiers; -import com.mysema.query.SearchResults; -import com.mysema.query.SimpleProjectable; -import com.mysema.query.SimpleQuery; -import com.mysema.query.lucene.LuceneSerializer; -import com.mysema.query.support.QueryMixin; -import com.mysema.query.types.EntityPath; -import com.mysema.query.types.OrderSpecifier; -import com.mysema.query.types.ParamExpression; -import com.mysema.query.types.Predicate; - -/** - * SearchQuery is a Query implementation for Hibernate Search - * - * @author tiwe - * - * @param <T> - */ -public class SearchQuery<T> implements SimpleQuery<SearchQuery<T>>, SimpleProjectable<T> { - - private final EntityPath<T> path; - - private final QueryMixin<SearchQuery<T>> queryMixin; - - private final LuceneSerializer serializer; - - private final FullTextSession session; - - /** - * Create a new SearchQuery instance - * - * @param session - * @param path - */ - public SearchQuery(FullTextSession session, EntityPath<T> path) { - this.queryMixin = new QueryMixin<SearchQuery<T>>(this); - this.session = session; - this.path = path; - this.serializer = SearchSerializer.DEFAULT; - queryMixin.from(path); - } - - public SearchQuery(Session session, EntityPath<T> path) { - this(Search.getFullTextSession(session), path); - } - - - @Override - public boolean exists() { - return createQuery(true).getResultSize() > 0; - } - - @Override - public boolean notExists() { - return createQuery(true).getResultSize() == 0; - } - - @Override - public long count() { - return createQuery(true).getResultSize(); - } - - private FullTextQuery createQuery(boolean forCount) { - QueryMetadata metadata = queryMixin.getMetadata(); - org.apache.lucene.search.Query query; - if (metadata.getWhere() != null) { - query = serializer.toQuery(metadata.getWhere(), metadata); - } else { - query = new MatchAllDocsQuery(); - } - FullTextQuery fullTextQuery = session.createFullTextQuery(query, path.getType()); - - // order - if (!metadata.getOrderBy().isEmpty() && !forCount) { - fullTextQuery.setSort(serializer.toSort(metadata.getOrderBy())); - } - - // paging - QueryModifiers modifiers = metadata.getModifiers(); - if (modifiers != null && modifiers.isRestricting() && !forCount) { - Integer limit = modifiers.getLimitAsInteger(); - Integer offset = modifiers.getOffsetAsInteger(); - if (limit != null) { - fullTextQuery.setMaxResults(limit.intValue()); - } - if (offset != null) { - fullTextQuery.setFirstResult(offset.intValue()); - } - } - return fullTextQuery; - } - - - @Override - public SearchQuery<T> distinct() { - // do nothing - return this; - } - - - @SuppressWarnings("unchecked") - public CloseableIterator<T> iterate() { - return new IteratorAdapter<T>(createQuery(false).iterate()); - } - - public CloseableIterator<T> iterateDistinct() { - return iterate(); - } - - @Override - public SearchQuery<T> limit(long limit) { - return queryMixin.limit(limit); - } - - @SuppressWarnings("unchecked") - @Override - public List<T> list() { - return createQuery(false).list(); - } - - @SuppressWarnings("unchecked") - @Override - public SearchResults<T> listResults() { - FullTextQuery query = createQuery(false); - return new SearchResults<T>(query.list(), queryMixin.getMetadata().getModifiers(), query.getResultSize()); - } - - @Override - public SearchQuery<T> offset(long offset) { - return queryMixin.offset(offset); - } - - @Override - public SearchQuery<T> orderBy(OrderSpecifier<?>... o) { - return queryMixin.orderBy(o); - } - - @Override - public SearchQuery<T> restrict(QueryModifiers modifiers) { - return queryMixin.restrict(modifiers); - } - - @Override - public <P> SearchQuery<T> set(ParamExpression<P> param, P value) { - return queryMixin.set(param, value); - } - - @Override - public T singleResult() { - return limit(1).uniqueResult(); - } - - @SuppressWarnings("unchecked") - @Override - public T uniqueResult() { - try { - return (T) createQuery(false).uniqueResult(); - } catch (org.hibernate.NonUniqueResultException e) { - throw new NonUniqueResultException(); - } - } - - @Override - public SearchQuery<T> where(Predicate... e) { - return queryMixin.where(e); - } - - -} diff --git a/querydsl-hibernate-search/src/main/java/com/mysema/query/hibernate/search/SearchSerializer.java b/querydsl-hibernate-search/src/main/java/com/mysema/query/hibernate/search/SearchSerializer.java deleted file mode 100644 index 880c147b21..0000000000 --- a/querydsl-hibernate-search/src/main/java/com/mysema/query/hibernate/search/SearchSerializer.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.hibernate.search; - -import org.hibernate.search.annotations.Field; - -import com.mysema.query.lucene.LuceneSerializer; -import com.mysema.query.types.Path; - -/** - * SearchSerializer extends the LuceneSerializer to use {@link Field} annotation data from paths - * - * @author tiwe - * - */ -public class SearchSerializer extends LuceneSerializer{ - - public static final SearchSerializer DEFAULT = new SearchSerializer(false,true); - - /** - * Create a new SearchSerializer instance - * - * @param lowerCase - * @param splitTerms - */ - public SearchSerializer(boolean lowerCase, boolean splitTerms) { - super(lowerCase, splitTerms); - } - - @Override - public String toField(Path<?> path) { - if (path.getAnnotatedElement() != null) { - Field fieldAnn = path.getAnnotatedElement().getAnnotation(Field.class); - if (fieldAnn != null && fieldAnn.name().length() > 0) { - return fieldAnn.name(); - } - } - return super.toField(path); - } - -} diff --git a/querydsl-hibernate-search/src/main/java/com/mysema/query/hibernate/search/package-info.java b/querydsl-hibernate-search/src/main/java/com/mysema/query/hibernate/search/package-info.java deleted file mode 100644 index 245cd2a63c..0000000000 --- a/querydsl-hibernate-search/src/main/java/com/mysema/query/hibernate/search/package-info.java +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ - -package com.mysema.query.hibernate.search; diff --git a/querydsl-hibernate-search/src/main/java/com/querydsl/hibernate/search/AbstractSearchQuery.java b/querydsl-hibernate-search/src/main/java/com/querydsl/hibernate/search/AbstractSearchQuery.java new file mode 100644 index 0000000000..eb1f3510b9 --- /dev/null +++ b/querydsl-hibernate-search/src/main/java/com/querydsl/hibernate/search/AbstractSearchQuery.java @@ -0,0 +1,168 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.hibernate.search; + +import java.util.List; + +import com.querydsl.lucene5.LuceneSerializer; +import org.apache.lucene.search.MatchAllDocsQuery; +import org.hibernate.Session; +import org.hibernate.search.FullTextQuery; +import org.hibernate.search.FullTextSession; +import org.hibernate.search.Search; + +import com.mysema.commons.lang.CloseableIterator; +import com.mysema.commons.lang.IteratorAdapter; +import com.querydsl.core.*; +import com.querydsl.core.support.QueryMixin; +import com.querydsl.core.types.EntityPath; +import com.querydsl.core.types.OrderSpecifier; +import com.querydsl.core.types.ParamExpression; +import com.querydsl.core.types.Predicate; + +/** + * Abstract base class for Hibernate Search query classes + * + * @param <T> result type + * @param <Q> concrete subtype + */ +public abstract class AbstractSearchQuery<T, Q extends AbstractSearchQuery<T,Q>> implements SimpleQuery<Q>, Fetchable<T> { + + private final EntityPath<T> path; + + private final QueryMixin<Q> queryMixin; + + private final LuceneSerializer serializer; + + private final FullTextSession session; + + @SuppressWarnings("unchecked") + public AbstractSearchQuery(FullTextSession session, EntityPath<T> path) { + this.queryMixin = new QueryMixin<Q>((Q) this); + this.session = session; + this.path = path; + this.serializer = SearchSerializer.DEFAULT; + queryMixin.from(path); + } + + public AbstractSearchQuery(Session session, EntityPath<T> path) { + this(Search.getFullTextSession(session), path); + } + + @Override + public long fetchCount() { + return createQuery(true).getResultSize(); + } + + private FullTextQuery createQuery(boolean forCount) { + QueryMetadata metadata = queryMixin.getMetadata(); + org.apache.lucene.search.Query query; + if (metadata.getWhere() != null) { + query = serializer.toQuery(metadata.getWhere(), metadata); + } else { + query = new MatchAllDocsQuery(); + } + FullTextQuery fullTextQuery = session.createFullTextQuery(query, path.getType()); + + // order + if (!metadata.getOrderBy().isEmpty() && !forCount) { + fullTextQuery.setSort(serializer.toSort(metadata.getOrderBy())); + } + + // paging + QueryModifiers modifiers = metadata.getModifiers(); + if (modifiers.isRestricting() && !forCount) { + Integer limit = modifiers.getLimitAsInteger(); + Integer offset = modifiers.getOffsetAsInteger(); + if (limit != null) { + fullTextQuery.setMaxResults(limit); + } + if (offset != null) { + fullTextQuery.setFirstResult(offset); + } + } + return fullTextQuery; + } + + + @Override + public Q distinct() { + return queryMixin.distinct(); + } + + @Override + @SuppressWarnings("unchecked") + public CloseableIterator<T> iterate() { + return new IteratorAdapter<T>(createQuery(false).iterate()); + } + + @Override + public Q limit(long limit) { + return queryMixin.limit(limit); + } + + @SuppressWarnings("unchecked") + @Override + public List<T> fetch() { + return createQuery(false).list(); + } + + @SuppressWarnings("unchecked") + @Override + public QueryResults<T> fetchResults() { + FullTextQuery query = createQuery(false); + return new QueryResults<T>(query.list(), queryMixin.getMetadata().getModifiers(), query.getResultSize()); + } + + @Override + public Q offset(long offset) { + return queryMixin.offset(offset); + } + + @Override + public Q orderBy(OrderSpecifier<?>... o) { + return queryMixin.orderBy(o); + } + + @Override + public Q restrict(QueryModifiers modifiers) { + return queryMixin.restrict(modifiers); + } + + @Override + public <P> Q set(ParamExpression<P> param, P value) { + return queryMixin.set(param, value); + } + + @Override + public T fetchFirst() { + return limit(1).fetchOne(); + } + + @SuppressWarnings("unchecked") + @Override + public T fetchOne() throws NonUniqueResultException { + try { + return (T) createQuery(false).uniqueResult(); + } catch (org.hibernate.NonUniqueResultException e) { + throw new NonUniqueResultException(e); + } + } + + @Override + public Q where(Predicate... e) { + return queryMixin.where(e); + } + +} diff --git a/querydsl-hibernate-search/src/main/java/com/querydsl/hibernate/search/SearchQuery.java b/querydsl-hibernate-search/src/main/java/com/querydsl/hibernate/search/SearchQuery.java new file mode 100644 index 0000000000..5df66045c1 --- /dev/null +++ b/querydsl-hibernate-search/src/main/java/com/querydsl/hibernate/search/SearchQuery.java @@ -0,0 +1,51 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.hibernate.search; + +import org.hibernate.Session; +import org.hibernate.search.FullTextSession; +import org.hibernate.search.Search; + +import com.querydsl.core.types.EntityPath; + +/** + * {@code SearchQuery} is a Query implementation for Hibernate Search + * + * @author tiwe + * + * @param <T> + */ +public class SearchQuery<T> extends AbstractSearchQuery<T, SearchQuery<T>> { + + /** + * Create a new SearchQuery instance + * + * @param session session + * @param path query source + */ + public SearchQuery(FullTextSession session, EntityPath<T> path) { + super(session, path); + } + + /** + * Create a new SearchQuery instance + * + * @param session session + * @param path query source + */ + public SearchQuery(Session session, EntityPath<T> path) { + this(Search.getFullTextSession(session), path); + } + +} diff --git a/querydsl-hibernate-search/src/main/java/com/querydsl/hibernate/search/SearchSerializer.java b/querydsl-hibernate-search/src/main/java/com/querydsl/hibernate/search/SearchSerializer.java new file mode 100644 index 0000000000..ba3d18b096 --- /dev/null +++ b/querydsl-hibernate-search/src/main/java/com/querydsl/hibernate/search/SearchSerializer.java @@ -0,0 +1,52 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.hibernate.search; + +import com.querydsl.lucene5.LuceneSerializer; +import org.hibernate.search.annotations.Field; + +import com.querydsl.core.types.Path; + +/** + * {@code SearchSerializer} extends the {@link LuceneSerializer} to use {@link Field} annotation data from paths + * + * @author tiwe + * + */ +public class SearchSerializer extends LuceneSerializer { + + public static final SearchSerializer DEFAULT = new SearchSerializer(false,true); + + /** + * Create a new SearchSerializer instance + * + * @param lowerCase lowercase names + * @param splitTerms split terms + */ + public SearchSerializer(boolean lowerCase, boolean splitTerms) { + super(lowerCase, splitTerms); + } + + @Override + public String toField(Path<?> path) { + if (path.getAnnotatedElement() != null) { + Field fieldAnn = path.getAnnotatedElement().getAnnotation(Field.class); + if (fieldAnn != null && fieldAnn.name().length() > 0) { + return fieldAnn.name(); + } + } + return super.toField(path); + } + +} diff --git a/querydsl-hibernate-search/src/main/java/com/querydsl/hibernate/search/package-info.java b/querydsl-hibernate-search/src/main/java/com/querydsl/hibernate/search/package-info.java new file mode 100644 index 0000000000..503d07dad5 --- /dev/null +++ b/querydsl-hibernate-search/src/main/java/com/querydsl/hibernate/search/package-info.java @@ -0,0 +1,18 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ + +/** + * Hibernate Search support + */ +package com.querydsl.hibernate.search; diff --git a/querydsl-hibernate-search/src/test/java/com/mysema/query/hibernate/search/AbstractQueryTest.java b/querydsl-hibernate-search/src/test/java/com/mysema/query/hibernate/search/AbstractQueryTest.java deleted file mode 100644 index 420b180163..0000000000 --- a/querydsl-hibernate-search/src/test/java/com/mysema/query/hibernate/search/AbstractQueryTest.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.hibernate.search; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.sql.SQLException; -import java.util.List; -import java.util.Properties; - -import org.hibernate.HibernateException; -import org.hibernate.Session; -import org.hibernate.SessionFactory; -import org.hibernate.cfg.AnnotationConfiguration; -import org.junit.After; -import org.junit.AfterClass; -import org.junit.Before; -import org.junit.BeforeClass; - -import com.mysema.util.FileUtils; - -public abstract class AbstractQueryTest { - - private static SessionFactory sessionFactory; - - @BeforeClass - public static void setUpClass() throws IOException{ - FileUtils.delete(new File("target/derbydb")); - FileUtils.delete(new File("target/lucene")); - AnnotationConfiguration cfg = new AnnotationConfiguration(); - cfg.addAnnotatedClass(User.class); - Properties props = new Properties(); - InputStream is = SearchQueryTest.class.getResourceAsStream("/derby.properties"); - try { - props.load(is); - } finally { - is.close(); - } - cfg.setProperties(props); - sessionFactory = cfg.buildSessionFactory(); - } - - @AfterClass - public static void tearDownClass() { - if (sessionFactory != null) { - sessionFactory.close(); - } - } - - private Session session; - - protected Session getSession() { - return session; - } - - @SuppressWarnings("unchecked") - @Before - public void setUp() { - session = sessionFactory.openSession(); - session.beginTransaction(); - - // clean up - List<User> users = session.createQuery("from User").list(); - for (User user : users) { - session.delete(user); - } - } - - @After - public void tearDown() throws HibernateException, SQLException{ - if (!session.getTransaction().wasRolledBack()) { - session.getTransaction().commit(); - } - session.close(); - } - -} diff --git a/querydsl-hibernate-search/src/test/java/com/mysema/query/hibernate/search/SearchQueryTest.java b/querydsl-hibernate-search/src/test/java/com/mysema/query/hibernate/search/SearchQueryTest.java deleted file mode 100644 index a299836c65..0000000000 --- a/querydsl-hibernate-search/src/test/java/com/mysema/query/hibernate/search/SearchQueryTest.java +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.hibernate.search; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import org.hibernate.Session; -import org.junit.Ignore; -import org.junit.Test; - -import com.mysema.query.NonUniqueResultException; -import com.mysema.query.SearchResults; -import com.mysema.query.types.OrderSpecifier; -import com.mysema.query.types.expr.BooleanExpression; - -public class SearchQueryTest extends AbstractQueryTest { - - private final QUser user = new QUser("user"); - - @Override - public void setUp() { - super.setUp(); - createUser("Bob", "Stewart", "Smith", "bob@example.com"); - - createUser("Barbara", "X", "Lock", "barbara@a.com"); - createUser("Anton", "X", "Bruckner", "anton@b.com"); - createUser("Robert", "X", "Downing", "bob@c.com"); - createUser("John", "X", "Stewart", "john@d.com"); - - Session session = getSession(); - session.flush(); - session.getTransaction().commit(); - session.beginTransaction(); - } - - @Test - public void Exists() { - assertTrue(query().where(user.emailAddress.eq("bob@example.com")).exists()); - assertFalse(query().where(user.emailAddress.eq("bobby@example.com")).exists()); - } - - @Test - public void NotExists() { - assertFalse(query().where(user.emailAddress.eq("bob@example.com")).notExists()); - assertTrue(query().where(user.emailAddress.eq("bobby@example.com")).notExists()); - } - - @Test - public void Count() { - BooleanExpression filter = user.emailAddress.eq("bob@example.com"); - assertEquals(1, query().where(filter).count()); - } - - @Test - public void UniqueResult() { - BooleanExpression filter = user.emailAddress.eq("bob@example.com"); - User u = query().where(filter).uniqueResult(); - assertNotNull(u); - assertEquals("bob@example.com", u.getEmailAddress()); - } - - @Test - public void List() { - BooleanExpression filter = user.emailAddress.eq("bob@example.com"); - List<User> list = query().where(filter).list(); - assertEquals(1, list.size()); - User u = query().where(filter).uniqueResult(); - assertEquals(u, list.get(0)); - } - - @Test(expected = NonUniqueResultException.class) - public void Unique_Result_Throws_Exception_On_Multiple_Results() { - query().where(user.middleName.eq("X")).uniqueResult(); - } - - @Test - public void SingleResult() { - assertNotNull(query().where(user.middleName.eq("X")).singleResult()); - } - - @Test - public void Ordering() { - BooleanExpression filter = user.middleName.eq("X"); - // asc - List<String> asc = getFirstNames(query().where(filter).orderBy( - user.firstName.asc()).list()); - assertEquals(Arrays.asList("Anton", "Barbara", "John", "Robert"), asc); - - // desc - List<String> desc = getFirstNames(query().where(filter).orderBy( - user.firstName.desc()).list()); - assertEquals(Arrays.asList("Robert", "John", "Barbara", "Anton"), desc); - } - - @Test - public void Paging() { - BooleanExpression filter = user.middleName.eq("X"); - OrderSpecifier<?> order = user.firstName.asc(); - - // limit - List<String> limit = getFirstNames(query().where(filter).orderBy(order) - .limit(2).list()); - assertEquals(Arrays.asList("Anton", "Barbara"), limit); - - // offset - List<String> offset = getFirstNames(query().where(filter) - .orderBy(order).offset(1).list()); - assertEquals(Arrays.asList("Barbara", "John", "Robert"), offset); - - // limit + offset - List<String> limitAndOffset = getFirstNames(query().where(filter) - .orderBy(order).limit(2).offset(1).list()); - assertEquals(Arrays.asList("Barbara", "John"), limitAndOffset); - } - - @Test - public void ListResults() { - BooleanExpression filter = user.middleName.eq("X"); - SearchResults<User> users = query().where(filter).orderBy( - user.firstName.asc()).limit(2).listResults(); - List<String> asc = getFirstNames(users.getResults()); - assertEquals(Arrays.asList("Anton", "Barbara"), asc); - assertEquals(4, users.getTotal()); - } - - @Test - public void No_Where() { - assertEquals(5, query().list().size()); - } - - @Test @Ignore // OufOfMemoryError - public void Limit_Max_Value() { - assertEquals(5, query().limit(Long.MAX_VALUE).list().size()); - } - - private List<String> getFirstNames(List<User> users) { - List<String> rv = new ArrayList<String>(users.size()); - for (User user : users) { - rv.add(user.getFirstName()); - } - return rv; - } - - private User createUser(String firstName, String middleName, - String lastName, String email) { - User user = new User(); - user.setFirstName(firstName); - user.setMiddleName(middleName); - user.setLastName(lastName); - user.setEmailAddress(email); - getSession().save(user); - return user; - } - - private SearchQuery<User> query() { - return new SearchQuery<User>(getSession(), user); - } - -} diff --git a/querydsl-hibernate-search/src/test/java/com/mysema/query/hibernate/search/User.java b/querydsl-hibernate-search/src/test/java/com/mysema/query/hibernate/search/User.java deleted file mode 100644 index 272a7c0cfc..0000000000 --- a/querydsl-hibernate-search/src/test/java/com/mysema/query/hibernate/search/User.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.hibernate.search; - -import java.io.Serializable; - -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import javax.persistence.Table; - -import org.hibernate.annotations.NaturalId; -import org.hibernate.search.annotations.Analyze; -import org.hibernate.search.annotations.Analyzer; -import org.hibernate.search.annotations.DocumentId; -import org.hibernate.search.annotations.Field; -import org.hibernate.search.annotations.Index; -import org.hibernate.search.annotations.Indexed; -import org.hibernate.search.annotations.Store; - -@Entity -@Table(name = "user_") -@Indexed -@Analyzer(impl = org.apache.lucene.analysis.standard.StandardAnalyzer.class) -public class User implements Serializable { - - private static final long serialVersionUID = 5955148455600241741L; - - @Id - @GeneratedValue - @DocumentId - private Long id; - - @Field(analyze = Analyze.NO, index = Index.YES, store = Store.YES) - private String firstName; - - @Field(analyze = Analyze.NO, index = Index.YES, store = Store.YES) - private String lastName; - - @Field(analyze = Analyze.NO, index = Index.YES, store = Store.YES) - private String middleName; - - @NaturalId - @Field(analyze = Analyze.NO, name="email", index = Index.YES, store = Store.YES) - private String emailAddress; - - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public String getFirstName() { - return firstName; - } - - public void setFirstName(String firstName) { - this.firstName = firstName; - } - - public String getLastName() { - return lastName; - } - - public void setLastName(String lastName) { - this.lastName = lastName; - } - - public String getMiddleName() { - return middleName; - } - - public void setMiddleName(String middleName) { - this.middleName = middleName; - } - - public String getEmailAddress() { - return emailAddress; - } - - public void setEmailAddress(String emailAddress) { - this.emailAddress = emailAddress; - } - -} diff --git a/querydsl-hibernate-search/src/test/java/com/querydsl/hibernate/search/AbstractQueryTest.java b/querydsl-hibernate-search/src/test/java/com/querydsl/hibernate/search/AbstractQueryTest.java new file mode 100644 index 0000000000..2965aa7b62 --- /dev/null +++ b/querydsl-hibernate-search/src/test/java/com/querydsl/hibernate/search/AbstractQueryTest.java @@ -0,0 +1,88 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.hibernate.search; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.sql.SQLException; +import java.util.List; +import java.util.Properties; + +import org.hibernate.HibernateException; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.cfg.Configuration; +import org.hibernate.resource.transaction.spi.TransactionStatus; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; + +import com.querydsl.core.util.FileUtils; + +public abstract class AbstractQueryTest { + + private static SessionFactory sessionFactory; + + @BeforeClass + public static void setUpClass() throws IOException { + FileUtils.delete(new File("target/derbydb")); + FileUtils.delete(new File("target/lucene3")); + Configuration cfg = new Configuration(); + cfg.addAnnotatedClass(User.class); + Properties props = new Properties(); + try (InputStream is = SearchQueryTest.class.getResourceAsStream("/derby.properties")) { + props.load(is); + } + cfg.setProperties(props); + sessionFactory = cfg.buildSessionFactory(); + } + + @AfterClass + public static void tearDownClass() { + if (sessionFactory != null) { + sessionFactory.close(); + } + } + + private Session session; + + protected Session getSession() { + return session; + } + + @SuppressWarnings("unchecked") + @Before + public void setUp() { + session = sessionFactory.openSession(); + session.beginTransaction(); + + // clean up + List<User> users = session.createQuery("from User").list(); + for (User user : users) { + session.delete(user); + } + session.flush(); + } + + @After + public void tearDown() throws HibernateException, SQLException { + if (session.getTransaction().getStatus().isNotOneOf(TransactionStatus.ROLLED_BACK, TransactionStatus.ROLLING_BACK, TransactionStatus.MARKED_ROLLBACK)) { + session.getTransaction().commit(); + } + session.close(); + } + +} diff --git a/querydsl-hibernate-search/src/test/java/com/mysema/query/hibernate/search/QUser.java b/querydsl-hibernate-search/src/test/java/com/querydsl/hibernate/search/QUser.java similarity index 80% rename from querydsl-hibernate-search/src/test/java/com/mysema/query/hibernate/search/QUser.java rename to querydsl-hibernate-search/src/test/java/com/querydsl/hibernate/search/QUser.java index c6284d61b6..513acabfcc 100644 --- a/querydsl-hibernate-search/src/test/java/com/mysema/query/hibernate/search/QUser.java +++ b/querydsl-hibernate-search/src/test/java/com/querydsl/hibernate/search/QUser.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,11 +11,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.hibernate.search; +package com.querydsl.hibernate.search; -import com.mysema.query.types.PathMetadataFactory; -import com.mysema.query.types.path.EntityPathBase; -import com.mysema.query.types.path.StringPath; +import com.querydsl.core.types.PathMetadataFactory; +import com.querydsl.core.types.dsl.EntityPathBase; +import com.querydsl.core.types.dsl.StringPath; public class QUser extends EntityPathBase<User> { diff --git a/querydsl-hibernate-search/src/test/java/com/querydsl/hibernate/search/SearchQueryTest.java b/querydsl-hibernate-search/src/test/java/com/querydsl/hibernate/search/SearchQueryTest.java new file mode 100644 index 0000000000..b2bd5da591 --- /dev/null +++ b/querydsl-hibernate-search/src/test/java/com/querydsl/hibernate/search/SearchQueryTest.java @@ -0,0 +1,174 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.hibernate.search; + +import static org.junit.Assert.*; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.hibernate.Session; +import org.junit.Ignore; +import org.junit.Test; + +import com.querydsl.core.NonUniqueResultException; +import com.querydsl.core.QueryResults; +import com.querydsl.core.types.OrderSpecifier; +import com.querydsl.core.types.dsl.BooleanExpression; + +public class SearchQueryTest extends AbstractQueryTest { + + private final QUser user = new QUser("user"); + + @Override + public void setUp() { + super.setUp(); + createUser("Bob", "Stewart", "Smith", "bob@example.com"); + + createUser("Barbara", "X", "Lock", "barbara@a.com"); + createUser("Anton", "X", "Bruckner", "anton@b.com"); + createUser("Robert", "X", "Downing", "bob@c.com"); + createUser("John", "X", "Stewart", "john@d.com"); + + Session session = getSession(); + session.flush(); + session.getTransaction().commit(); + session.beginTransaction(); + } + + @Test + public void exists() { + assertTrue(query().where(user.emailAddress.eq("bob@example.com")).fetchCount() > 0); + assertFalse(query().where(user.emailAddress.eq("bobby@example.com")).fetchCount() > 0); + } + + @Test + public void notExists() { + assertFalse(query().where(user.emailAddress.eq("bob@example.com")).fetchCount() == 0); + assertTrue(query().where(user.emailAddress.eq("bobby@example.com")).fetchCount() == 0); + } + + @Test + public void count() { + BooleanExpression filter = user.emailAddress.eq("bob@example.com"); + assertEquals(1, query().where(filter).fetchCount()); + } + + @Test + public void uniqueResult() { + BooleanExpression filter = user.emailAddress.eq("bob@example.com"); + User u = query().where(filter).fetchOne(); + assertNotNull(u); + assertEquals("bob@example.com", u.getEmailAddress()); + } + + @Test + public void list() { + BooleanExpression filter = user.emailAddress.eq("bob@example.com"); + List<User> list = query().where(filter).fetch(); + assertEquals(1, list.size()); + User u = query().where(filter).fetchOne(); + assertEquals(u, list.get(0)); + } + + @Test(expected = NonUniqueResultException.class) + public void unique_result_throws_exception_on_multiple_results() { + query().where(user.middleName.eq("X")).fetchOne(); + } + + @Test + public void singleResult() { + assertNotNull(query().where(user.middleName.eq("X")).fetchFirst()); + } + + @Test + public void ordering() { + BooleanExpression filter = user.middleName.eq("X"); + // asc + List<String> asc = getFirstNames(query().where(filter).orderBy( + user.firstName.asc()).fetch()); + assertEquals(Arrays.asList("Anton", "Barbara", "John", "Robert"), asc); + + // desc + List<String> desc = getFirstNames(query().where(filter).orderBy( + user.firstName.desc()).fetch()); + assertEquals(Arrays.asList("Robert", "John", "Barbara", "Anton"), desc); + } + + @Test + public void paging() { + BooleanExpression filter = user.middleName.eq("X"); + OrderSpecifier<?> order = user.firstName.asc(); + + // limit + List<String> limit = getFirstNames(query().where(filter).orderBy(order) + .limit(2).fetch()); + assertEquals(Arrays.asList("Anton", "Barbara"), limit); + + // offset + List<String> offset = getFirstNames(query().where(filter) + .orderBy(order).offset(1).fetch()); + assertEquals(Arrays.asList("Barbara", "John", "Robert"), offset); + + // limit + offset + List<String> limitAndOffset = getFirstNames(query().where(filter) + .orderBy(order).limit(2).offset(1).fetch()); + assertEquals(Arrays.asList("Barbara", "John"), limitAndOffset); + } + + @Test + public void listResults() { + BooleanExpression filter = user.middleName.eq("X"); + QueryResults<User> users = query().where(filter).orderBy( + user.firstName.asc()).limit(2).fetchResults(); + List<String> asc = getFirstNames(users.getResults()); + assertEquals(Arrays.asList("Anton", "Barbara"), asc); + assertEquals(4, users.getTotal()); + } + + @Test + public void no_where() { + assertEquals(5, query().fetch().size()); + } + + @Test @Ignore // OufOfMemoryError + public void limit_max_value() { + assertEquals(5, query().limit(Long.MAX_VALUE).fetch().size()); + } + + private List<String> getFirstNames(List<User> users) { + List<String> rv = new ArrayList<String>(users.size()); + for (User user : users) { + rv.add(user.getFirstName()); + } + return rv; + } + + private User createUser(String firstName, String middleName, + String lastName, String email) { + User user = new User(); + user.setFirstName(firstName); + user.setMiddleName(middleName); + user.setLastName(lastName); + user.setEmailAddress(email); + getSession().save(user); + return user; + } + + private SearchQuery<User> query() { + return new SearchQuery<User>(getSession(), user); + } + +} diff --git a/querydsl-hibernate-search/src/test/java/com/mysema/query/hibernate/search/SearchSerializerTest.java b/querydsl-hibernate-search/src/test/java/com/querydsl/hibernate/search/SearchSerializerTest.java similarity index 81% rename from querydsl-hibernate-search/src/test/java/com/mysema/query/hibernate/search/SearchSerializerTest.java rename to querydsl-hibernate-search/src/test/java/com/querydsl/hibernate/search/SearchSerializerTest.java index af73823364..e9ba40f56a 100644 --- a/querydsl-hibernate-search/src/test/java/com/mysema/query/hibernate/search/SearchSerializerTest.java +++ b/querydsl-hibernate-search/src/test/java/com/querydsl/hibernate/search/SearchSerializerTest.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,18 +11,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.hibernate.search; +package com.querydsl.hibernate.search; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; import org.junit.Test; -import com.mysema.query.hibernate.search.SearchSerializer; - public class SearchSerializerTest { @Test - public void ToField() { + public void toField() { SearchSerializer serializer = SearchSerializer.DEFAULT; QUser user = new QUser("user"); assertEquals("email", serializer.toField(user.emailAddress)); diff --git a/querydsl-hibernate-search/src/test/java/com/querydsl/hibernate/search/User.java b/querydsl-hibernate-search/src/test/java/com/querydsl/hibernate/search/User.java new file mode 100644 index 0000000000..bfb91ff15f --- /dev/null +++ b/querydsl-hibernate-search/src/test/java/com/querydsl/hibernate/search/User.java @@ -0,0 +1,93 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.hibernate.search; + +import java.io.Serializable; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Table; + +import org.hibernate.annotations.NaturalId; +import org.hibernate.search.annotations.*; + +@Entity +@Table(name = "user_") +@Indexed +@Analyzer(impl = org.apache.lucene.analysis.standard.StandardAnalyzer.class) +public class User implements Serializable { + + private static final long serialVersionUID = 5955148455600241741L; + + @Id + @GeneratedValue + @DocumentId + private Long id; + + @SortableField + @Field(analyze = Analyze.NO, index = Index.YES, store = Store.YES) + private String firstName; + + @Field(analyze = Analyze.NO, index = Index.YES, store = Store.YES) + private String lastName; + + @Field(analyze = Analyze.NO, index = Index.YES, store = Store.YES) + private String middleName; + + @NaturalId + @Field(analyze = Analyze.NO, name = "email", index = Index.YES, store = Store.YES) + private String emailAddress; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public String getMiddleName() { + return middleName; + } + + public void setMiddleName(String middleName) { + this.middleName = middleName; + } + + public String getEmailAddress() { + return emailAddress; + } + + public void setEmailAddress(String emailAddress) { + this.emailAddress = emailAddress; + } + +} diff --git a/querydsl-hibernate-search/src/test/resources/derby.properties b/querydsl-hibernate-search/src/test/resources/derby.properties index 802938d213..4d96c12e66 100644 --- a/querydsl-hibernate-search/src/test/resources/derby.properties +++ b/querydsl-hibernate-search/src/test/resources/derby.properties @@ -1,16 +1,15 @@ -## Derby -hibernate.dialect=org.hibernate.dialect.DerbyDialect -hibernate.connection.driver_class=org.apache.derby.jdbc.EmbeddedDriver -hibernate.connection.url=jdbc:derby:target/derbydb;create=true -hibernate.connection.pool_size=0 - -## Common properties -hibernate.show_sql=false -hibernate.flushMode=FLUSH_AUTO -hibernate.hbm2ddl.auto=update - -hibernate.search.default.directory_provider=org.hibernate.search.store.impl.FSDirectoryProvider -hibernate.search.default.indexBase=target/lucene/indexes -hibernate.search.default.batch.merge_factor=10 -hibernate.search.default.batch.max_buffered_docs=10 - +## Derby +hibernate.dialect=org.hibernate.dialect.DerbyDialect +hibernate.connection.driver_class=org.apache.derby.jdbc.EmbeddedDriver +hibernate.connection.url=jdbc:derby:target/derbydb;create=true +hibernate.connection.pool_size=0 + +## Common properties +hibernate.show_sql=false +hibernate.flushMode=FLUSH_AUTO +hibernate.hbm2ddl.auto=update + +hibernate.search.default.directory_provider=org.hibernate.search.store.impl.FSDirectoryProvider +hibernate.search.default.indexBase=target/lucene/indexes +hibernate.search.default.batch.merge_factor=10 +hibernate.search.default.batch.max_buffered_docs=10 diff --git a/querydsl-hibernate-search/template.mf b/querydsl-hibernate-search/template.mf deleted file mode 100644 index 44bb92527f..0000000000 --- a/querydsl-hibernate-search/template.mf +++ /dev/null @@ -1,10 +0,0 @@ -Bundle-SymbolicName: com.mysema.querydsl.hibernate-search -Bundle-Name: Querydsl Hibernate Search -Bundle-Vendor: Mysema -Bundle-ManifestVersion: 2 -Import-Template: - com.mysema.commons.lang.*;version="${mysema.lang.version}", - com.mysema.query.*;version="${project.version}", - org.apache.lucene.*;version="[3.0.0,3.1.0)", - org.hibernate.*;version="[3.0.0,4.0.0)", - org.slf4j.*;version="${slf4j.version}" \ No newline at end of file diff --git a/querydsl-jdo/README.md b/querydsl-jdo/README.md index a79dbd2436..3fb53b5104 100644 --- a/querydsl-jdo/README.md +++ b/querydsl-jdo/README.md @@ -6,43 +6,49 @@ The JDO module provides integration with the JDO API. Add the following dependencies to your Maven project : - <dependency> - <groupId>com.mysema.querydsl</groupId> - <artifactId>querydsl-apt</artifactId> - <version>${querydsl.version}</version> - <scope>provided</scope> - </dependency> - - <dependency> - <groupId>com.mysema.querydsl</groupId> - <artifactId>querydsl-jdo</artifactId> - <version>${querydsl.version}</version> - </dependency> +```XML +<dependency> + <groupId>com.querydsl</groupId> + <artifactId>querydsl-apt</artifactId> + <version>${querydsl.version}</version> + <scope>provided</scope> +</dependency> - <dependency> - <groupId>org.slf4j</groupId> - <artifactId>slf4j-log4j12</artifactId> - <version>1.6.1</version> - </dependency> +<dependency> + <groupId>com.querydsl</groupId> + <artifactId>querydsl-jdo</artifactId> + <version>${querydsl.version}</version> +</dependency> +``` And now, configure the Maven APT plugin which generates the query types used by Querydsl : - <plugin> - <groupId>com.mysema.maven</groupId> - <artifactId>apt-maven-plugin</artifactId> - <version>1.0.6</version> - <executions> - <execution> - <goals> - <goal>process</goal> - </goals> - <configuration> - <outputDirectory>target/generated-sources/java</outputDirectory> - <processor>com.mysema.query.apt.jdo.JDOAnnotationProcessor</processor> - </configuration> - </execution> - </executions> - </plugin> +```XML +<project> + <build> + <plugins> + ... + <plugin> + <groupId>com.mysema.maven</groupId> + <artifactId>apt-maven-plugin</artifactId> + <version>1.1.3</version> + <executions> + <execution> + <goals> + <goal>process</goal> + </goals> + <configuration> + <outputDirectory>target/generated-sources/java</outputDirectory> + <processor>com.querydsl.apt.jdo.JDOAnnotationProcessor</processor> + </configuration> + </execution> + </executions> + </plugin> + ... + </plugins> + </build> +</project> +``` The JDOAnnotationProcessor finds domain types annotated with the javax.jdo.annotations.PersistenceCapable annotation and generates Querydsl query types for them. @@ -56,11 +62,14 @@ Now you are able to construct JDOQL query instances and instances of the query d Querying with Querydsl JDO is as simple as this : - QCustomer customer = QCustomer.customer; - JDOQuery query = new JDOQuery(pm); - Customer bob = query.from(customer) - .where(customer.firstName.eq("Bob")) - .uniqueResult(customer); - query.close(); +```JAVA +QCustomer customer = QCustomer.customer; +JDOQuery<?> query = new JDOQuery<Void>(pm); +Customer bob = query.select(customer) + .from(customer) + .where(customer.firstName.eq("Bob")) + .fetchOne(); +query.close(); +``` -For more information on the Querydsl JDO module visit the reference documentation http://www.querydsl.com/static/querydsl/latest/reference/html/ch02s02.html \ No newline at end of file +For more information on the Querydsl JDO module visit the reference documentation http://www.querydsl.com/static/querydsl/latest/reference/html/ch02s02.html diff --git a/querydsl-jdo/pom.xml b/querydsl-jdo/pom.xml index 4bf79f0d78..f16e30deee 100644 --- a/querydsl-jdo/pom.xml +++ b/querydsl-jdo/pom.xml @@ -1,15 +1,15 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0" encoding="UTF-8"?> <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <modelVersion>4.0.0</modelVersion> <parent> - <groupId>com.mysema.querydsl</groupId> + <groupId>com.querydsl</groupId> <artifactId>querydsl-root</artifactId> - <version>3.4.1.BUILD-SNAPSHOT</version> - <relativePath>../querydsl-root/pom.xml</relativePath> + <version>5.1.0</version> + <relativePath>../pom.xml</relativePath> </parent> - <groupId>com.mysema.querydsl</groupId> + <groupId>com.querydsl</groupId> <artifactId>querydsl-jdo</artifactId> <name>Querydsl - JDO support</name> <description>JDO support for Querydsl</description> @@ -23,58 +23,48 @@ </scm> <properties> - <dn.version>3.2.0-release</dn.version> - <dn.plugin.version>3.2.0-release</dn.plugin.version> + <dn.version>5.2.8</dn.version> + <dn.plugin.version>5.2.1</dn.plugin.version> </properties> <dependencies> - + + <dependency> - <groupId>javax.jdo</groupId> - <artifactId>jdo-api</artifactId> - <version>3.0.1</version> + <groupId>org.datanucleus</groupId> + <artifactId>javax.jdo</artifactId> + <scope>provided</scope> </dependency> - <!-- <dependency> - <groupId>javax.jdo</groupId> - <artifactId>jdo2-api</artifactId> - <version>2.3-eb</version> - </dependency> - --> - <dependency> - <groupId>com.mysema.querydsl</groupId> + <groupId>com.querydsl</groupId> <artifactId>querydsl-core</artifactId> <version>${project.version}</version> </dependency> <dependency> - <groupId>com.mysema.querydsl</groupId> + <groupId>org.jetbrains</groupId> + <artifactId>annotations</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>com.querydsl</groupId> <artifactId>querydsl-codegen</artifactId> <version>${project.version}</version> <scope>provided</scope> </dependency> <dependency> - <groupId>com.mysema.querydsl</groupId> + <groupId>com.querydsl</groupId> <artifactId>querydsl-apt</artifactId> <version>${project.version}</version> <scope>provided</scope> </dependency> <dependency> - <groupId>com.mysema.querydsl</groupId> + <groupId>com.querydsl</groupId> <artifactId>querydsl-sql</artifactId> <version>${project.version}</version> <scope>compile</scope> <optional>true</optional> - </dependency> - - <dependency> - <groupId>org.slf4j</groupId> - <artifactId>slf4j-api</artifactId> </dependency> - <dependency> - <groupId>org.slf4j</groupId> - <artifactId>slf4j-log4j12</artifactId> - </dependency> <!-- test --> @@ -106,18 +96,23 @@ <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> - <version>${h2.version}</version> <scope>test</scope> </dependency> <dependency> - <groupId>com.mysema.querydsl</groupId> + <groupId>com.querydsl</groupId> <artifactId>querydsl-core</artifactId> <version>${project.version}</version> <scope>test</scope> <type>test-jar</type> </dependency> + <dependency> + <groupId>io.github.classgraph</groupId> + <artifactId>classgraph</artifactId> + <scope>test</scope> + </dependency> + <dependency> <groupId>jdepend</groupId> <artifactId>jdepend</artifactId> @@ -130,8 +125,8 @@ <build> <plugins> <plugin> - <groupId>com.springsource.bundlor</groupId> - <artifactId>com.springsource.bundlor.maven</artifactId> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> </plugin> <plugin> @@ -149,6 +144,13 @@ </configuration> </execution> </executions> + <configuration> + <archive> + <manifestEntries> + <Automatic-Module-Name>com.querydsl.jdo</Automatic-Module-Name> + </manifestEntries> + </archive> + </configuration> </plugin> <!-- this plugin does the JDO class enhancement --> @@ -158,7 +160,7 @@ <version>${dn.plugin.version}</version> <configuration> <metadataDirectory>target/test-classes</metadataDirectory> - <metadataIncludes>com/mysema/query/jdo/test/domain/*.class</metadataIncludes> + <metadataIncludes>com/querydsl/jdo/test/domain/*.class</metadataIncludes> <log4jConfiguration>src/test/resources/log4j.properties</log4jConfiguration> <verbose>true</verbose> <props>src/test/resources/datanucleus.properties</props> @@ -226,7 +228,7 @@ </property> </systemProperties> <includes> - <include>com/mysema/query/PackageVerification.java</include> + <include>com/querydsl/jdo/PackageVerification.java</include> </includes> </configuration> </execution> @@ -244,7 +246,7 @@ </goals> <configuration> <outputDirectory>target/generated-test-sources/java</outputDirectory> - <processor>com.mysema.query.apt.QuerydslAnnotationProcessor</processor> + <processor>com.querydsl.apt.QuerydslAnnotationProcessor</processor> <logOnlyOnError>true</logOnlyOnError> </configuration> </execution> @@ -252,13 +254,13 @@ </plugin> <plugin> - <groupId>com.mysema.querydsl</groupId> + <groupId>com.querydsl</groupId> <artifactId>querydsl-maven-plugin</artifactId> <version>${project.version}</version> <configuration> <jdbcDriver>org.hsqldb.jdbcDriver</jdbcDriver> <jdbcUrl>jdbc:hsqldb:target/jdo</jdbcUrl> - <packageName>com.mysema.query.jdo.test.domain.sql</packageName> + <packageName>com.querydsl.jdo.test.domain.sql</packageName> <userName>sa</userName> <targetFolder>src/test/java</targetFolder> <namePrefix>S</namePrefix> @@ -267,7 +269,7 @@ <dependency> <groupId>hsqldb</groupId> <artifactId>hsqldb</artifactId> - <version>1.8.0.7</version> + <version>1.8.0.10</version> </dependency> </dependencies> </plugin> @@ -278,15 +280,15 @@ <repositories> <repository> <id>datanucleus</id> - <url>http://www.datanucleus.org/downloads/maven2</url> + <url>https://www.datanucleus.org/downloads/maven2</url> </repository> </repositories> <pluginRepositories> <pluginRepository> <id>datanucleus</id> - <url>http://www.datanucleus.org/downloads/maven2</url> + <url>https://www.datanucleus.org/downloads/maven2</url> </pluginRepository> </pluginRepositories> -</project> +</project> diff --git a/querydsl-jdo/src/apt/META-INF/services/javax.annotation.processing.Processor b/querydsl-jdo/src/apt/META-INF/services/javax.annotation.processing.Processor index 390c5f8f7f..ff511957d0 100644 --- a/querydsl-jdo/src/apt/META-INF/services/javax.annotation.processing.Processor +++ b/querydsl-jdo/src/apt/META-INF/services/javax.annotation.processing.Processor @@ -1 +1 @@ -com.mysema.query.apt.jdo.JDOAnnotationProcessor \ No newline at end of file +com.querydsl.apt.jdo.JDOAnnotationProcessor \ No newline at end of file diff --git a/querydsl-jdo/src/main/assembly.xml b/querydsl-jdo/src/main/assembly.xml index 8f6d041068..aebd32e50a 100644 --- a/querydsl-jdo/src/main/assembly.xml +++ b/querydsl-jdo/src/main/assembly.xml @@ -8,30 +8,28 @@ <includeBaseDirectory>false</includeBaseDirectory> <fileSets> <fileSet> - <directory>src/apt</directory> - <outputDirectory>/</outputDirectory> - </fileSet> - </fileSets> + <directory>src/apt</directory> + <outputDirectory>/</outputDirectory> + </fileSet> + </fileSets> <dependencySets> <dependencySet> <unpack>true</unpack> <scope>compile</scope> - <excludes> - <exclude>cglib:cglib</exclude> - <exclude>com.mysema.querydsl:querydsl-sql</exclude> - <exclude>com.mysema.querydsl:querydsl-jdo</exclude> - <exclude>org.slf4j:slf4j-api</exclude> - <exclude>org.slf4j:slf4j-log4j12</exclude> - </excludes> + <excludes> + <exclude>cglib:cglib</exclude> + <exclude>com.querydsl:querydsl-sql</exclude> + <exclude>com.querydsl:querydsl-jdo</exclude> + </excludes> </dependencySet> <dependencySet> <unpack>true</unpack> - <scope>provided</scope> - <includes> - <include>com.mysema.querydsl:*</include> - <include>com.mysema.codegen:*</include> - </includes> - </dependencySet> + <scope>provided</scope> + <includes> + <include>com.querydsl:*</include> + <include>com.querydsl.codegen.utils:*</include> + </includes> + </dependencySet> </dependencySets> </assembly> diff --git a/querydsl-jdo/src/main/java/com/mysema/query/jdo/AbstractJDOQuery.java b/querydsl-jdo/src/main/java/com/mysema/query/jdo/AbstractJDOQuery.java deleted file mode 100644 index 9c3165210c..0000000000 --- a/querydsl-jdo/src/main/java/com/mysema/query/jdo/AbstractJDOQuery.java +++ /dev/null @@ -1,361 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jdo; - -import java.io.Closeable; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import javax.annotation.Nullable; -import javax.jdo.PersistenceManager; -import javax.jdo.Query; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.common.collect.Lists; -import com.mysema.commons.lang.CloseableIterator; -import com.mysema.commons.lang.IteratorAdapter; -import com.mysema.query.DefaultQueryMetadata; -import com.mysema.query.NonUniqueResultException; -import com.mysema.query.QueryException; -import com.mysema.query.QueryMetadata; -import com.mysema.query.QueryModifiers; -import com.mysema.query.SearchResults; -import com.mysema.query.Tuple; -import com.mysema.query.support.ProjectableQuery; -import com.mysema.query.types.EntityPath; -import com.mysema.query.types.Expression; -import com.mysema.query.types.FactoryExpression; - -/** - * Abstract base class for custom implementations of the JDOCommonQuery interface. - * - * @author tiwe - * - * @param <Q> - */ -public abstract class AbstractJDOQuery<Q extends AbstractJDOQuery<Q>> extends ProjectableQuery<Q> implements JDOQLQuery{ - - private static final Logger logger = LoggerFactory.getLogger(JDOQuery.class); - - private final Closeable closeable = new Closeable() { - @Override - public void close() throws IOException { - AbstractJDOQuery.this.close(); - } - }; - - private final boolean detach; - - private List<Object> orderedConstants = new ArrayList<Object>(); - - @Nullable - private final PersistenceManager persistenceManager; - - private final List<Query> queries = new ArrayList<Query>(2); - - private final JDOQLTemplates templates; - - protected final Set<String> fetchGroups = new HashSet<String>(); - - @Nullable - protected Integer maxFetchDepth; - - @Nullable - private FactoryExpression<?> projection; - - public AbstractJDOQuery(@Nullable PersistenceManager persistenceManager) { - this(persistenceManager, JDOQLTemplates.DEFAULT, new DefaultQueryMetadata(), false); - } - - @SuppressWarnings("unchecked") - public AbstractJDOQuery( - @Nullable PersistenceManager persistenceManager, - JDOQLTemplates templates, - QueryMetadata metadata, boolean detach) { - super(new JDOQueryMixin<Q>(metadata)); - this.queryMixin.setSelf((Q) this); - this.templates = templates; - this.persistenceManager = persistenceManager; - this.detach = detach; - } - - /** - * Add the fetch group to the set of active fetch groups. - * - * @param string - * @return - */ - @Override - public Q addFetchGroup(String fetchGroupName) { - fetchGroups.add(fetchGroupName); - return (Q)this; - } - - /** - * Close the query and related resources - */ - @Override - public void close() { - for (Query query : queries) { - query.closeAll(); - } - } - - @Override - public long count() { - Query query = createQuery(true); - query.setUnique(true); - reset(); - Long rv = (Long) execute(query, true); - if (rv != null) { - return rv.longValue(); - } else { - throw new QueryException("Query returned null"); - } - } - - @Override - public boolean exists() { - boolean rv = limit(1).uniqueResult(getSource()) != null; - close(); - return rv; - } - - private Expression<?> getSource() { - return queryMixin.getMetadata().getJoins().get(0).getTarget(); - } - - private Query createQuery(boolean forCount) { - Expression<?> source = getSource(); - - // serialize - JDOQLSerializer serializer = new JDOQLSerializer(getTemplates(), source); - serializer.serialize(queryMixin.getMetadata(), forCount, false); - - logQuery(serializer.toString()); - - // create Query - Query query = persistenceManager.newQuery(serializer.toString()); - orderedConstants = serializer.getConstants(); - queries.add(query); - - if (!forCount) { - List<? extends Expression<?>> projection = queryMixin.getMetadata().getProjection(); - if (projection.get(0) instanceof FactoryExpression) { - this.projection = (FactoryExpression<?>)projection.get(0); - } - if (!fetchGroups.isEmpty()) { - query.getFetchPlan().setGroups(fetchGroups); - } - if (maxFetchDepth != null) { - query.getFetchPlan().setMaxFetchDepth(maxFetchDepth); - } - } - - return query; - } - - protected void logQuery(String queryString) { - if (logger.isDebugEnabled()) { - logger.debug(queryString.replace('\n', ' ')); - } - } - - @SuppressWarnings("unchecked") - private <T> T detach(T results) { - if (results instanceof Collection) { - return (T) persistenceManager.detachCopyAll(results); - } else { - return persistenceManager.detachCopy(results); - } - } - - private Object project(FactoryExpression<?> expr, Object row) { - if (row == null) { - return null; - } else if (row.getClass().isArray()) { - return expr.newInstance((Object[])row); - } else { - return expr.newInstance(new Object[]{row}); - } - } - - @Nullable - private Object execute(Query query, boolean forCount) { - Object rv; - if (!orderedConstants.isEmpty()) { - rv = query.executeWithArray(orderedConstants.toArray()); - } else { - rv = query.execute(); - } - if (isDetach()) { - rv = detach(rv); - } - if (projection != null && !forCount) { - if (rv instanceof List) { - List<?> original = (List<?>)rv; - rv = Lists.newArrayList(); - for (Object o : original) { - ((List)rv).add(project(projection, o)); - } - } else { - rv = project(projection, rv); - } - } - - return rv; - } - - @Override - public Q from(EntityPath<?>... args) { - return queryMixin.from(args); - } - - public QueryMetadata getMetadata() { - return queryMixin.getMetadata(); - } - - public JDOQLTemplates getTemplates() { - return templates; - } - - public boolean isDetach() { - return detach; - } - - @Override - public CloseableIterator<Tuple> iterate(Expression<?>... args) { - return new IteratorAdapter<Tuple>(list(args).iterator(), closeable); - } - - @Override - public <RT> CloseableIterator<RT> iterate(Expression<RT> projection) { - return new IteratorAdapter<RT>(list(projection).iterator(), closeable); - } - - @Override - public List<Tuple> list(Expression<?>... args) { - return list(queryMixin.createProjection(args)); - } - - @Override - @SuppressWarnings("unchecked") - public <RT> List<RT> list(Expression<RT> expr) { - queryMixin.addProjection(expr); - Object rv = execute(createQuery(false), false); - reset(); - return rv instanceof List ? (List<RT>)rv : Collections.singletonList((RT)rv); - } - - @Override - public SearchResults<Tuple> listResults(Expression<?>... args) { - return listResults(queryMixin.createProjection(args)); - } - - @Override - @SuppressWarnings("unchecked") - public <RT> SearchResults<RT> listResults(Expression<RT> expr) { - queryMixin.addProjection(expr); - Query countQuery = createQuery(true); - countQuery.setUnique(true); - countQuery.setResult("count(this)"); - long total = (Long) execute(countQuery, true); - if (total > 0) { - QueryModifiers modifiers = queryMixin.getMetadata().getModifiers(); - Query query = createQuery(false); - reset(); - return new SearchResults<RT>((List<RT>) execute(query, false), modifiers, total); - } else { - reset(); - return SearchResults.emptyResults(); - } - } - - private void reset() { - queryMixin.getMetadata().reset(); - } - - /** - * Set the maximum fetch depth when fetching. - * A value of 0 has no meaning and will throw a JDOUserException. - * A value of -1 means that no limit is placed on fetching. - * A positive integer will result in that number of references from the - * initial object to be fetched. - * - * @param maxFetchDepth - * @return - */ - @Override - public Q setMaxFetchDepth(int depth) { - maxFetchDepth = depth; - return (Q)this; - } - - @Override - public String toString() { - if (!queryMixin.getMetadata().getJoins().isEmpty()) { - Expression<?> source = getSource(); - JDOQLSerializer serializer = new JDOQLSerializer(getTemplates(), source); - serializer.serialize(queryMixin.getMetadata(), false, false); - return serializer.toString().trim(); - } else { - return super.toString(); - } - } - - @Override - @Nullable - public Tuple uniqueResult(Expression<?>... args) { - return uniqueResult(queryMixin.createProjection(args)); - } - - @Override - @SuppressWarnings("unchecked") - @Nullable - public <RT> RT uniqueResult(Expression<RT> expr) { - queryMixin.addProjection(expr); - return (RT)uniqueResult(); - } - - @Nullable - private Object uniqueResult() { - if (getMetadata().getModifiers().getLimit() == null) { - limit(2); - } - Query query = createQuery(false); - reset(); - Object rv = execute(query, false); - if (rv instanceof List) { - List<?> list = (List)rv; - if (!list.isEmpty()) { - if (list.size() > 1) { - throw new NonUniqueResultException(); - } - return list.get(0); - } else { - return null; - } - } else { - return rv; - } - } - -} diff --git a/querydsl-jdo/src/main/java/com/mysema/query/jdo/AbstractJDOSubQuery.java b/querydsl-jdo/src/main/java/com/mysema/query/jdo/AbstractJDOSubQuery.java deleted file mode 100644 index 5c07f535ec..0000000000 --- a/querydsl-jdo/src/main/java/com/mysema/query/jdo/AbstractJDOSubQuery.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jdo; - -import com.mysema.query.DefaultQueryMetadata; -import com.mysema.query.QueryMetadata; -import com.mysema.query.support.DetachableQuery; -import com.mysema.query.types.CollectionExpression; -import com.mysema.query.types.EntityPath; -import com.mysema.query.types.Expression; - -/** - * Abstract superclass for SubQuery implementations - * - * @author tiwe - * - * @param <Q> - */ -public class AbstractJDOSubQuery<Q extends AbstractJDOSubQuery<Q>> extends DetachableQuery<Q> implements JDOCommonQuery<Q> { - - public AbstractJDOSubQuery() { - this(new DefaultQueryMetadata().noValidate()); - } - - @SuppressWarnings("unchecked") - public AbstractJDOSubQuery(QueryMetadata metadata) { - super(new JDOQueryMixin<Q>(metadata)); - this.queryMixin.setSelf((Q)this); - } - - public Q from(EntityPath<?> arg) { - return queryMixin.from(arg); - } - - public Q from(EntityPath<?>... args) { - return queryMixin.from(args); - } - - public <P> Q from(CollectionExpression<?,P> target, EntityPath<P> alias) { - return queryMixin.join(target, alias); - } - - @Override - public String toString() { - if (!queryMixin.getMetadata().getJoins().isEmpty()) { - Expression<?> source = queryMixin.getMetadata().getJoins().get(0).getTarget(); - JDOQLSerializer serializer = new JDOQLSerializer(JDOQLTemplates.DEFAULT, source); - serializer.setStrict(false); - serializer.serialize(queryMixin.getMetadata(), false, false); - return serializer.toString().trim(); - } else { - return super.toString(); - } - } - -} diff --git a/querydsl-jdo/src/main/java/com/mysema/query/jdo/JDOCommonQuery.java b/querydsl-jdo/src/main/java/com/mysema/query/jdo/JDOCommonQuery.java deleted file mode 100644 index 4ca54bcf49..0000000000 --- a/querydsl-jdo/src/main/java/com/mysema/query/jdo/JDOCommonQuery.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jdo; - -import com.mysema.query.Query; -import com.mysema.query.types.EntityPath; - -/** - * JDOCommonQuery is a parent interface for JDOQLQuery and JDOSubQuery - * - * @author tiwe - * - * @param <Q> - */ -public interface JDOCommonQuery<Q extends JDOCommonQuery<Q>> extends Query<Q> { - - /** - * Add query sources - * - * @param sources - * @return - */ - Q from(EntityPath<?>... sources); - -} diff --git a/querydsl-jdo/src/main/java/com/mysema/query/jdo/JDOQLQuery.java b/querydsl-jdo/src/main/java/com/mysema/query/jdo/JDOQLQuery.java deleted file mode 100644 index 09e4bda98a..0000000000 --- a/querydsl-jdo/src/main/java/com/mysema/query/jdo/JDOQLQuery.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jdo; - -import java.io.Closeable; - -import javax.jdo.PersistenceManager; - -import com.mysema.query.Projectable; - -/** - * Query interface for JDOQL queries - * - * @author tiwe - * - */ -public interface JDOQLQuery extends JDOCommonQuery<JDOQLQuery>, Projectable, Closeable { - - /** - * Clone the state of the query for the given PersistenceManager - * - * @param persistenceManager - * @return - */ - JDOQLQuery clone(PersistenceManager persistenceManager); - - /** - * Add the fetch group to the set of active fetch groups. - * - * @param string - * @return - */ - JDOQLQuery addFetchGroup(String fetchGroupName); - - /** - * Set the maximum fetch depth when fetching. - * A value of 0 has no meaning and will throw a JDOUserException. - * A value of -1 means that no limit is placed on fetching. - * A positive integer will result in that number of references from the - * initial object to be fetched. - * - * @param maxFetchDepth - * @return - */ - JDOQLQuery setMaxFetchDepth(int maxFetchDepth); - - /** - * Close the query and related resources - */ - @Override - void close(); - -} diff --git a/querydsl-jdo/src/main/java/com/mysema/query/jdo/JDOQLSerializer.java b/querydsl-jdo/src/main/java/com/mysema/query/jdo/JDOQLSerializer.java deleted file mode 100644 index a110011502..0000000000 --- a/querydsl-jdo/src/main/java/com/mysema/query/jdo/JDOQLSerializer.java +++ /dev/null @@ -1,340 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jdo; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Stack; - -import javax.annotation.Nullable; - -import com.google.common.collect.ImmutableList; -import com.google.common.primitives.Primitives; -import com.mysema.query.JoinExpression; -import com.mysema.query.QueryMetadata; -import com.mysema.query.support.SerializerBase; -import com.mysema.query.types.Constant; -import com.mysema.query.types.EntityPath; -import com.mysema.query.types.Expression; -import com.mysema.query.types.ExpressionUtils; -import com.mysema.query.types.Operation; -import com.mysema.query.types.Operator; -import com.mysema.query.types.Ops; -import com.mysema.query.types.OrderSpecifier; -import com.mysema.query.types.ParamExpression; -import com.mysema.query.types.ParamNotSetException; -import com.mysema.query.types.Path; -import com.mysema.query.types.Predicate; -import com.mysema.query.types.SubQueryExpression; -import com.mysema.query.types.expr.Param; - -/** - * JDOQLSerializer serializes Querydsl queries and expressions into JDOQL strings - * - * @author tiwe - * - */ -public final class JDOQLSerializer extends SerializerBase<JDOQLSerializer> { - - private static final String COMMA = ", "; - - private static final String FROM = "\nFROM "; - - private static final String GROUP_BY = "\nGROUP BY "; - - private static final String HAVING = "\nHAVING "; - - private static final String ORDER_BY = "\nORDER BY "; - - private static final String PARAMETERS = "\nPARAMETERS "; - - private static final String RANGE = "\nRANGE "; - - private static final String SELECT = "SELECT "; - - private static final String SELECT_COUNT = "SELECT count("; - - private static final String SELECT_COUNT_THIS = "SELECT count(this)\n"; - - private static final String SELECT_DISTINCT = "SELECT DISTINCT "; - - private static final String SELECT_UNIQUE = "SELECT UNIQUE "; - - private static final String THIS = "this"; - - private static final String VARIABLES = "\nVARIABLES "; - - private static final String WHERE = "\nWHERE "; - - private static Comparator<Map.Entry<Object,String>> comparator = new Comparator<Map.Entry<Object,String>>() { - @Override - public int compare(Entry<Object, String> o1, Entry<Object, String> o2) { - return o1.getValue().compareTo(o2.getValue()); - } - }; - - private final Expression<?> candidatePath; - - private final List<Object> constants = new ArrayList<Object>(); - - private final Stack<Map<Object,String>> constantToLabel = new Stack<Map<Object,String>>(); - - public JDOQLSerializer(JDOQLTemplates templates, Expression<?> candidate) { - super(templates); - this.candidatePath = candidate; - this.constantToLabel.push(new HashMap<Object,String>()); - } - - public Expression<?> getCandidatePath() { - return candidatePath; - } - - public List<Object> getConstants() { - return constants; - } - - @Override - public Map<Object,String> getConstantToLabel() { - return constantToLabel.peek(); - } - - public void serialize(QueryMetadata metadata, boolean forCountRow, boolean subQuery) { - final List<? extends Expression<?>> select = metadata.getProjection(); - final List<JoinExpression> joins = metadata.getJoins(); - final Expression<?> source = joins.get(0).getTarget(); - final Predicate where = metadata.getWhere(); - final List<? extends Expression<?>> groupBy = metadata.getGroupBy(); - final Predicate having = metadata.getHaving(); - final List<OrderSpecifier<?>> orderBy = metadata.getOrderBy(); - - constantToLabel.push(new HashMap<Object,String>()); - - // select - boolean skippedSelect = false; - if (forCountRow) { - if (joins.size() == 1 && !subQuery) { - append(SELECT_COUNT_THIS); - } else { - append(SELECT_COUNT); - boolean first = true; - for (JoinExpression je : joins) { - if (!first) { - append(COMMA); - } - handle(je.getTarget()); - first = false; - } - append(")"); - } - - } else if (!select.isEmpty()) { - if (metadata.isDistinct()) { - append(SELECT_DISTINCT); - } else if (metadata.isUnique() && !subQuery) { - append(SELECT_UNIQUE); - } else { - append(SELECT); - } - if (select.size() >1 || !select.get(0).equals(source) || metadata.isDistinct()) { - handle(COMMA, select); - } else { - skippedSelect = true; - } - } - - // from - append(skippedSelect ? FROM.substring(1) : FROM); - if (source instanceof Operation && subQuery) { - handle(source); - } else { - append(source.getType().getName()); - if (!source.equals(candidatePath)) { - append(" ").handle(source); - } - } - - // where - if (where != null) { - append(WHERE).handle(where); - } - - // variables - if (joins.size() > 1) { - serializeVariables(joins); - } - - int position = getLength(); - - // group by - if (!groupBy.isEmpty()) { - append(GROUP_BY).handle(COMMA, groupBy); - } - - // having - if (having != null) { - append(HAVING).handle(having); - } - - // order by - if (!orderBy.isEmpty() && !forCountRow) { - append(ORDER_BY); - boolean first = true; - for (final OrderSpecifier<?> os : orderBy) { - if (!first) { - append(COMMA); - } - handle(os.getTarget()); - append(" " + os.getOrder()); - first = false; - } - } - - // range - if (!forCountRow && metadata.getModifiers().isRestricting()) { - Long limit = metadata.getModifiers().getLimit(); - Long offset = metadata.getModifiers().getOffset(); - serializeModifiers(limit, offset); - } - - // parameters - if (!getConstantToLabel().isEmpty()) { - insert(position, serializeParameters(metadata.getParams())); - } - - constantToLabel.pop(); - - } - - private void serializeModifiers(@Nullable Long limit, @Nullable Long offset) { - append(RANGE); - if (offset != null) { - append(String.valueOf(offset)); - if (limit != null) { - append(COMMA); - append(String.valueOf(offset + limit)); - } - } else { - append("0, ").append(String.valueOf(limit)); - } - } - - private String serializeParameters(Map<ParamExpression<?>, Object> params) { - final StringBuilder b = new StringBuilder(); - b.append(PARAMETERS); - boolean first = true; - final List<Map.Entry<Object, String>> entries = new ArrayList<Map.Entry<Object, String>>(getConstantToLabel().entrySet()); - Collections.sort(entries, comparator); - for (Map.Entry<Object, String> entry : entries) { - if (!first) { - b.append(COMMA); - } - if (Param.class.isInstance(entry.getKey())) { - Object constant = params.get(entry.getKey()); - if (constant == null) { - throw new ParamNotSetException((Param<?>) entry.getKey()); - } - constants.add(constant); - b.append(((Param<?>)entry.getKey()).getType().getName()); - } else { - constants.add(entry.getKey()); - b.append(entry.getKey().getClass().getName()); - } - b.append(" ").append(entry.getValue()); - first = false; - } - return b.toString(); - } - - private void serializeVariables(List<JoinExpression> joins) { - append(VARIABLES); - for (int i = 1; i < joins.size(); i++) { - final JoinExpression je = joins.get(i); - if (i > 1) { - append("; "); - } - - // type specifier - if (je.getTarget() instanceof EntityPath) { - final EntityPath<?> pe = (EntityPath<?>) je.getTarget(); - if (pe.getMetadata().getParent() == null) { - append(pe.getType().getName()).append(" "); - } - } - handle(je.getTarget()); - } - } - - @Override - public Void visit(Path<?> path, Void context) { - if (path.equals(candidatePath)) { - append(THIS); - } else { - super.visit(path, context); - } - return null; - } - - @Override - public Void visit(SubQueryExpression<?> query, Void context) { - append("("); - serialize(query.getMetadata(), false, true); - append(")"); - return null; - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - @Override - protected void visitOperation(Class<?> type, Operator<?> operator, List<? extends Expression<?>> args) { - if (operator == Ops.INSTANCE_OF) { - handle(args.get(0)).append(" instanceof "); - append(((Constant<Class<?>>) args.get(1)).getConstant().getName()); - - } else if (operator == Ops.LIKE || operator == Ops.LIKE_ESCAPE) { - super.visitOperation(type, Ops.MATCHES, - ImmutableList.of(args.get(0), ExpressionUtils.likeToRegex((Expression<String>) args.get(1), false))); - - // exists - } else if (operator == Ops.EXISTS && args.get(0) instanceof SubQueryExpression) { - final SubQueryExpression subQuery = (SubQueryExpression) args.get(0); - append("("); - serialize(subQuery.getMetadata(), true, true); - append(") > 0"); - - // not exists - } else if (operator == Ops.NOT && args.get(0) instanceof Operation - && ((Operation)args.get(0)).getOperator().equals(Ops.EXISTS)) { - final SubQueryExpression subQuery = (SubQueryExpression) ((Operation)args.get(0)).getArg(0); - append("("); - serialize(subQuery.getMetadata(), true, true); - append(") == 0"); - - } else if (operator == Ops.NUMCAST) { - Class<?> clazz = ((Constant<Class<?>>)args.get(1)).getConstant(); - if (Number.class.isAssignableFrom(clazz) && Primitives.isWrapperType(clazz)) { - clazz = Primitives.unwrap(clazz); - } - append("("+clazz.getSimpleName()+")").handle(args.get(0)); - - } else { - super.visitOperation(type, operator, args); - } - } - - -} diff --git a/querydsl-jdo/src/main/java/com/mysema/query/jdo/JDOQLTemplates.java b/querydsl-jdo/src/main/java/com/mysema/query/jdo/JDOQLTemplates.java deleted file mode 100644 index 0844765f1f..0000000000 --- a/querydsl-jdo/src/main/java/com/mysema/query/jdo/JDOQLTemplates.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jdo; - -import com.mysema.query.types.JavaTemplates; -import com.mysema.query.types.Ops; - -/** - * JDOQLTemplates provides patterns for JDOQL serialization - * - * @author tiwe - * - */ -public final class JDOQLTemplates extends JavaTemplates { - - public static final JDOQLTemplates DEFAULT = new JDOQLTemplates(); - - protected JDOQLTemplates() { - // String - add(Ops.STRING_CONTAINS, "{0}.indexOf({1}) > -1", 25); - add(Ops.STRING_CONTAINS_IC, "{0l}.indexOf({1l}) > -1", 25); - add(Ops.EQ_IGNORE_CASE, "{0l}.equals({1l})"); - add(Ops.STRING_IS_EMPTY, "{0} == \"\"", 25); - add(Ops.LIKE, "{0}.like({1})"); - add(Ops.LIKE_ESCAPE, "{0}.like({1})"); - - add(Ops.STRING_CAST, "(String){0}"); - - // Date - add(Ops.DateTimeOps.MONTH, "({0}.getMonth() + 1)"); // getMonth() in JDO returns a range from 0-11 - add(Ops.DateTimeOps.DAY_OF_MONTH, "{0}.getDay()"); - add(Ops.DateTimeOps.MILLISECOND, "0"); // NOT supported in JDOQL - - add(Ops.DateTimeOps.YEAR_MONTH, "({0}.getYear() * 100 + {0}.getMonth() + 1)"); - - // other - add(Ops.ALIAS, "{0} {1}"); - } - -} diff --git a/querydsl-jdo/src/main/java/com/mysema/query/jdo/JDOQuery.java b/querydsl-jdo/src/main/java/com/mysema/query/jdo/JDOQuery.java deleted file mode 100644 index b21187c4aa..0000000000 --- a/querydsl-jdo/src/main/java/com/mysema/query/jdo/JDOQuery.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jdo; - -import javax.jdo.PersistenceManager; - -import com.mysema.query.DefaultQueryMetadata; -import com.mysema.query.QueryMetadata; - -/** - * JDOQuery is the default implementation of the JDOQLQuery interface - * - * @author tiwe - * - * @param <A> - */ -public final class JDOQuery extends AbstractJDOQuery<JDOQuery> { - - /** - * Create a detached JDOQuery instance - * The query can be attached via the clone method - * - * @param persistenceManager - */ - public JDOQuery() { - super(null, JDOQLTemplates.DEFAULT, new DefaultQueryMetadata(), false); - } - - /** - * Create a new JDOQuery instance - * - * @param persistenceManager PersistenceManager instance to use - * @param templates JDOQLTemplates to use - * @param detach detached results or not - */ - public JDOQuery(PersistenceManager persistenceManager, JDOQLTemplates templates, boolean detach) { - super(persistenceManager, templates, new DefaultQueryMetadata(), detach); - } - - /** - * Create a new JDOQuery instance - * - * @param persistenceManager PersistenceManager instance to use - * @param detach detached results or not - */ - public JDOQuery(PersistenceManager persistenceManager, boolean detach) { - super(persistenceManager, JDOQLTemplates.DEFAULT, new DefaultQueryMetadata(), detach); - } - - /** - * Create a new JDOQuery instance - * - * @param persistenceManager PersistenceManager instance to use - */ - public JDOQuery(PersistenceManager persistenceManager) { - super(persistenceManager, JDOQLTemplates.DEFAULT, new DefaultQueryMetadata(), false); - } - - /** - * Create a new JDOQuery instance - * - * @param persistenceManager - * @param templates - * @param metadata - * @param detach - */ - protected JDOQuery(PersistenceManager persistenceManager, JDOQLTemplates templates, - QueryMetadata metadata, boolean detach) { - super(persistenceManager, templates, metadata, detach); - } - - /** - * Clone the state of this query to a new JDOQuery instance with the given PersistenceManager - * - * @param persistenceManager - * @return - */ - public JDOQuery clone(PersistenceManager persistenceManager) { - JDOQuery query = new JDOQuery(persistenceManager, getTemplates(), - getMetadata().clone(), isDetach()); - query.fetchGroups.addAll(fetchGroups); - query.maxFetchDepth = maxFetchDepth; - return query; - } - -} diff --git a/querydsl-jdo/src/main/java/com/mysema/query/jdo/JDOQueryFactory.java b/querydsl-jdo/src/main/java/com/mysema/query/jdo/JDOQueryFactory.java deleted file mode 100644 index 3406d049ad..0000000000 --- a/querydsl-jdo/src/main/java/com/mysema/query/jdo/JDOQueryFactory.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jdo; - -import javax.inject.Provider; -import javax.jdo.PersistenceManager; - -import com.mysema.query.QueryFactory; -import com.mysema.query.jdo.dml.JDODeleteClause; -import com.mysema.query.types.EntityPath; - -/** - * Factory class for query and DML clause creation - * - * @author tiwe - * - */ -public class JDOQueryFactory implements QueryFactory<JDOQuery, JDOSubQuery> { - - private final Provider<PersistenceManager> persistenceManager; - - public JDOQueryFactory(Provider<PersistenceManager> persistenceManager) { - this.persistenceManager = persistenceManager; - } - - public JDODeleteClause delete(EntityPath<?> path) { - return new JDODeleteClause(persistenceManager.get(), path); - } - - public JDOQuery from(EntityPath<?> from) { - return query().from(from); - } - - public JDOQuery query() { - return new JDOQuery(persistenceManager.get()); - } - - public JDOSubQuery subQuery() { - return new JDOSubQuery(); - } - -} \ No newline at end of file diff --git a/querydsl-jdo/src/main/java/com/mysema/query/jdo/JDOQueryMixin.java b/querydsl-jdo/src/main/java/com/mysema/query/jdo/JDOQueryMixin.java deleted file mode 100644 index 143080b0a2..0000000000 --- a/querydsl-jdo/src/main/java/com/mysema/query/jdo/JDOQueryMixin.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jdo; - -import com.mysema.query.QueryMetadata; -import com.mysema.query.support.CollectionAnyVisitor; -import com.mysema.query.support.Context; -import com.mysema.query.support.QueryMixin; -import com.mysema.query.types.EntityPath; -import com.mysema.query.types.ExpressionUtils; -import com.mysema.query.types.Ops; -import com.mysema.query.types.Path; -import com.mysema.query.types.Predicate; -import com.mysema.query.types.PredicateOperation; - -/** - * JDOQueryMixin extends {@link QueryMixin} to provide module specific extensions - * - * @author tiwe - * - * @param <T> - */ -public class JDOQueryMixin<T> extends QueryMixin<T> { - - public JDOQueryMixin() {} - - public JDOQueryMixin(QueryMetadata metadata) { - super(metadata); - } - - public JDOQueryMixin(T self, QueryMetadata metadata) { - super(self, metadata); - } - - @Override - protected Predicate normalize(Predicate predicate, boolean where) { - predicate = (Predicate)ExpressionUtils.extract(predicate); - if (predicate != null) { - Context context = new Context(); - Predicate transformed = (Predicate) predicate.accept(CollectionAnyVisitor.DEFAULT, context); - for (int i = 0; i < context.paths.size(); i++) { - Path<?> path = context.paths.get(i); - addCondition(context, i, path, where); - } - return transformed; - } else { - return null; - } - } - - @SuppressWarnings("unchecked") - private void addCondition(Context context, int i, Path<?> path, boolean where) { - EntityPath<?> alias = context.replacements.get(i); - from(alias); - Predicate condition = PredicateOperation.create(Ops.IN, alias, path.getMetadata().getParent()); - if (where) { - super.where(condition); - } else { - super.having(condition); - } - } - -} diff --git a/querydsl-jdo/src/main/java/com/mysema/query/jdo/JDOSubQuery.java b/querydsl-jdo/src/main/java/com/mysema/query/jdo/JDOSubQuery.java deleted file mode 100644 index 4285c47b26..0000000000 --- a/querydsl-jdo/src/main/java/com/mysema/query/jdo/JDOSubQuery.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jdo; - -import com.mysema.query.QueryMetadata; -import com.mysema.query.types.Expression; -import com.mysema.query.types.Operation; -import com.mysema.query.types.Ops; -import com.mysema.query.types.expr.BooleanExpression; -import com.mysema.query.types.expr.NumberOperation; -import com.mysema.query.types.query.NumberSubQuery; - -/** - * JDOSubQuery is subquery implementation for JDOQL - * - * @author tiwe - * - */ -public class JDOSubQuery extends AbstractJDOSubQuery<JDOSubQuery> { - - public JDOSubQuery() { - super(); - } - - public JDOSubQuery(QueryMetadata metadata) { - super(metadata); - } - - @Override - public BooleanExpression exists() { - return count().gt(0l); - } - - @Override - public BooleanExpression notExists() { - return count().eq(0l); - } - - @SuppressWarnings("unchecked") - @Override - public NumberSubQuery<Long> count() { - Expression<?> target = queryMixin.getMetadata().getJoins().get(0).getTarget(); - if (target instanceof Operation && ((Operation)target).getOperator() == Ops.ALIAS) { - target = ((Operation)target).getArg(1); - } - return unique(NumberOperation.create(Long.class, Ops.AggOps.COUNT_AGG, target)); - } - -} diff --git a/querydsl-jdo/src/main/java/com/mysema/query/jdo/dml/JDOUpdateClause.java b/querydsl-jdo/src/main/java/com/mysema/query/jdo/dml/JDOUpdateClause.java deleted file mode 100644 index 4fe34d853f..0000000000 --- a/querydsl-jdo/src/main/java/com/mysema/query/jdo/dml/JDOUpdateClause.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jdo.dml; - -import java.util.List; - -import com.mysema.query.DefaultQueryMetadata; -import com.mysema.query.QueryMetadata; -import com.mysema.query.dml.UpdateClause; -import com.mysema.query.types.Expression; -import com.mysema.query.types.ExpressionUtils; -import com.mysema.query.types.NullExpression; -import com.mysema.query.types.Path; -import com.mysema.query.types.Predicate; - -/** - * UpdateClause implementation for JDO - * - * @author tiwe - * - */ -public class JDOUpdateClause implements UpdateClause<JDOUpdateClause> { - - private final QueryMetadata metadata = new DefaultQueryMetadata(); - - @Override - public long execute() { - // TODO : implement - throw new UnsupportedOperationException("Not yet implemented"); - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - @Override - public JDOUpdateClause set(List<? extends Path<?>> paths, List<?> values) { - for (int i = 0; i < paths.size(); i++) { - if (values.get(i) != null) { - metadata.addProjection(ExpressionUtils.eqConst(((Expression)paths.get(i)), values.get(i))); - } else { - metadata.addProjection(ExpressionUtils.eq(((Expression)paths.get(i)), - new NullExpression(paths.get(i).getType()))); - } - } - return this; - } - - @Override - public <T> JDOUpdateClause set(Path<T> path, T value) { - if (value != null) { - metadata.addProjection(ExpressionUtils.eqConst(path, value)); - } else { - metadata.addProjection(ExpressionUtils.eq(path, new NullExpression<T>(path.getType()))); - } - return this; - } - - - @Override - public <T> JDOUpdateClause set(Path<T> path, Expression<? extends T> expression) { - metadata.addProjection(ExpressionUtils.eq(path, expression)); - return this; - } - - @Override - public <T> JDOUpdateClause setNull(Path<T> path) { - metadata.addProjection(ExpressionUtils.eq(path, new NullExpression<T>(path.getType()))); - return this; - } - - @Override - public JDOUpdateClause where(Predicate... o) { - for (Predicate p : o) { - metadata.addWhere(p); - } - return this; - } - - @Override - public boolean isEmpty() { - return metadata.getProjection().isEmpty(); - } - - -} diff --git a/querydsl-jdo/src/main/java/com/mysema/query/jdo/dml/package-info.java b/querydsl-jdo/src/main/java/com/mysema/query/jdo/dml/package-info.java deleted file mode 100644 index f2555d0450..0000000000 --- a/querydsl-jdo/src/main/java/com/mysema/query/jdo/dml/package-info.java +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ - -/** - * DML operations support for Querydsl JDOQL - */ -package com.mysema.query.jdo.dml; diff --git a/querydsl-jdo/src/main/java/com/mysema/query/jdo/package-info.java b/querydsl-jdo/src/main/java/com/mysema/query/jdo/package-info.java deleted file mode 100644 index f513725e6c..0000000000 --- a/querydsl-jdo/src/main/java/com/mysema/query/jdo/package-info.java +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -/** - * JDOQL support for Querydsl - */ -package com.mysema.query.jdo; diff --git a/querydsl-jdo/src/main/java/com/mysema/query/jdo/sql/AbstractSQLQuery.java b/querydsl-jdo/src/main/java/com/mysema/query/jdo/sql/AbstractSQLQuery.java deleted file mode 100644 index f220ce32a1..0000000000 --- a/querydsl-jdo/src/main/java/com/mysema/query/jdo/sql/AbstractSQLQuery.java +++ /dev/null @@ -1,287 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jdo.sql; - -import javax.annotation.Nullable; -import javax.jdo.PersistenceManager; -import javax.jdo.Query; -import java.io.Closeable; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; - -import com.google.common.collect.Lists; -import com.mysema.commons.lang.CloseableIterator; -import com.mysema.commons.lang.IteratorAdapter; -import com.mysema.query.*; -import com.mysema.query.sql.Configuration; -import com.mysema.query.sql.ProjectableSQLQuery; -import com.mysema.query.sql.SQLSerializer; -import com.mysema.query.support.QueryMixin; -import com.mysema.query.types.Expression; -import com.mysema.query.types.FactoryExpression; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Base class for JDO based SQLQuery implementations - * - * @author tiwe - * - * @param <T> - */ -@SuppressWarnings("rawtypes") -public abstract class AbstractSQLQuery<T extends AbstractSQLQuery<T>> extends ProjectableSQLQuery<T> { - - - private static final Logger logger = LoggerFactory.getLogger(JDOSQLQuery.class); - - private final Closeable closeable = new Closeable() { - @Override - public void close() throws IOException { - AbstractSQLQuery.this.close(); - } - }; - - protected final boolean detach; - - private List<Object> orderedConstants = new ArrayList<Object>(); - - @Nullable - protected final PersistenceManager persistenceManager; - - protected List<Query> queries = new ArrayList<Query>(2); - - @Nullable - protected FactoryExpression<?> projection; - - protected final QueryMixin<T> queryMixin; - - @Nullable - protected Expression<?> union; - - protected boolean unionAll; - - @SuppressWarnings("unchecked") - public AbstractSQLQuery(QueryMetadata metadata, Configuration conf, PersistenceManager persistenceManager, - boolean detach) { - super(new QueryMixin<T>(metadata, false), conf); - this.queryMixin = super.queryMixin; - this.queryMixin.setSelf((T)this); - this.persistenceManager = persistenceManager; - this.detach = detach; - } - - public void close() { - for (Query query : queries) { - query.closeAll(); - } - } - - @Override - public long count() { - Query query = createQuery(true); - query.setUnique(true); - reset(); - Long rv = (Long) execute(query, true); - if (rv != null) { - return rv.longValue(); - } else { - throw new QueryException("Query returned null"); - } - } - - private Query createQuery(boolean forCount) { - SQLSerializer serializer = new SQLSerializer(configuration); - if (union != null) { - serializer.serializeUnion(union, queryMixin.getMetadata(), unionAll); - } else { - serializer.serialize(queryMixin.getMetadata(), forCount); - } - - - // create Query - if (logger.isDebugEnabled()) { - logger.debug(serializer.toString()); - } - Query query = persistenceManager.newQuery("javax.jdo.query.SQL",serializer.toString()); - orderedConstants = serializer.getConstants(); - queries.add(query); - - if (!forCount) { - List<? extends Expression<?>> projection = queryMixin.getMetadata().getProjection(); - if (projection.get(0) instanceof FactoryExpression) { - this.projection = (FactoryExpression<?>)projection.get(0); - } - } else { - query.setResultClass(Long.class); - } - - return query; - } - - @SuppressWarnings("unchecked") - private <T> T detach(T results) { - if (results instanceof Collection) { - return (T) persistenceManager.detachCopyAll(results); - } else { - return persistenceManager.detachCopy(results); - } - } - - private Object project(FactoryExpression<?> expr, Object row) { - if (row == null) { - return null; - } else if (row.getClass().isArray()) { - return expr.newInstance((Object[])row); - } else { - return expr.newInstance(new Object[]{row}); - } - } - - private Object execute(Query query, boolean forCount) { - Object rv; - if (!orderedConstants.isEmpty()) { - rv = query.executeWithArray(orderedConstants.toArray()); - } else { - rv = query.execute(); - } - if (isDetach()) { - rv = detach(rv); - } - if (projection != null && !forCount) { - if (rv instanceof List) { - List<?> original = (List<?>)rv; - rv = Lists.newArrayList(); - for (Object o : original) { - ((List)rv).add(project(projection, o)); - } - } else { - rv = project(projection, rv); - } - } - return rv; - } - - @Override - public QueryMetadata getMetadata() { - return queryMixin.getMetadata(); - } - - public boolean isDetach() { - return detach; - } - - @Override - public CloseableIterator<Tuple> iterate(Expression<?>... args) { - return iterate(queryMixin.createProjection(args)); - } - - @Override - public <RT> CloseableIterator<RT> iterate(Expression<RT> projection) { - return new IteratorAdapter<RT>(list(projection).iterator(), closeable); - } - - @Override - public List<Tuple> list(Expression<?>... args) { - return list(queryMixin.createProjection(args)); - } - - @Override - @SuppressWarnings("unchecked") - public <RT> List<RT> list(Expression<RT> expr) { - queryMixin.addProjection(expr); - Object rv = execute(createQuery(false), false); - reset(); - return rv instanceof List ? (List<RT>)rv : Collections.singletonList((RT) rv); - } - - @Override - public SearchResults<Tuple> listResults(Expression<?>... args) { - return listResults(queryMixin.createProjection(args)); - } - - @Override - @SuppressWarnings("unchecked") - public <RT> SearchResults<RT> listResults(Expression<RT> expr) { - queryMixin.addProjection(expr); - Query countQuery = createQuery(true); - countQuery.setUnique(true); - long total = (Long) execute(countQuery, true); - if (total > 0) { - QueryModifiers modifiers = queryMixin.getMetadata().getModifiers(); - Query query = createQuery(false); - reset(); - return new SearchResults<RT>((List<RT>) execute(query, false), modifiers, total); - } else { - reset(); - return SearchResults.emptyResults(); - } - } - - private void reset() { - queryMixin.getMetadata().reset(); - } - - @Override - public String toString() { - if (!queryMixin.getMetadata().getJoins().isEmpty()) { - SQLSerializer serializer = new SQLSerializer(configuration); - serializer.serialize(queryMixin.getMetadata(), false); - return serializer.toString().trim(); - } else { - return super.toString(); - } - } - - - @Override - @Nullable - public Tuple uniqueResult(Expression<?>... args) { - return uniqueResult(queryMixin.createProjection(args)); - } - - @Override - @SuppressWarnings("unchecked") - @Nullable - public <RT> RT uniqueResult(Expression<RT> expr) { - queryMixin.addProjection(expr); - return (RT)uniqueResult(); - } - - @Nullable - private Object uniqueResult() { - if (getMetadata().getModifiers().getLimit() == null) { - limit(2); - } - Query query = createQuery(false); - reset(); - Object rv = execute(query, false); - if (rv instanceof List) { - List<?> list = (List<?>)rv; - if (!list.isEmpty()) { - if (list.size() > 1) { - throw new NonUniqueResultException(); - } - return list.get(0); - } else { - return null; - } - } else { - return rv; - } - } -} diff --git a/querydsl-jdo/src/main/java/com/mysema/query/jdo/sql/JDOSQLQuery.java b/querydsl-jdo/src/main/java/com/mysema/query/jdo/sql/JDOSQLQuery.java deleted file mode 100644 index 23321a2996..0000000000 --- a/querydsl-jdo/src/main/java/com/mysema/query/jdo/sql/JDOSQLQuery.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jdo.sql; - -import com.mysema.query.DefaultQueryMetadata; -import com.mysema.query.QueryMetadata; -import com.mysema.query.sql.Configuration; -import com.mysema.query.sql.SQLSerializer; -import com.mysema.query.sql.SQLTemplates; - -import javax.annotation.Nullable; -import javax.jdo.PersistenceManager; - -/** - * JDOSQLQuery is an SQLQuery implementation that uses JDO's SQL query functionality - * to execute queries - * - * @author tiwe - * - */ -public final class JDOSQLQuery extends AbstractSQLQuery<JDOSQLQuery> { - - public JDOSQLQuery(@Nullable PersistenceManager persistenceManager, SQLTemplates templates) { - this(persistenceManager, new Configuration(templates), new DefaultQueryMetadata().noValidate(), false); - } - - public JDOSQLQuery(@Nullable PersistenceManager persistenceManager, Configuration configuration) { - this(persistenceManager, configuration, new DefaultQueryMetadata().noValidate(), false); - } - - public JDOSQLQuery( - @Nullable PersistenceManager persistenceManager, - Configuration configuration, - QueryMetadata metadata, boolean detach) { - super(metadata, configuration, persistenceManager, detach); - } - - @Override - public JDOSQLQuery clone() { - JDOSQLQuery query = new JDOSQLQuery(persistenceManager, configuration, getMetadata().clone(), detach); - query.clone(this); - return query; - } - - @Override - protected SQLSerializer createSerializer() { - return new SQLSerializer(configuration); - } -} diff --git a/querydsl-jdo/src/main/java/com/mysema/query/jdo/sql/package-info.java b/querydsl-jdo/src/main/java/com/mysema/query/jdo/sql/package-info.java deleted file mode 100644 index f9bd56fa7b..0000000000 --- a/querydsl-jdo/src/main/java/com/mysema/query/jdo/sql/package-info.java +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ - -package com.mysema.query.jdo.sql; diff --git a/querydsl-jdo/src/main/java/com/querydsl/jdo/AbstractJDOQuery.java b/querydsl-jdo/src/main/java/com/querydsl/jdo/AbstractJDOQuery.java new file mode 100644 index 0000000000..5a1d749048 --- /dev/null +++ b/querydsl-jdo/src/main/java/com/querydsl/jdo/AbstractJDOQuery.java @@ -0,0 +1,335 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jdo; + +import java.io.Closeable; +import java.io.IOException; +import java.util.*; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.stream.Stream; + +import org.jetbrains.annotations.Nullable; +import javax.jdo.JDOUserException; +import javax.jdo.PersistenceManager; +import javax.jdo.Query; + +import com.mysema.commons.lang.CloseableIterator; +import com.mysema.commons.lang.IteratorAdapter; +import com.querydsl.core.*; +import com.querydsl.core.support.FetchableSubQueryBase; +import com.querydsl.core.types.*; + +/** + * Abstract base class for custom implementations of the {@link JDOQLQuery} interface. + * + * @author tiwe + * + * @param <T> result type + * @param <Q> concrete subclass + */ +public abstract class AbstractJDOQuery<T, Q extends AbstractJDOQuery<T, Q>> extends FetchableSubQueryBase<T, Q> implements JDOQLQuery<T> { + + private static final Logger logger = Logger.getLogger(JDOQuery.class.getName()); + + private final Closeable closeable = new Closeable() { + @Override + public void close() throws IOException { + AbstractJDOQuery.this.close(); + } + }; + + private final boolean detach; + + private List<Object> orderedConstants = new ArrayList<Object>(); + + @Nullable + private final PersistenceManager persistenceManager; + + private final List<Query> queries = new ArrayList<Query>(2); + + private final JDOQLTemplates templates; + + protected final Set<String> fetchGroups = new HashSet<String>(); + + @Nullable + protected Integer maxFetchDepth; + + @Nullable + private FactoryExpression<?> projection; + + public AbstractJDOQuery(@Nullable PersistenceManager persistenceManager) { + this(persistenceManager, JDOQLTemplates.DEFAULT, new DefaultQueryMetadata(), false); + } + + @SuppressWarnings("unchecked") + public AbstractJDOQuery( + @Nullable PersistenceManager persistenceManager, + JDOQLTemplates templates, + QueryMetadata metadata, boolean detach) { + super(new JDOQueryMixin<Q>(metadata)); + this.queryMixin.setSelf((Q) this); + this.templates = templates; + this.persistenceManager = persistenceManager; + this.detach = detach; + } + + /** + * Add the fetch group to the set of active fetch groups. + * + * @param fetchGroupName fetch group name + * @return the current object + */ + @Override + public Q addFetchGroup(String fetchGroupName) { + fetchGroups.add(fetchGroupName); + return queryMixin.getSelf(); + } + + /** + * Close the query and related resources + */ + @Override + public void close() { + for (Query query : queries) { + query.closeAll(); + } + } + + @Override + public long fetchCount() { + try { + Query query = createQuery(true); + query.setUnique(true); + Long rv = (Long) execute(query, true); + if (rv != null) { + return rv; + } else { + throw new QueryException("Query returned null"); + } + } finally { + reset(); + } + + } + + private Expression<?> getSource() { + return queryMixin.getMetadata().getJoins().get(0).getTarget(); + } + + private Query createQuery(boolean forCount) { + Expression<?> source = getSource(); + + // serialize + JDOQLSerializer serializer = new JDOQLSerializer(getTemplates(), source); + serializer.serialize(queryMixin.getMetadata(), forCount, false); + + logQuery(serializer.toString(), serializer.getConstantToLabel()); + + // create Query + Query query = persistenceManager.newQuery(serializer.toString()); + orderedConstants = serializer.getConstants(); + queries.add(query); + + if (!forCount) { + Expression<?> projection = queryMixin.getMetadata().getProjection(); + if (projection instanceof FactoryExpression) { + this.projection = (FactoryExpression<?>) projection; + } + if (!fetchGroups.isEmpty()) { + query.getFetchPlan().setGroups(fetchGroups); + } + if (maxFetchDepth != null) { + query.getFetchPlan().setMaxFetchDepth(maxFetchDepth); + } + } + + return query; + } + + protected void logQuery(String queryString, Map<Object, String> parameters) { + if (logger.isLoggable(Level.FINE)) { + String normalizedQuery = queryString.replace('\n', ' '); + logger.fine(normalizedQuery); + } + } + + @SuppressWarnings("unchecked") + private <T> T detach(T results) { + if (results instanceof Collection) { + return (T) persistenceManager.detachCopyAll((Collection<?>) results); + } else { + return persistenceManager.detachCopy(results); + } + } + + private Object project(FactoryExpression<?> expr, Object row) { + if (row == null) { + return null; + } else if (row.getClass().isArray()) { + return expr.newInstance((Object[]) row); + } else { + return expr.newInstance(new Object[]{row}); + } + } + + @Nullable + private Object execute(Query query, boolean forCount) { + Object rv; + if (!orderedConstants.isEmpty()) { + rv = query.executeWithArray(orderedConstants.toArray()); + } else { + rv = query.execute(); + } + if (isDetach()) { + rv = detach(rv); + } + if (projection != null && !forCount) { + if (rv instanceof List) { + List<?> original = (List<?>) rv; + rv = new ArrayList<>(); + for (Object o : original) { + ((List) rv).add(project(projection, o)); + } + } else { + rv = project(projection, rv); + } + } + + return rv; + } + + @Override + public Q from(EntityPath<?>... args) { + return queryMixin.from(args); + } + + @Override + public <U> Q from(CollectionExpression<?, U> path, Path<U> alias) { + return (Q) queryMixin.from((Expression) ExpressionUtils.as((Path) path, alias)); + } + + public JDOQLTemplates getTemplates() { + return templates; + } + + public boolean isDetach() { + return detach; + } + + @Override + public CloseableIterator<T> iterate() { + return new IteratorAdapter<T>(fetch().iterator(), closeable); + } + + @Override + public Stream<T> stream() { + return fetch().stream().onClose(this::close); + } + + @Override + public List<T> fetch() { + try { + Object rv = execute(createQuery(false), false); + @SuppressWarnings("unchecked") // Compile time checking of user code mandates it to be T + List<T> result = rv instanceof List ? (List<T>) rv : Collections.singletonList((T) rv); + return result; + } finally { + reset(); + } + } + + @Override + public QueryResults<T> fetchResults() { + try { + Query countQuery = createQuery(true); + countQuery.setUnique(true); + countQuery.setResult("count(this)"); + long total = (Long) execute(countQuery, true); + if (total > 0) { + QueryModifiers modifiers = queryMixin.getMetadata().getModifiers(); + Query query = createQuery(false); + return new QueryResults<T>((List<T>) execute(query, false), modifiers, total); + } else { + return QueryResults.emptyResults(); + } + } finally { + reset(); + } + } + + private void reset() { + } + + /** + * Set the maximum fetch depth when fetching. + * A value of 0 has no meaning and will throw a {@link JDOUserException}. + * A value of -1 means that no limit is placed on fetching. + * A positive integer will result in that number of references from the + * initial object to be fetched. + * + * @param depth fetch depth + * @return the current object + */ + @Override + public Q setMaxFetchDepth(int depth) { + maxFetchDepth = depth; + return queryMixin.getSelf(); + } + + @Override + public String toString() { + if (!queryMixin.getMetadata().getJoins().isEmpty()) { + Expression<?> source = getSource(); + JDOQLSerializer serializer = new JDOQLSerializer(getTemplates(), source); + serializer.serialize(queryMixin.getMetadata(), false, false); + return serializer.toString().trim(); + } else { + return super.toString(); + } + } + + @Nullable + @Override + public T fetchOne() throws NonUniqueResultException { + if (getMetadata().getModifiers().getLimit() == null) { + limit(2); + } + try { + Query query = createQuery(false); + Object rv = execute(query, false); + if (rv instanceof List) { + @SuppressWarnings("unchecked") // Compile time checking of user code mandates this + List<T> list = (List<T>) rv; + if (!list.isEmpty()) { + if (list.size() > 1) { + throw new NonUniqueResultException(); + } + return list.get(0); + } else { + return null; + } + } else { + // it is not a List typed expression + @SuppressWarnings("unchecked") // Compile time checking of user code mandates this + T result = (T) rv; + return result; + } + } finally { + reset(); + } + + } + +} diff --git a/querydsl-jdo/src/main/java/com/querydsl/jdo/JDOExpressions.java b/querydsl-jdo/src/main/java/com/querydsl/jdo/JDOExpressions.java new file mode 100644 index 0000000000..03ad666e0b --- /dev/null +++ b/querydsl-jdo/src/main/java/com/querydsl/jdo/JDOExpressions.java @@ -0,0 +1,100 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jdo; + +import com.querydsl.core.Tuple; +import com.querydsl.core.types.EntityPath; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.dsl.Expressions; + +/** + * Common JDO expressions + */ +public final class JDOExpressions { + + /** + * Create a new detached {@link JDOQuery} instance with the given projection + * + * @param expr projection + * @param <T> + * @return select(expr) + */ + public static <T> JDOQuery<T> select(Expression<T> expr) { + return new JDOQuery<Void>().select(expr); + } + + /** + * Create a new detached {@link JDOQuery} instance with the given projection + * + * @param exprs projection + * @return select(exprs) + */ + public static JDOQuery<Tuple> select(Expression<?>... exprs) { + return new JDOQuery<Void>().select(exprs); + } + + /** + * Create a new detached {@link JDOQuery} instance with the given projection + * + * @param expr projection + * @param <T> + * @return select(distinct expr) + */ + public static <T> JDOQuery<T> selectDistinct(Expression<T> expr) { + return select(expr).distinct(); + } + + /** + * Create a new detached {@link JDOQuery} instance with the given projection + * + * @param exprs projection + * @return select(distinct exprs) + */ + public static JDOQuery<Tuple> selectDistinct(Expression<?>... exprs) { + return select(exprs).distinct(); + } + + + /** + * Create a new detached {@link JDOQuery} instance with the given projection 0 + * + * @return select(0) + */ + public static JDOQuery<Integer> selectZero() { + return select(Expressions.ZERO); + } + + /** + * Create a new detached {@link JDOQuery} instance with the projection 1 + * + * @return select(1) + */ + public static JDOQuery<Integer> selectOne() { + return select(Expressions.ONE); + } + + /** + * Create a new detached {@link JDOQuery} instance with the given projection + * + * @param expr projection and source + * @param <T> + * @return select(expr).from(expr) + */ + public static <T> JDOQuery<T> selectFrom(EntityPath<T> expr) { + return select(expr).from(expr); + } + + private JDOExpressions() { } + +} diff --git a/querydsl-jdo/src/main/java/com/querydsl/jdo/JDOQLQuery.java b/querydsl-jdo/src/main/java/com/querydsl/jdo/JDOQLQuery.java new file mode 100644 index 0000000000..d326270673 --- /dev/null +++ b/querydsl-jdo/src/main/java/com/querydsl/jdo/JDOQLQuery.java @@ -0,0 +1,88 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jdo; + +import java.io.Closeable; + +import javax.jdo.PersistenceManager; + +import com.querydsl.core.FetchableQuery; +import com.querydsl.core.Query; +import com.querydsl.core.support.ExtendedSubQuery; +import com.querydsl.core.types.CollectionExpression; +import com.querydsl.core.types.EntityPath; +import com.querydsl.core.types.Path; + +/** + * Query interface for JDOQL queries + * + * @author tiwe + * + * @param <T> result type + */ +public interface JDOQLQuery<T> extends FetchableQuery<T, JDOQLQuery<T>>, Query<JDOQLQuery<T>>, ExtendedSubQuery<T>, Closeable { + + /** + * Add query sources + * + * @param sources sources + * @return the current object + */ + JDOQLQuery<T> from(EntityPath<?>... sources); + + /** + * Add query sources + * + * @param path source + * @param alias alias + * @param <U> + * @return the current object + */ + <U> JDOQLQuery<T> from(CollectionExpression<?, U> path, Path<U> alias); + + /** + * Clone the state of the query for the given PersistenceManager + * + * @param persistenceManager persistence manager + * @return cloned query + */ + JDOQLQuery<T> clone(PersistenceManager persistenceManager); + + /** + * Add the fetch group to the set of active fetch groups. + * + * @param fetchGroupName fetch group name + * @return the current object + */ + JDOQLQuery<T> addFetchGroup(String fetchGroupName); + + /** + * Set the maximum fetch depth when fetching. + * A value of 0 has no meaning and will throw a JDOUserException. + * A value of -1 means that no limit is placed on fetching. + * A positive integer will result in that number of references from the + * initial object to be fetched. + * + * @param maxFetchDepth max fetch depth + * @return the current object + */ + JDOQLQuery<T> setMaxFetchDepth(int maxFetchDepth); + + /** + * Close the query and related resources + */ + @Override + void close(); + +} diff --git a/querydsl-jdo/src/main/java/com/querydsl/jdo/JDOQLSerializer.java b/querydsl-jdo/src/main/java/com/querydsl/jdo/JDOQLSerializer.java new file mode 100644 index 0000000000..971509cc14 --- /dev/null +++ b/querydsl-jdo/src/main/java/com/querydsl/jdo/JDOQLSerializer.java @@ -0,0 +1,333 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jdo; + +import java.util.*; +import java.util.Map.Entry; + +import org.jetbrains.annotations.Nullable; + +import com.querydsl.core.JoinExpression; +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.support.SerializerBase; +import com.querydsl.core.types.*; +import com.querydsl.core.types.dsl.Param; +import com.querydsl.core.util.PrimitiveUtils; + +/** + * {@code JDOQLSerializer} serializes Querydsl queries and expressions into JDOQL strings + * + * @author tiwe + * + */ +public final class JDOQLSerializer extends SerializerBase<JDOQLSerializer> { + + private static final String COMMA = ", "; + + private static final String FROM = "\nFROM "; + + private static final String GROUP_BY = "\nGROUP BY "; + + private static final String HAVING = "\nHAVING "; + + private static final String ORDER_BY = "\nORDER BY "; + + private static final String PARAMETERS = "\nPARAMETERS "; + + private static final String RANGE = "\nRANGE "; + + private static final String SELECT = "SELECT "; + + private static final String SELECT_COUNT = "SELECT count("; + + private static final String SELECT_COUNT_THIS = "SELECT count(this)\n"; + + private static final String SELECT_DISTINCT = "SELECT DISTINCT "; + + private static final String SELECT_UNIQUE = "SELECT UNIQUE "; + + private static final String THIS = "this"; + + private static final String VARIABLES = "\nVARIABLES "; + + private static final String WHERE = "\nWHERE "; + + private static Comparator<Map.Entry<Object,String>> comparator = new Comparator<Map.Entry<Object,String>>() { + @Override + public int compare(Entry<Object, String> o1, Entry<Object, String> o2) { + return o1.getValue().compareTo(o2.getValue()); + } + }; + + private final Expression<?> candidatePath; + + private final List<Object> constants = new ArrayList<Object>(); + + private final Stack<Map<Object,String>> constantToLabel = new Stack<Map<Object,String>>(); + + public JDOQLSerializer(JDOQLTemplates templates, Expression<?> candidate) { + super(templates); + this.candidatePath = candidate; + this.constantToLabel.push(new LinkedHashMap<>()); + } + + public Expression<?> getCandidatePath() { + return candidatePath; + } + + @Override + public List<Object> getConstants() { + return constants; + } + + @Override + public Map<Object,String> getConstantToLabel() { + return constantToLabel.peek(); + } + + public void serialize(QueryMetadata metadata, boolean forCountRow, boolean subQuery) { + final Expression<?> select = metadata.getProjection(); + final List<JoinExpression> joins = metadata.getJoins(); + final Expression<?> source = joins.get(0).getTarget(); + final Predicate where = metadata.getWhere(); + final List<? extends Expression<?>> groupBy = metadata.getGroupBy(); + final Predicate having = metadata.getHaving(); + final List<OrderSpecifier<?>> orderBy = metadata.getOrderBy(); + + constantToLabel.push(new LinkedHashMap<Object,String>()); + + // select + boolean skippedSelect = false; + if (forCountRow) { + if (joins.size() == 1 && !subQuery) { + append(SELECT_COUNT_THIS); + } else { + append(SELECT_COUNT); + handle(source); + append(")"); + } + + } else if (select != null) { + if (metadata.isDistinct()) { + append(SELECT_DISTINCT); + } else if (metadata.isUnique() && !subQuery) { + append(SELECT_UNIQUE); + } else { + append(SELECT); + } + if (!select.equals(source) || metadata.isDistinct()) { + handle(select); + } else { + skippedSelect = true; + } + } + + // from + append(skippedSelect ? FROM.substring(1) : FROM); + if (source instanceof Operation && subQuery) { + handle(source); + } else { + append(source.getType().getName()); + if (!source.equals(candidatePath)) { + append(" ").handle(source); + } + } + + // where + if (where != null) { + append(WHERE).handle(where); + } + + // variables + if (joins.size() > 1) { + serializeVariables(joins); + } + + int position = getLength(); + + // group by + if (!groupBy.isEmpty()) { + append(GROUP_BY).handle(COMMA, groupBy); + } + + // having + if (having != null) { + append(HAVING).handle(having); + } + + // order by + if (!orderBy.isEmpty() && !forCountRow) { + append(ORDER_BY); + boolean first = true; + for (final OrderSpecifier<?> os : orderBy) { + if (!first) { + append(COMMA); + } + handle(os.getTarget()); + append(" " + os.getOrder()); + first = false; + } + } + + // range + if (!forCountRow && metadata.getModifiers().isRestricting()) { + Long limit = metadata.getModifiers().getLimit(); + Long offset = metadata.getModifiers().getOffset(); + serializeModifiers(limit, offset); + } + + // parameters + if (!getConstantToLabel().isEmpty()) { + insert(position, serializeParameters(metadata.getParams())); + } + + constantToLabel.pop(); + + } + + private void serializeModifiers(@Nullable Long limit, @Nullable Long offset) { + append(RANGE); + if (offset != null) { + append(String.valueOf(offset)); + if (limit != null) { + append(COMMA); + append(String.valueOf(offset + limit)); + } + } else { + append("0, ").append(String.valueOf(limit)); + } + } + + private String serializeParameters(Map<ParamExpression<?>, Object> params) { + final StringBuilder b = new StringBuilder(); + b.append(PARAMETERS); + boolean first = true; + final Collection<Map.Entry<Object, String>> entries = getConstantToLabel().entrySet(); + for (Map.Entry<Object, String> entry : entries) { + if (!first) { + b.append(COMMA); + } + if (entry.getKey() instanceof Param) { + Object constant = params.get(entry.getKey()); + if (constant == null) { + throw new ParamNotSetException((Param<?>) entry.getKey()); + } + constants.add(constant); + b.append(((Param<?>) entry.getKey()).getType().getName()); + } else { + constants.add(entry.getKey()); + b.append(entry.getKey().getClass().getName()); + } + b.append(" ").append(entry.getValue()); + first = false; + } + return b.toString(); + } + + private void serializeVariables(List<JoinExpression> joins) { + append(VARIABLES); + for (int i = 1; i < joins.size(); i++) { + final JoinExpression je = joins.get(i); + if (i > 1) { + append("; "); + } + + // type specifier + if (je.getTarget() instanceof EntityPath) { + final EntityPath<?> pe = (EntityPath<?>) je.getTarget(); + if (pe.getMetadata().getParent() == null) { + append(pe.getType().getName()).append(" "); + } + } + handle(je.getTarget()); + } + } + + @Override + public Void visit(Path<?> path, Void context) { + if (path.equals(candidatePath)) { + append(THIS); + } else { + super.visit(path, context); + } + return null; + } + + @Override + public Void visit(SubQueryExpression<?> query, Void context) { + append("("); + serialize(query.getMetadata(), false, true); + append(")"); + return null; + } + + @Override + protected void visitOperation(Class<?> type, Operator operator, List<? extends Expression<?>> args) { + if (operator == Ops.INSTANCE_OF) { + handle(args.get(0)).append(" instanceof "); + @SuppressWarnings("unchecked") //This is the expected type for instanceOf + Constant<Class<?>> rightArg = (Constant<Class<?>>) args.get(1); + append(rightArg.getConstant().getName()); + + } else if (operator == Ops.LIKE || operator == Ops.LIKE_ESCAPE || operator == Ops.LIKE_IC || operator == Ops.LIKE_ESCAPE_IC) { + @SuppressWarnings("unchecked") //This is the expected type for like + Expression<String> string = (Expression<String>) args.get(0); + @SuppressWarnings("unchecked") //This is the expected type for like + Expression<String> regex = ExpressionUtils.likeToRegex((Expression<String>) args.get(1), false); + if (operator == Ops.LIKE_IC || operator == Ops.LIKE_ESCAPE_IC) { + string = ExpressionUtils.toLower(string); + regex = ExpressionUtils.toLower(regex); + } + super.visitOperation(type, Ops.MATCHES, + Arrays.asList(string, regex)); + + // exists + } else if (operator == Ops.EXISTS && args.get(0) instanceof SubQueryExpression) { + final SubQueryExpression subQuery = (SubQueryExpression) args.get(0); + append("("); + serialize(subQuery.getMetadata(), true, true); + append(") > 0"); + + // not exists + } else if (operator == Ops.NOT && args.get(0) instanceof Operation + && ((Operation) args.get(0)).getOperator().equals(Ops.EXISTS)) { + final SubQueryExpression subQuery = (SubQueryExpression) ((Operation) args.get(0)).getArg(0); + append("("); + serialize(subQuery.getMetadata(), true, true); + append(") == 0"); + + } else if (operator == Ops.NUMCAST) { + @SuppressWarnings("unchecked") //This is the expected type for castToNum + Constant<Class<?>> rightArg = (Constant<Class<?>>) args.get(1); + Class<?> clazz = rightArg.getConstant(); + if (Number.class.isAssignableFrom(clazz) && PrimitiveUtils.isWrapperType(clazz)) { + clazz = PrimitiveUtils.unwrap(clazz); + } + append("(" + clazz.getSimpleName() + ")").handle(args.get(0)); + + } else if (operator == Ops.ALIAS) { + if (args.get(1) instanceof Path && !((Path<?>) args.get(1)).getMetadata().isRoot()) { + Path<?> path = (Path<?>) args.get(1); + args = Arrays.asList(args.get(0), + ExpressionUtils.path(path.getType(), path.getMetadata().getName())); + } + super.visitOperation(type, operator, args); + + } else { + super.visitOperation(type, operator, args); + } + } + + +} diff --git a/querydsl-jdo/src/main/java/com/querydsl/jdo/JDOQLTemplates.java b/querydsl-jdo/src/main/java/com/querydsl/jdo/JDOQLTemplates.java new file mode 100644 index 0000000000..f14a4a52d7 --- /dev/null +++ b/querydsl-jdo/src/main/java/com/querydsl/jdo/JDOQLTemplates.java @@ -0,0 +1,54 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jdo; + +import com.querydsl.core.types.JavaTemplates; +import com.querydsl.core.types.Ops; + +/** + * {@code JDOQLTemplates} provides patterns for JDOQL serialization + * + * @author tiwe + * + */ +public final class JDOQLTemplates extends JavaTemplates { + + @SuppressWarnings("FieldNameHidesFieldInSuperclass") //Intentional + public static final JDOQLTemplates DEFAULT = new JDOQLTemplates(); + + protected JDOQLTemplates() { + // String + add(Ops.STRING_CONTAINS, "{0}.indexOf({1}) > -1", Precedence.COMPARISON); + add(Ops.STRING_CONTAINS_IC, "{0l}.indexOf({1l}) > -1", Precedence.COMPARISON); + add(Ops.EQ_IGNORE_CASE, "{0l}.equals({1l})"); + add(Ops.STRING_IS_EMPTY, "{0} == \"\"", Precedence.EQUALITY); + add(Ops.LIKE, "{0}.like({1})"); + add(Ops.LIKE_IC, "{0l}.like({1l})"); + add(Ops.LIKE_ESCAPE, "{0}.like({1})"); + add(Ops.LIKE_ESCAPE_IC, "{0l}.like({1l})"); + + add(Ops.STRING_CAST, "(String){0}"); + + // Date + add(Ops.DateTimeOps.MONTH, "({0}.getMonth() + 1)"); // getMonth() in JDO returns a range from 0-11 + add(Ops.DateTimeOps.DAY_OF_MONTH, "{0}.getDay()"); + add(Ops.DateTimeOps.MILLISECOND, "0"); // NOT supported in JDOQL + + add(Ops.DateTimeOps.YEAR_MONTH, "({0}.getYear() * 100 + {0}.getMonth() + 1)"); + + // other + add(Ops.ALIAS, "{0} {1}"); + } + +} diff --git a/querydsl-jdo/src/main/java/com/querydsl/jdo/JDOQuery.java b/querydsl-jdo/src/main/java/com/querydsl/jdo/JDOQuery.java new file mode 100644 index 0000000000..326fc776ec --- /dev/null +++ b/querydsl-jdo/src/main/java/com/querydsl/jdo/JDOQuery.java @@ -0,0 +1,115 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jdo; + +import javax.jdo.PersistenceManager; + +import com.querydsl.core.DefaultQueryMetadata; +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.Tuple; +import com.querydsl.core.types.Expression; + +/** + * {@code JDOQuery} is the default implementation of the {@link JDOQLQuery} interface + * + * @author tiwe + * + * @param <T> result type + */ +public class JDOQuery<T> extends AbstractJDOQuery<T, JDOQuery<T>> { + + /** + * Create a detached {@link JDOQuery} instance + * The query can be attached via the clone method + * + */ + public JDOQuery() { + super(null, JDOQLTemplates.DEFAULT, new DefaultQueryMetadata(), false); + } + + /** + * Create a new {@link JDOQuery} instance + * + * @param persistenceManager PersistenceManager instance to use + * @param templates JDOQLTemplates to use + * @param detach detached results or not + */ + public JDOQuery(PersistenceManager persistenceManager, JDOQLTemplates templates, boolean detach) { + super(persistenceManager, templates, new DefaultQueryMetadata(), detach); + } + + /** + * Create a new {@link JDOQuery} instance + * + * @param persistenceManager PersistenceManager instance to use + * @param detach detached results or not + */ + public JDOQuery(PersistenceManager persistenceManager, boolean detach) { + super(persistenceManager, JDOQLTemplates.DEFAULT, new DefaultQueryMetadata(), detach); + } + + /** + * Create a new {@link JDOQuery} instance + * + * @param persistenceManager PersistenceManager instance to use + */ + public JDOQuery(PersistenceManager persistenceManager) { + super(persistenceManager, JDOQLTemplates.DEFAULT, new DefaultQueryMetadata(), false); + } + + /** + * Create a new {@link JDOQuery} instance + * + * @param persistenceManager PersistenceManager instance to use + * @param templates templates to use + * @param metadata query metadata + * @param detach detached results or not + */ + protected JDOQuery(PersistenceManager persistenceManager, JDOQLTemplates templates, + QueryMetadata metadata, boolean detach) { + super(persistenceManager, templates, metadata, detach); + } + + /** + * Clone the state of this query to a new {@link JDOQuery} instance with the given {@link PersistenceManager} + * + * @param persistenceManager PersistenceManager instance to use + * @return cloned query + */ + @Override + public JDOQuery<T> clone(PersistenceManager persistenceManager) { + JDOQuery<T> query = new JDOQuery<T>(persistenceManager, getTemplates(), + getMetadata().clone(), isDetach()); + query.fetchGroups.addAll(fetchGroups); + query.maxFetchDepth = maxFetchDepth; + return query; + } + + @Override + public <U> JDOQuery<U> select(Expression<U> expr) { + queryMixin.setProjection(expr); + @SuppressWarnings("unchecked") // This is the new projection type + JDOQuery<U> newType = (JDOQuery<U>) this; + return newType; + } + + @Override + public JDOQuery<Tuple> select(Expression<?>... exprs) { + queryMixin.setProjection(exprs); + @SuppressWarnings("unchecked") // This is the new projection type + JDOQuery<Tuple> newType = (JDOQuery<Tuple>) this; + return newType; + } + +} diff --git a/querydsl-jdo/src/main/java/com/querydsl/jdo/JDOQueryFactory.java b/querydsl-jdo/src/main/java/com/querydsl/jdo/JDOQueryFactory.java new file mode 100644 index 0000000000..23a2b0e9f9 --- /dev/null +++ b/querydsl-jdo/src/main/java/com/querydsl/jdo/JDOQueryFactory.java @@ -0,0 +1,126 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jdo; + +import javax.jdo.PersistenceManager; + +import com.querydsl.core.QueryFactory; +import com.querydsl.core.Tuple; +import com.querydsl.core.types.EntityPath; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.jdo.dml.JDODeleteClause; + +import java.util.function.Supplier; + +/** + * Factory class for query and DML clause creation + * + * @author tiwe + * + */ +public class JDOQueryFactory implements QueryFactory<JDOQuery<?>> { + + private final Supplier<PersistenceManager> persistenceManager; + + public JDOQueryFactory(Supplier<PersistenceManager> persistenceManager) { + this.persistenceManager = persistenceManager; + } + + public JDODeleteClause delete(EntityPath<?> path) { + return new JDODeleteClause(persistenceManager.get(), path); + } + + /** + * Create a new {@link JDOQuery} instance with the given projection + * + * @param expr projection + * @param <T> + * @return select(expr) + */ + public <T> JDOQuery<T> select(Expression<T> expr) { + return query().select(expr); + } + + /** + * Create a new {@link JDOQuery} instance with the given projection + * + * @param exprs projection + * @return select(exprs) + */ + public JDOQuery<Tuple> select(Expression<?>... exprs) { + return query().select(exprs); + } + + /** + * Create a new {@link JDOQuery} instance with the given projection + * + * @param expr projection + * @param <T> + * @return select(distinct expr) + */ + public <T> JDOQuery<T> selectDistinct(Expression<T> expr) { + return query().select(expr).distinct(); + } + + /** + * Create a new {@link JDOQuery} instance with the given projection + * + * @param exprs projection + * @return select(distinct exprs) + */ + public JDOQuery<Tuple> selectDistinct(Expression<?>... exprs) { + return query().select(exprs).distinct(); + } + + /** + * Create a new {@link JDOQuery} instance with the projection 0 + * + * @return select(0) + */ + public JDOQuery<Integer> selectZero() { + return select(Expressions.ZERO); + } + + /** + * Create a new {@link JDOQuery} instance with the projection 1 + * + * @return select(1) + */ + public JDOQuery<Integer> selectOne() { + return select(Expressions.ONE); + } + + /** + * Create a new {@link JDOQuery} instance with the given projection + * + * @param expr projection and source + * @param <T> + * @return select(expr).from(expr) + */ + public <T> JDOQuery<T> selectFrom(EntityPath<T> expr) { + return select(expr).from(expr); + } + + public JDOQuery<?> from(EntityPath<?> from) { + return query().from(from); + } + + @Override + public JDOQuery<?> query() { + return new JDOQuery<Void>(persistenceManager.get()); + } + + +} \ No newline at end of file diff --git a/querydsl-jdo/src/main/java/com/querydsl/jdo/JDOQueryMixin.java b/querydsl-jdo/src/main/java/com/querydsl/jdo/JDOQueryMixin.java new file mode 100644 index 0000000000..20a4a63a84 --- /dev/null +++ b/querydsl-jdo/src/main/java/com/querydsl/jdo/JDOQueryMixin.java @@ -0,0 +1,68 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jdo; + +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.support.Context; +import com.querydsl.core.support.QueryMixin; +import com.querydsl.core.types.*; + +/** + * {@code JDOQueryMixin} extends {@link QueryMixin} to provide module-specific extensions + * + * @author tiwe + * + * @param <T> + */ +public class JDOQueryMixin<T> extends QueryMixin<T> { + + public JDOQueryMixin() { } + + public JDOQueryMixin(QueryMetadata metadata) { + super(metadata); + } + + public JDOQueryMixin(T self, QueryMetadata metadata) { + super(self, metadata); + } + + @Override + protected Predicate convert(Predicate predicate, Role role) { + predicate = (Predicate) ExpressionUtils.extract(predicate); + if (predicate != null) { + Context context = new Context(); + Predicate transformed = (Predicate) predicate.accept(collectionAnyVisitor, context); + for (int i = 0; i < context.paths.size(); i++) { + Path<?> path = context.paths.get(i); + addCondition(context, i, path, role); + } + return transformed; + } else { + return null; + } + } + + @SuppressWarnings("unchecked") + private void addCondition(Context context, int i, Path<?> path, Role role) { + EntityPath<?> alias = context.replacements.get(i); + from(alias); + Predicate condition = ExpressionUtils.predicate(Ops.IN, alias, path.getMetadata().getParent()); + if (role == Role.WHERE) { + super.where(condition); + } else { + super.having(condition); + } + } + +} diff --git a/querydsl-jdo/src/main/java/com/mysema/query/jdo/dml/JDODeleteClause.java b/querydsl-jdo/src/main/java/com/querydsl/jdo/dml/JDODeleteClause.java similarity index 83% rename from querydsl-jdo/src/main/java/com/mysema/query/jdo/dml/JDODeleteClause.java rename to querydsl-jdo/src/main/java/com/querydsl/jdo/dml/JDODeleteClause.java index 568c0ecb65..9beb6ccf61 100644 --- a/querydsl-jdo/src/main/java/com/mysema/query/jdo/dml/JDODeleteClause.java +++ b/querydsl-jdo/src/main/java/com/querydsl/jdo/dml/JDODeleteClause.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.jdo.dml; +package com.querydsl.jdo.dml; import java.util.ArrayList; import java.util.List; @@ -20,17 +20,17 @@ import javax.jdo.PersistenceManager; import javax.jdo.Query; -import com.mysema.query.DefaultQueryMetadata; -import com.mysema.query.JoinType; -import com.mysema.query.QueryMetadata; -import com.mysema.query.dml.DeleteClause; -import com.mysema.query.jdo.JDOQLSerializer; -import com.mysema.query.jdo.JDOQLTemplates; -import com.mysema.query.types.EntityPath; -import com.mysema.query.types.Predicate; +import com.querydsl.core.DefaultQueryMetadata; +import com.querydsl.core.JoinType; +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.dml.DeleteClause; +import com.querydsl.core.types.EntityPath; +import com.querydsl.core.types.Predicate; +import com.querydsl.jdo.JDOQLSerializer; +import com.querydsl.jdo.JDOQLTemplates; /** - * DeleteClause implementation for JDO + * {@link DeleteClause} implementation for JDO * * @author tiwe * @@ -49,7 +49,7 @@ public JDODeleteClause(PersistenceManager pm, EntityPath<?> entity) { this(pm, entity, JDOQLTemplates.DEFAULT); } - public JDODeleteClause(PersistenceManager persistenceManager, EntityPath<?> entity, + public JDODeleteClause(PersistenceManager persistenceManager, EntityPath<?> entity, JDOQLTemplates templates) { this.entity = entity; this.persistenceManager = persistenceManager; @@ -66,7 +66,7 @@ public long execute() { query.setFilter(serializer.toString()); Map<Object,String> constToLabel = serializer.getConstantToLabel(); - try{ + try { if (!constToLabel.isEmpty()) { List<Object> constants = new ArrayList<Object>(constToLabel.size()); StringBuilder builder = new StringBuilder(); @@ -83,26 +83,26 @@ public long execute() { } else { return query.deletePersistentAll(); } - }finally{ + } finally { query.closeAll(); } } else { - try{ + try { return query.deletePersistentAll(); - }finally{ + } finally { query.closeAll(); } } } - + @Override public JDODeleteClause where(Predicate... o) { for (Predicate p : o) { - metadata.addWhere(p); - } + metadata.addWhere(p); + } return this; } - + @Override public String toString() { JDOQLSerializer serializer = new JDOQLSerializer(templates, entity); diff --git a/querydsl-jdo/src/main/java/com/querydsl/jdo/dml/JDOUpdateClause.java b/querydsl-jdo/src/main/java/com/querydsl/jdo/dml/JDOUpdateClause.java new file mode 100644 index 0000000000..4bb2ac71ff --- /dev/null +++ b/querydsl-jdo/src/main/java/com/querydsl/jdo/dml/JDOUpdateClause.java @@ -0,0 +1,96 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jdo.dml; + +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import com.querydsl.core.DefaultQueryMetadata; +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.dml.UpdateClause; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.Predicate; +import com.querydsl.core.types.dsl.Expressions; + +/** + * {@link UpdateClause} implementation for JDO + * + * @author tiwe + * + */ +public class JDOUpdateClause implements UpdateClause<JDOUpdateClause> { + + private final QueryMetadata metadata = new DefaultQueryMetadata(); + + private final Map<Path<?>, Expression<?>> updates = new LinkedHashMap<>(); + + @Override + public long execute() { + // TODO : implement + throw new UnsupportedOperationException("Not yet implemented"); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Override + public JDOUpdateClause set(List<? extends Path<?>> paths, List<?> values) { + for (int i = 0; i < paths.size(); i++) { + if (values.get(i) != null) { + updates.put(paths.get(i), Expressions.constant(values.get(i))); + } else { + updates.put(paths.get(i), Expressions.nullExpression(paths.get(i))); + } + } + return this; + } + + @Override + public <T> JDOUpdateClause set(Path<T> path, T value) { + if (value != null) { + updates.put(path, Expressions.constant(value)); + } else { + updates.put(path, Expressions.nullExpression(path)); + } + return this; + } + + + @Override + public <T> JDOUpdateClause set(Path<T> path, Expression<? extends T> expression) { + updates.put(path, expression); + return this; + } + + @Override + public <T> JDOUpdateClause setNull(Path<T> path) { + updates.put(path, Expressions.nullExpression(path)); + return this; + } + + @Override + public JDOUpdateClause where(Predicate... o) { + for (Predicate p : o) { + metadata.addWhere(p); + } + return this; + } + + @Override + public boolean isEmpty() { + return updates.isEmpty(); + } + + +} diff --git a/querydsl-jdo/src/main/java/com/querydsl/jdo/dml/package-info.java b/querydsl-jdo/src/main/java/com/querydsl/jdo/dml/package-info.java new file mode 100644 index 0000000000..e4ef354a29 --- /dev/null +++ b/querydsl-jdo/src/main/java/com/querydsl/jdo/dml/package-info.java @@ -0,0 +1,18 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ + +/** + * DML operations support + */ +package com.querydsl.jdo.dml; diff --git a/querydsl-jdo/src/main/java/com/querydsl/jdo/package-info.java b/querydsl-jdo/src/main/java/com/querydsl/jdo/package-info.java new file mode 100644 index 0000000000..bb52784eb4 --- /dev/null +++ b/querydsl-jdo/src/main/java/com/querydsl/jdo/package-info.java @@ -0,0 +1,18 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ + +/** + * JDO support + */ +package com.querydsl.jdo; diff --git a/querydsl-jdo/src/main/java/com/querydsl/jdo/sql/AbstractSQLQuery.java b/querydsl-jdo/src/main/java/com/querydsl/jdo/sql/AbstractSQLQuery.java new file mode 100644 index 0000000000..1744f38fe3 --- /dev/null +++ b/querydsl-jdo/src/main/java/com/querydsl/jdo/sql/AbstractSQLQuery.java @@ -0,0 +1,243 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jdo.sql; + +import java.io.Closeable; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; + +import org.jetbrains.annotations.Nullable; +import javax.jdo.PersistenceManager; +import javax.jdo.Query; + +import com.mysema.commons.lang.CloseableIterator; +import com.mysema.commons.lang.IteratorAdapter; +import com.querydsl.core.*; +import com.querydsl.core.support.QueryMixin; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.FactoryExpression; +import com.querydsl.sql.Configuration; +import com.querydsl.sql.ProjectableSQLQuery; +import com.querydsl.sql.SQLQuery; +import com.querydsl.sql.SQLSerializer; + +/** + * Base class for JDO-based {@link SQLQuery} implementations + * + * @author tiwe + * + * @param <T> result type + * @param <Q> concrete subclass + */ +@SuppressWarnings("rawtypes") +public abstract class AbstractSQLQuery<T, Q extends AbstractSQLQuery<T, Q>> extends ProjectableSQLQuery<T, Q> { + + private static final Logger logger = Logger.getLogger(JDOSQLQuery.class.getName()); + + private final Closeable closeable = new Closeable() { + @Override + public void close() throws IOException { + AbstractSQLQuery.this.close(); + } + }; + + protected final boolean detach; + + private List<Object> orderedConstants = new ArrayList<Object>(); + + @Nullable + protected final PersistenceManager persistenceManager; + + protected List<Query> queries = new ArrayList<Query>(2); + + @Nullable + protected FactoryExpression<?> projection; + + protected final QueryMixin<Q> queryMixin; + + @SuppressWarnings("unchecked") + public AbstractSQLQuery(QueryMetadata metadata, Configuration conf, PersistenceManager persistenceManager, + boolean detach) { + super(new QueryMixin<Q>(metadata, false), conf); + this.queryMixin = super.queryMixin; + this.queryMixin.setSelf((Q) this); + this.persistenceManager = persistenceManager; + this.detach = detach; + } + + /** + * Close the query and related resources + */ + public void close() { + for (Query query : queries) { + query.closeAll(); + } + } + + @Override + public long fetchCount() { + Query query = createQuery(true); + query.setUnique(true); + Long rv = (Long) execute(query, true); + if (rv != null) { + return rv; + } else { + throw new QueryException("Query returned null"); + } + } + + private Query createQuery(boolean forCount) { + SQLSerializer serializer = new SQLSerializer(configuration); + if (union != null) { + serializer.serializeUnion(union, queryMixin.getMetadata(), unionAll); + } else { + serializer.serialize(queryMixin.getMetadata(), forCount); + } + + + // create Query + if (logger.isLoggable(Level.FINE)) { + logger.fine(serializer.toString()); + } + Query query = persistenceManager.newQuery("javax.jdo.query.SQL", serializer.toString()); + orderedConstants = serializer.getConstants(); + queries.add(query); + + if (!forCount) { + Expression<?> projection = queryMixin.getMetadata().getProjection(); + if (projection instanceof FactoryExpression) { + this.projection = (FactoryExpression<?>) projection; + } + } else { + query.setResultClass(Long.class); + } + + return query; + } + + @SuppressWarnings("unchecked") + private <T> T detach(T results) { + if (results instanceof Collection) { + return (T) persistenceManager.detachCopyAll(results); + } else { + return persistenceManager.detachCopy(results); + } + } + + private Object project(FactoryExpression<?> expr, Object row) { + if (row == null) { + return null; + } else if (row.getClass().isArray()) { + return expr.newInstance((Object[]) row); + } else { + return expr.newInstance(row); + } + } + + @SuppressWarnings("unchecked") + private Object execute(Query query, boolean forCount) { + Object rv; + if (!orderedConstants.isEmpty()) { + rv = query.executeWithArray(orderedConstants.toArray()); + } else { + rv = query.execute(); + } + if (isDetach()) { + rv = detach(rv); + } + if (projection != null && !forCount) { + if (rv instanceof List) { + List<?> original = (List<?>) rv; + rv = new ArrayList<>(); + for (Object o : original) { + ((List) rv).add(project(projection, o)); + } + } else { + rv = project(projection, rv); + } + } + return rv; + } + + public boolean isDetach() { + return detach; + } + + @Override + public CloseableIterator<T> iterate() { + return new IteratorAdapter<T>(fetch().iterator(), closeable); + } + + @Override + @SuppressWarnings("unchecked") + public List<T> fetch() { + Object rv = execute(createQuery(false), false); + return rv instanceof List ? (List<T>) rv : Collections.singletonList((T) rv); + } + + @Override + @SuppressWarnings("unchecked") + public QueryResults<T> fetchResults() { + Query countQuery = createQuery(true); + countQuery.setUnique(true); + long total = (Long) execute(countQuery, true); + if (total > 0) { + QueryModifiers modifiers = queryMixin.getMetadata().getModifiers(); + Query query = createQuery(false); + return new QueryResults<T>((List<T>) execute(query, false), modifiers, total); + } else { + return QueryResults.emptyResults(); + } + } + + @Override + public String toString() { + if (!queryMixin.getMetadata().getJoins().isEmpty()) { + SQLSerializer serializer = new SQLSerializer(configuration); + serializer.serialize(queryMixin.getMetadata(), false); + return serializer.toString().trim(); + } else { + return super.toString(); + } + } + + @SuppressWarnings("unchecked") + @Override + @Nullable + public T fetchOne() throws NonUniqueResultException { + if (getMetadata().getModifiers().getLimit() == null) { + limit(2); + } + Query query = createQuery(false); + Object rv = execute(query, false); + if (rv instanceof List) { + List<?> list = (List<?>) rv; + if (!list.isEmpty()) { + if (list.size() > 1) { + throw new NonUniqueResultException(); + } + return (T) list.get(0); + } else { + return null; + } + } else { + return (T) rv; + } + } +} diff --git a/querydsl-jdo/src/main/java/com/querydsl/jdo/sql/JDOSQLQuery.java b/querydsl-jdo/src/main/java/com/querydsl/jdo/sql/JDOSQLQuery.java new file mode 100644 index 0000000000..bf2c34189e --- /dev/null +++ b/querydsl-jdo/src/main/java/com/querydsl/jdo/sql/JDOSQLQuery.java @@ -0,0 +1,81 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jdo.sql; + +import org.jetbrains.annotations.Nullable; +import javax.jdo.PersistenceManager; + +import com.querydsl.core.DefaultQueryMetadata; +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.Tuple; +import com.querydsl.core.types.Expression; +import com.querydsl.sql.Configuration; +import com.querydsl.sql.SQLQuery; +import com.querydsl.sql.SQLSerializer; +import com.querydsl.sql.SQLTemplates; + +/** + * {@code JDOSQLQuery} is a {@link SQLQuery} implementation that uses JDO's SQL query functionality + * to execute queries + * + * @author tiwe + * + * @param <T> result type + * + */ +public final class JDOSQLQuery<T> extends AbstractSQLQuery<T, JDOSQLQuery<T>> { + + public JDOSQLQuery(@Nullable PersistenceManager persistenceManager, SQLTemplates templates) { + this(persistenceManager, new Configuration(templates), new DefaultQueryMetadata(), false); + } + + public JDOSQLQuery(@Nullable PersistenceManager persistenceManager, Configuration configuration) { + this(persistenceManager, configuration, new DefaultQueryMetadata(), false); + } + + public JDOSQLQuery( + @Nullable PersistenceManager persistenceManager, + Configuration configuration, + QueryMetadata metadata, boolean detach) { + super(metadata, configuration, persistenceManager, detach); + } + + @Override + public JDOSQLQuery<T> clone() { + JDOSQLQuery<T> query = new JDOSQLQuery<T>(persistenceManager, configuration, getMetadata().clone(), detach); + query.clone(this); + return query; + } + + @Override + protected SQLSerializer createSerializer() { + return new SQLSerializer(configuration); + } + + @Override + public <U> JDOSQLQuery<U> select(Expression<U> expr) { + queryMixin.setProjection(expr); + @SuppressWarnings("unchecked") // This is the new type + JDOSQLQuery<U> newType = (JDOSQLQuery<U>) this; + return newType; + } + + @Override + public JDOSQLQuery<Tuple> select(Expression<?>... exprs) { + queryMixin.setProjection(exprs); + @SuppressWarnings("unchecked") // This is the new type + JDOSQLQuery<Tuple> newType = (JDOSQLQuery<Tuple>) this; + return newType; + } +} diff --git a/querydsl-jdo/src/main/java/com/querydsl/jdo/sql/package-info.java b/querydsl-jdo/src/main/java/com/querydsl/jdo/sql/package-info.java new file mode 100644 index 0000000000..c6c43c2bef --- /dev/null +++ b/querydsl-jdo/src/main/java/com/querydsl/jdo/sql/package-info.java @@ -0,0 +1,18 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ + +/** + * SQL queries for JDO + */ +package com.querydsl.jdo.sql; diff --git a/querydsl-jdo/src/test/java/com/mysema/query/JDOQueryStandardTest.java b/querydsl-jdo/src/test/java/com/mysema/query/JDOQueryStandardTest.java deleted file mode 100644 index 07d3d595c7..0000000000 --- a/querydsl-jdo/src/test/java/com/mysema/query/JDOQueryStandardTest.java +++ /dev/null @@ -1,220 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -import java.util.Calendar; -import java.util.Date; -import java.util.List; - -import javax.jdo.PersistenceManager; -import javax.jdo.Transaction; - -import org.junit.BeforeClass; -import org.junit.Ignore; -import org.junit.Test; - -import com.mysema.commons.lang.Pair; -import com.mysema.query.jdo.AbstractJDOTest; -import com.mysema.query.jdo.test.domain.Product; -import com.mysema.query.jdo.test.domain.QProduct; -import com.mysema.query.jdo.test.domain.QStore; -import com.mysema.query.jdo.test.domain.Store; -import com.mysema.query.types.ArrayConstructorExpression; -import com.mysema.query.types.ConstructorExpression; -import com.mysema.query.types.Expression; -import com.mysema.query.types.ParamNotSetException; -import com.mysema.query.types.Predicate; -import com.mysema.query.types.QTuple; -import com.mysema.query.types.expr.Param; - -public class JDOQueryStandardTest extends AbstractJDOTest { - - public static class Projection { - - public Projection(String str) {} - - } - - private static final Date publicationDate; - - private static final java.sql.Date date; - - private static final java.sql.Time time; - - static{ - Calendar cal = Calendar.getInstance(); - cal.set(2000, 1, 2, 3, 4); - cal.set(Calendar.MILLISECOND, 0); - publicationDate = cal.getTime(); - date = new java.sql.Date(cal.getTimeInMillis()); - time = new java.sql.Time(cal.getTimeInMillis()); - } - - private static String productName = "ABCD"; - - private static String otherName = "ABC0"; - - @BeforeClass - public static void doPersist() { - // Persistence of a Product and a Book. - PersistenceManager pm = pmf.getPersistenceManager(); - Transaction tx = pm.currentTransaction(); - try { - tx.begin(); - for (int i = 0; i < 10; i++) { - // Product instances - pm.makePersistent(new Product("ABC" + i, "F" + i, i * 200.00, 2, publicationDate)); - pm.makePersistent(new Product("DEF" + i, "E" + i, i * 200.00, 4, publicationDate)); - pm.makePersistent(new Product("GHI" + i, "D" + i, i * 200.00, 6, publicationDate)); - - // Product of Store - Product product = new Product(productName,"A",100.0,1, publicationDate); - pm.makePersistent(product); - - // Store instances - Store store = new Store(); - store.getProducts().add(product); - store.getProductsByName().put(productName, product); - pm.makePersistent(store); - } - tx.commit(); - } finally { - if (tx.isActive()) { - tx.rollback(); - } - pm.close(); - } - System.out.println(""); - - } - - private final QueryExecution standardTest = new QueryExecution(Module.JDO, Target.H2) { - @Override - protected Pair<Projectable, Expression<?>[]> createQuery() { - return Pair.of( - (Projectable)query().from(store, product, otherProduct), - new Expression<?>[]{store, product, otherProduct}); - } - @Override - protected Pair<Projectable, Expression<?>[]> createQuery(Predicate filter) { - return Pair.of( - (Projectable)query().from(store, product, otherProduct).where(filter), - new Expression<?>[]{store, product, otherProduct}); - } - }; - - private final QProduct product = QProduct.product; - - private final QProduct otherProduct = new QProduct("otherProduct"); - - private final QStore store = QStore.store; - - private final QStore otherStore = new QStore("otherStore"); - - @Test - public void StandardTest() { - Product p = query().from(product).where(product.name.eq(productName)).limit(1).uniqueResult(product); - Product p2 = query().from(product).where(product.name.startsWith(otherName)).limit(1).uniqueResult(product); - standardTest.noProjections(); - standardTest.noCounts(); - - standardTest.runBooleanTests(product.name.isNull(), otherProduct.price.lt(10.00)); - standardTest.runCollectionTests(store.products, otherStore.products, p, p2); - standardTest.runDateTests(product.dateField, otherProduct.dateField, date); - standardTest.runDateTimeTests(product.publicationDate, otherProduct.publicationDate, publicationDate); - // NO list support in JDOQL -// testData.listTests(store.products, otherStore.products, p); - standardTest.runMapTests(store.productsByName, otherStore.productsByName, productName, p, "X", p2); - standardTest.runNumericCasts(product.price, otherProduct.price, 200.0); - standardTest.runNumericTests(product.amount, otherProduct.amount, 2); - standardTest.runStringTests(product.name, otherProduct.name, productName); - standardTest.runTimeTests(product.timeField, otherProduct.timeField, time); - - standardTest.report(); - } - - @Test - public void TupleProjection() { - List<Tuple> tuples = query().from(product).list(new QTuple(product.name, product.price)); - assertFalse(tuples.isEmpty()); - for (Tuple tuple : tuples) { - assertNotNull(tuple); - assertNotNull(tuple.get(product.name)); - assertNotNull(tuple.get(product.price)); - assertNotNull(tuple.get(0,String.class)); - assertNotNull(tuple.get(1,Double.class)); - } - } - - @SuppressWarnings("unchecked") - @Test - @Ignore - public void ArrayProjection() { - // typed array not supported - List<String[]> results = query().from(store) - .list(new ArrayConstructorExpression<String>(String[].class, store.name)); - assertFalse(results.isEmpty()); - for (String[] result : results) { - assertNotNull(result); - assertNotNull(result[0]); - } - } - - @Test - @Ignore - public void ConstructorProjection() { - List<Projection> results = query().from(store) - .list(ConstructorExpression.create(Projection.class, store.name)); - assertFalse(results.isEmpty()); - for (Projection result : results) { - assertNotNull(result); - } - } - - @Test - public void Params() { - Param<String> name = new Param<String>(String.class,"name"); - assertEquals("ABC0",query().from(product).where(product.name.eq(name)).set(name, "ABC0") - .uniqueResult(product.name)); - } - - @Test - public void Params_anon() { - Param<String> name = new Param<String>(String.class); - assertEquals("ABC0",query().from(product).where(product.name.eq(name)).set(name, "ABC0") - .uniqueResult(product.name)); - } - - @Test(expected=ParamNotSetException.class) - public void Params_not_set() { - Param<String> name = new Param<String>(String.class,"name"); - assertEquals("ABC0",query().from(product).where(product.name.eq(name)) - .uniqueResult(product.name)); - } - - @Test - public void Exists() { - assertTrue(query().from(product).where(product.name.eq("ABC0")).exists()); - } - - @Test - public void NotExists() { - assertTrue(query().from(product).where(product.name.eq("XXX")).notExists()); - } -} diff --git a/querydsl-jdo/src/test/java/com/mysema/query/PackageVerification.java b/querydsl-jdo/src/test/java/com/mysema/query/PackageVerification.java deleted file mode 100644 index 61cbc40b7f..0000000000 --- a/querydsl-jdo/src/test/java/com/mysema/query/PackageVerification.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import java.io.File; -import java.net.URL; -import java.net.URLClassLoader; - -import javax.jdo.annotations.PersistenceCapable; - -import org.junit.Test; - -import com.google.common.base.Charsets; -import com.google.common.io.Resources; -import com.mysema.codegen.CodeWriter; -import com.mysema.query.apt.jdo.JDOAnnotationProcessor; -import com.mysema.query.codegen.CodegenModule; -import com.mysema.query.types.Expression; - -public class PackageVerification { - - @Test - public void Verify_Package() throws Exception{ - String version = System.getProperty("version"); - verify(new File("target/querydsl-jdo-"+version+"-apt-one-jar.jar")); - } - - private void verify(File oneJar) throws Exception { - assertTrue(oneJar.getPath() + " doesn't exist", oneJar.exists()); - // verify classLoader - URLClassLoader oneJarClassLoader = new URLClassLoader(new URL[]{oneJar.toURI().toURL()}); - oneJarClassLoader.loadClass(Expression.class.getName()); // querydsl-core - oneJarClassLoader.loadClass(CodeWriter.class.getName()); // codegen - oneJarClassLoader.loadClass(CodegenModule.class.getName()).newInstance(); - oneJarClassLoader.loadClass(PersistenceCapable.class.getName()); // jdo - Class cl = oneJarClassLoader.loadClass(JDOAnnotationProcessor.class.getName()); // querydsl-apt - cl.newInstance(); - String resourceKey = "META-INF/services/javax.annotation.processing.Processor"; - assertEquals(JDOAnnotationProcessor.class.getName(), - Resources.toString(oneJarClassLoader.findResource(resourceKey), Charsets.UTF_8)); - } - -} diff --git a/querydsl-jdo/src/test/java/com/mysema/query/jdo/AbstractJDOTest.java b/querydsl-jdo/src/test/java/com/mysema/query/jdo/AbstractJDOTest.java deleted file mode 100644 index f4934ebf36..0000000000 --- a/querydsl-jdo/src/test/java/com/mysema/query/jdo/AbstractJDOTest.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jdo; - -import java.util.List; - -import javax.jdo.JDOHelper; -import javax.jdo.PersistenceManager; -import javax.jdo.PersistenceManagerFactory; -import javax.jdo.Transaction; - -import org.junit.After; -import org.junit.AfterClass; -import org.junit.Before; - -import com.mysema.query.jdo.dml.JDODeleteClause; -import com.mysema.query.jdo.test.domain.Book; -import com.mysema.query.jdo.test.domain.Product; -import com.mysema.query.jdo.test.domain.Store; -import com.mysema.query.types.EntityPath; -import com.mysema.query.types.Predicate; - -public abstract class AbstractJDOTest { - - private static final JDOQLTemplates templates = new JDOQLTemplates(); - - protected static final PersistenceManagerFactory pmf = - JDOHelper.getPersistenceManagerFactory("datanucleus.properties"); - - protected PersistenceManager pm; - - protected Transaction tx; - - protected JDOQuery query() { - return new JDOQuery(pm, templates, false); - } - - protected JDOQuery detachedQuery() { - return new JDOQuery(pm, templates, true); - } - - protected JDOSubQuery sub() { - return new JDOSubQuery(); - } - - protected <T> List<T> query(EntityPath<T> source, Predicate condition) { - return query().from(source).where(condition).list(source); - } - - protected JDODeleteClause delete(EntityPath<?> entity) { - return new JDODeleteClause(pm, entity, templates); - } - - @Before - public void setUp() { - pm = pmf.getPersistenceManager(); - tx = pm.currentTransaction(); - tx.begin(); - } - - @After - public void tearDown() { - if (tx.isActive()) { - tx.rollback(); - } - pm.close(); - } - - @AfterClass - public static void doCleanUp() { - // Clean out the database - PersistenceManager pm = pmf.getPersistenceManager(); - Transaction tx = pm.currentTransaction(); - try { - tx.begin(); - pm.newQuery(Store.class).deletePersistentAll(); - pm.newQuery(Book.class).deletePersistentAll(); - pm.newQuery(Product.class).deletePersistentAll(); - tx.commit(); - } finally { - if (tx.isActive()) { - tx.rollback(); - } - pm.close(); - } - } - -} diff --git a/querydsl-jdo/src/test/java/com/mysema/query/jdo/AggregateTest.java b/querydsl-jdo/src/test/java/com/mysema/query/jdo/AggregateTest.java deleted file mode 100644 index 94dbf5610c..0000000000 --- a/querydsl-jdo/src/test/java/com/mysema/query/jdo/AggregateTest.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jdo; - -import static org.junit.Assert.assertEquals; - -import javax.jdo.PersistenceManager; -import javax.jdo.Transaction; - -import org.junit.BeforeClass; -import org.junit.Test; - -import com.mysema.query.jdo.test.domain.Product; -import com.mysema.query.jdo.test.domain.QProduct; - -public class AggregateTest extends AbstractJDOTest{ - - private final QProduct product = QProduct.product; - - @Test - public void Unique() { - double min = 200.00, avg = 400.00, max = 600.00; - assertEquals(Double.valueOf(min), query().from(product).uniqueResult(product.price.min())); - assertEquals(Double.valueOf(avg), query().from(product).uniqueResult(product.price.avg())); - assertEquals(Double.valueOf(max), query().from(product).uniqueResult(product.price.max())); - } - - @Test - public void List() { - double min = 200.00, avg = 400.00, max = 600.00; - assertEquals(Double.valueOf(min), query().from(product).list(product.price.min()).get(0)); - assertEquals(Double.valueOf(avg), query().from(product).list(product.price.avg()).get(0)); - assertEquals(Double.valueOf(max), query().from(product).list(product.price.max()).get(0)); - } - - @BeforeClass - public static void doPersist() { - // Persistence of a Product and a Book. - PersistenceManager pm = pmf.getPersistenceManager(); - Transaction tx = pm.currentTransaction(); - try { - tx.begin(); - for (int i = 0; i < 10; i++) { - pm.makePersistent(new Product("C" + i, "F", 200.00, 2)); - pm.makePersistent(new Product("B" + i, "E", 400.00, 4)); - pm.makePersistent(new Product("A" + i, "D", 600.00, 6)); - } - tx.commit(); - } finally { - if (tx.isActive()) { - tx.rollback(); - } - pm.close(); - } - System.out.println(""); - - } - -} diff --git a/querydsl-jdo/src/test/java/com/mysema/query/jdo/BasicsTest.java b/querydsl-jdo/src/test/java/com/mysema/query/jdo/BasicsTest.java deleted file mode 100644 index ba38935797..0000000000 --- a/querydsl-jdo/src/test/java/com/mysema/query/jdo/BasicsTest.java +++ /dev/null @@ -1,273 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jdo; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; - -import java.io.IOException; - -import javax.jdo.PersistenceManager; -import javax.jdo.Transaction; - -import com.mysema.query.types.Projections; -import org.junit.BeforeClass; -import org.junit.Ignore; -import org.junit.Test; - -import com.mysema.query.BooleanBuilder; -import com.mysema.query.NonUniqueResultException; -import com.mysema.query.jdo.test.domain.Book; -import com.mysema.query.jdo.test.domain.Product; -import com.mysema.query.jdo.test.domain.QBook; -import com.mysema.query.jdo.test.domain.QProduct; -import com.mysema.query.types.Expression; - -public class BasicsTest extends AbstractJDOTest { - - private static final JDOQLTemplates templates = new JDOQLTemplates(); - - private final QBook book = QBook.book; - - private final QProduct product = QProduct.product; - - private final QProduct product2 = new QProduct("product2"); - - @Test - public void Serialization() throws IOException{ - JDOQuery query = query(); - - assertEquals("FROM com.mysema.query.jdo.test.domain.Product", query.from(product).toString()); - assertEquals("FROM com.mysema.query.jdo.test.domain.Product" + - "\nVARIABLES com.mysema.query.jdo.test.domain.Product product2", - query.from(product2).toString()); - - query.where(product.ne(product2)).list(product, product2); - query.close(); - } - - @Test - public void SubQuerySerialization() throws IOException{ - JDOSubQuery query = sub(); - - assertEquals("FROM com.mysema.query.jdo.test.domain.Product", query.from(product).toString()); - assertEquals("FROM com.mysema.query.jdo.test.domain.Product" + - "\nVARIABLES com.mysema.query.jdo.test.domain.Product product2", - query.from(product2).toString()); - - } - - @Test - public void Delete() { - long count = query().from(product).count(); - assertEquals(0, delete(product).where(product.name.eq("XXX")).execute()); - assertEquals(count, delete(product).execute()); - } - - @Test - public void CountTests() { - assertEquals("count", 2, query().from(product).count()); - } - - @Test - public void List_Distinct() { - query().from(product).distinct().list(product); - } - - @Test - public void List_Distinct_Two_Sources() { - query().from(product, product2).distinct().list(product, product2); - } - - @Test - public void Single_Result() { - query().from(product).singleResult(product); - } - - @Test - public void Single_Result_With_Array() { - query().from(product).singleResult(new Expression<?>[]{product}); - } - - @Test - public void FactoryExpression_In_GroupBy() { - Expression<Product> productBean = Projections.bean(Product.class, product.name, product.description); - assertFalse(query().from(product).groupBy(productBean).list(productBean).isEmpty()); - } - - @Test(expected=NonUniqueResultException.class) - public void Unique_Result_Throws_Exception_On_Multiple_Results() { - query().from(product).uniqueResult(product); - } - - @Test - public void SimpleTest() throws IOException{ - JDOQuery query = new JDOQuery(pm, templates, false); - assertEquals("Sony Discman", query.from(product).where(product.name.eq("Sony Discman")) - .uniqueResult(product.name)); - query.close(); - } - - @Test - public void ProjectionTests() { - assertEquals("Sony Discman", query().from(product).where(product.name.eq("Sony Discman")) - .uniqueResult(product.name)); - } - - @Test - public void BasicTests() { - assertEquals("list", 2, query().from(product).list(product).size()); - assertEquals("list", 2, query().from(product).list(product.name,product.description).size()); - assertEquals("list", 1, query().from(book).list(book).size()); - assertEquals("eq", 1, query(product, product.name.eq("Sony Discman")).size()); - assertEquals("instanceof ", 1, query(product,product.instanceOf(Book.class)).size()); - } - - @Test - @Ignore - public void DetachedResults() { - for (Product p : detachedQuery().from(product).list(product)) { - System.out.println(p); - } - } - - @Test - public void Empty_BooleanBuilder() { - assertEquals("empty boolean builder", 2, query(product, new BooleanBuilder()).size()); - } - - @Test - public void And() { - assertEquals("and", 1, query(product, product.name.eq("Sony Discman").and(product.price.loe(300.00))).size()); - } - - @Test - public void Or() { - assertEquals("or", 2, query(product, product.name.eq("Sony Discman").or(product.price.loe(300.00))).size()); - } - - @Test - public void Not() { - assertEquals("not", 2, query(product, product.name.eq("Sony MP3 player").not()).size()); - } - - @Test - public void NumericTests() { - // numeric - // TODO + - // TODO - - // TODO * - // TODO / - // TODO % - // TODO Math.abs - // TODO Math.sqrt - } - - @Test - public void Eq() { - assertEquals("eq", 1, query(product, product.price.eq(200.00)).size()); - assertEquals("eq", 0, query(product, product.price.eq(100.00)).size()); - } - - @Test - public void Ne() { - assertEquals("ne", 2, query(product, product.price.ne(100.00)).size()); - } - - @Test - public void Lt() { - assertEquals("lt", 2, query(product, product.price.lt(300.00)).size()); - } - - @Test - public void Gt() { - assertEquals("gt", 1, query(product, product.price.gt(100.00)).size()); - } - - @Test - public void Goe() { - assertEquals("goe", 1, query(product, product.price.goe(100.00)).size()); - } - - @Test - public void Loe() { - assertEquals("loe", 2, query(product, product.price.loe(300.00)).size()); - } - - @Test - public void Starts_With() { - assertEquals("startsWith", 1, query(product,product.name.startsWith("Sony Discman")).size()); - } - - @Test - public void Matches() { - assertEquals("matches", 1, query(product,product.name.matches("Sony.*")).size()); - } - - @Test - public void Like() { - assertEquals("matches", 1, query(product,product.name.like("Sony%")).size()); - } - - @Test - public void Ends_With() { - assertEquals("endsWith", 1, query(product,product.name.endsWith("Discman")).size()); - } - - @Test - public void To_LowerCase() { - assertEquals("toLowerCase", 1, query(product,product.name.lower().eq("sony discman")).size()); - } - - @Test - public void To_UpperCase() { - assertEquals("toUpperCase", 1, query(product,product.name.upper().eq("SONY DISCMAN")).size()); - } - - @Test - public void Index_Of() { - assertEquals("indexOf", 1, query(product,product.name.indexOf("S").eq(0)).size()); - } - - @Test - public void Substring1() { - assertEquals("substring", 1, query(product,product.name.substring(5).eq("Discman")).size()); - } - - @Test - public void Substring2() { - assertEquals("substring", 1, query(product,product.name.substring(0, 4).eq("Sony")).size()); - } - - @BeforeClass - public static void doPersist() { - // Persistence of a Product and a Book. - PersistenceManager pm = pmf.getPersistenceManager(); - Transaction tx = pm.currentTransaction(); - try { - tx.begin(); - pm.makePersistent(new Product("Sony Discman","A standard discman from Sony", 200.00, 3)); - pm.makePersistent(new Book("Lord of the Rings by Tolkien","The classic story", 49.99, 5, "JRR Tolkien", "12345678","MyBooks Factory")); - tx.commit(); - } finally { - if (tx.isActive()) { - tx.rollback(); - } - pm.close(); - } - System.out.println(""); - - } - -} diff --git a/querydsl-jdo/src/test/java/com/mysema/query/jdo/CollectionTest.java b/querydsl-jdo/src/test/java/com/mysema/query/jdo/CollectionTest.java deleted file mode 100644 index ee8020eeb6..0000000000 --- a/querydsl-jdo/src/test/java/com/mysema/query/jdo/CollectionTest.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jdo; - -import javax.jdo.PersistenceManager; -import javax.jdo.Transaction; - -import org.junit.BeforeClass; -import org.junit.Ignore; -import org.junit.Test; - -import com.mysema.query.jdo.test.domain.Book; -import com.mysema.query.jdo.test.domain.Product; -import com.mysema.query.jdo.test.domain.QProduct; -import com.mysema.query.jdo.test.domain.QStore; - -public class CollectionTest extends AbstractJDOTest { - - private final QStore store = QStore.store; - - @Test - public void Contains_Key() { - query(store, store.productsByName.containsKey("XXX")); - } - - @Test - public void Contains_Value() { - Product product = query().from(QProduct.product).list(QProduct.product).get(0); - query(store, store.productsByName.containsValue(product)); - } - - @Test - @Ignore - public void Get() { - query(store, store.products.get(0).name.isNotNull()); - } - - @Test - public void isEmpty() { - query(store, store.products.isEmpty()); - } - - @Test - public void isNotEmpty() { - query(store, store.products.isNotEmpty()); - } - - @Test - public void Size() { - query(store, store.products.size().gt(0)); - } - - @Test - public void Collection_Any() { - query(store, store.products.any().name.eq("Sony Discman")); - } - - @Test - public void Collection_Any_And() { - query(store, store.products.any().name.eq("Sony Discman").and(store.products.any().price.gt(10.0))); - } - - @Test - @Ignore // Not supported - public void Collection_Any_In_Projection() { - query().from(store).list(store.products.any()); - } - - @BeforeClass - public static void doPersist() { - // Persistence of a Product and a Book. - PersistenceManager pm = pmf.getPersistenceManager(); - Transaction tx = pm.currentTransaction(); - try { - tx.begin(); - pm.makePersistent(new Product("Sony Discman","A standard discman from Sony", 200.00, 3)); - pm.makePersistent(new Book("Lord of the Rings by Tolkien","The classic story", 49.99, 5, "JRR Tolkien", "12345678","MyBooks Factory")); - tx.commit(); - } finally { - if (tx.isActive()) { - tx.rollback(); - } - pm.close(); - } - System.out.println(""); - - } - -} diff --git a/querydsl-jdo/src/test/java/com/mysema/query/jdo/DependenciesTest.java b/querydsl-jdo/src/test/java/com/mysema/query/jdo/DependenciesTest.java deleted file mode 100644 index be4d64c523..0000000000 --- a/querydsl-jdo/src/test/java/com/mysema/query/jdo/DependenciesTest.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jdo; - -import static org.junit.Assert.assertFalse; - -import java.io.IOException; - -import jdepend.framework.JDepend; - -import org.junit.Ignore; -import org.junit.Test; - -public class DependenciesTest { - - @Test - @Ignore - public void test() throws IOException{ - JDepend jdepend = new JDepend(); - jdepend.addDirectory("target/classes/com/mysema/query/jdo"); - jdepend.addDirectory("target/classes/com/mysema/query/jdo/dml"); - jdepend.addDirectory("target/classes/com/mysema/query/jdo/sql"); - - jdepend.analyze(); - assertFalse(jdepend.containsCycles()); - - } - -} diff --git a/querydsl-jdo/src/test/java/com/mysema/query/jdo/FetchPlanTest.java b/querydsl-jdo/src/test/java/com/mysema/query/jdo/FetchPlanTest.java deleted file mode 100644 index c0dc45362f..0000000000 --- a/querydsl-jdo/src/test/java/com/mysema/query/jdo/FetchPlanTest.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jdo; - -import static org.junit.Assert.assertEquals; - -import java.lang.reflect.Field; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; - -import javax.jdo.PersistenceManager; -import javax.jdo.Query; -import javax.jdo.Transaction; - -import org.junit.After; -import org.junit.BeforeClass; -import org.junit.Test; - -import com.mysema.query.jdo.test.domain.Product; -import com.mysema.query.jdo.test.domain.QProduct; -import com.mysema.query.jdo.test.domain.QStore; - -public class FetchPlanTest extends AbstractJDOTest{ - - private JDOQuery query; - - @After - public void tearDown() { - if (query != null) { - query.close(); - } - super.tearDown(); - } - - @SuppressWarnings("unchecked") - @Test - public void ListProducts() throws Exception{ - QProduct product = QProduct.product; - query = query(); - query.from(product) - .where(product.name.startsWith("A")) - .addFetchGroup("myfetchgroup1") - .addFetchGroup("myfetchgroup2") - .setMaxFetchDepth(2) - .list(product); -// query.close(); - - Field queriesField = AbstractJDOQuery.class.getDeclaredField("queries"); - queriesField.setAccessible(true); - List<Query> queries = (List<Query>)queriesField.get(query); - Query jdoQuery = queries.get(0); - assertEquals(new HashSet<String>(Arrays.asList("myfetchgroup1","myfetchgroup2")), - jdoQuery.getFetchPlan().getGroups()); - assertEquals(2, jdoQuery.getFetchPlan().getMaxFetchDepth()); - } - - @SuppressWarnings("unchecked") - @Test - public void ListStores() throws Exception{ - QStore store = QStore.store; - query = query(); - query.from(store) - .addFetchGroup("products") - .list(store); - - Field queriesField = AbstractJDOQuery.class.getDeclaredField("queries"); - queriesField.setAccessible(true); - List<Query> queries = (List<Query>)queriesField.get(query); - Query jdoQuery = queries.get(0); - assertEquals(new HashSet<String>(Arrays.asList("products")), - jdoQuery.getFetchPlan().getGroups()); - assertEquals(1, jdoQuery.getFetchPlan().getMaxFetchDepth()); - } - - @BeforeClass - public static void doPersist() { - PersistenceManager pm = pmf.getPersistenceManager(); - Transaction tx = pm.currentTransaction(); - try { - tx.begin(); - for (int i = 0; i < 10; i++) { - pm.makePersistent(new Product("C" + i, "F", 200.00, 2)); - pm.makePersistent(new Product("B" + i, "E", 400.00, 4)); - pm.makePersistent(new Product("A" + i, "D", 600.00, 6)); - } - tx.commit(); - } finally { - if (tx.isActive()) { - tx.rollback(); - } - pm.close(); - } - System.out.println(""); - - } - -} diff --git a/querydsl-jdo/src/test/java/com/mysema/query/jdo/GroupByTest.java b/querydsl-jdo/src/test/java/com/mysema/query/jdo/GroupByTest.java deleted file mode 100644 index 9fc8912329..0000000000 --- a/querydsl-jdo/src/test/java/com/mysema/query/jdo/GroupByTest.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jdo; - -import static org.junit.Assert.assertEquals; - -import javax.jdo.PersistenceManager; -import javax.jdo.Transaction; - -import org.junit.BeforeClass; -import org.junit.Test; - -import com.mysema.query.jdo.test.domain.Product; -import com.mysema.query.jdo.test.domain.QProduct; - -public class GroupByTest extends AbstractJDOTest { - - private QProduct product = QProduct.product; - - @Test - public void Distinct() { - assertEquals(3, query().from(product).distinct().list(product.description).size()); - assertEquals(3, query().from(product).distinct().list(product.price).size()); - } - - @Test - public void GroupBy() { - assertEquals(3, query().from(product).groupBy(product.description).list(product.description).size()); - assertEquals(3, query().from(product).groupBy(product.price).list(product.price).size()); - } - - @Test - public void Having() { - assertEquals(3, query().from(product) - .groupBy(product.description).having(product.description.ne("XXX")) - .list(product.description).size()); - assertEquals(3, query().from(product) - .groupBy(product.price).having(product.price.gt(0)) - .list(product.price).size()); - } - - @BeforeClass - public static void doPersist() { - PersistenceManager pm = pmf.getPersistenceManager(); - Transaction tx = pm.currentTransaction(); - try { - tx.begin(); - for (int i = 0; i < 10; i++) { - pm.makePersistent(new Product("C" + i, "F", 200.00, 2)); - pm.makePersistent(new Product("B" + i, "E", 400.00, 4)); - pm.makePersistent(new Product("A" + i, "D", 600.00, 6)); - } - tx.commit(); - } finally { - if (tx.isActive()) { - tx.rollback(); - } - pm.close(); - } - System.out.println(""); - - } - -} diff --git a/querydsl-jdo/src/test/java/com/mysema/query/jdo/JDOQLMethodsTest.java b/querydsl-jdo/src/test/java/com/mysema/query/jdo/JDOQLMethodsTest.java deleted file mode 100644 index a83696aafd..0000000000 --- a/querydsl-jdo/src/test/java/com/mysema/query/jdo/JDOQLMethodsTest.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jdo; - -import java.util.Arrays; -import java.util.List; - -import javax.jdo.PersistenceManager; -import javax.jdo.Transaction; - -import org.junit.BeforeClass; -import org.junit.Test; - -import com.mysema.query.jdo.test.domain.Product; -import com.mysema.query.jdo.test.domain.QProduct; -import com.mysema.query.jdo.test.domain.QStore; -import com.mysema.query.types.expr.BooleanExpression; -import com.mysema.query.types.expr.NumberExpression; -import com.mysema.query.types.expr.StringExpression; -import com.mysema.query.types.path.ListPath; -import com.mysema.query.types.path.MapPath; - -public class JDOQLMethodsTest extends AbstractJDOTest { - - private QProduct product = QProduct.product; - - private QStore store = QStore.store; - - @Test - public void test() { - Product p = query().from(product).limit(1).uniqueResult(product); - for (BooleanExpression f : getFilters( - product.name, product.description, "A0", - store.products, p, - store.productsByName, "A0", p, - product.amount)) { - query().from(store, product).where(f).list(store, product); - } - } - - private <A,K,V> List<BooleanExpression> getFilters( - StringExpression str, StringExpression other, String knownString, - ListPath<A,?> list, A element, - MapPath<K,V, ?> map, K key, V value, - NumberExpression<Integer> number) { - return Arrays.<BooleanExpression>asList( - // java.lang.String - str.startsWith(knownString), - str.endsWith(knownString), - str.indexOf(knownString).gt(-1), - str.indexOf(knownString, 1).gt(-1), - str.substring(1).eq(knownString), - str.substring(1,2).eq(knownString), - str.lower().eq(knownString), - str.upper().eq(knownString), - str.matches(".*"), - // java.util.Collection - list.isEmpty(), - list.isNotEmpty(), - list.contains(element), - list.size().gt(0), - // java.util.Map - map.isEmpty(), - map.isNotEmpty(), - map.containsKey(key), - map.containsValue(value), - map.get(key).eq(value), - map.size().gt(0), - number.abs().gt(0), - number.sqrt().gt(0) - ); - } - - @BeforeClass - public static void doPersist() { - // Persistence of a Product and a Book. - PersistenceManager pm = pmf.getPersistenceManager(); - Transaction tx = pm.currentTransaction(); - try { - tx.begin(); - for (int i = 0; i < 10; i++) { - pm.makePersistent(new Product("C" + i, "F" + i, i * 200.00, 2)); - pm.makePersistent(new Product("B" + i, "E" + i, i * 200.00, 4)); - pm.makePersistent(new Product("A" + i, "D" + i, i * 200.00, 6)); - } - tx.commit(); - } finally { - if (tx.isActive()) { - tx.rollback(); - } - pm.close(); - } - System.out.println(""); - - } -} diff --git a/querydsl-jdo/src/test/java/com/mysema/query/jdo/JDOQueryFactoryTest.java b/querydsl-jdo/src/test/java/com/mysema/query/jdo/JDOQueryFactoryTest.java deleted file mode 100644 index 34381e8d35..0000000000 --- a/querydsl-jdo/src/test/java/com/mysema/query/jdo/JDOQueryFactoryTest.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jdo; - -import static org.junit.Assert.assertNotNull; - -import javax.inject.Provider; -import javax.jdo.PersistenceManager; - -import org.easymock.EasyMock; -import org.junit.Before; -import org.junit.Test; - -import com.mysema.query.jdo.test.domain.QProduct; - -public class JDOQueryFactoryTest { - - private JDOQueryFactory queryFactory; - - @Before - public void setUp() { - Provider<PersistenceManager> provider = new Provider<PersistenceManager>() { - @Override - public PersistenceManager get() { - return EasyMock.createNiceMock(PersistenceManager.class); - } - }; - queryFactory = new JDOQueryFactory(provider); - } - - @Test - public void Query() { - assertNotNull(queryFactory.query()); - } - - @Test - public void SubQuery() { - assertNotNull(queryFactory.subQuery()); - } - - @Test - public void From() { - assertNotNull(queryFactory.from(QProduct.product)); - } - - @Test - public void Delete() { - assertNotNull(queryFactory.delete(QProduct.product)); - } - -} diff --git a/querydsl-jdo/src/test/java/com/mysema/query/jdo/JDOSQLQueryTest.java b/querydsl-jdo/src/test/java/com/mysema/query/jdo/JDOSQLQueryTest.java deleted file mode 100644 index 8efdd20c95..0000000000 --- a/querydsl-jdo/src/test/java/com/mysema/query/jdo/JDOSQLQueryTest.java +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jdo; - -import javax.jdo.PersistenceManager; -import javax.jdo.Transaction; -import java.sql.SQLException; -import java.util.List; - -import com.mysema.query.NonUniqueResultException; -import com.mysema.query.SearchResults; -import com.mysema.query.Tuple; -import com.mysema.query.jdo.sql.JDOSQLQuery; -import com.mysema.query.jdo.test.domain.Product; -import com.mysema.query.jdo.test.domain.sql.SProduct; -import com.mysema.query.sql.HSQLDBTemplates; -import com.mysema.query.sql.SQLSubQuery; -import com.mysema.query.sql.SQLTemplates; -import com.mysema.query.types.ConstructorExpression; -import com.mysema.query.types.Expression; -import com.mysema.query.types.SubQueryExpression; -import com.mysema.query.types.expr.BooleanExpression; -import org.junit.BeforeClass; -import org.junit.Ignore; -import org.junit.Test; -import static org.junit.Assert.*; - -public class JDOSQLQueryTest extends AbstractJDOTest{ - - private final SQLTemplates sqlTemplates = new HSQLDBTemplates(); - - private final SProduct product = SProduct.product; - - private JDOSQLQuery sql() { - return new JDOSQLQuery(pm, sqlTemplates); - } - - protected SQLSubQuery sq() { - return new SQLSubQuery(); - } - - - @Test - public void Count() { - assertEquals(30l, sql().from(product).count()); - } - - @Test(expected=NonUniqueResultException.class) - public void UniqueResult() { - sql().from(product).uniqueResult(product.name); - } - - @Test - public void SingleResult() { - sql().from(product).singleResult(product.name); - } - - @Test - public void SingleResult_With_Array() { - sql().from(product).singleResult(new Expression[]{product.name}); - } - - @Test - public void StartsWith_Count() { - assertEquals(10l, sql().from(product).where(product.name.startsWith("A")).count()); - assertEquals(10l, sql().from(product).where(product.name.startsWith("B")).count()); - assertEquals(10l, sql().from(product).where(product.name.startsWith("C")).count()); - - } - - @Test - public void Eq_Count() { - for (int i = 0; i < 10; i++) { - assertEquals(1l, sql().from(product).where(product.name.eq("A"+i)).count()); - assertEquals(1l, sql().from(product).where(product.name.eq("B"+i)).count()); - assertEquals(1l, sql().from(product).where(product.name.eq("C"+i)).count()); - } - } - - @Test - public void ScalarQueries() { - BooleanExpression filter = product.name.startsWith("A"); - - // count - assertEquals(10l, sql().from(product).where(filter).count()); - - // countDistinct - assertEquals(10l, sql().from(product).where(filter).distinct().count()); - - // list - assertEquals(10, sql().from(product).where(filter).list(product.name).size()); - - // list with limit - assertEquals(3, sql().from(product).limit(3).list(product.name).size()); - - // list with offset -// assertEquals(7, sql().from(product).offset(3).list(product.name).size()); - - // list with limit and offset - assertEquals(3, sql().from(product).offset(3).limit(3).list(product.name).size()); - - // list multiple - for (Tuple row : sql().from(product).list(product.productId, product.name, product.amount)) { - assertNotNull(row.get(0, Object.class)); - assertNotNull(row.get(1, Object.class)); - assertNotNull(row.get(2, Object.class)); - } - - // listResults - SearchResults<String> results = sql().from(product).limit(3).listResults(product.name); - assertEquals(3, results.getResults().size()); - assertEquals(30l, results.getTotal()); - - } - - @Ignore - @Test - @SuppressWarnings("unchecked") - public void Union() throws SQLException { - SubQueryExpression<Integer> sq1 = sq().from(product).unique(product.amount.max()); - SubQueryExpression<Integer> sq2 = sq().from(product).unique(product.amount.min()); - List<Integer> list = sql().union(sq1, sq2).list(); - assertFalse(list.isEmpty()); - } - - @Ignore - @Test - @SuppressWarnings("unchecked") - public void Union_All() { - SubQueryExpression<Integer> sq1 = sq().from(product).unique(product.amount.max()); - SubQueryExpression<Integer> sq2 = sq().from(product).unique(product.amount.min()); - List<Integer> list = sql().unionAll(sq1, sq2).list(); - assertFalse(list.isEmpty()); - } - - @Test - public void EntityProjections() { - List<Product> products = sql() - .from(product) - .list(ConstructorExpression.create(Product.class, - product.name, product.description, product.price, product.amount)); - assertEquals(30, products.size()); - for (Product p : products) { - assertNotNull(p.getName()); - assertNotNull(p.getDescription()); - assertNotNull(p.getPrice()); - assertNotNull(p.getAmount()); - } - } - - @BeforeClass - public static void doPersist() { - // Persistence of a Product and a Book. - PersistenceManager pm = pmf.getPersistenceManager(); - Transaction tx = pm.currentTransaction(); - try { - tx.begin(); - for (int i = 0; i < 10; i++) { - pm.makePersistent(new Product("C" + i, "F", 200.00, 2)); - pm.makePersistent(new Product("B" + i, "E", 400.00, 4)); - pm.makePersistent(new Product("A" + i, "D", 600.00, 6)); - } - tx.commit(); - } finally { - if (tx.isActive()) { - tx.rollback(); - } - pm.close(); - } - System.out.println(""); - - } - -} diff --git a/querydsl-jdo/src/test/java/com/mysema/query/jdo/JDOSubQueryTest.java b/querydsl-jdo/src/test/java/com/mysema/query/jdo/JDOSubQueryTest.java deleted file mode 100644 index f0d3043d66..0000000000 --- a/querydsl-jdo/src/test/java/com/mysema/query/jdo/JDOSubQueryTest.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jdo; - -import static org.junit.Assert.assertEquals; - -import org.junit.Test; - -import com.mysema.query.jdo.test.domain.QProduct; - -public class JDOSubQueryTest { - - @Test - public void Multiple_Projections() { - JDOSubQuery query = new JDOSubQuery(); - query.from(QProduct.product); - assertEquals(1, query.list(QProduct.product).getMetadata().getProjection().size()); - assertEquals(1, query.list(QProduct.product).getMetadata().getProjection().size()); - } - -} diff --git a/querydsl-jdo/src/test/java/com/mysema/query/jdo/OrderingTest.java b/querydsl-jdo/src/test/java/com/mysema/query/jdo/OrderingTest.java deleted file mode 100644 index df96122d9e..0000000000 --- a/querydsl-jdo/src/test/java/com/mysema/query/jdo/OrderingTest.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jdo; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import java.util.Arrays; -import java.util.List; - -import javax.jdo.PersistenceManager; -import javax.jdo.Transaction; - -import org.junit.BeforeClass; -import org.junit.Test; - -import com.mysema.query.SearchResults; -import com.mysema.query.Tuple; -import com.mysema.query.jdo.test.domain.Product; -import com.mysema.query.jdo.test.domain.QProduct; - -public class OrderingTest extends AbstractJDOTest { - - private QProduct product = QProduct.product; - - @Test - public void Order_Asc() { - List<String> namesAsc = query().from(product).orderBy( - product.name.asc(), product.description.desc()).list( - product.name); - assertEquals(30, namesAsc.size()); - String prev = null; - for (String name : namesAsc) { - if (prev != null) { - assertTrue(prev.compareTo(name) < 0); - } - prev = name; - } - } - - @Test - public void Order_Desc() { - List<String> namesDesc = query().from(product).orderBy( - product.name.desc()).list(product.name); - assertEquals(30, namesDesc.size()); - String prev = null; - for (String name : namesDesc) { - if (prev != null) { - assertTrue(prev.compareTo(name) > 0); - } - prev = name; - } - } - - @Test - public void TabularResults() { - List<Tuple> rows = query().from(product).orderBy(product.name.asc()) - .list(product.name, product.description); - assertEquals(30, rows.size()); - for (Tuple row : rows) { - assertEquals(row.get(0, String.class).substring(1), - row.get(1, String.class).substring(1)); - } - } - - @Test - public void Limit_Order_Asc() { - assertEquals(Arrays.asList("A0", "A1"), - query().from(product).orderBy(product.name.asc()).limit(2).list(product.name)); - } - - @Test - public void Limit_Order_Desc() { - assertEquals(Arrays.asList("C9", "C8"), - query().from(product).orderBy(product.name.desc()).limit(2).list(product.name)); - } - - public void Limit_and_Offset() { - assertEquals(Arrays.asList("A2", "A3", "A4"), - query().from(product).orderBy(product.name.asc()).offset(2).limit(3).list(product.name)); - } - - @Test - public void SearchResults() { - SearchResults<String> results = query().from(product).orderBy( - product.name.asc()).limit(2).listResults(product.name); - assertEquals(Arrays.asList("A0", "A1"), results.getResults()); - assertEquals(30, results.getTotal()); - - } - - @BeforeClass - public static void doPersist() { - // Persistence of a Product and a Book. - PersistenceManager pm = pmf.getPersistenceManager(); - Transaction tx = pm.currentTransaction(); - try { - tx.begin(); - for (int i = 0; i < 10; i++) { - pm.makePersistent(new Product("C" + i, "F" + i, i * 200.00, 2)); - pm.makePersistent(new Product("B" + i, "E" + i, i * 200.00, 4)); - pm.makePersistent(new Product("A" + i, "D" + i, i * 200.00, 6)); - } - tx.commit(); - } finally { - if (tx.isActive()) { - tx.rollback(); - } - pm.close(); - } - System.out.println(""); - - } - -} diff --git a/querydsl-jdo/src/test/java/com/mysema/query/jdo/QueryMutabilityTest.java b/querydsl-jdo/src/test/java/com/mysema/query/jdo/QueryMutabilityTest.java deleted file mode 100644 index f0d86eb1f8..0000000000 --- a/querydsl-jdo/src/test/java/com/mysema/query/jdo/QueryMutabilityTest.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jdo; - -import static org.junit.Assert.assertEquals; - -import java.io.IOException; -import java.lang.reflect.InvocationTargetException; - -import org.junit.Test; - -import com.mysema.query.QueryMutability; -import com.mysema.query.jdo.test.domain.QProduct; - -public class QueryMutabilityTest extends AbstractJDOTest{ - - @Test - public void QueryMutability() throws IOException, SecurityException, - IllegalArgumentException, NoSuchMethodException, - IllegalAccessException, InvocationTargetException { - QProduct product = QProduct.product; - JDOQuery query = (JDOQuery) query().from(product); - new QueryMutability(query).test(product.name, product.description); - } - - @Test - public void Clone() { - QProduct product = QProduct.product; - JDOQuery query = new JDOQuery().from(product).where(product.name.isNotNull()); - JDOQuery query2 = query.clone(pm); - assertEquals(query.getMetadata().getJoins(), query2.getMetadata().getJoins()); - assertEquals(query.getMetadata().getWhere(), query2.getMetadata().getWhere()); - query2.list(product); - } - -} diff --git a/querydsl-jdo/src/test/java/com/mysema/query/jdo/SubqueriesTest.java b/querydsl-jdo/src/test/java/com/mysema/query/jdo/SubqueriesTest.java deleted file mode 100644 index 292e1b6dd1..0000000000 --- a/querydsl-jdo/src/test/java/com/mysema/query/jdo/SubqueriesTest.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jdo; - -import javax.jdo.PersistenceManager; -import javax.jdo.Transaction; - -import org.junit.BeforeClass; -import org.junit.Test; - -import com.mysema.query.jdo.test.domain.Product; -import com.mysema.query.jdo.test.domain.QProduct; - -public class SubqueriesTest extends AbstractJDOTest { - - private QProduct product = QProduct.product; - - private QProduct other = new QProduct("other"); - - @Test - public void List_Exists() { - query().from(product).where(sub().from(other).list(other).exists()).list(product); - } - - @Test - public void List_NotExists() { - query().from(product).where(sub().from(other).list(other).notExists()).list(product); - } - - @Test - public void List_Contains() { - query().from(product).where(sub().from(other).list(other.name).contains(product.name)).list(product); - } - - @Test - public void Gt_Subquery() { - for (double price : query().from(product) - .where(product.price.gt(sub().from(other).unique(other.price.avg()))) - .list(product.price)) { - System.out.println(price); - } - } - - @Test - public void Gt_Subquery_with_Condition() { - for (double price : query().from(product) - .where(product.price.gt(sub().from(other).where(other.name.eq("XXX")).unique(other.price.avg()))) - .list(product.price)) { - System.out.println(price); - } - } - - @Test - public void Eq_Subquery() { - for (double price : query().from(product) - .where(product.price.eq(sub().from(other).unique(other.price.avg()))) - .list(product.price)) { - System.out.println(price); - } - } - - - @Test - public void In_Subquery() { - for (double price : query().from(product) - .where(product.price.in( - sub().from(other).where(other.name.eq("Some name")).list(other.price))) - .list(product.price)) { - System.out.println(price); - } - } - - @Test - public void Count() { - for (double price : query().from(product) - .where(sub().from(other).where(other.price.gt(product.price)).count().gt(0)) - .list(product.price)) { - System.out.println(price); - } - } - - @Test - public void Exists() { - for (double price : query().from(product) - .where(sub().from(other).where(other.price.gt(product.price)).exists()) - .list(product.price)) { - System.out.println(price); - } - } - - @Test - public void Not_Exists() { - for (double price : query().from(product) - .where(sub().from(other).where(other.price.gt(product.price)).notExists()) - .list(product.price)) { - System.out.println(price); - } - } - - - - @BeforeClass - public static void doPersist() { - // Persistence of a Product and a Book. - PersistenceManager pm = pmf.getPersistenceManager(); - Transaction tx = pm.currentTransaction(); - try { - tx.begin(); - for (int i = 0; i < 10; i++) { - pm.makePersistent(new Product("C" + i, "F" + i, i * 200.00, 2)); - pm.makePersistent(new Product("B" + i, "E" + i, i * 200.00, 4)); - pm.makePersistent(new Product("A" + i, "D" + i, i * 200.00, 6)); - } - tx.commit(); - } finally { - if (tx.isActive()) { - tx.rollback(); - } - pm.close(); - } - System.out.println(""); - - } -} diff --git a/querydsl-jdo/src/test/java/com/mysema/query/jdo/models/company/Account.java b/querydsl-jdo/src/test/java/com/mysema/query/jdo/models/company/Account.java deleted file mode 100644 index b874746b8b..0000000000 --- a/querydsl-jdo/src/test/java/com/mysema/query/jdo/models/company/Account.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jdo.models.company; - -import com.mysema.query.annotations.QueryEntity; - -/** - * User account for a person. - * - * @version $Revision: 1.2 $ - */ -@QueryEntity -public class Account { - private long id; // PK if app id - private String username; - private boolean enabled; - - public Account() { - } - - public void setId(long id) { - this.id = id; - } - - public long getId() { - return id; - } - - public boolean getEnabled() { - return enabled; - } - - public void setEnabled(boolean b) { - enabled = b; - } - - public String getUsername() { - return username; - } - - public void setUsername(String s) { - username = s; - } -} diff --git a/querydsl-jdo/src/test/java/com/mysema/query/jdo/models/company/Department.java b/querydsl-jdo/src/test/java/com/mysema/query/jdo/models/company/Department.java deleted file mode 100644 index fb7213f0a0..0000000000 --- a/querydsl-jdo/src/test/java/com/mysema/query/jdo/models/company/Department.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jdo.models.company; - -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import com.mysema.query.annotations.QueryEntity; - -/** - * Department in a company. Has a Manager, and a set of Projects being worked - * on. - * - * @version $Revision: 1.1 $ - */ -@QueryEntity -public class Department { - private String name; - private Manager manager; - private Set<Project> projects = new HashSet<Project>(); - private List<Employee> employees; - - public Department() { - - } - - public Department(String name) { - this.name = name; - } - - public String getName() { - return this.name; - } - - public void setName(String name) { - this.name = name; - } - - public void setManager(Manager mgr) { - this.manager = mgr; - } - - public Manager getManager() { - return this.manager; - } - - public Set<Project> getProjects() { - return projects; - } - - public void setProjects(Set<Project> projects) { - this.projects = projects; - } - - public void addProject(Project proj) { - this.projects.add(proj); - } - - public String toString() { - return name; - } - - public List<Employee> getEmployees() { - return employees; - } - -} diff --git a/querydsl-jdo/src/test/java/com/mysema/query/jdo/models/company/Employee.java b/querydsl-jdo/src/test/java/com/mysema/query/jdo/models/company/Employee.java deleted file mode 100644 index 5cd01fc5ad..0000000000 --- a/querydsl-jdo/src/test/java/com/mysema/query/jdo/models/company/Employee.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jdo.models.company; - -import com.mysema.query.annotations.QueryEntity; - -/** - * Employee in a company. - * - * @version $Revision: 1.3 $ - */ -@QueryEntity -public class Employee extends Person { - private String serialNo; - private float salary; - private String salaryCurrency; - private Integer yearsInCompany; - private Manager manager; - private Account account; - private int weeklyhours; - private Department department; - - /** Used for the querying of static fields. */ - public static final String FIRSTNAME = "Bart"; - - public Employee() { - } - - public Employee(long id, String firstname, String lastname, String email, - float sal, String serial) { - super(id, firstname, lastname, email); - this.salary = sal; - this.serialNo = serial; - } - - public Employee(long id, String firstname, String lastname, String email, - float sal, String serial, Integer yearsInCompany) { - super(id, firstname, lastname, email); - this.salary = sal; - this.serialNo = serial; - this.yearsInCompany = yearsInCompany; - } - - public Account getAccount() { - return this.account; - } - - public String getSerialNo() { - return this.serialNo; - } - - public float getSalary() { - return this.salary; - } - - public String getSalaryCurrency() { - return this.salaryCurrency; - } - - public Manager getManager() { - return this.manager; - } - - public Integer getYearsInCompany() { - return this.yearsInCompany; - } - - public void setManager(Manager mgr) { - this.manager = mgr; - } - - public void setAccount(Account acct) { - this.account = acct; - } - - public void setSerialNo(String sn) { - this.serialNo = sn; - } - - public void setSalary(float s) { - this.salary = s; - } - - public void setSalaryCurrency(String s) { - this.salaryCurrency = s; - } - - public void setYearsInCompany(Integer y) { - this.yearsInCompany = y; - } - - public int getWeeklyhours() { - return weeklyhours; - } - - public Department getDepartment() { - return department; - } - -} diff --git a/querydsl-jdo/src/test/java/com/mysema/query/jdo/models/company/Person.java b/querydsl-jdo/src/test/java/com/mysema/query/jdo/models/company/Person.java deleted file mode 100644 index f04fb499a7..0000000000 --- a/querydsl-jdo/src/test/java/com/mysema/query/jdo/models/company/Person.java +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jdo.models.company; - -import java.io.Serializable; -import java.util.HashMap; -import java.util.Map; -import java.util.Random; -import java.util.StringTokenizer; - -import com.mysema.query.annotations.QueryEntity; - -/** - * Person in a company. - */ -@QueryEntity -public class Person implements Cloneable { - - public static class Id implements Serializable { - - private static final long serialVersionUID = -4893934512712167318L; - - public String globalNum; - - public long personNum; - - public Id() { - } - - public Id(String str) { - StringTokenizer toke = new StringTokenizer(str, "::"); - - str = toke.nextToken(); - this.personNum = Integer.parseInt(str); - str = toke.nextToken(); - this.globalNum = str; - } - - public boolean equals(Object obj) { - if (obj == this) { - return true; - } - - if (!(obj instanceof Id)) { - return false; - } - - Id c = (Id) obj; - return personNum == c.personNum && globalNum.equals(c.globalNum); - } - - public int hashCode() { - return ((int) this.personNum) ^ this.globalNum.hashCode(); - } - - public String toString() { - return String.valueOf(this.personNum) + "::" - + String.valueOf(this.globalNum); - } - } - - /** Used for the querying of static fields. */ - public static final String FIRSTNAME = "Woody"; - - private static Random random = new Random(); - - private int age; - - private Person bestFriend; - - private String emailAddress; - - private String firstName; - - private String globalNum; // Part of PK when app id - - private String lastName; - - private long personNum; // Part of PK when app id - - private Map<String, PhoneNumber> phoneNumbers = new HashMap<String, PhoneNumber>(); - - public Person() { - } - - public Person(long num, String first, String last, String email) { - globalNum = "global:" + random.nextInt(); - personNum = num; - firstName = first; - lastName = last; - emailAddress = email; - } - - public String asString() { - return "Person : number=" + getPersonNum() + " forename=" - + getFirstName() + " surname=" + getLastName() + " email=" - + getEmailAddress() + " bestfriend=" + getBestFriend(); - } - - public Object clone() { - Object o = null; - - try { - o = super.clone(); - } catch (CloneNotSupportedException e) { - /* can't happen */ - } - - return o; - } - - public boolean compareTo(Object obj) { - // TODO Use globalNum here too ? - Person p = (Person) obj; - return bestFriend == p.bestFriend && firstName.equals(p.firstName) - && lastName.equals(p.lastName) - && emailAddress.equals(p.emailAddress) - && personNum == p.personNum; - } - - // Note that this is only really correct for application identity, but we - // also use this class for datastore id - public boolean equals(Object o) { - if (o == this) { - return true; - } - if ((o == null) || (o.getClass() != this.getClass())) - return false; - - Person other = (Person) o; - return personNum == other.personNum - && (globalNum == other.globalNum || (globalNum != null && globalNum - .equals(other.globalNum))); - } - - public int getAge() { - return age; - } - - public Person getBestFriend() { - return bestFriend; - } - - public String getEmailAddress() { - return emailAddress; - } - - public String getFirstName() { - return firstName; - } - - public String getGlobalNum() { - return globalNum; - } - - public synchronized String getLastName() { - return lastName; - } - - public long getPersonNum() { - return personNum; - } - - public Map<String, PhoneNumber> getPhoneNumbers() { - return phoneNumbers; - } - - // Note that this is only really correct for application identity, but we - // also use this class for datastore id - public int hashCode() { - int hash = 7; - hash = 31 * hash + (int) personNum; - hash = 31 * hash + (null == globalNum ? 0 : globalNum.hashCode()); - return hash; - } - - public void setAge(int age) { - this.age = age; - } - - public void setBestFriend(Person p) { - this.bestFriend = p; - } - - public void setEmailAddress(String s) { - emailAddress = s; - } - - public void setFirstName(String s) { - firstName = s; - } - - public void setGlobalNum(String globalNum) { - this.globalNum = globalNum; - } - - public void setLastName(String s) { - lastName = s; - } - - public void setPersonNum(long num) { - personNum = num; - } -} diff --git a/querydsl-jdo/src/test/java/com/mysema/query/jdo/models/company/PhoneNumber.java b/querydsl-jdo/src/test/java/com/mysema/query/jdo/models/company/PhoneNumber.java deleted file mode 100644 index af9707eff9..0000000000 --- a/querydsl-jdo/src/test/java/com/mysema/query/jdo/models/company/PhoneNumber.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jdo.models.company; - -import com.mysema.query.annotations.QueryEntity; - -/** - * Phone number of a person. - * - * @version $Revision: 1.1 $ - */ -@QueryEntity -public class PhoneNumber { - long id; // PK when using app id - String name; - String number; - - public PhoneNumber() { - } - - public PhoneNumber(String name, String number) { - this.name = name; - this.number = number; - } - - public void setId(long id) { - this.id = id; - } - - public long getId() { - return id; - } - - public String getName() { - return name; - } - - public String getNumber() { - return number; - } -} diff --git a/querydsl-jdo/src/test/java/com/mysema/query/jdo/serialization/AbstractTest.java b/querydsl-jdo/src/test/java/com/mysema/query/jdo/serialization/AbstractTest.java deleted file mode 100644 index 60a302707a..0000000000 --- a/querydsl-jdo/src/test/java/com/mysema/query/jdo/serialization/AbstractTest.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jdo.serialization; - -import com.mysema.query.jdo.JDOQLSerializer; -import com.mysema.query.jdo.JDOSubQuery; -import com.mysema.query.jdo.JDOQLTemplates; -import com.mysema.query.types.Expression; -import com.mysema.query.types.SubQueryExpression; - -public abstract class AbstractTest { - - protected JDOSubQuery query() { - return new JDOSubQuery(); - } - - protected String serialize(SubQueryExpression<?> expr) { - Expression<?> source = expr.getMetadata().getJoins().get(0).getTarget(); - JDOQLSerializer serializer = new JDOQLSerializer(JDOQLTemplates.DEFAULT, source); - serializer.serialize(expr.getMetadata(), false, false); - String rv = serializer.toString().replace('\n', ' '); - return rv; - } - -} diff --git a/querydsl-jdo/src/test/java/com/mysema/query/jdo/serialization/ContainerTest.java b/querydsl-jdo/src/test/java/com/mysema/query/jdo/serialization/ContainerTest.java deleted file mode 100644 index 78dc0c523a..0000000000 --- a/querydsl-jdo/src/test/java/com/mysema/query/jdo/serialization/ContainerTest.java +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jdo.serialization; - -import static org.junit.Assert.assertEquals; - -import org.junit.Before; -import org.junit.Test; - -import com.mysema.query.jdo.models.fitness.QGym; -import com.mysema.query.jdo.models.fitness.Wardrobe; - -public class ContainerTest extends AbstractTest{ - - private QGym gym = QGym.gym1; - - private Wardrobe wrd = new Wardrobe(), wrd1 = new Wardrobe(), wrd2 = new Wardrobe(); - - @Before - public void setUp() { - wrd.setModel("model"); - } - - @Test - public void NotContainsValuesInMapFields() { - -// "SELECT FROM org.jpox.samples.models.fitness.Gym " -// + "WHERE !this.wardrobes.containsValue(wrd) " -// + "PARAMETERS org.jpox.samples.models.fitness.Wardrobe wrd"); - assertEquals( - "SELECT FROM com.mysema.query.jdo.models.fitness.Gym " + - "WHERE !this.wardrobes.containsValue(a1) " + - "PARAMETERS com.mysema.query.jdo.models.fitness.Wardrobe a1", - - serialize(query().from(gym) - .where(gym.wardrobes.containsValue(wrd).not()).list(gym))); - -// "SELECT FROM org.jpox.samples.models.fitness.Gym " -// + "WHERE !this.wardrobes.containsValue(wrd) && !this.wardrobes.containsValue(wrd2) " -// + "PARAMETERS org.jpox.samples.models.fitness.Wardrobe wrd,org.jpox.samples.models.fitness.Wardrobe wrd2"); - - assertEquals( - "SELECT FROM com.mysema.query.jdo.models.fitness.Gym " + - "WHERE !this.wardrobes.containsValue(a1) && !this.wardrobes.containsValue(a2) " + - "PARAMETERS com.mysema.query.jdo.models.fitness.Wardrobe a1, com.mysema.query.jdo.models.fitness.Wardrobe a2", - - serialize(query().from(gym) - .where(gym.wardrobes.containsValue(wrd).not(), gym.wardrobes.containsValue(wrd2).not()) - .list(gym))); -// -// "SELECT FROM org.jpox.samples.models.fitness.Gym " -// + "WHERE !this.wardrobes.containsValue(wrd) && !this.wardrobes.containsValue(wrd2) && this.wardrobes.containsValue(wrd1) " -// + "PARAMETERS org.jpox.samples.models.fitness.Wardrobe wrd,org.jpox.samples.models.fitness.Wardrobe wrd2,org.jpox.samples.models.fitness.Wardrobe wrd1"); - - assertEquals( - "SELECT FROM com.mysema.query.jdo.models.fitness.Gym " + - "WHERE !this.wardrobes.containsValue(a1) && !this.wardrobes.containsValue(a2) && this.wardrobes.containsValue(a3) " + - "PARAMETERS com.mysema.query.jdo.models.fitness.Wardrobe a1, com.mysema.query.jdo.models.fitness.Wardrobe a2, com.mysema.query.jdo.models.fitness.Wardrobe a3", - - serialize(query().from(gym) - .where( - gym.wardrobes.containsValue(wrd).not(), - gym.wardrobes.containsValue(wrd1).not(), - gym.wardrobes.containsValue(wrd2)) - .list(gym))); - } - - @Test - public void NotContainsKeysInMapFields() { - -// "SELECT FROM org.jpox.samples.models.fitness.Gym " -// + "WHERE !this.wardrobes2.containsKey(wrd) " -// + "PARAMETERS org.jpox.samples.models.fitness.Wardrobe wrd"); - assertEquals( - "SELECT FROM com.mysema.query.jdo.models.fitness.Gym " + - "WHERE !this.wardrobes2.containsKey(a1) " + - "PARAMETERS com.mysema.query.jdo.models.fitness.Wardrobe a1", - - serialize(query().from(gym) - .where(gym.wardrobes2.containsKey(wrd).not()).list(gym))); -// -// "SELECT FROM org.jpox.samples.models.fitness.Gym " -// + "WHERE !this.wardrobes2.containsKey(wrd) && !this.wardrobes2.containsKey(wrd2) " -// + "PARAMETERS org.jpox.samples.models.fitness.Wardrobe wrd,org.jpox.samples.models.fitness.Wardrobe wrd2"); - assertEquals( - "SELECT FROM com.mysema.query.jdo.models.fitness.Gym " + - "WHERE !this.wardrobes2.containsKey(a1) && !this.wardrobes2.containsKey(a2) " + - "PARAMETERS com.mysema.query.jdo.models.fitness.Wardrobe a1, com.mysema.query.jdo.models.fitness.Wardrobe a2", - - serialize(query().from(gym) - .where( - gym.wardrobes2.containsKey(wrd).not(), - gym.wardrobes2.containsKey(wrd2).not()) - .list(gym))); -// -// "SELECT FROM org.jpox.samples.models.fitness.Gym " -// + "WHERE !this.wardrobes2.containsKey(wrd) && !this.wardrobes2.containsKey(wrd2) && this.wardrobes2.containsKey(wrd1) " -// + "PARAMETERS org.jpox.samples.models.fitness.Wardrobe wrd,org.jpox.samples.models.fitness.Wardrobe wrd2,org.jpox.samples.models.fitness.Wardrobe wrd1"); - assertEquals( - "SELECT FROM com.mysema.query.jdo.models.fitness.Gym " + - "WHERE !this.wardrobes2.containsKey(a1) && !this.wardrobes2.containsKey(a2) && this.wardrobes2.containsKey(a3) " + - "PARAMETERS com.mysema.query.jdo.models.fitness.Wardrobe a1, com.mysema.query.jdo.models.fitness.Wardrobe a2, com.mysema.query.jdo.models.fitness.Wardrobe a3", - - serialize(query().from(gym) - .where( - gym.wardrobes2.containsKey(wrd).not(), - gym.wardrobes2.containsKey(wrd2).not(), - gym.wardrobes2.containsKey(wrd1)) - .list(gym))); - } - - @Test - public void NotContainsEntryInMapFields() { - // NOTE : containsEntry is not supported in Querydsl - -// "SELECT FROM org.jpox.samples.models.fitness.Gym " -// + "WHERE !this.wardrobes.containsEntry(wrd.model,wrd) " -// + "PARAMETERS org.jpox.samples.models.fitness.Wardrobe wrd"); -// -// "SELECT FROM org.jpox.samples.models.fitness.Gym " -// + "WHERE !this.wardrobes.containsEntry(wrd.model,wrd) && !this.wardrobes.containsEntry(wrd2.model,wrd2) " -// + "PARAMETERS org.jpox.samples.models.fitness.Wardrobe wrd,org.jpox.samples.models.fitness.Wardrobe wrd2"); -// -// "SELECT FROM org.jpox.samples.models.fitness.Gym " -// + "WHERE !this.wardrobes.containsEntry(wrd.model,wrd) && !this.wardrobes.containsEntry(wrd2.model,wrd2) && this.wardrobes.containsEntry(wrd1.model,wrd1) " -// + "PARAMETERS org.jpox.samples.models.fitness.Wardrobe wrd,org.jpox.samples.models.fitness.Wardrobe wrd2,org.jpox.samples.models.fitness.Wardrobe wrd1"); - - } - - @Test - public void GetInMapFields() { - -// "SELECT FROM org.jpox.samples.models.fitness.Gym " -// + "WHERE this.wardrobes.get(wrd.model) == wrd " -// + "PARAMETERS org.jpox.samples.models.fitness.Wardrobe wrd"); - assertEquals( - "SELECT FROM com.mysema.query.jdo.models.fitness.Gym " + - "WHERE this.wardrobes.get(a1) == a2 " + - "PARAMETERS java.lang.String a1, com.mysema.query.jdo.models.fitness.Wardrobe a2", - - serialize(query().from(gym) - .where(gym.wardrobes.get(wrd.getModel()).eq(wrd)).list(gym))); - } - - @Test - public void GetInOrderingInMapFields() { -// "SELECT FROM org.jpox.samples.models.fitness.Gym " -// + "PARAMETERS org.jpox.samples.models.fitness.Wardrobe wrd"); -// .setOrdering("this.wardrobes.get(wrd.model).model ascending"); - assertEquals( - "SELECT FROM com.mysema.query.jdo.models.fitness.Gym " + - "PARAMETERS java.lang.String a1 " + - "ORDER BY this.wardrobes.get(a1).model ASC", - - serialize(query().from(gym) - .orderBy(gym.wardrobes.get(wrd.getModel()).model.asc()).list(gym))); - } - -} diff --git a/querydsl-jdo/src/test/java/com/mysema/query/jdo/serialization/GroupByTest.java b/querydsl-jdo/src/test/java/com/mysema/query/jdo/serialization/GroupByTest.java deleted file mode 100644 index ff2fa56c60..0000000000 --- a/querydsl-jdo/src/test/java/com/mysema/query/jdo/serialization/GroupByTest.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.mysema.query.jdo.serialization; - -import static org.junit.Assert.assertEquals; - -import org.junit.Test; - -import com.mysema.query.jdo.models.company.QEmployee; - -public class GroupByTest extends AbstractTest { - - @Test - public void GroupBy() { - QEmployee employee = QEmployee.employee; - assertEquals( - "SELECT FROM com.mysema.query.jdo.models.company.Employee "+ - "PARAMETERS java.lang.String a1 "+ - "GROUP BY this.emailAddress "+ - "HAVING this.emailAddress != a1", - - serialize(query() - .from(employee) - .groupBy(employee.emailAddress).having(employee.emailAddress.ne("XXX")) - .list(employee))); - } - -} diff --git a/querydsl-jdo/src/test/java/com/mysema/query/jdo/serialization/QuerySerializationTest.java b/querydsl-jdo/src/test/java/com/mysema/query/jdo/serialization/QuerySerializationTest.java deleted file mode 100644 index 48d4b3ebba..0000000000 --- a/querydsl-jdo/src/test/java/com/mysema/query/jdo/serialization/QuerySerializationTest.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jdo.serialization; - -import static org.junit.Assert.assertEquals; - -import org.junit.Test; - -import com.mysema.query.jdo.test.domain.Book; -import com.mysema.query.jdo.test.domain.QProduct; - -public class QuerySerializationTest extends AbstractTest{ - - private QProduct product = QProduct.product; - - private QProduct other = new QProduct("other"); - - @Test - public void SelectFromWhereOrder() { - assertEquals( - "SELECT UNIQUE this.name " + - "FROM com.mysema.query.jdo.test.domain.Product " + - "WHERE this.name == a1 " + - "PARAMETERS java.lang.String a1 " + - "ORDER BY this.name ASC", - - serialize(query().from(product) - .where(product.name.eq("Test")) - .orderBy(product.name.asc()) - .unique(product.name))); - } - - @Test - public void SelectFromWhereGroupBy() { - assertEquals( - "SELECT this.name " + - "FROM com.mysema.query.jdo.test.domain.Product " + - "WHERE this.name.startsWith(a1) || this.name.endsWith(a2) " + - "PARAMETERS java.lang.String a1, java.lang.String a2 " + - "GROUP BY this.price", - - serialize(query().from(product) - .where(product.name.startsWith("A").or(product.name.endsWith("B"))) - .groupBy(product.price) - .list(product.name))); - } - - @Test - public void SelectFrom2Sources() { - assertEquals( - "SELECT this.name " + - "FROM com.mysema.query.jdo.test.domain.Product " + - "WHERE this.name == other.name " + - "VARIABLES com.mysema.query.jdo.test.domain.Product other", - - serialize(query().from(product, other) - .where(product.name.eq(other.name)) - .list(product.name))); - } - - @Test - public void WithSubQuery() { - assertEquals( - "SELECT this.price " + - "FROM com.mysema.query.jdo.test.domain.Product " + - "WHERE this.price < " + - "(SELECT avg(other.price) FROM com.mysema.query.jdo.test.domain.Product other)", - - serialize(query().from(product) - .where(product.price.lt(query().from(other).unique(other.price.avg()))) - .list(product.price))); - } - - @Test - public void WithSubQuery2() { - // FIXME : how to model this ?!? - assertEquals( - "SELECT this.name " + - "FROM com.mysema.query.jdo.test.domain.Product " + - "WHERE (SELECT other.price FROM com.mysema.query.jdo.test.domain.Product other " + - "WHERE other.name == a1 " + - "PARAMETERS java.lang.String a1).contains(this.price)", - - serialize(query().from(product) - .where(product.price.in(query().from(other).where(other.name.eq("Some name")).list(other.price))) - .list(product.name))); - } - - @Test - public void InstanceofQuery() { - assertEquals( - "SELECT " + - "FROM com.mysema.query.jdo.test.domain.Product " + - "WHERE this instanceof com.mysema.query.jdo.test.domain.Book", - - serialize(query().from(product) - .where(product.instanceOf(Book.class)) - .list(product))); - } - -} diff --git a/querydsl-jdo/src/test/java/com/mysema/query/jdo/serialization/SubqueriesTest.java b/querydsl-jdo/src/test/java/com/mysema/query/jdo/serialization/SubqueriesTest.java deleted file mode 100644 index 029abfe8d4..0000000000 --- a/querydsl-jdo/src/test/java/com/mysema/query/jdo/serialization/SubqueriesTest.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jdo.serialization; - -import static org.junit.Assert.assertEquals; - -import org.junit.Test; - -import com.mysema.query.jdo.models.company.QDepartment; -import com.mysema.query.jdo.models.company.QEmployee; - -public class SubqueriesTest extends AbstractTest{ - - private QDepartment department = QDepartment.department; - - private QDepartment d = new QDepartment("d"); - - private QEmployee e = new QEmployee("e"); - - private QEmployee employee = QEmployee.employee; - -/* "SELECT FROM " + Department.class.getName() + " WHERE this.employees.size() == " + - * "(SELECT MAX(d.employees.size()) FROM " + Department.class.getName() + " d)"; */ - @Test - public void test1() { - assertEquals( - "SELECT FROM com.mysema.query.jdo.models.company.Department " + - "WHERE this.employees.size() == " + - "(SELECT max(d.employees.size()) FROM com.mysema.query.jdo.models.company.Department d)", - - serialize(query().from(department).where(department.employees.size().eq( - query().from(d).unique(d.employees.size().max()) - )).list(department)) - ); - } - -/* "SELECT FROM " + Employee.class.getName() + " WHERE this.weeklyhours > " + - * "(SELECT AVG(e.weeklyhours) FROM this.department.employees e)"; */ - @Test - public void test2() { - assertEquals( - "SELECT FROM com.mysema.query.jdo.models.company.Employee " + - "WHERE this.weeklyhours > " + - "(SELECT avg(e.weeklyhours) FROM this.department.employees e)", - - serialize(query().from(employee).where(employee.weeklyhours.gt( - query().from(employee.department.employees, e).unique(e.weeklyhours.avg()) - )).list(employee)) - ); - } - -/* "SELECT FROM " + Employee.class.getName() + - * " WHERE this.weeklyhours > " + - * "(SELECT AVG(e.weeklyhours) FROM this.department.employees e " + - * " WHERE e.manager == this.manager)"; */ - @Test - public void test3() { - assertEquals( - "SELECT FROM com.mysema.query.jdo.models.company.Employee " + - "WHERE this.weeklyhours > " + - "(SELECT avg(e.weeklyhours) FROM this.department.employees e WHERE e.manager == this.manager)", - - serialize(query().from(employee).where(employee.weeklyhours.gt( - query().from(employee.department.employees, e).where(e.manager.eq(employee.manager)).unique(e.weeklyhours.avg()) - )).list(employee)) - ); - } -/* "SELECT FROM " + Employee.class.getName() + " WHERE this.weeklyhours > " + - * "(SELECT AVG(e.weeklyhours) FROM " + Employee.class.getName() + " e)"; */ - @Test - public void test4() { - assertEquals( - "SELECT FROM com.mysema.query.jdo.models.company.Employee " + - "WHERE this.weeklyhours > " + - "(SELECT avg(e.weeklyhours) FROM com.mysema.query.jdo.models.company.Employee e)", - - serialize(query().from(employee).where(employee.weeklyhours.gt( - query().from(e).unique(e.weeklyhours.avg()) - )).list(employee)) - ); - } - -/* "SELECT FROM " + Employee.class.getName() + - * " WHERE this.weeklyhours == emp.weeklyhours && " + - * "emp.firstname == 'emp1First' VARIABLES Employee emp"; */ - @Test - public void test5() { - assertEquals( - "SELECT FROM com.mysema.query.jdo.models.company.Employee " + - "WHERE this.weeklyhours == e.weeklyhours && this.firstName == a1 " + - "VARIABLES com.mysema.query.jdo.models.company.Employee e " + - "PARAMETERS java.lang.String a1", - - serialize(query().from(employee, e) - .where( - employee.weeklyhours.eq(e.weeklyhours), - employee.firstName.eq("emp1First") - ).list(employee)) - ); - } - -} diff --git a/querydsl-jdo/src/test/java/com/mysema/query/jdo/test/domain/Book.java b/querydsl-jdo/src/test/java/com/mysema/query/jdo/test/domain/Book.java deleted file mode 100644 index e91c801d28..0000000000 --- a/querydsl-jdo/src/test/java/com/mysema/query/jdo/test/domain/Book.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jdo.test.domain; - -import java.util.Date; - -import javax.jdo.annotations.Inheritance; -import javax.jdo.annotations.InheritanceStrategy; -import javax.jdo.annotations.PersistenceCapable; - -/** - * Definition of a Book. Extends basic Product class. - */ -@PersistenceCapable -@Inheritance(strategy = InheritanceStrategy.NEW_TABLE) -public class Book extends Product { - private String author = null; - - private String isbn = null; - - private String publisher = null; - - protected Book() { - super(); - } - - public Book(String name, String description, double price, int amount, String author, - String isbn, String publisher) { - this(name, description, price, amount, author, isbn, publisher, new Date()); - } - - public Book(String name, String description, double price, int amount, String author, - String isbn, String publisher, Date date) { - super(name, description, price, amount, date); - this.author = author; - this.isbn = isbn; - this.publisher = publisher; - } - - public String getAuthor() { - return author; - } - - public String getIsbn() { - return isbn; - } - - public String getPublisher() { - return publisher; - } - - public void setAuthor(String author) { - this.author = author; - } - - public void setIsbn(String isbn) { - this.isbn = isbn; - } - - public void setPublisher(String publisher) { - this.publisher = publisher; - } - - public String toString() { - return "Book : " + author + " - " + getName(); - } -} diff --git a/querydsl-jdo/src/test/java/com/mysema/query/jdo/test/domain/Product.java b/querydsl-jdo/src/test/java/com/mysema/query/jdo/test/domain/Product.java deleted file mode 100644 index 262408cd6e..0000000000 --- a/querydsl-jdo/src/test/java/com/mysema/query/jdo/test/domain/Product.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jdo.test.domain; - -import java.util.Date; - -import javax.jdo.annotations.Inheritance; -import javax.jdo.annotations.InheritanceStrategy; -import javax.jdo.annotations.PersistenceCapable; -import javax.jdo.annotations.Persistent; - -/** - * Definition of a Product Represents a product, and contains the key aspects of - * the item. - */ -@PersistenceCapable -@Inheritance(strategy = InheritanceStrategy.NEW_TABLE) -public class Product { - private String name = null; - - private String description = null; - - private double price = 0.0; - - private Date publicationDate; - - @Persistent - private java.sql.Date dateField; - - @Persistent - private java.sql.Time timeField; - - private int amount; - - public Product() { - } - - public Product(String name, String description, double price, int amount) { - this(name, description, price, amount, new Date()); - } - - public Product(String name, String description, double price, int amount, Date publicationDate) { - this.name = name; - this.description = description; - this.price = price; - this.amount = amount; - this.publicationDate = new Date(publicationDate.getTime()); - this.dateField = new java.sql.Date(publicationDate.getTime()); - this.timeField = new java.sql.Time(publicationDate.getTime()); - } - - public String getName() { - return name; - } - - public String getDescription() { - return description; - } - - public double getPrice() { - return price; - } - - public void setName(String name) { - this.name = name; - } - - public void setDescription(String description) { - this.description = description; - } - - public void setPrice(double price) { - this.price = price; - } - - public int getAmount() { - return amount; - } - - public void setAmount(int amount) { - this.amount = amount; - } - - public Date getPublicationDate() { - return publicationDate; - } - - public void setPublicationDate(Date publicationDate) { - this.publicationDate = new java.sql.Date(publicationDate.getTime()); - } - - public java.sql.Date getDateField() { - return new java.sql.Date(dateField.getTime()); - } - - public void setDateField(java.sql.Date dateField) { - this.dateField = new java.sql.Date(dateField.getTime()); - } - - public java.sql.Time getTimeField() { - return timeField; - } - - public void setTimeField(java.sql.Time timeField) { - this.timeField = timeField; - } - - public String toString() { - return "Product : " + name + " [" + description + "]"; - } -} diff --git a/querydsl-jdo/src/test/java/com/mysema/query/jdo/test/domain/QBook.java b/querydsl-jdo/src/test/java/com/mysema/query/jdo/test/domain/QBook.java deleted file mode 100644 index e8cd5581e1..0000000000 --- a/querydsl-jdo/src/test/java/com/mysema/query/jdo/test/domain/QBook.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jdo.test.domain; - -import com.mysema.query.types.PathMetadata; -import com.mysema.query.types.PathMetadataFactory; -import com.mysema.query.types.path.DateTimePath; -import com.mysema.query.types.path.EntityPathBase; -import com.mysema.query.types.path.NumberPath; -import com.mysema.query.types.path.StringPath; - -/** - * QBook is a Querydsl query type for Book - * - */ -@SuppressWarnings("serial") -public class QBook extends EntityPathBase<com.mysema.query.jdo.test.domain.Book>{ - - public static final QBook book = new QBook("book"); - - public final StringPath author = createString("author"); - - public final StringPath description = createString("description"); - - public final StringPath isbn = createString("isbn"); - - public final StringPath name = createString("name"); - - public final StringPath publisher = createString("publisher"); - - public final DateTimePath<java.util.Date> publicationDate = createDateTime("publicationDate",java.util.Date.class); - - public final NumberPath<Integer> amount = createNumber("amount",Integer.class); - - public final NumberPath<Double> price = createNumber("price",Double.class); - - public QBook(String path) { - this(com.mysema.query.jdo.test.domain.Book.class, path); - } - - public QBook(Class<? extends com.mysema.query.jdo.test.domain.Book> cl, String path) { - super(cl, PathMetadataFactory.forVariable(path)); - } - - public QBook(PathMetadata<?> metadata) { - super(com.mysema.query.jdo.test.domain.Book.class, metadata); - } - -} diff --git a/querydsl-jdo/src/test/java/com/mysema/query/jdo/test/domain/QProduct.java b/querydsl-jdo/src/test/java/com/mysema/query/jdo/test/domain/QProduct.java deleted file mode 100644 index 1ba0192a95..0000000000 --- a/querydsl-jdo/src/test/java/com/mysema/query/jdo/test/domain/QProduct.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jdo.test.domain; - -import com.mysema.query.types.PathMetadata; -import com.mysema.query.types.PathMetadataFactory; -import com.mysema.query.types.path.DatePath; -import com.mysema.query.types.path.DateTimePath; -import com.mysema.query.types.path.EntityPathBase; -import com.mysema.query.types.path.NumberPath; -import com.mysema.query.types.path.StringPath; -import com.mysema.query.types.path.TimePath; - -/** - * QProduct is a Querydsl query type for Product - * - */ -@SuppressWarnings("serial") -public class QProduct extends EntityPathBase<com.mysema.query.jdo.test.domain.Product>{ - - public static final QProduct product = new QProduct("product"); - - public final StringPath description = createString("description"); - - public final StringPath name = createString("name"); - - public final DateTimePath<java.util.Date> publicationDate = createDateTime("publicationDate",java.util.Date.class); - - public final DatePath<java.sql.Date> dateField = createDate("dateField", java.sql.Date.class); - - public final TimePath<java.sql.Time> timeField = createTime("timeField", java.sql.Time.class); - - public final NumberPath<Integer> amount = createNumber("amount",Integer.class); - - public final NumberPath<Double> price = createNumber("price",Double.class); - - public QProduct(String path) { - this(com.mysema.query.jdo.test.domain.Product.class, path); - } - - public QProduct(Class<? extends com.mysema.query.jdo.test.domain.Product> cl, String path) { - super(cl, PathMetadataFactory.forVariable(path)); - } - - public QProduct(PathMetadata<?> metadata) { - super(com.mysema.query.jdo.test.domain.Product.class, metadata); - } - -} diff --git a/querydsl-jdo/src/test/java/com/mysema/query/jdo/test/domain/QStore.java b/querydsl-jdo/src/test/java/com/mysema/query/jdo/test/domain/QStore.java deleted file mode 100644 index f6fbf65103..0000000000 --- a/querydsl-jdo/src/test/java/com/mysema/query/jdo/test/domain/QStore.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jdo.test.domain; - -import com.mysema.query.types.PathMetadata; -import com.mysema.query.types.PathMetadataFactory; -import com.mysema.query.types.path.EntityPathBase; -import com.mysema.query.types.path.ListPath; -import com.mysema.query.types.path.MapPath; -import com.mysema.query.types.path.PathInits; -import com.mysema.query.types.path.StringPath; - -/** - * QStore is a Querydsl query type for Store - * - */ -@SuppressWarnings("serial") -public class QStore extends EntityPathBase<com.mysema.query.jdo.test.domain.Store>{ - - public static final QStore store = new QStore("store"); - - public final StringPath name = createString("name"); - - public final MapPath<String, Product, QProduct> productsByName = this.<String, Product, QProduct>createMap("productsByName",String.class,Product.class,QProduct.class); - - public final ListPath<Product, QProduct> products = this.<Product, QProduct>createList("products",Product.class,QProduct.class, PathInits.DIRECT); - - public QProduct productsByName(String key) { - return new QProduct(PathMetadataFactory.forMapAccess(productsByName,key)); - } - - public QProduct productsByName(com.mysema.query.types.Expression<String> key) { - return new QProduct(PathMetadataFactory.forMapAccess(productsByName,key)); - } - - public QStore(String path) { - this(Store.class, path); - } - - public QStore(Class<? extends Store> cl, String path) { - super(cl, PathMetadataFactory.forVariable(path)); - } - - public QStore(PathMetadata<?> metadata) { - super(Store.class, metadata); - } - -} diff --git a/querydsl-jdo/src/test/java/com/mysema/query/jdo/test/domain/Store.java b/querydsl-jdo/src/test/java/com/mysema/query/jdo/test/domain/Store.java deleted file mode 100644 index 3f2f106e21..0000000000 --- a/querydsl-jdo/src/test/java/com/mysema/query/jdo/test/domain/Store.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jdo.test.domain; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.jdo.annotations.*; - -@PersistenceCapable -@Inheritance(strategy = InheritanceStrategy.NEW_TABLE) -@FetchGroups({ - @FetchGroup(name="products", members={@Persistent(name="products")}) -}) -public class Store { - - private String name; - - @Join - @Element(types=Product.class) - private List<Product> products = new ArrayList<Product>(); - - @Join - @Key(types=String.class) - @Value(types=Product.class) - private Map<String,Product> productsByName = new HashMap<String,Product>(); - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public Map<String, Product> getProductsByName() { - return productsByName; - } - - public void setProductsByName(Map<String, Product> productsByName) { - this.productsByName = productsByName; - } - - public List<Product> getProducts() { - return products; - } - - public void setProducts(List<Product> products) { - this.products = products; - } - -} diff --git a/querydsl-jdo/src/test/java/com/mysema/query/jdo/test/domain/sql/SBook.java b/querydsl-jdo/src/test/java/com/mysema/query/jdo/test/domain/sql/SBook.java deleted file mode 100644 index d903d6bd43..0000000000 --- a/querydsl-jdo/src/test/java/com/mysema/query/jdo/test/domain/sql/SBook.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jdo.test.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.forVariable; - -import com.mysema.query.sql.ForeignKey; -import com.mysema.query.sql.PrimaryKey; -import com.mysema.query.sql.RelationalPathBase; -import com.mysema.query.types.PathMetadata; -import com.mysema.query.types.path.BeanPath; -import com.mysema.query.types.path.NumberPath; -import com.mysema.query.types.path.StringPath; - - -/** - * SBook is a Querydsl query type for SBook - */ -//@Table(value="BOOK") -public class SBook extends RelationalPathBase<SBook> { - - private static final long serialVersionUID = -1566558053; - - public static final SBook book = new SBook("BOOK"); - - public final StringPath author = createString("AUTHOR"); - - public final NumberPath<Long> bookId = createNumber("BOOK_ID", Long.class); - - public final StringPath isbn = createString("ISBN"); - - public final StringPath publisher = createString("PUBLISHER"); - - public final PrimaryKey<SBook> sysIdx65 = createPrimaryKey(bookId); - - public final ForeignKey<SProduct> bookFk1 = new ForeignKey<SProduct>(this, bookId, "PRODUCT_ID"); - - public SBook(String variable) { - super(SBook.class, forVariable(variable), null, "BOOK"); - } - - public SBook(BeanPath<? extends SBook> entity) { - super(entity.getType(),entity.getMetadata(), null, "BOOK"); - } - - public SBook(PathMetadata<?> metadata) { - super(SBook.class, metadata, null, "BOOK"); - } - -} - diff --git a/querydsl-jdo/src/test/java/com/mysema/query/jdo/test/domain/sql/SProduct.java b/querydsl-jdo/src/test/java/com/mysema/query/jdo/test/domain/sql/SProduct.java deleted file mode 100644 index 1f3023b0ab..0000000000 --- a/querydsl-jdo/src/test/java/com/mysema/query/jdo/test/domain/sql/SProduct.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jdo.test.domain.sql; - -import com.mysema.query.sql.ColumnMetadata; -import com.mysema.query.sql.ForeignKey; -import com.mysema.query.sql.PrimaryKey; -import com.mysema.query.sql.RelationalPathBase; -import com.mysema.query.types.PathMetadata; -import com.mysema.query.types.path.*; -import static com.mysema.query.types.PathMetadataFactory.forVariable; - - -/** - * SProduct is a Querydsl query type for SProduct - */ -//@Table(value="PRODUCT") -public class SProduct extends RelationalPathBase<SProduct> { - - private static final long serialVersionUID = -590374403; - - public static final SProduct product = new SProduct("PRODUCT"); - - public final NumberPath<Integer> amount = createNumber("AMOUNT", Integer.class); - - public final DatePath<java.sql.Date> datefield = createDate("DATEFIELD", java.sql.Date.class); - - public final StringPath description = createString("DESCRIPTION"); - - public final StringPath name = createString("NAME"); - - public final NumberPath<Double> price = createNumber("PRICE", Double.class); - - public final NumberPath<Long> productId = createNumber("PRODUCT_ID", Long.class); - - public final DateTimePath<java.util.Date> publicationdate = createDateTime("PUBLICATIONDATE", java.util.Date.class); - - public final TimePath<java.sql.Time> timefield = createTime("TIMEFIELD", java.sql.Time.class); - - public final PrimaryKey<SProduct> sysIdx47 = createPrimaryKey(productId); - - public final ForeignKey<SStoreProducts> _storeProductsFk2 = new ForeignKey<SStoreProducts>(this, productId, "PRODUCT_ID_EID"); - - public final ForeignKey<SBook> _bookFk1 = new ForeignKey<SBook>(this, productId, "BOOK_ID"); - - public final ForeignKey<SStoreProductsbyname> _storeProductsbynameFk2 = new ForeignKey<SStoreProductsbyname>(this, productId, "PRODUCT_ID_VID"); - - public SProduct(String variable) { - super(SProduct.class, forVariable(variable), null, "PRODUCT"); - addMetadata(); - } - - public SProduct(BeanPath<? extends SProduct> entity) { - super(entity.getType(),entity.getMetadata(), null, "PRODUCT"); - addMetadata(); - } - - public SProduct(PathMetadata<?> metadata) { - super(SProduct.class, metadata, null, "PRODUCT"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(amount, ColumnMetadata.named("AMOUNT")); - addMetadata(datefield, ColumnMetadata.named("DATEFIELD")); - addMetadata(description, ColumnMetadata.named("DESCRIPTION")); - addMetadata(name, ColumnMetadata.named("NAME")); - addMetadata(price, ColumnMetadata.named("PRICE")); - addMetadata(productId, ColumnMetadata.named("PRODUCT_ID")); - addMetadata(publicationdate, ColumnMetadata.named("PUBLICATIONDATE")); - addMetadata(timefield, ColumnMetadata.named("TIMEFIELD")); - } - -} - diff --git a/querydsl-jdo/src/test/java/com/mysema/query/jdo/test/domain/sql/SStore.java b/querydsl-jdo/src/test/java/com/mysema/query/jdo/test/domain/sql/SStore.java deleted file mode 100644 index 0123c13005..0000000000 --- a/querydsl-jdo/src/test/java/com/mysema/query/jdo/test/domain/sql/SStore.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jdo.test.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.forVariable; - -import com.mysema.query.sql.ForeignKey; -import com.mysema.query.sql.PrimaryKey; -import com.mysema.query.sql.RelationalPathBase; -import com.mysema.query.types.PathMetadata; -import com.mysema.query.types.path.BeanPath; -import com.mysema.query.types.path.NumberPath; -import com.mysema.query.types.path.StringPath; - - -/** - * SStore is a Querydsl query type for SStore - */ -//@Table(value="STORE") -public class SStore extends RelationalPathBase<SStore> { - - private static final long serialVersionUID = -1302810257; - - public static final SStore store = new SStore("STORE"); - - public final StringPath name = createString("NAME"); - - public final NumberPath<Long> storeId = createNumber("STORE_ID", Long.class); - - public final PrimaryKey<SStore> sysIdx51 = createPrimaryKey(storeId); - - public final ForeignKey<SStoreProductsbyname> _storeProductsbynameFk1 = new ForeignKey<SStoreProductsbyname>(this, storeId, "STORE_ID_OID"); - - public final ForeignKey<SStoreProducts> _storeProductsFk1 = new ForeignKey<SStoreProducts>(this, storeId, "STORE_ID_OID"); - - public SStore(String variable) { - super(SStore.class, forVariable(variable), null, "STORE"); - } - - public SStore(BeanPath<? extends SStore> entity) { - super(entity.getType(),entity.getMetadata(), null, "STORE"); - } - - public SStore(PathMetadata<?> metadata) { - super(SStore.class, metadata, null, "STORE"); - } - -} - diff --git a/querydsl-jdo/src/test/java/com/mysema/query/jdo/test/domain/sql/SStoreProducts.java b/querydsl-jdo/src/test/java/com/mysema/query/jdo/test/domain/sql/SStoreProducts.java deleted file mode 100644 index a2d4d0466d..0000000000 --- a/querydsl-jdo/src/test/java/com/mysema/query/jdo/test/domain/sql/SStoreProducts.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jdo.test.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.forVariable; - -import com.mysema.query.sql.ForeignKey; -import com.mysema.query.sql.PrimaryKey; -import com.mysema.query.sql.RelationalPathBase; -import com.mysema.query.types.PathMetadata; -import com.mysema.query.types.path.BeanPath; -import com.mysema.query.types.path.NumberPath; - - -/** - * SStoreProducts is a Querydsl query type for SStoreProducts - */ -//@Table(value="STORE_PRODUCTS") -public class SStoreProducts extends RelationalPathBase<SStoreProducts> { - - private static final long serialVersionUID = 1019873267; - - public static final SStoreProducts storeProducts = new SStoreProducts("STORE_PRODUCTS"); - - public final NumberPath<Integer> idx = createNumber("IDX", Integer.class); - - public final NumberPath<Long> productIdEid = createNumber("PRODUCT_ID_EID", Long.class); - - public final NumberPath<Long> storeIdOid = createNumber("STORE_ID_OID", Long.class); - - public final PrimaryKey<SStoreProducts> sysIdx55 = createPrimaryKey(idx, storeIdOid); - - public final ForeignKey<SProduct> storeProductsFk2 = new ForeignKey<SProduct>(this, productIdEid, "PRODUCT_ID"); - - public final ForeignKey<SStore> storeProductsFk1 = new ForeignKey<SStore>(this, storeIdOid, "STORE_ID"); - - public SStoreProducts(String variable) { - super(SStoreProducts.class, forVariable(variable), null, "STORE_PRODUCTS"); - } - - public SStoreProducts(BeanPath<? extends SStoreProducts> entity) { - super(entity.getType(),entity.getMetadata(), null, "STORE_PRODUCTS"); - } - - public SStoreProducts(PathMetadata<?> metadata) { - super(SStoreProducts.class, metadata, null, "STORE_PRODUCTS"); - } - -} - diff --git a/querydsl-jdo/src/test/java/com/mysema/query/jdo/test/domain/sql/SStoreProductsbyname.java b/querydsl-jdo/src/test/java/com/mysema/query/jdo/test/domain/sql/SStoreProductsbyname.java deleted file mode 100644 index 7e4ddd5629..0000000000 --- a/querydsl-jdo/src/test/java/com/mysema/query/jdo/test/domain/sql/SStoreProductsbyname.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jdo.test.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.forVariable; - -import com.mysema.query.sql.ForeignKey; -import com.mysema.query.sql.PrimaryKey; -import com.mysema.query.sql.RelationalPathBase; -import com.mysema.query.types.PathMetadata; -import com.mysema.query.types.path.BeanPath; -import com.mysema.query.types.path.NumberPath; -import com.mysema.query.types.path.StringPath; - - -/** - * SStoreProductsbyname is a Querydsl query type for SStoreProductsbyname - */ -//@Table(value="STORE_PRODUCTSBYNAME") -public class SStoreProductsbyname extends RelationalPathBase<SStoreProductsbyname> { - - private static final long serialVersionUID = 764053781; - - public static final SStoreProductsbyname storeProductsbyname = new SStoreProductsbyname("STORE_PRODUCTSBYNAME"); - - public final StringPath key = createString("KEY"); - - public final NumberPath<Long> productIdVid = createNumber("PRODUCT_ID_VID", Long.class); - - public final NumberPath<Long> storeIdOid = createNumber("STORE_ID_OID", Long.class); - - public final PrimaryKey<SStoreProductsbyname> sysIdx53 = createPrimaryKey(key, storeIdOid); - - public final ForeignKey<SStore> storeProductsbynameFk1 = new ForeignKey<SStore>(this, storeIdOid, "STORE_ID"); - - public final ForeignKey<SProduct> storeProductsbynameFk2 = new ForeignKey<SProduct>(this, productIdVid, "PRODUCT_ID"); - - public SStoreProductsbyname(String variable) { - super(SStoreProductsbyname.class, forVariable(variable), null, "STORE_PRODUCTSBYNAME"); - } - - public SStoreProductsbyname(BeanPath<? extends SStoreProductsbyname> entity) { - super(entity.getType(),entity.getMetadata(), null, "STORE_PRODUCTSBYNAME"); - } - - public SStoreProductsbyname(PathMetadata<?> metadata) { - super(SStoreProductsbyname.class, metadata, null, "STORE_PRODUCTSBYNAME"); - } - -} - diff --git a/querydsl-jdo/src/test/java/com/querydsl/jdo/AbstractJDOTest.java b/querydsl-jdo/src/test/java/com/querydsl/jdo/AbstractJDOTest.java new file mode 100644 index 0000000000..1cc38112b6 --- /dev/null +++ b/querydsl-jdo/src/test/java/com/querydsl/jdo/AbstractJDOTest.java @@ -0,0 +1,110 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jdo; + +import java.util.List; + +import javax.jdo.JDOHelper; +import javax.jdo.PersistenceManager; +import javax.jdo.PersistenceManagerFactory; +import javax.jdo.Transaction; + +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; + +import com.querydsl.core.types.EntityPath; +import com.querydsl.core.types.Predicate; +import com.querydsl.jdo.dml.JDODeleteClause; +import com.querydsl.jdo.test.domain.Book; +import com.querydsl.jdo.test.domain.Product; +import com.querydsl.jdo.test.domain.Store; + +public abstract class AbstractJDOTest { + + private static final JDOQLTemplates templates = new JDOQLTemplates(); + + protected static final PersistenceManagerFactory pmf = + JDOHelper.getPersistenceManagerFactory("datanucleus.properties"); + + protected PersistenceManager pm; + + protected Transaction tx; + + protected JDOQuery<?> query() { + return new JDOQuery<Void>(pm, templates, false); + } + + protected JDOQuery<?> detachedQuery() { + return new JDOQuery<Void>(pm, templates, true); + } + + protected <T> List<T> query(EntityPath<T> source, Predicate condition) { + return query().from(source).where(condition).select(source).fetch(); + } + + protected JDODeleteClause delete(EntityPath<?> entity) { + return new JDODeleteClause(pm, entity, templates); + } + + @Before + public void setUp() { + pm = pmf.getPersistenceManager(); + tx = pm.currentTransaction(); + tx.begin(); + } + + @After + public void tearDown() { + if (tx.isActive()) { + tx.rollback(); + } + pm.close(); + } + + @AfterClass + public static void doCleanUp() { + // Clean out the database + PersistenceManager pm = pmf.getPersistenceManager(); + Transaction tx = pm.currentTransaction(); + try { + tx.begin(); + pm.newQuery(Store.class).deletePersistentAll(); + pm.newQuery(Book.class).deletePersistentAll(); + pm.newQuery(Product.class).deletePersistentAll(); + tx.commit(); + } finally { + if (tx.isActive()) { + tx.rollback(); + } + pm.close(); + } + } + + protected static void doPersist(List<?> entities) { + PersistenceManager pm = pmf.getPersistenceManager(); + Transaction tx = pm.currentTransaction(); + try { + tx.begin(); + pm.makePersistentAll(entities); + tx.commit(); + } finally { + if (tx.isActive()) { + tx.rollback(); + } + pm.close(); + } + } + +} diff --git a/querydsl-jdo/src/test/java/com/querydsl/jdo/AggregateTest.java b/querydsl-jdo/src/test/java/com/querydsl/jdo/AggregateTest.java new file mode 100644 index 0000000000..515b430a64 --- /dev/null +++ b/querydsl-jdo/src/test/java/com/querydsl/jdo/AggregateTest.java @@ -0,0 +1,58 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jdo; + +import static org.junit.Assert.assertEquals; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.BeforeClass; +import org.junit.Test; + +import com.querydsl.jdo.test.domain.Product; +import com.querydsl.jdo.test.domain.QProduct; + +public class AggregateTest extends AbstractJDOTest { + + private final QProduct product = QProduct.product; + + @Test + public void unique() { + double min = 200.00, avg = 400.00, max = 600.00; + assertEquals(Double.valueOf(min), query().from(product).select(product.price.min()).fetchOne()); + assertEquals(Double.valueOf(avg), query().from(product).select(product.price.avg()).fetchOne()); + assertEquals(Double.valueOf(max), query().from(product).select(product.price.max()).fetchOne()); + } + + @Test + public void list() { + double min = 200.00, avg = 400.00, max = 600.00; + assertEquals(Double.valueOf(min), query().from(product).select(product.price.min()).fetch().get(0)); + assertEquals(Double.valueOf(avg), query().from(product).select(product.price.avg()).fetch().get(0)); + assertEquals(Double.valueOf(max), query().from(product).select(product.price.max()).fetch().get(0)); + } + + @BeforeClass + public static void doPersist() { + List<Product> entities = new ArrayList<>(); + for (int i = 0; i < 10; i++) { + entities.add(new Product("C" + i, "F", 200.00, 2)); + entities.add(new Product("B" + i, "E", 400.00, 4)); + entities.add(new Product("A" + i, "D", 600.00, 6)); + } + doPersist(entities); + } + +} diff --git a/querydsl-jdo/src/test/java/com/querydsl/jdo/BasicsTest.java b/querydsl-jdo/src/test/java/com/querydsl/jdo/BasicsTest.java new file mode 100644 index 0000000000..682ccbbf93 --- /dev/null +++ b/querydsl-jdo/src/test/java/com/querydsl/jdo/BasicsTest.java @@ -0,0 +1,290 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jdo; + +import static org.junit.Assert.*; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; + +import org.junit.Assume; +import org.junit.BeforeClass; +import org.junit.Ignore; +import org.junit.Test; + +import com.querydsl.core.BooleanBuilder; +import com.querydsl.core.NonUniqueResultException; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.Projections; +import com.querydsl.jdo.test.domain.Book; +import com.querydsl.jdo.test.domain.Product; +import com.querydsl.jdo.test.domain.QBook; +import com.querydsl.jdo.test.domain.QProduct; + +public class BasicsTest extends AbstractJDOTest { + + private static final JDOQLTemplates templates = new JDOQLTemplates(); + + private final QBook book = QBook.book; + + private final QProduct product = QProduct.product; + + private final QProduct product2 = new QProduct("product2"); + + @Test + public void serialization() throws IOException { + JDOQuery<?> query = query(); + + assertEquals("FROM com.querydsl.jdo.test.domain.Product", query.from(product).toString()); + assertEquals("FROM com.querydsl.jdo.test.domain.Product" + + "\nVARIABLES com.querydsl.jdo.test.domain.Product product2", + query.from(product2).toString()); + + query.where(product.ne(product2)).select(product, product2).fetch(); + query.close(); + } + + @Test + public void subQuerySerialization() throws IOException { + JDOQuery<?> query = query(); + + assertEquals("FROM com.querydsl.jdo.test.domain.Product", query.from(product).toString()); + assertEquals("FROM com.querydsl.jdo.test.domain.Product" + + "\nVARIABLES com.querydsl.jdo.test.domain.Product product2", + query.from(product2).toString()); + + } + + @Test + public void delete() { + long count = query().from(product).fetchCount(); + assertEquals(0, delete(product).where(product.name.eq("XXX")).execute()); + assertEquals(count, delete(product).execute()); + } + + @Test + public void alias() { + assertEquals(2, query().from(product).select(product.name.as(product.name)).fetch().size()); + } + + @Test + public void countTests() { + assertEquals("count", 2, query().from(product).fetchCount()); + } + + @Test + public void list_distinct() { + // XXX List implementation of JDO provider has weird equals implementation + assertEquals( + new ArrayList<>(query().from(product).orderBy(product.name.asc()).select(product.name).fetch()), + new ArrayList<>(query().from(product).orderBy(product.name.asc()).distinct().select(product.name).fetch())); + } + + @Test + public void list_distinct_two_sources() { + try { + // XXX List implementation of JDO provider has weird equals implementation + assertEquals( + new ArrayList<>(query().from(product, product2).select(product, product2).fetch()), + new ArrayList<>(query().from(product, product2).distinct().select(product, product2).fetch())); + } catch (AssertionError e) { + Assume.assumeNoException("Unreliable test, but keep around", e); + } + } + + @Test + public void single_result() { + query().from(product).select(product).fetchFirst(); + } + + @Test + public void single_result_with_array() { + query().from(product).select(new Expression<?>[]{product}).fetchFirst(); + } + + @Test + public void factoryExpression_in_groupBy() { + Expression<Product> productBean = Projections.bean(Product.class, product.name, product.description); + assertFalse(query().from(product).groupBy(productBean).select(productBean).fetch().isEmpty()); + } + + @Test(expected = NonUniqueResultException.class) + public void unique_result_throws_exception_on_multiple_results() { + query().from(product).select(product).fetchOne(); + } + + @Test + public void simpleTest() throws IOException { + JDOQuery<?> query = new JDOQuery<Void>(pm, templates, false); + assertEquals("Sony Discman", query.from(product).where(product.name.eq("Sony Discman")) + .select(product.name).fetchOne()); + query.close(); + } + + @Test + public void projectionTests() { + assertEquals("Sony Discman", query().from(product).where(product.name.eq("Sony Discman")) + .select(product.name).fetchOne()); + } + + @Test + public void basicTests() { + assertEquals("list", 2, query().from(product).select(product).fetch().size()); + assertEquals("list", 2, query().from(product).select(product.name,product.description).fetch().size()); + assertEquals("list", 1, query().from(book).select(book).fetch().size()); + assertEquals("eq", 1, query(product, product.name.eq("Sony Discman")).size()); + assertEquals("instanceof ", 1, query(product,product.instanceOf(Book.class)).size()); + } + + @Test + @Ignore + public void detachedResults() { + for (Product p : detachedQuery().from(product).select(product).fetch()) { + assertNotNull(p); + } + } + + @Test + public void empty_booleanBuilder() { + assertEquals("empty boolean builder", 2, query(product, new BooleanBuilder()).size()); + } + + @Test + public void and() { + assertEquals("and", 1, query(product, product.name.eq("Sony Discman").and(product.price.loe(300.00))).size()); + } + + @Test + public void or() { + assertEquals("or", 2, query(product, product.name.eq("Sony Discman").or(product.price.loe(300.00))).size()); + } + + @Test + public void not() { + assertEquals("not", 2, query(product, product.name.eq("Sony MP3 player").not()).size()); + } + + @Test + public void numericTests() { + // numeric + // TODO + + // TODO - + // TODO * + // TODO / + // TODO % + // TODO Math.abs + // TODO Math.sqrt + } + + @Test + public void eq() { + assertEquals("eq", 1, query(product, product.price.eq(200.00)).size()); + assertEquals("eq", 0, query(product, product.price.eq(100.00)).size()); + } + + @Test + public void ne() { + assertEquals("ne", 2, query(product, product.price.ne(100.00)).size()); + } + + @Test + public void in_empty() { + assertEquals(0, query(product, product.name.in(Collections.emptyList())).size()); + } + + @Test + public void not_in_empty() { + int count = query(product, product.name.isNotNull()).size(); + assertEquals(count, query(product, product.name.notIn(Collections.emptyList())).size()); + } + + @Test + public void lt() { + assertEquals("lt", 2, query(product, product.price.lt(300.00)).size()); + } + + @Test + public void gt() { + assertEquals("gt", 1, query(product, product.price.gt(100.00)).size()); + } + + @Test + public void goe() { + assertEquals("goe", 1, query(product, product.price.goe(100.00)).size()); + } + + @Test + public void loe() { + assertEquals("loe", 2, query(product, product.price.loe(300.00)).size()); + } + + @Test + public void starts_with() { + assertEquals("startsWith", 1, query(product,product.name.startsWith("Sony Discman")).size()); + } + + @Test + public void matches() { + assertEquals("matches", 1, query(product,product.name.matches("Sony.*")).size()); + assertSame( + query(product, product.name.matches("Sony.*")).size(), + query(product, product.name.likeIgnoreCase("sony%")).size() + ); + } + + @Test + public void like() { + assertEquals("matches", 1, query(product,product.name.like("Sony%")).size()); + } + + @Test + public void ends_with() { + assertEquals("endsWith", 1, query(product,product.name.endsWith("Discman")).size()); + } + + @Test + public void to_lowerCase() { + assertEquals("toLowerCase", 1, query(product,product.name.lower().eq("sony discman")).size()); + } + + @Test + public void to_upperCase() { + assertEquals("toUpperCase", 1, query(product,product.name.upper().eq("SONY DISCMAN")).size()); + } + + @Test + public void index_of() { + assertEquals("indexOf", 1, query(product,product.name.indexOf("S").eq(0)).size()); + } + + @Test + public void substring1() { + assertEquals("substring", 1, query(product,product.name.substring(5).eq("Discman")).size()); + } + + @Test + public void substring2() { + assertEquals("substring", 1, query(product,product.name.substring(0, 4).eq("Sony")).size()); + } + + @BeforeClass + public static void doPersist() { + doPersist(Arrays.asList( + new Product("Sony Discman", "A standard discman from Sony", 200.00, 3), + new Book("Lord of the Rings by Tolkien", "The classic story", 49.99, 5, "JRR Tolkien", "12345678", "MyBooks Factory"))); + } + +} diff --git a/querydsl-jdo/src/test/java/com/querydsl/jdo/CollectionTest.java b/querydsl-jdo/src/test/java/com/querydsl/jdo/CollectionTest.java new file mode 100644 index 0000000000..10466e6ae1 --- /dev/null +++ b/querydsl-jdo/src/test/java/com/querydsl/jdo/CollectionTest.java @@ -0,0 +1,91 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jdo; + +import java.util.Arrays; + +import org.junit.BeforeClass; +import org.junit.Ignore; +import org.junit.Test; + +import com.querydsl.jdo.test.domain.Book; +import com.querydsl.jdo.test.domain.Product; +import com.querydsl.jdo.test.domain.QProduct; +import com.querydsl.jdo.test.domain.QStore; + +public class CollectionTest extends AbstractJDOTest { + + private final QStore store = QStore.store; + + @Test + public void contains_key() { + query(store, store.productsByName.containsKey("XXX")); + } + + @Test + public void contains_value() { + Product product = query().from(QProduct.product).select(QProduct.product).fetch().get(0); + query(store, store.productsByName.containsValue(product)); + } + + @Test + @Ignore + public void get() { + query(store, store.products.get(0).name.isNotNull()); + } + + @Test + public void isEmpty() { + query(store, store.products.isEmpty()); + } + + @Test + public void isNotEmpty() { + query(store, store.products.isNotEmpty()); + } + + @Test + public void size() { + query(store, store.products.size().gt(0)); + } + + @Test + public void collection_any() { + query(store, store.products.any().name.eq("Sony Discman")); + } + + @Test + public void collection_any_and() { + query(store, store.products.any().name.eq("Sony Discman").and(store.products.any().price.gt(10.0))); + } + + @Test + public void collection_any_count() { + query().from(store).where(store.products.any().name.eq("Sony Discman")).fetchCount(); + } + + @Test + @Ignore // Not supported + public void collection_any_in_projection() { + query().from(store).select(store.products.any()).fetch(); + } + + @BeforeClass + public static void doPersist() { + doPersist(Arrays.asList( + new Product("Sony Discman", "A standard discman from Sony", 200.00, 3), + new Book("Lord of the Rings by Tolkien","The classic story", 49.99, 5, "JRR Tolkien", "12345678","MyBooks Factory"))); + } + +} diff --git a/querydsl-jdo/src/test/java/com/querydsl/jdo/DependenciesTest.java b/querydsl-jdo/src/test/java/com/querydsl/jdo/DependenciesTest.java new file mode 100644 index 0000000000..34931cccb1 --- /dev/null +++ b/querydsl-jdo/src/test/java/com/querydsl/jdo/DependenciesTest.java @@ -0,0 +1,40 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jdo; + +import static org.junit.Assert.assertFalse; + +import java.io.IOException; + +import org.junit.Ignore; +import org.junit.Test; + +import jdepend.framework.JDepend; + +public class DependenciesTest { + + @Test + @Ignore + public void test() throws IOException { + JDepend jdepend = new JDepend(); + jdepend.addDirectory("target/classes/com/querydsl/jdo"); + jdepend.addDirectory("target/classes/com/querydsl/jdo/dml"); + jdepend.addDirectory("target/classes/com/querydsl/jdo/sql"); + + jdepend.analyze(); + assertFalse(jdepend.containsCycles()); + + } + +} diff --git a/querydsl-jdo/src/test/java/com/querydsl/jdo/FetchPlanTest.java b/querydsl-jdo/src/test/java/com/querydsl/jdo/FetchPlanTest.java new file mode 100644 index 0000000000..47d02d48eb --- /dev/null +++ b/querydsl-jdo/src/test/java/com/querydsl/jdo/FetchPlanTest.java @@ -0,0 +1,98 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jdo; + +import static org.junit.Assert.assertEquals; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; + +import javax.jdo.Query; + +import org.junit.After; +import org.junit.BeforeClass; +import org.junit.Test; + +import com.querydsl.jdo.test.domain.Product; +import com.querydsl.jdo.test.domain.QProduct; +import com.querydsl.jdo.test.domain.QStore; + +public class FetchPlanTest extends AbstractJDOTest { + + private JDOQuery<?> query; + + @After + public void tearDown() { + if (query != null) { + query.close(); + } + super.tearDown(); + } + + @SuppressWarnings("unchecked") + @Test + public void listProducts() throws Exception { + QProduct product = QProduct.product; + query = query(); + query.from(product) + .where(product.name.startsWith("A")) + .addFetchGroup("myfetchgroup1") + .addFetchGroup("myfetchgroup2") + .setMaxFetchDepth(2) + .select(product).fetch(); +// query.close(); + + Field queriesField = AbstractJDOQuery.class.getDeclaredField("queries"); + queriesField.setAccessible(true); + List<Query> queries = (List<Query>) queriesField.get(query); + Query jdoQuery = queries.get(0); + assertEquals(new HashSet<String>(Arrays.asList("myfetchgroup1","myfetchgroup2")), + jdoQuery.getFetchPlan().getGroups()); + assertEquals(2, jdoQuery.getFetchPlan().getMaxFetchDepth()); + } + + @SuppressWarnings("unchecked") + @Test + public void listStores() throws Exception { + QStore store = QStore.store; + query = query(); + query.from(store) + .addFetchGroup("products") + .select(store).fetch(); + + Field queriesField = AbstractJDOQuery.class.getDeclaredField("queries"); + queriesField.setAccessible(true); + List<Query> queries = (List<Query>) queriesField.get(query); + Query jdoQuery = queries.get(0); + assertEquals(new HashSet<String>(Collections.singletonList("products")), + jdoQuery.getFetchPlan().getGroups()); + assertEquals(1, jdoQuery.getFetchPlan().getMaxFetchDepth()); + } + + @BeforeClass + public static void doPersist() { + List<Object> entities = new ArrayList<>(); + for (int i = 0; i < 10; i++) { + entities.add(new Product("C" + i, "F", 200.00, 2)); + entities.add(new Product("B" + i, "E", 400.00, 4)); + entities.add(new Product("A" + i, "D", 600.00, 6)); + } + doPersist(entities); + } + +} diff --git a/querydsl-jdo/src/test/java/com/querydsl/jdo/GroupByTest.java b/querydsl-jdo/src/test/java/com/querydsl/jdo/GroupByTest.java new file mode 100644 index 0000000000..56c27c795a --- /dev/null +++ b/querydsl-jdo/src/test/java/com/querydsl/jdo/GroupByTest.java @@ -0,0 +1,64 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jdo; + +import static org.junit.Assert.assertEquals; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.BeforeClass; +import org.junit.Test; + +import com.querydsl.jdo.test.domain.Product; +import com.querydsl.jdo.test.domain.QProduct; + +public class GroupByTest extends AbstractJDOTest { + + private QProduct product = QProduct.product; + + @Test + public void distinct() { + assertEquals(3, query().from(product).distinct().select(product.description).fetch().size()); + assertEquals(3, query().from(product).distinct().select(product.price).fetch().size()); + } + + @Test + public void groupBy() { + assertEquals(3, query().from(product).groupBy(product.description).select(product.description).fetch().size()); + assertEquals(3, query().from(product).groupBy(product.price).select(product.price).fetch().size()); + } + + @Test + public void having() { + assertEquals(3, query().from(product) + .groupBy(product.description).having(product.description.ne("XXX")) + .select(product.description).fetch().size()); + assertEquals(3, query().from(product) + .groupBy(product.price).having(product.price.gt(0)) + .select(product.price).fetch().size()); + } + + @BeforeClass + public static void doPersist() { + List<Object> entities = new ArrayList<>(); + for (int i = 0; i < 10; i++) { + entities.add(new Product("C" + i, "F", 200.00, 2)); + entities.add(new Product("B" + i, "E", 400.00, 4)); + entities.add(new Product("A" + i, "D", 600.00, 6)); + } + doPersist(entities); + } + +} diff --git a/querydsl-jdo/src/test/java/com/querydsl/jdo/JDOQLMethodsTest.java b/querydsl-jdo/src/test/java/com/querydsl/jdo/JDOQLMethodsTest.java new file mode 100644 index 0000000000..70de43f8b1 --- /dev/null +++ b/querydsl-jdo/src/test/java/com/querydsl/jdo/JDOQLMethodsTest.java @@ -0,0 +1,90 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jdo; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.junit.BeforeClass; +import org.junit.Test; + +import com.querydsl.core.types.dsl.*; +import com.querydsl.jdo.test.domain.Product; +import com.querydsl.jdo.test.domain.QProduct; +import com.querydsl.jdo.test.domain.QStore; + +public class JDOQLMethodsTest extends AbstractJDOTest { + + private QProduct product = QProduct.product; + + private QStore store = QStore.store; + + @Test + public void test() { + Product p = query().from(product).limit(1).select(product).fetchOne(); + for (BooleanExpression f : getFilters( + product.name, product.description, "A0", + store.products, p, + store.productsByName, "A0", p, + product.amount)) { + query().from(store, product).where(f).select(store, product); + } + } + + private <A,K,V> List<BooleanExpression> getFilters( + StringExpression str, StringExpression other, String knownString, + ListPath<A,?> list, A element, + MapPath<K,V, ?> map, K key, V value, + NumberExpression<Integer> number) { + return Arrays.<BooleanExpression>asList( + // java.lang.String + str.startsWith(knownString), + str.endsWith(knownString), + str.indexOf(knownString).gt(-1), + str.indexOf(knownString, 1).gt(-1), + str.substring(1).eq(knownString), + str.substring(1,2).eq(knownString), + str.lower().eq(knownString), + str.likeIgnoreCase(knownString), + str.upper().eq(knownString), + str.matches(".*"), + // java.util.Collection + list.isEmpty(), + list.isNotEmpty(), + list.contains(element), + list.size().gt(0), + // java.util.Map + map.isEmpty(), + map.isNotEmpty(), + map.containsKey(key), + map.containsValue(value), + map.get(key).eq(value), + map.size().gt(0), + number.abs().gt(0), + number.sqrt().gt(0) + ); + } + + @BeforeClass + public static void doPersist() { + List<Object> entities = new ArrayList<>(); + for (int i = 0; i < 10; i++) { + entities.add(new Product("C" + i, "F" + i, i * 200.00, 2)); + entities.add(new Product("B" + i, "E" + i, i * 200.00, 4)); + entities.add(new Product("A" + i, "D" + i, i * 200.00, 6)); + } + doPersist(entities); + } +} diff --git a/querydsl-jdo/src/test/java/com/querydsl/jdo/JDOQLTemplatesTest.java b/querydsl-jdo/src/test/java/com/querydsl/jdo/JDOQLTemplatesTest.java new file mode 100644 index 0000000000..bdc537806b --- /dev/null +++ b/querydsl-jdo/src/test/java/com/querydsl/jdo/JDOQLTemplatesTest.java @@ -0,0 +1,70 @@ +package com.querydsl.jdo; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.Operator; +import com.querydsl.core.types.Ops; +import com.querydsl.core.types.TemplatesTestUtils; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.StringPath; + +public class JDOQLTemplatesTest { + + @Test + public void precedence() { +// Cast +// Unary ("~") ("!") + int p1 = getPrecedence(Ops.NOT); +// Unary ("+") ("-") + int p2 = getPrecedence(Ops.NEGATE); +// Multiplicative ("*") ("/") ("%") + int p3 = getPrecedence(Ops.MULT, Ops.DIV, Ops.MOD); +// Additive ("+") ("-") + int p4 = getPrecedence(Ops.ADD, Ops.SUB); +// Relational (">=") (">") ("<=") ("<") ("instanceof") + int p5 = getPrecedence(Ops.GOE, Ops.GT, Ops.LOE, Ops.LT, Ops.INSTANCE_OF); +// Equality ("==") ("!=") + int p6 = getPrecedence(Ops.EQ, Ops.EQ_IGNORE_CASE, Ops.NE); +// Boolean logical AND ("&") +// Boolean logical OR ("|") +// Conditional AND ("&&") + int p7 = getPrecedence(Ops.AND); +// Conditional OR ("||") + int p8 = getPrecedence(Ops.OR); + + assertTrue(p1 < p2); + assertTrue(p2 < p3); + assertTrue(p3 < p4); + assertTrue(p4 < p5); + assertTrue(p5 < p6); + assertTrue(p6 < p7); + assertTrue(p7 < p8); + } + + protected int getPrecedence(Operator... ops) { + int precedence = JDOQLTemplates.DEFAULT.getPrecedence(ops[0]); + for (int i = 1; i < ops.length; i++) { + assertEquals(ops[i].name(), precedence, JDOQLTemplates.DEFAULT.getPrecedence(ops[i])); + } + return precedence; + } + + @Test + public void generic_precedence() { + TemplatesTestUtils.testPrecedence(JDOQLTemplates.DEFAULT); + } + + @Test + public void concat() { + StringPath a = Expressions.stringPath("a"); + StringPath b = Expressions.stringPath("b"); + StringPath c = Expressions.stringPath("c"); + Expression<?> expr = a.append(b).toLowerCase(); + String str = new JDOQLSerializer(JDOQLTemplates.DEFAULT, c).handle(expr).toString(); + assertEquals("(a + b).toLowerCase()", str); + } +} diff --git a/querydsl-jdo/src/test/java/com/querydsl/jdo/JDOQueryFactoryTest.java b/querydsl-jdo/src/test/java/com/querydsl/jdo/JDOQueryFactoryTest.java new file mode 100644 index 0000000000..8c837b1155 --- /dev/null +++ b/querydsl-jdo/src/test/java/com/querydsl/jdo/JDOQueryFactoryTest.java @@ -0,0 +1,53 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jdo; + +import static org.junit.Assert.assertNotNull; + +import javax.jdo.PersistenceManager; + +import org.easymock.EasyMock; +import org.junit.Before; +import org.junit.Test; + +import com.querydsl.jdo.test.domain.QProduct; + +import java.util.function.Supplier; + +public class JDOQueryFactoryTest { + + private JDOQueryFactory queryFactory; + + @Before + public void setUp() { + Supplier<PersistenceManager> provider = () -> EasyMock.<PersistenceManager> createNiceMock(PersistenceManager.class); + queryFactory = new JDOQueryFactory(provider); + } + + @Test + public void query() { + assertNotNull(queryFactory.query()); + } + + @Test + public void from() { + assertNotNull(queryFactory.from(QProduct.product)); + } + + @Test + public void delete() { + assertNotNull(queryFactory.delete(QProduct.product)); + } + +} diff --git a/querydsl-jdo/src/test/java/com/querydsl/jdo/JDOQueryStandardTest.java b/querydsl-jdo/src/test/java/com/querydsl/jdo/JDOQueryStandardTest.java new file mode 100644 index 0000000000..cfbaeb8316 --- /dev/null +++ b/querydsl-jdo/src/test/java/com/querydsl/jdo/JDOQueryStandardTest.java @@ -0,0 +1,196 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jdo; + +import static org.junit.Assert.*; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.List; + +import org.junit.BeforeClass; +import org.junit.Ignore; +import org.junit.Test; + +import com.querydsl.core.*; +import com.querydsl.core.types.ArrayConstructorExpression; +import com.querydsl.core.types.ParamNotSetException; +import com.querydsl.core.types.Predicate; +import com.querydsl.core.types.Projections; +import com.querydsl.core.types.dsl.Param; +import com.querydsl.jdo.test.domain.Book; +import com.querydsl.jdo.test.domain.Product; +import com.querydsl.jdo.test.domain.QBook; +import com.querydsl.jdo.test.domain.QProduct; +import com.querydsl.jdo.test.domain.QStore; +import com.querydsl.jdo.test.domain.Store; + +public class JDOQueryStandardTest extends AbstractJDOTest { + + public static class Projection { + + public Projection(String str) { } + + } + + private static final Date publicationDate; + + private static final java.sql.Date date; + + private static final java.sql.Time time; + + static { + Calendar cal = Calendar.getInstance(); + cal.set(2000, 1, 2, 3, 4); + cal.set(Calendar.MILLISECOND, 0); + publicationDate = cal.getTime(); + date = new java.sql.Date(cal.getTimeInMillis()); + time = new java.sql.Time(cal.getTimeInMillis()); + } + + private static String productName = "ABCD"; + + private static String otherName = "ABC0"; + + @BeforeClass + public static void doPersist() { + List<Object> entities = new ArrayList<>(); + for (int i = 0; i < 10; i++) { + // Product instances + entities.add(new Product("ABC" + i, "F" + i, i * 200.00, 2, publicationDate)); + entities.add(new Product("DEF" + i, "E" + i, i * 200.00, 4, publicationDate)); + entities.add(new Product("GHI" + i, "D" + i, i * 200.00, 6, publicationDate)); + + // Product of Store + Product product = new Product(productName,"A",100.0,1, publicationDate); + entities.add(product); + + // Store instances + Store store = new Store(); + store.getProducts().add(product); + store.getProductsByName().put(productName, product); + entities.add(store); + } + doPersist(entities); + } + + private final QueryExecution standardTest = new QueryExecution(QuerydslModule.JDO, Target.H2) { + @Override + protected Fetchable createQuery() { + return query().from(store, product, otherProduct).select(store, product, otherProduct); + } + @Override + protected Fetchable createQuery(Predicate filter) { + return query().from(store, product, otherProduct).where(filter) + .select(store, product, otherProduct); + } + }; + + private final QProduct product = QProduct.product; + + private final QProduct otherProduct = new QProduct("otherProduct"); + + private final QStore store = QStore.store; + + private final QStore otherStore = new QStore("otherStore"); + + @Test + public void standardTest() { + Product p = query().from(product).where(product.name.eq(productName)).limit(1).select(product).fetchOne(); + Product p2 = query().from(product).where(product.name.startsWith(otherName)).limit(1).select(product).fetchOne(); + standardTest.noProjections(); + standardTest.noCounts(); + + standardTest.runBooleanTests(product.name.isNull(), otherProduct.price.lt(10.00)); + standardTest.runCollectionTests(store.products, otherStore.products, p, p2); + standardTest.runDateTests(product.dateField, otherProduct.dateField, date); + standardTest.runDateTimeTests(product.publicationDate, otherProduct.publicationDate, publicationDate); + // NO list support in JDOQL +// testData.listTests(store.products, otherStore.products, p); + standardTest.runMapTests(store.productsByName, otherStore.productsByName, productName, p, "X", p2); + standardTest.runNumericCasts(product.price, otherProduct.price, 200.0); + standardTest.runNumericTests(product.amount, otherProduct.amount, 2); + standardTest.runStringTests(product.name, otherProduct.name, productName); + standardTest.runTimeTests(product.timeField, otherProduct.timeField, time); + + standardTest.report(); + } + + @Test + public void tupleProjection() { + List<Tuple> tuples = query().from(product).select(product.name, product.price).fetch(); + assertFalse(tuples.isEmpty()); + for (Tuple tuple : tuples) { + assertNotNull(tuple); + assertNotNull(tuple.get(product.name)); + assertNotNull(tuple.get(product.price)); + assertNotNull(tuple.get(0,String.class)); + assertNotNull(tuple.get(1,Double.class)); + } + } + + @SuppressWarnings("unchecked") + @Test + @Ignore + public void arrayProjection() { + // typed array not supported + List<String[]> results = query().from(store) + .select(new ArrayConstructorExpression<String>(String[].class, store.name)).fetch(); + assertFalse(results.isEmpty()); + for (String[] result : results) { + assertNotNull(result); + assertNotNull(result[0]); + } + } + + @Test + @Ignore + public void constructorProjection() { + List<Projection> results = query().from(store) + .select(Projections.constructor(Projection.class, store.name)).fetch(); + assertFalse(results.isEmpty()); + for (Projection result : results) { + assertNotNull(result); + } + } + + @Test + public void params() { + Param<String> name = new Param<String>(String.class,"name"); + assertEquals("ABC0",query().from(product).where(product.name.eq(name)).set(name, "ABC0") + .select(product.name).fetchFirst()); + } + + @Test + public void params_anon() { + Param<String> name = new Param<String>(String.class); + assertEquals("ABC0",query().from(product).where(product.name.eq(name)).set(name, "ABC0") + .select(product.name).fetchFirst()); + } + + @Test(expected = ParamNotSetException.class) + public void params_not_set() { + Param<String> name = new Param<String>(String.class,"name"); + assertEquals("ABC0",query().from(product).where(product.name.eq(name)) + .select(product.name).fetchFirst()); + } + + @Test + public void detatchCollection() { + new JDOQuery<Book>(pm, true) + .select(QBook.book).from(QBook.book) + .fetch(); + } +} diff --git a/querydsl-jdo/src/test/java/com/querydsl/jdo/JDOSQLQueryTest.java b/querydsl-jdo/src/test/java/com/querydsl/jdo/JDOSQLQueryTest.java new file mode 100644 index 0000000000..1749a679bf --- /dev/null +++ b/querydsl-jdo/src/test/java/com/querydsl/jdo/JDOSQLQueryTest.java @@ -0,0 +1,170 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jdo; + +import static org.junit.Assert.*; + +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +import org.junit.BeforeClass; +import org.junit.Ignore; +import org.junit.Test; + +import com.querydsl.core.NonUniqueResultException; +import com.querydsl.core.QueryResults; +import com.querydsl.core.Tuple; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.Projections; +import com.querydsl.core.types.SubQueryExpression; +import com.querydsl.core.types.dsl.BooleanExpression; +import com.querydsl.jdo.sql.JDOSQLQuery; +import com.querydsl.jdo.test.domain.Product; +import com.querydsl.jdo.test.domain.sql.SProduct; +import com.querydsl.sql.HSQLDBTemplates; +import com.querydsl.sql.SQLTemplates; + +public class JDOSQLQueryTest extends AbstractJDOTest { + + private final SQLTemplates sqlTemplates = new HSQLDBTemplates(); + + private final SProduct product = SProduct.product; + + protected JDOSQLQuery<?> sql() { + return new JDOSQLQuery<Void>(pm, sqlTemplates); + } + + @Test + public void count() { + assertEquals(30L, sql().from(product).fetchCount()); + } + + @Test(expected = NonUniqueResultException.class) + public void uniqueResult() { + sql().from(product).orderBy(product.name.asc()).select(product.name).fetchOne(); + } + + @Test + public void singleResult() { + assertEquals("A0", sql().from(product).orderBy(product.name.asc()) + .select(product.name).fetchFirst()); + } + + @Test + public void singleResult_with_array() { + assertEquals("A0", sql().from(product).orderBy(product.name.asc()) + .select(new Expression<?>[]{product.name}).fetchFirst().get(product.name)); + } + + @Test + public void startsWith_count() { + assertEquals(10L, sql().from(product).where(product.name.startsWith("A")).fetchCount()); + assertEquals(10L, sql().from(product).where(product.name.startsWith("B")).fetchCount()); + assertEquals(10L, sql().from(product).where(product.name.startsWith("C")).fetchCount()); + + } + + @Test + public void eq_count() { + for (int i = 0; i < 10; i++) { + assertEquals(1L, sql().from(product).where(product.name.eq("A" + i)).fetchCount()); + assertEquals(1L, sql().from(product).where(product.name.eq("B" + i)).fetchCount()); + assertEquals(1L, sql().from(product).where(product.name.eq("C" + i)).fetchCount()); + } + } + + @Test + public void scalarQueries() { + BooleanExpression filter = product.name.startsWith("A"); + + // fetchCount + assertEquals(10L, sql().from(product).where(filter).fetchCount()); + + // countDistinct + assertEquals(10L, sql().from(product).where(filter).distinct().fetchCount()); + + // fetch + assertEquals(10, sql().from(product).where(filter).select(product.name).fetch().size()); + + // fetch with limit + assertEquals(3, sql().from(product).limit(3).select(product.name).fetch().size()); + + // fetch with offset +// assertEquals(7, sql().from(product).offset(3).fetch(product.name).size()); + + // fetch with limit and offset + assertEquals(3, sql().from(product).offset(3).limit(3).select(product.name).fetch().size()); + + // fetch multiple + for (Tuple row : sql().from(product).select(product.productId, product.name, product.amount).fetch()) { + assertNotNull(row.get(0, Object.class)); + assertNotNull(row.get(1, Object.class)); + assertNotNull(row.get(2, Object.class)); + } + + // fetchResults + QueryResults<String> results = sql().from(product).limit(3).select(product.name).fetchResults(); + assertEquals(3, results.getResults().size()); + assertEquals(30L, results.getTotal()); + + } + + @Ignore + @Test + @SuppressWarnings("unchecked") + public void union() throws SQLException { + SubQueryExpression<Integer> sq1 = sql().from(product).select(product.amount.max()); + SubQueryExpression<Integer> sq2 = sql().from(product).select(product.amount.min()); + List<Integer> list = sql().union(sq1, sq2).list(); + assertFalse(list.isEmpty()); + } + + @Ignore + @Test + @SuppressWarnings("unchecked") + public void union_all() { + SubQueryExpression<Integer> sq1 = sql().from(product).select(product.amount.max()); + SubQueryExpression<Integer> sq2 = sql().from(product).select(product.amount.min()); + List<Integer> list = sql().unionAll(sq1, sq2).list(); + assertFalse(list.isEmpty()); + } + + @Test + public void entityProjections() { + List<Product> products = sql() + .from(product) + .select(Projections.constructor(Product.class, + product.name, product.description, product.price, product.amount)).fetch(); + assertEquals(30, products.size()); + for (Product p : products) { + assertNotNull(p.getName()); + assertNotNull(p.getDescription()); + assertNotNull(p.getPrice()); + assertNotNull(p.getAmount()); + } + } + + @BeforeClass + public static void doPersist() { + List<Object> entities = new ArrayList<>(); + for (int i = 0; i < 10; i++) { + entities.add(new Product("C" + i, "F", 200.00, 2)); + entities.add(new Product("B" + i, "E", 400.00, 4)); + entities.add(new Product("A" + i, "D", 600.00, 6)); + } + doPersist(entities); + } + +} diff --git a/querydsl-jdo/src/test/java/com/querydsl/jdo/OrderingTest.java b/querydsl-jdo/src/test/java/com/querydsl/jdo/OrderingTest.java new file mode 100644 index 0000000000..3840f4e96b --- /dev/null +++ b/querydsl-jdo/src/test/java/com/querydsl/jdo/OrderingTest.java @@ -0,0 +1,112 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jdo; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.junit.BeforeClass; +import org.junit.Test; + +import com.querydsl.core.QueryResults; +import com.querydsl.core.Tuple; +import com.querydsl.jdo.test.domain.Product; +import com.querydsl.jdo.test.domain.QProduct; + +public class OrderingTest extends AbstractJDOTest { + + private QProduct product = QProduct.product; + + @Test + public void order_asc() { + List<String> namesAsc = query().from(product).orderBy( + product.name.asc(), product.description.desc()).select( + product.name).fetch(); + assertEquals(30, namesAsc.size()); + String prev = null; + for (String name : namesAsc) { + if (prev != null) { + assertTrue(prev.compareTo(name) < 0); + } + prev = name; + } + } + + @Test + public void order_desc() { + List<String> namesDesc = query().from(product).orderBy( + product.name.desc()).select(product.name).fetch(); + assertEquals(30, namesDesc.size()); + String prev = null; + for (String name : namesDesc) { + if (prev != null) { + assertTrue(prev.compareTo(name) > 0); + } + prev = name; + } + } + + @Test + public void tabularResults() { + List<Tuple> rows = query().from(product).orderBy(product.name.asc()) + .select(product.name, product.description).fetch(); + assertEquals(30, rows.size()); + for (Tuple row : rows) { + assertEquals(row.get(0, String.class).substring(1), + row.get(1, String.class).substring(1)); + } + } + + @Test + public void limit_order_asc() { + assertEquals(Arrays.asList("A0", "A1"), + query().from(product).orderBy(product.name.asc()).limit(2).select(product.name).fetch()); + } + + @Test + public void limit_order_desc() { + assertEquals(Arrays.asList("C9", "C8"), + query().from(product).orderBy(product.name.desc()).limit(2).select(product.name).fetch()); + } + + public void limit_and_offset() { + assertEquals(Arrays.asList("A2", "A3", "A4"), + query().from(product).orderBy(product.name.asc()).offset(2).limit(3).select(product.name).fetch()); + } + + @Test + public void queryResults() { + QueryResults<String> results = query().from(product).orderBy( + product.name.asc()).limit(2).select(product.name).fetchResults(); + assertEquals(Arrays.asList("A0", "A1"), results.getResults()); + assertEquals(30, results.getTotal()); + + } + + @BeforeClass + public static void doPersist() { + List<Object> entities = new ArrayList<>(); + for (int i = 0; i < 10; i++) { + entities.add(new Product("C" + i, "F" + i, i * 200.00, 2)); + entities.add(new Product("B" + i, "E" + i, i * 200.00, 4)); + entities.add(new Product("A" + i, "D" + i, i * 200.00, 6)); + } + doPersist(entities); + } + +} diff --git a/querydsl-jdo/src/test/java/com/querydsl/jdo/PackageVerification.java b/querydsl-jdo/src/test/java/com/querydsl/jdo/PackageVerification.java new file mode 100644 index 0000000000..f2ded1fba3 --- /dev/null +++ b/querydsl-jdo/src/test/java/com/querydsl/jdo/PackageVerification.java @@ -0,0 +1,56 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jdo; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.Scanner; + +import javax.jdo.annotations.PersistenceCapable; + +import org.junit.Test; + +import com.querydsl.codegen.utils.CodeWriter; +import com.querydsl.apt.jdo.JDOAnnotationProcessor; +import com.querydsl.codegen.CodegenModule; +import com.querydsl.core.types.Expression; + +public class PackageVerification { + + @Test + public void verify_package() throws Exception { + String version = System.getProperty("version"); + verify(new File("target/querydsl-jdo-" + version + "-apt-one-jar.jar")); + } + + private void verify(File oneJar) throws Exception { + assertTrue(oneJar.getPath() + " doesn't exist", oneJar.exists()); + // verify classLoader + URLClassLoader oneJarClassLoader = new URLClassLoader(new URL[]{oneJar.toURI().toURL()}); + oneJarClassLoader.loadClass(Expression.class.getName()); // querydsl-core + oneJarClassLoader.loadClass(CodeWriter.class.getName()); // codegen + oneJarClassLoader.loadClass(CodegenModule.class.getName()).newInstance(); + oneJarClassLoader.loadClass(PersistenceCapable.class.getName()); // jdo + Class cl = oneJarClassLoader.loadClass(JDOAnnotationProcessor.class.getName()); // querydsl-apt + cl.newInstance(); + String resourceKey = "META-INF/services/javax.annotation.processing.Processor"; + assertEquals(JDOAnnotationProcessor.class.getName(), + new Scanner(oneJarClassLoader.findResource(resourceKey).openStream()).nextLine()); + } + +} diff --git a/querydsl-jdo/src/test/java/com/querydsl/jdo/QueryMutabilityTest.java b/querydsl-jdo/src/test/java/com/querydsl/jdo/QueryMutabilityTest.java new file mode 100644 index 0000000000..a383b9860a --- /dev/null +++ b/querydsl-jdo/src/test/java/com/querydsl/jdo/QueryMutabilityTest.java @@ -0,0 +1,47 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jdo; + +import static org.junit.Assert.assertEquals; + +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; + +import org.junit.Test; + +import com.querydsl.core.QueryMutability; +import com.querydsl.jdo.test.domain.QProduct; + +public class QueryMutabilityTest extends AbstractJDOTest { + + @Test + public void queryMutability() throws IOException, SecurityException, + IllegalArgumentException, NoSuchMethodException, + IllegalAccessException, InvocationTargetException { + QProduct product = QProduct.product; + JDOQuery<?> query = query().from(product); + new QueryMutability(query).test(product.name, product.description); + } + + @Test + public void clone_() { + QProduct product = QProduct.product; + JDOQuery<?> query = new JDOQuery<Void>().from(product).where(product.name.isNotNull()); + JDOQuery<?> query2 = query.clone(pm); + assertEquals(query.getMetadata().getJoins(), query2.getMetadata().getJoins()); + assertEquals(query.getMetadata().getWhere(), query2.getMetadata().getWhere()); + query2.select(product).fetch(); + } + +} diff --git a/querydsl-jdo/src/test/java/com/querydsl/jdo/SubqueriesTest.java b/querydsl-jdo/src/test/java/com/querydsl/jdo/SubqueriesTest.java new file mode 100644 index 0000000000..2583a8909e --- /dev/null +++ b/querydsl-jdo/src/test/java/com/querydsl/jdo/SubqueriesTest.java @@ -0,0 +1,128 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jdo; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.BeforeClass; +import org.junit.Test; + +import com.querydsl.jdo.test.domain.Product; +import com.querydsl.jdo.test.domain.QProduct; + +public class SubqueriesTest extends AbstractJDOTest { + + private QProduct product = QProduct.product; + + private QProduct other = new QProduct("other"); + + @Test + public void list_exists() { + query().from(product).where(query().from(other).select(other).exists()).select(product).fetch(); + } + + @Test + public void list_notExists() { + query().from(product).where(query().from(other).select(other).notExists()).select(product).fetch(); + } + + @Test + public void list_contains() { + query().from(product).where(product.name.in(query().from(other).select(other.name))).select(product).fetch(); + } + + @Test + public void gt_subquery() { + double avg = query().from(product).select(product.price.avg()).fetchFirst(); + for (double price : query().from(product) + .where(product.price.gt(query().from(other).select(other.price.avg()))) + .select(product.price).fetch()) { + assertTrue(price > avg); + } + } + + @Test + public void gt_subquery_with_condition() { + for (double price : query().from(product) + .where(product.price.gt(query().from(other).where(other.name.eq("XXX")).select(other.price.avg()))) + .select(product.price).fetch()) { + System.out.println(price); + } + } + + @Test + public void eq_subquery() { + double avg = query().from(product).select(product.price.avg()).fetchFirst(); + for (double price : query().from(product) + .where(product.price.eq(query().from(other).select(other.price.avg()))) + .select(product.price).fetch()) { + assertEquals(avg, price, 0.0001); + } + } + + + @Test + public void in_subquery() { + for (double price : query().from(product) + .where(product.price.in( + query().from(other).where(other.name.eq("Some name")).select(other.price))) + .select(product.price).fetch()) { + System.out.println(price); + } + } + + @Test + public void count() { + for (double price : query().from(product) + .where(query().from(other).where(other.price.gt(product.price)).select(other.count()).gt(0L)) + .select(product.price).fetch()) { + System.out.println(price); + } + } + + @Test + public void exists() { + for (double price : query().from(product) + .where(query().from(other).where(other.price.gt(product.price)).exists()) + .select(product.price).fetch()) { + System.out.println(price); + } + } + + @Test + public void not_exists() { + for (double price : query().from(product) + .where(query().from(other).where(other.price.gt(product.price)).notExists()) + .select(product.price).fetch()) { + System.out.println(price); + } + } + + + + @BeforeClass + public static void doPersist() { + List<Object> entities = new ArrayList<>(); + for (int i = 0; i < 10; i++) { + entities.add(new Product("C" + i, "F" + i, i * 200.00, 2)); + entities.add(new Product("B" + i, "E" + i, i * 200.00, 4)); + entities.add(new Product("A" + i, "D" + i, i * 200.00, 6)); + } + doPersist(entities); + } +} diff --git a/querydsl-jdo/src/test/java/com/querydsl/jdo/TemplatesTest.java b/querydsl-jdo/src/test/java/com/querydsl/jdo/TemplatesTest.java new file mode 100644 index 0000000000..2485ea037e --- /dev/null +++ b/querydsl-jdo/src/test/java/com/querydsl/jdo/TemplatesTest.java @@ -0,0 +1,22 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team). + * + * 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. + */ +package com.querydsl.jdo; + +import com.querydsl.core.TemplatesTestBase; + +public class TemplatesTest extends TemplatesTestBase { + +} diff --git a/querydsl-jdo/src/test/java/com/querydsl/jdo/models/company/Account.java b/querydsl-jdo/src/test/java/com/querydsl/jdo/models/company/Account.java new file mode 100644 index 0000000000..cf7379cdda --- /dev/null +++ b/querydsl-jdo/src/test/java/com/querydsl/jdo/models/company/Account.java @@ -0,0 +1,55 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jdo.models.company; + +import com.querydsl.core.annotations.QueryEntity; + +/** + * User account for a person. + * + * @version $Revision: 1.2 $ + */ +@QueryEntity +public class Account { + private long id; // PK if app id + private String username; + private boolean enabled; + + public Account() { + } + + public void setId(long id) { + this.id = id; + } + + public long getId() { + return id; + } + + public boolean getEnabled() { + return enabled; + } + + public void setEnabled(boolean b) { + enabled = b; + } + + public String getUsername() { + return username; + } + + public void setUsername(String s) { + username = s; + } +} diff --git a/querydsl-jdo/src/test/java/com/querydsl/jdo/models/company/Department.java b/querydsl-jdo/src/test/java/com/querydsl/jdo/models/company/Department.java new file mode 100644 index 0000000000..8d2019cde4 --- /dev/null +++ b/querydsl-jdo/src/test/java/com/querydsl/jdo/models/company/Department.java @@ -0,0 +1,79 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jdo.models.company; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import com.querydsl.core.annotations.QueryEntity; + +/** + * Department in a company. Has a Manager, and a set of Projects being worked + * on. + * + * @version $Revision: 1.1 $ + */ +@QueryEntity +public class Department { + private String name; + private Manager manager; + private Set<Project> projects = new HashSet<Project>(); + private List<Employee> employees; + + public Department() { + + } + + public Department(String name) { + this.name = name; + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public void setManager(Manager mgr) { + this.manager = mgr; + } + + public Manager getManager() { + return this.manager; + } + + public Set<Project> getProjects() { + return projects; + } + + public void setProjects(Set<Project> projects) { + this.projects = projects; + } + + public void addProject(Project proj) { + this.projects.add(proj); + } + + public String toString() { + return name; + } + + public List<Employee> getEmployees() { + return employees; + } + +} diff --git a/querydsl-jdo/src/test/java/com/mysema/query/jdo/models/company/Developer.java b/querydsl-jdo/src/test/java/com/querydsl/jdo/models/company/Developer.java similarity index 88% rename from querydsl-jdo/src/test/java/com/mysema/query/jdo/models/company/Developer.java rename to querydsl-jdo/src/test/java/com/querydsl/jdo/models/company/Developer.java index 68b8977a49..2ae53dd237 100644 --- a/querydsl-jdo/src/test/java/com/mysema/query/jdo/models/company/Developer.java +++ b/querydsl-jdo/src/test/java/com/querydsl/jdo/models/company/Developer.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,9 +11,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.jdo.models.company; +package com.querydsl.jdo.models.company; -import com.mysema.query.annotations.QueryEntity; +import com.querydsl.core.annotations.QueryEntity; /** * Developer of software for a system. diff --git a/querydsl-jdo/src/test/java/com/mysema/query/jdo/models/company/DeveloperRC.java b/querydsl-jdo/src/test/java/com/querydsl/jdo/models/company/DeveloperRC.java similarity index 86% rename from querydsl-jdo/src/test/java/com/mysema/query/jdo/models/company/DeveloperRC.java rename to querydsl-jdo/src/test/java/com/querydsl/jdo/models/company/DeveloperRC.java index 4d8d42e603..6f8cb05082 100644 --- a/querydsl-jdo/src/test/java/com/mysema/query/jdo/models/company/DeveloperRC.java +++ b/querydsl-jdo/src/test/java/com/querydsl/jdo/models/company/DeveloperRC.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,12 +11,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.jdo.models.company; +package com.querydsl.jdo.models.company; import java.math.BigDecimal; import java.math.BigInteger; -import com.mysema.query.annotations.QueryEntity; +import com.querydsl.core.annotations.QueryEntity; @QueryEntity public class DeveloperRC extends PersonRC { @@ -44,7 +44,7 @@ public void setId(Long id) { * The id to set. */ public void setId(BigDecimal id) { - this.id = Long.valueOf(id.longValue()); + this.id = id.longValue(); } /** @@ -52,7 +52,7 @@ public void setId(BigDecimal id) { * The id to set. */ public void setId(BigInteger id) { - this.id = Long.valueOf(id.longValue()); + this.id = id.longValue(); } /** diff --git a/querydsl-jdo/src/test/java/com/querydsl/jdo/models/company/Employee.java b/querydsl-jdo/src/test/java/com/querydsl/jdo/models/company/Employee.java new file mode 100644 index 0000000000..e540d649c4 --- /dev/null +++ b/querydsl-jdo/src/test/java/com/querydsl/jdo/models/company/Employee.java @@ -0,0 +1,111 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jdo.models.company; + +import com.querydsl.core.annotations.QueryEntity; + +/** + * Employee in a company. + * + * @version $Revision: 1.3 $ + */ +@QueryEntity +public class Employee extends Person { + private String serialNo; + private float salary; + private String salaryCurrency; + private Integer yearsInCompany; + private Manager manager; + private Account account; + private int weeklyhours; + private Department department; + + /** Used for the querying of static fields. */ + public static final String FIRSTNAME = "Bart"; + + public Employee() { + } + + public Employee(long id, String firstname, String lastname, String email, + float sal, String serial) { + super(id, firstname, lastname, email); + this.salary = sal; + this.serialNo = serial; + } + + public Employee(long id, String firstname, String lastname, String email, + float sal, String serial, Integer yearsInCompany) { + super(id, firstname, lastname, email); + this.salary = sal; + this.serialNo = serial; + this.yearsInCompany = yearsInCompany; + } + + public Account getAccount() { + return this.account; + } + + public String getSerialNo() { + return this.serialNo; + } + + public float getSalary() { + return this.salary; + } + + public String getSalaryCurrency() { + return this.salaryCurrency; + } + + public Manager getManager() { + return this.manager; + } + + public Integer getYearsInCompany() { + return this.yearsInCompany; + } + + public void setManager(Manager mgr) { + this.manager = mgr; + } + + public void setAccount(Account acct) { + this.account = acct; + } + + public void setSerialNo(String sn) { + this.serialNo = sn; + } + + public void setSalary(float s) { + this.salary = s; + } + + public void setSalaryCurrency(String s) { + this.salaryCurrency = s; + } + + public void setYearsInCompany(Integer y) { + this.yearsInCompany = y; + } + + public int getWeeklyhours() { + return weeklyhours; + } + + public Department getDepartment() { + return department; + } + +} diff --git a/querydsl-jdo/src/test/java/com/mysema/query/jdo/models/company/InsuranceDepartment.java b/querydsl-jdo/src/test/java/com/querydsl/jdo/models/company/InsuranceDepartment.java similarity index 87% rename from querydsl-jdo/src/test/java/com/mysema/query/jdo/models/company/InsuranceDepartment.java rename to querydsl-jdo/src/test/java/com/querydsl/jdo/models/company/InsuranceDepartment.java index 837e2e7933..6b2d80b610 100644 --- a/querydsl-jdo/src/test/java/com/mysema/query/jdo/models/company/InsuranceDepartment.java +++ b/querydsl-jdo/src/test/java/com/querydsl/jdo/models/company/InsuranceDepartment.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,9 +11,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.jdo.models.company; +package com.querydsl.jdo.models.company; -import com.mysema.query.annotations.QueryEntity; +import com.querydsl.core.annotations.QueryEntity; @QueryEntity public class InsuranceDepartment extends Department { diff --git a/querydsl-jdo/src/test/java/com/mysema/query/jdo/models/company/Manager.java b/querydsl-jdo/src/test/java/com/querydsl/jdo/models/company/Manager.java similarity index 92% rename from querydsl-jdo/src/test/java/com/mysema/query/jdo/models/company/Manager.java rename to querydsl-jdo/src/test/java/com/querydsl/jdo/models/company/Manager.java index b5f11d00ee..36154060c9 100644 --- a/querydsl-jdo/src/test/java/com/mysema/query/jdo/models/company/Manager.java +++ b/querydsl-jdo/src/test/java/com/querydsl/jdo/models/company/Manager.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,13 +11,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.jdo.models.company; +package com.querydsl.jdo.models.company; import java.util.Collection; import java.util.HashSet; import java.util.Set; -import com.mysema.query.annotations.QueryEntity; +import com.querydsl.core.annotations.QueryEntity; /** * Manager of a set of Employees, and departments. diff --git a/querydsl-jdo/src/test/java/com/mysema/query/jdo/models/company/Office.java b/querydsl-jdo/src/test/java/com/querydsl/jdo/models/company/Office.java similarity index 94% rename from querydsl-jdo/src/test/java/com/mysema/query/jdo/models/company/Office.java rename to querydsl-jdo/src/test/java/com/querydsl/jdo/models/company/Office.java index b645b2fcdd..7d1f800fb9 100644 --- a/querydsl-jdo/src/test/java/com/mysema/query/jdo/models/company/Office.java +++ b/querydsl-jdo/src/test/java/com/querydsl/jdo/models/company/Office.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.jdo.models.company; +package com.querydsl.jdo.models.company; import java.io.Serializable; import java.util.Date; @@ -19,7 +19,7 @@ import java.util.Set; import java.util.StringTokenizer; -import com.mysema.query.annotations.QueryEntity; +import com.querydsl.core.annotations.QueryEntity; /** * An office in the company. @@ -55,7 +55,7 @@ public void setDate(Date date) { } /** - * Accessor for the roomt name + * Accessor for the room name * * @return Returns the room name. */ @@ -112,8 +112,9 @@ public boolean equals(Object o) { if (o == this) { return true; } - if ((o == null) || (o.getClass() != this.getClass())) + if ((o == null) || (o.getClass() != this.getClass())) { return false; + } Office other = (Office) o; return floor == other.floor diff --git a/querydsl-jdo/src/test/java/com/mysema/query/jdo/models/company/Organisation.java b/querydsl-jdo/src/test/java/com/querydsl/jdo/models/company/Organisation.java similarity index 84% rename from querydsl-jdo/src/test/java/com/mysema/query/jdo/models/company/Organisation.java rename to querydsl-jdo/src/test/java/com/querydsl/jdo/models/company/Organisation.java index 598fde8d4d..a5e4bf1b65 100644 --- a/querydsl-jdo/src/test/java/com/mysema/query/jdo/models/company/Organisation.java +++ b/querydsl-jdo/src/test/java/com/querydsl/jdo/models/company/Organisation.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,9 +11,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.jdo.models.company; +package com.querydsl.jdo.models.company; -import com.mysema.query.annotations.QueryEntity; +import com.querydsl.core.annotations.QueryEntity; /** * Organisation that hands out qualifications to employees after taking training diff --git a/querydsl-jdo/src/test/java/com/querydsl/jdo/models/company/Person.java b/querydsl-jdo/src/test/java/com/querydsl/jdo/models/company/Person.java new file mode 100644 index 0000000000..ce4b7ae1a2 --- /dev/null +++ b/querydsl-jdo/src/test/java/com/querydsl/jdo/models/company/Person.java @@ -0,0 +1,215 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jdo.models.company; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; +import java.util.Random; +import java.util.StringTokenizer; + +import com.querydsl.core.annotations.QueryEntity; + +/** + * Person in a company. + */ +@QueryEntity +public class Person implements Cloneable { + + public static class Id implements Serializable { + + private static final long serialVersionUID = -4893934512712167318L; + + public String globalNum; + + public long personNum; + + public Id() { + } + + public Id(String str) { + StringTokenizer toke = new StringTokenizer(str, "::"); + + str = toke.nextToken(); + this.personNum = Integer.parseInt(str); + str = toke.nextToken(); + this.globalNum = str; + } + + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof Id)) { + return false; + } + + Id c = (Id) obj; + return personNum == c.personNum && globalNum.equals(c.globalNum); + } + + public int hashCode() { + return ((int) this.personNum) ^ this.globalNum.hashCode(); + } + + public String toString() { + return String.valueOf(this.personNum) + "::" + + String.valueOf(this.globalNum); + } + } + + /** Used for the querying of static fields. */ + public static final String FIRSTNAME = "Woody"; + + private static Random random = new Random(); + + private int age; + + private Person bestFriend; + + private String emailAddress; + + private String firstName; + + private String globalNum; // Part of PK when app id + + private String lastName; + + private long personNum; // Part of PK when app id + + private Map<String, PhoneNumber> phoneNumbers = new HashMap<String, PhoneNumber>(); + + public Person() { + } + + public Person(long num, String first, String last, String email) { + globalNum = "global:" + random.nextInt(); + personNum = num; + firstName = first; + lastName = last; + emailAddress = email; + } + + public String asString() { + return "Person : number=" + getPersonNum() + " forename=" + + getFirstName() + " surname=" + getLastName() + " email=" + + getEmailAddress() + " bestfriend=" + getBestFriend(); + } + + public Object clone() { + Object o = null; + + try { + o = super.clone(); + } catch (CloneNotSupportedException e) { + /* can't happen */ + } + + return o; + } + + public boolean compareTo(Object obj) { + // TODO Use globalNum here too ? + Person p = (Person) obj; + return bestFriend == p.bestFriend && firstName.equals(p.firstName) + && lastName.equals(p.lastName) + && emailAddress.equals(p.emailAddress) + && personNum == p.personNum; + } + + // Note that this is only really correct for application identity, but we + // also use this class for datastore id + public boolean equals(Object o) { + if (o == this) { + return true; + } + if ((o == null) || (o.getClass() != this.getClass())) { + return false; + } + + Person other = (Person) o; + return personNum == other.personNum + && (globalNum == other.globalNum || (globalNum != null && globalNum + .equals(other.globalNum))); + } + + public int getAge() { + return age; + } + + public Person getBestFriend() { + return bestFriend; + } + + public String getEmailAddress() { + return emailAddress; + } + + public String getFirstName() { + return firstName; + } + + public String getGlobalNum() { + return globalNum; + } + + public synchronized String getLastName() { + return lastName; + } + + public long getPersonNum() { + return personNum; + } + + public Map<String, PhoneNumber> getPhoneNumbers() { + return phoneNumbers; + } + + // Note that this is only really correct for application identity, but we + // also use this class for datastore id + public int hashCode() { + int hash = 7; + hash = 31 * hash + (int) personNum; + hash = 31 * hash + (null == globalNum ? 0 : globalNum.hashCode()); + return hash; + } + + public void setAge(int age) { + this.age = age; + } + + public void setBestFriend(Person p) { + this.bestFriend = p; + } + + public void setEmailAddress(String s) { + emailAddress = s; + } + + public void setFirstName(String s) { + firstName = s; + } + + public void setGlobalNum(String globalNum) { + this.globalNum = globalNum; + } + + public void setLastName(String s) { + lastName = s; + } + + public void setPersonNum(long num) { + personNum = num; + } +} diff --git a/querydsl-jdo/src/test/java/com/mysema/query/jdo/models/company/PersonHolder.java b/querydsl-jdo/src/test/java/com/querydsl/jdo/models/company/PersonHolder.java similarity index 94% rename from querydsl-jdo/src/test/java/com/mysema/query/jdo/models/company/PersonHolder.java rename to querydsl-jdo/src/test/java/com/querydsl/jdo/models/company/PersonHolder.java index 6c72c4f979..7cf78a2985 100644 --- a/querydsl-jdo/src/test/java/com/mysema/query/jdo/models/company/PersonHolder.java +++ b/querydsl-jdo/src/test/java/com/querydsl/jdo/models/company/PersonHolder.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,9 +11,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.jdo.models.company; +package com.querydsl.jdo.models.company; -import com.mysema.query.annotations.QueryEntity; +import com.querydsl.core.annotations.QueryEntity; /** * Convenience class that can be used in query results for holding Person diff --git a/querydsl-jdo/src/test/java/com/mysema/query/jdo/models/company/PersonRC.java b/querydsl-jdo/src/test/java/com/querydsl/jdo/models/company/PersonRC.java similarity index 93% rename from querydsl-jdo/src/test/java/com/mysema/query/jdo/models/company/PersonRC.java rename to querydsl-jdo/src/test/java/com/querydsl/jdo/models/company/PersonRC.java index fd890c36bf..723fbbb854 100644 --- a/querydsl-jdo/src/test/java/com/mysema/query/jdo/models/company/PersonRC.java +++ b/querydsl-jdo/src/test/java/com/querydsl/jdo/models/company/PersonRC.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,12 +11,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.jdo.models.company; +package com.querydsl.jdo.models.company; import java.math.BigDecimal; import java.math.BigInteger; -import com.mysema.query.annotations.QueryEntity; +import com.querydsl.core.annotations.QueryEntity; @QueryEntity public class PersonRC { diff --git a/querydsl-jdo/src/test/java/com/mysema/query/jdo/models/company/PersonalDetails.java b/querydsl-jdo/src/test/java/com/querydsl/jdo/models/company/PersonalDetails.java similarity index 93% rename from querydsl-jdo/src/test/java/com/mysema/query/jdo/models/company/PersonalDetails.java rename to querydsl-jdo/src/test/java/com/querydsl/jdo/models/company/PersonalDetails.java index da0b68758b..d3c67bbd43 100644 --- a/querydsl-jdo/src/test/java/com/mysema/query/jdo/models/company/PersonalDetails.java +++ b/querydsl-jdo/src/test/java/com/querydsl/jdo/models/company/PersonalDetails.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,9 +11,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.jdo.models.company; +package com.querydsl.jdo.models.company; -import com.mysema.query.annotations.QueryEntity; +import com.querydsl.core.annotations.QueryEntity; /** * Details of a person. Represents a subset of the information available from diff --git a/querydsl-jdo/src/test/java/com/querydsl/jdo/models/company/PhoneNumber.java b/querydsl-jdo/src/test/java/com/querydsl/jdo/models/company/PhoneNumber.java new file mode 100644 index 0000000000..61f8a00cf8 --- /dev/null +++ b/querydsl-jdo/src/test/java/com/querydsl/jdo/models/company/PhoneNumber.java @@ -0,0 +1,52 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jdo.models.company; + +import com.querydsl.core.annotations.QueryEntity; + +/** + * Phone number of a person. + * + * @version $Revision: 1.1 $ + */ +@QueryEntity +public class PhoneNumber { + long id; // PK when using app id + String name; + String number; + + public PhoneNumber() { + } + + public PhoneNumber(String name, String number) { + this.name = name; + this.number = number; + } + + public void setId(long id) { + this.id = id; + } + + public long getId() { + return id; + } + + public String getName() { + return name; + } + + public String getNumber() { + return number; + } +} diff --git a/querydsl-jdo/src/test/java/com/mysema/query/jdo/models/company/Project.java b/querydsl-jdo/src/test/java/com/querydsl/jdo/models/company/Project.java similarity index 87% rename from querydsl-jdo/src/test/java/com/mysema/query/jdo/models/company/Project.java rename to querydsl-jdo/src/test/java/com/querydsl/jdo/models/company/Project.java index 0325ecaa45..519c0da252 100644 --- a/querydsl-jdo/src/test/java/com/mysema/query/jdo/models/company/Project.java +++ b/querydsl-jdo/src/test/java/com/querydsl/jdo/models/company/Project.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,9 +11,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.jdo.models.company; +package com.querydsl.jdo.models.company; -import com.mysema.query.annotations.QueryEntity; +import com.querydsl.core.annotations.QueryEntity; /** * Project in a company. diff --git a/querydsl-jdo/src/test/java/com/mysema/query/jdo/models/company/Qualification.java b/querydsl-jdo/src/test/java/com/querydsl/jdo/models/company/Qualification.java similarity index 91% rename from querydsl-jdo/src/test/java/com/mysema/query/jdo/models/company/Qualification.java rename to querydsl-jdo/src/test/java/com/querydsl/jdo/models/company/Qualification.java index faa54b28f1..9d307d6517 100644 --- a/querydsl-jdo/src/test/java/com/mysema/query/jdo/models/company/Qualification.java +++ b/querydsl-jdo/src/test/java/com/querydsl/jdo/models/company/Qualification.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,11 +11,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.jdo.models.company; +package com.querydsl.jdo.models.company; import java.util.Date; -import com.mysema.query.annotations.QueryEntity; +import com.querydsl.core.annotations.QueryEntity; /** * Qualification of a person. diff --git a/querydsl-jdo/src/test/java/com/mysema/query/jdo/models/fitness/Cloth.java b/querydsl-jdo/src/test/java/com/querydsl/jdo/models/fitness/Cloth.java similarity index 83% rename from querydsl-jdo/src/test/java/com/mysema/query/jdo/models/fitness/Cloth.java rename to querydsl-jdo/src/test/java/com/querydsl/jdo/models/fitness/Cloth.java index f23339896d..9d69e8c8a3 100644 --- a/querydsl-jdo/src/test/java/com/mysema/query/jdo/models/fitness/Cloth.java +++ b/querydsl-jdo/src/test/java/com/querydsl/jdo/models/fitness/Cloth.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,9 +11,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.jdo.models.fitness; +package com.querydsl.jdo.models.fitness; -import com.mysema.query.annotations.QueryEntity; +import com.querydsl.core.annotations.QueryEntity; /** * Item of clothing in a Gym. diff --git a/querydsl-jdo/src/test/java/com/mysema/query/jdo/models/fitness/Gym.java b/querydsl-jdo/src/test/java/com/querydsl/jdo/models/fitness/Gym.java similarity index 94% rename from querydsl-jdo/src/test/java/com/mysema/query/jdo/models/fitness/Gym.java rename to querydsl-jdo/src/test/java/com/querydsl/jdo/models/fitness/Gym.java index 5a5414675a..5319e03f59 100644 --- a/querydsl-jdo/src/test/java/com/mysema/query/jdo/models/fitness/Gym.java +++ b/querydsl-jdo/src/test/java/com/querydsl/jdo/models/fitness/Gym.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,12 +11,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.jdo.models.fitness; +package com.querydsl.jdo.models.fitness; import java.util.HashMap; import java.util.Map; -import com.mysema.query.annotations.QueryEntity; +import com.querydsl.core.annotations.QueryEntity; /** * Gymnasium. @@ -29,7 +29,7 @@ public class Gym { private String location; private String name; - // this must be initialized in the constructor. dont change it + // this must be initialized in the constructor. don't change it private Map<String, Wardrobe> wardrobes; // store Wardrobe in values private Map<Wardrobe, String> wardrobes2; // store Wardrobe in keys private Map<String, Wardrobe> wardrobesInverse; // store Wardrobe in values @@ -53,7 +53,7 @@ public class Gym { private String stringValue; public Gym() { - // this must be initialized in the constructor. dont change it + // this must be initialized in the constructor. don't change it wardrobes = new HashMap<String, Wardrobe>(); equipments = new HashMap<String, GymEquipment>(); partners = new HashMap<String, Gym>(); diff --git a/querydsl-jdo/src/test/java/com/mysema/query/jdo/models/fitness/GymEquipment.java b/querydsl-jdo/src/test/java/com/querydsl/jdo/models/fitness/GymEquipment.java similarity index 87% rename from querydsl-jdo/src/test/java/com/mysema/query/jdo/models/fitness/GymEquipment.java rename to querydsl-jdo/src/test/java/com/querydsl/jdo/models/fitness/GymEquipment.java index e3a5e458e1..444c54fdfb 100644 --- a/querydsl-jdo/src/test/java/com/mysema/query/jdo/models/fitness/GymEquipment.java +++ b/querydsl-jdo/src/test/java/com/querydsl/jdo/models/fitness/GymEquipment.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,9 +11,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.jdo.models.fitness; +package com.querydsl.jdo.models.fitness; -import com.mysema.query.annotations.QueryEntity; +import com.querydsl.core.annotations.QueryEntity; /** * Piece of equipment in a Gym. diff --git a/querydsl-jdo/src/test/java/com/mysema/query/jdo/models/fitness/Wardrobe.java b/querydsl-jdo/src/test/java/com/querydsl/jdo/models/fitness/Wardrobe.java similarity index 82% rename from querydsl-jdo/src/test/java/com/mysema/query/jdo/models/fitness/Wardrobe.java rename to querydsl-jdo/src/test/java/com/querydsl/jdo/models/fitness/Wardrobe.java index 3afdbfadd5..8f99409026 100644 --- a/querydsl-jdo/src/test/java/com/mysema/query/jdo/models/fitness/Wardrobe.java +++ b/querydsl-jdo/src/test/java/com/querydsl/jdo/models/fitness/Wardrobe.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,12 +11,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.jdo.models.fitness; +package com.querydsl.jdo.models.fitness; import java.util.ArrayList; import java.util.List; -import com.mysema.query.annotations.QueryEntity; +import com.querydsl.core.annotations.QueryEntity; /** * Container for clothes in a Gym. @@ -25,7 +25,7 @@ */ @QueryEntity public class Wardrobe { - // this must be initialized in the constructor. dont change it + // this must be initialized in the constructor. don't change it private List<Cloth> clothes; private String model; private Gym gym; @@ -33,7 +33,7 @@ public class Wardrobe { private String stringValue; public Wardrobe() { - // this must be initialized in the constructor. dont change it + // this must be initialized in the constructor. don't change it clothes = new ArrayList<Cloth>(); } diff --git a/querydsl-jdo/src/test/java/com/querydsl/jdo/serialization/AbstractTest.java b/querydsl-jdo/src/test/java/com/querydsl/jdo/serialization/AbstractTest.java new file mode 100644 index 0000000000..82ebb3cb23 --- /dev/null +++ b/querydsl-jdo/src/test/java/com/querydsl/jdo/serialization/AbstractTest.java @@ -0,0 +1,30 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jdo.serialization; + +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.SubQueryExpression; +import com.querydsl.jdo.JDOQLSerializer; +import com.querydsl.jdo.JDOQLTemplates; + +public abstract class AbstractTest { + + protected String serialize(SubQueryExpression<?> expr) { + Expression<?> source = expr.getMetadata().getJoins().get(0).getTarget(); + JDOQLSerializer serializer = new JDOQLSerializer(JDOQLTemplates.DEFAULT, source); + serializer.serialize(expr.getMetadata(), false, false); + return serializer.toString().replace('\n', ' '); + } + +} diff --git a/querydsl-jdo/src/test/java/com/querydsl/jdo/serialization/ContainerTest.java b/querydsl-jdo/src/test/java/com/querydsl/jdo/serialization/ContainerTest.java new file mode 100644 index 0000000000..721c7afe55 --- /dev/null +++ b/querydsl-jdo/src/test/java/com/querydsl/jdo/serialization/ContainerTest.java @@ -0,0 +1,167 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jdo.serialization; + +import static com.querydsl.jdo.JDOExpressions.selectFrom; +import static org.junit.Assert.assertEquals; + +import org.junit.Before; +import org.junit.Test; + +import com.querydsl.jdo.models.fitness.QGym; +import com.querydsl.jdo.models.fitness.Wardrobe; + +public class ContainerTest extends AbstractTest { + + private QGym gym = QGym.gym1; + + private Wardrobe wrd = new Wardrobe(), wrd1 = new Wardrobe(), wrd2 = new Wardrobe(); + + @Before + public void setUp() { + wrd.setModel("model"); + } + + @Test + public void notContainsValuesInMapFields() { + +// "SELECT FROM org.jpox.samples.models.fitness.Gym " +// + "WHERE !this.wardrobes.containsValue(wrd) " +// + "PARAMETERS org.jpox.samples.models.fitness.Wardrobe wrd"); + assertEquals( + "SELECT FROM com.querydsl.jdo.models.fitness.Gym " + + "WHERE !this.wardrobes.containsValue(a1) " + + "PARAMETERS com.querydsl.jdo.models.fitness.Wardrobe a1", + + serialize(selectFrom(gym) + .where(gym.wardrobes.containsValue(wrd).not()))); + +// "SELECT FROM org.jpox.samples.models.fitness.Gym " +// + "WHERE !this.wardrobes.containsValue(wrd) && !this.wardrobes.containsValue(wrd2) " +// + "PARAMETERS org.jpox.samples.models.fitness.Wardrobe wrd,org.jpox.samples.models.fitness.Wardrobe wrd2"); + + assertEquals( + "SELECT FROM com.querydsl.jdo.models.fitness.Gym " + + "WHERE !this.wardrobes.containsValue(a1) && !this.wardrobes.containsValue(a2) " + + "PARAMETERS com.querydsl.jdo.models.fitness.Wardrobe a1, com.querydsl.jdo.models.fitness.Wardrobe a2", + + serialize(selectFrom(gym) + .where(gym.wardrobes.containsValue(wrd).not(), gym.wardrobes.containsValue(wrd2).not()))); +// +// "SELECT FROM org.jpox.samples.models.fitness.Gym " +// + "WHERE !this.wardrobes.containsValue(wrd) && !this.wardrobes.containsValue(wrd2) && this.wardrobes.containsValue(wrd1) " +// + "PARAMETERS org.jpox.samples.models.fitness.Wardrobe wrd,org.jpox.samples.models.fitness.Wardrobe wrd2,org.jpox.samples.models.fitness.Wardrobe wrd1"); + + assertEquals( + "SELECT FROM com.querydsl.jdo.models.fitness.Gym " + + "WHERE !this.wardrobes.containsValue(a1) && !this.wardrobes.containsValue(a2) && this.wardrobes.containsValue(a3) " + + "PARAMETERS com.querydsl.jdo.models.fitness.Wardrobe a1, com.querydsl.jdo.models.fitness.Wardrobe a2, com.querydsl.jdo.models.fitness.Wardrobe a3", + + serialize(selectFrom(gym) + .where( + gym.wardrobes.containsValue(wrd).not(), + gym.wardrobes.containsValue(wrd1).not(), + gym.wardrobes.containsValue(wrd2)))); + } + + @Test + public void notContainsKeysInMapFields() { + +// "SELECT FROM org.jpox.samples.models.fitness.Gym " +// + "WHERE !this.wardrobes2.containsKey(wrd) " +// + "PARAMETERS org.jpox.samples.models.fitness.Wardrobe wrd"); + assertEquals( + "SELECT FROM com.querydsl.jdo.models.fitness.Gym " + + "WHERE !this.wardrobes2.containsKey(a1) " + + "PARAMETERS com.querydsl.jdo.models.fitness.Wardrobe a1", + + serialize(selectFrom(gym) + .where(gym.wardrobes2.containsKey(wrd).not()))); +// +// "SELECT FROM org.jpox.samples.models.fitness.Gym " +// + "WHERE !this.wardrobes2.containsKey(wrd) && !this.wardrobes2.containsKey(wrd2) " +// + "PARAMETERS org.jpox.samples.models.fitness.Wardrobe wrd,org.jpox.samples.models.fitness.Wardrobe wrd2"); + assertEquals( + "SELECT FROM com.querydsl.jdo.models.fitness.Gym " + + "WHERE !this.wardrobes2.containsKey(a1) && !this.wardrobes2.containsKey(a2) " + + "PARAMETERS com.querydsl.jdo.models.fitness.Wardrobe a1, com.querydsl.jdo.models.fitness.Wardrobe a2", + + serialize(selectFrom(gym) + .where( + gym.wardrobes2.containsKey(wrd).not(), + gym.wardrobes2.containsKey(wrd2).not()))); +// +// "SELECT FROM org.jpox.samples.models.fitness.Gym " +// + "WHERE !this.wardrobes2.containsKey(wrd) && !this.wardrobes2.containsKey(wrd2) && this.wardrobes2.containsKey(wrd1) " +// + "PARAMETERS org.jpox.samples.models.fitness.Wardrobe wrd,org.jpox.samples.models.fitness.Wardrobe wrd2,org.jpox.samples.models.fitness.Wardrobe wrd1"); + assertEquals( + "SELECT FROM com.querydsl.jdo.models.fitness.Gym " + + "WHERE !this.wardrobes2.containsKey(a1) && !this.wardrobes2.containsKey(a2) && this.wardrobes2.containsKey(a3) " + + "PARAMETERS com.querydsl.jdo.models.fitness.Wardrobe a1, com.querydsl.jdo.models.fitness.Wardrobe a2, com.querydsl.jdo.models.fitness.Wardrobe a3", + + serialize(selectFrom(gym) + .where( + gym.wardrobes2.containsKey(wrd).not(), + gym.wardrobes2.containsKey(wrd2).not(), + gym.wardrobes2.containsKey(wrd1)))); + } + + @Test + public void notContainsEntryInMapFields() { + // NOTE : containsEntry is not supported in Querydsl + +// "SELECT FROM org.jpox.samples.models.fitness.Gym " +// + "WHERE !this.wardrobes.containsEntry(wrd.model,wrd) " +// + "PARAMETERS org.jpox.samples.models.fitness.Wardrobe wrd"); +// +// "SELECT FROM org.jpox.samples.models.fitness.Gym " +// + "WHERE !this.wardrobes.containsEntry(wrd.model,wrd) && !this.wardrobes.containsEntry(wrd2.model,wrd2) " +// + "PARAMETERS org.jpox.samples.models.fitness.Wardrobe wrd,org.jpox.samples.models.fitness.Wardrobe wrd2"); +// +// "SELECT FROM org.jpox.samples.models.fitness.Gym " +// + "WHERE !this.wardrobes.containsEntry(wrd.model,wrd) && !this.wardrobes.containsEntry(wrd2.model,wrd2) && this.wardrobes.containsEntry(wrd1.model,wrd1) " +// + "PARAMETERS org.jpox.samples.models.fitness.Wardrobe wrd,org.jpox.samples.models.fitness.Wardrobe wrd2,org.jpox.samples.models.fitness.Wardrobe wrd1"); + + } + + @Test + public void getInMapFields() { + +// "SELECT FROM org.jpox.samples.models.fitness.Gym " +// + "WHERE this.wardrobes.get(wrd.model) == wrd " +// + "PARAMETERS org.jpox.samples.models.fitness.Wardrobe wrd"); + assertEquals( + "SELECT FROM com.querydsl.jdo.models.fitness.Gym " + + "WHERE this.wardrobes.get(a1) == a2 " + + "PARAMETERS java.lang.String a1, com.querydsl.jdo.models.fitness.Wardrobe a2", + + serialize(selectFrom(gym) + .where(gym.wardrobes.get(wrd.getModel()).eq(wrd)))); + } + + @Test + public void getInOrderingInMapFields() { +// "SELECT FROM org.jpox.samples.models.fitness.Gym " +// + "PARAMETERS org.jpox.samples.models.fitness.Wardrobe wrd"); +// .setOrdering("this.wardrobes.get(wrd.model).model ascending"); + assertEquals( + "SELECT FROM com.querydsl.jdo.models.fitness.Gym " + + "PARAMETERS java.lang.String a1 " + + "ORDER BY this.wardrobes.get(a1).model ASC", + + serialize(selectFrom(gym) + .orderBy(gym.wardrobes.get(wrd.getModel()).model.asc()))); + } + +} diff --git a/querydsl-jdo/src/test/java/com/mysema/query/jdo/serialization/ExprSerializationTest.java b/querydsl-jdo/src/test/java/com/querydsl/jdo/serialization/ExprSerializationTest.java similarity index 86% rename from querydsl-jdo/src/test/java/com/mysema/query/jdo/serialization/ExprSerializationTest.java rename to querydsl-jdo/src/test/java/com/querydsl/jdo/serialization/ExprSerializationTest.java index 69b2ade6f8..a110f63c1f 100644 --- a/querydsl-jdo/src/test/java/com/mysema/query/jdo/serialization/ExprSerializationTest.java +++ b/querydsl-jdo/src/test/java/com/querydsl/jdo/serialization/ExprSerializationTest.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,20 +11,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.jdo.serialization; +package com.querydsl.jdo.serialization; import static org.junit.Assert.assertEquals; import org.junit.Test; -import com.mysema.query.jdo.JDOQLSerializer; -import com.mysema.query.jdo.JDOQLTemplates; -import com.mysema.query.jdo.test.domain.Book; -import com.mysema.query.jdo.test.domain.Product; -import com.mysema.query.jdo.test.domain.QBook; -import com.mysema.query.jdo.test.domain.QProduct; -import com.mysema.query.jdo.test.domain.QStore; -import com.mysema.query.types.Expression; +import com.querydsl.core.types.Expression; +import com.querydsl.jdo.JDOQLSerializer; +import com.querydsl.jdo.JDOQLTemplates; +import com.querydsl.jdo.test.domain.*; public class ExprSerializationTest { @@ -35,20 +31,20 @@ public class ExprSerializationTest { private QStore store = QStore.store; @Test - public void InstanceOf() { + public void instanceOf() { assertEquals( - "product instanceof com.mysema.query.jdo.test.domain.Book", + "product instanceof com.querydsl.jdo.test.domain.Book", serialize(product.instanceOf(Book.class))); } @Test - public void Eq() { + public void eq() { assertEquals("this.name == product.name", serialize(book.name.eq(product.name))); assertEquals("this == product", serialize(book.eq(product))); } @Test - public void Aggregation() { + public void aggregation() { assertEquals("sum(product.price)", serialize(product.price.sum())); assertEquals("min(product.price)", serialize(product.price.min())); assertEquals("max(product.price)", serialize(product.price.max())); @@ -57,7 +53,7 @@ public void Aggregation() { } @Test - public void BooleanTests() { + public void booleanTests() { // boolean assertEquals("product.name == a1 && product.price <= a2", serialize(product.name.eq("Sony Discman").and(product.price.loe(300.00)))); @@ -68,7 +64,7 @@ public void BooleanTests() { } @Test - public void CollectionTests() { + public void collectionTests() { Product product = new Product(); // collection assertEquals("store.products.contains(a1)", @@ -84,7 +80,7 @@ public void CollectionTests() { } @Test - public void MapTests() { + public void mapTests() { assertEquals("store.productsByName.containsKey(a1)", serialize(store.productsByName.containsKey(""))); assertEquals("store.productsByName.containsValue(a1)", @@ -97,7 +93,7 @@ public void MapTests() { } @Test - public void NumericTests() { + public void numericTests() { // numeric assertEquals("product.price == a1", serialize(product.price.eq(200.00))); assertEquals("product.price != a1", serialize(product.price.ne(100.00))); @@ -115,7 +111,7 @@ public void NumericTests() { } @Test - public void StringTests() { + public void stringTests() { // string assertEquals("product.name.startsWith(a1)", serialize(product.name.startsWith("Sony Discman"))); assertEquals("product.name.endsWith(a1)", serialize(product.name.endsWith("Discman"))); diff --git a/querydsl-jdo/src/test/java/com/querydsl/jdo/serialization/GroupByTest.java b/querydsl-jdo/src/test/java/com/querydsl/jdo/serialization/GroupByTest.java new file mode 100644 index 0000000000..f4e29eb90c --- /dev/null +++ b/querydsl-jdo/src/test/java/com/querydsl/jdo/serialization/GroupByTest.java @@ -0,0 +1,25 @@ +package com.querydsl.jdo.serialization; + +import static com.querydsl.jdo.JDOExpressions.selectFrom; +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import com.querydsl.jdo.models.company.QEmployee; + +public class GroupByTest extends AbstractTest { + + @Test + public void groupBy() { + QEmployee employee = QEmployee.employee; + assertEquals( + "SELECT FROM com.querydsl.jdo.models.company.Employee " + + "PARAMETERS java.lang.String a1 " + + "GROUP BY this.emailAddress " + + "HAVING this.emailAddress != a1", + + serialize(selectFrom(employee) + .groupBy(employee.emailAddress).having(employee.emailAddress.ne("XXX")))); + } + +} diff --git a/querydsl-jdo/src/test/java/com/querydsl/jdo/serialization/QuerySerializationTest.java b/querydsl-jdo/src/test/java/com/querydsl/jdo/serialization/QuerySerializationTest.java new file mode 100644 index 0000000000..d1e379f282 --- /dev/null +++ b/querydsl-jdo/src/test/java/com/querydsl/jdo/serialization/QuerySerializationTest.java @@ -0,0 +1,107 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jdo.serialization; + +import static com.querydsl.jdo.JDOExpressions.select; +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import com.querydsl.jdo.test.domain.Book; +import com.querydsl.jdo.test.domain.QProduct; + +public class QuerySerializationTest extends AbstractTest { + + private QProduct product = QProduct.product; + + private QProduct other = new QProduct("other"); + + @Test + public void selectFromWhereOrder() { + assertEquals( + "SELECT this.name " + + "FROM com.querydsl.jdo.test.domain.Product " + + "WHERE this.name == a1 " + + "PARAMETERS java.lang.String a1 " + + "ORDER BY this.name ASC", + + serialize(select(product.name).from(product) + .where(product.name.eq("Test")) + .orderBy(product.name.asc()))); + } + + @Test + public void selectFromWhereGroupBy() { + assertEquals( + "SELECT this.name " + + "FROM com.querydsl.jdo.test.domain.Product " + + "WHERE this.name.startsWith(a1) || this.name.endsWith(a2) " + + "PARAMETERS java.lang.String a1, java.lang.String a2 " + + "GROUP BY this.price", + + serialize(select(product.name).from(product) + .where(product.name.startsWith("A").or(product.name.endsWith("B"))) + .groupBy(product.price))); + } + + @Test + public void selectFrom2Sources() { + assertEquals( + "SELECT this.name " + + "FROM com.querydsl.jdo.test.domain.Product " + + "WHERE this.name == other.name " + + "VARIABLES com.querydsl.jdo.test.domain.Product other", + + serialize(select(product.name).from(product, other) + .where(product.name.eq(other.name)))); + } + + @Test + public void withSubQuery() { + assertEquals( + "SELECT this.price " + + "FROM com.querydsl.jdo.test.domain.Product " + + "WHERE this.price < " + + "(SELECT avg(other.price) FROM com.querydsl.jdo.test.domain.Product other)", + + serialize(select(product.price).from(product) + .where(product.price.lt(select(other.price.avg()).from(other))))); + } + + @Test + public void withSubQuery2() { + // FIXME : how to model this ?!? + assertEquals( + "SELECT this.name " + + "FROM com.querydsl.jdo.test.domain.Product " + + "WHERE (SELECT other.price FROM com.querydsl.jdo.test.domain.Product other " + + "WHERE other.name == a1 " + + "PARAMETERS java.lang.String a1).contains(this.price)", + + serialize(select(product.name).from(product) + .where(product.price.in(select(other.price).from(other).where(other.name.eq("Some name")))))); + } + + @Test + public void instanceofQuery() { + assertEquals( + "SELECT " + + "FROM com.querydsl.jdo.test.domain.Product " + + "WHERE this instanceof com.querydsl.jdo.test.domain.Book", + + serialize(select(product).from(product) + .where(product.instanceOf(Book.class)))); + } + +} diff --git a/querydsl-jdo/src/test/java/com/querydsl/jdo/serialization/SubqueriesTest.java b/querydsl-jdo/src/test/java/com/querydsl/jdo/serialization/SubqueriesTest.java new file mode 100644 index 0000000000..81824762b8 --- /dev/null +++ b/querydsl-jdo/src/test/java/com/querydsl/jdo/serialization/SubqueriesTest.java @@ -0,0 +1,114 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jdo.serialization; + +import static com.querydsl.jdo.JDOExpressions.select; +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import com.querydsl.jdo.models.company.QDepartment; +import com.querydsl.jdo.models.company.QEmployee; + +public class SubqueriesTest extends AbstractTest { + + private QDepartment department = QDepartment.department; + + private QDepartment d = new QDepartment("d"); + + private QEmployee e = new QEmployee("e"); + + private QEmployee employee = QEmployee.employee; + +/* "SELECT FROM " + Department.class.getName() + " WHERE this.employees.size() == " + + * "(SELECT MAX(d.employees.size()) FROM " + Department.class.getName() + " d)"; */ + @Test + public void test1() { + assertEquals( + "SELECT FROM com.querydsl.jdo.models.company.Department " + + "WHERE this.employees.size() == " + + "(SELECT max(d.employees.size()) FROM com.querydsl.jdo.models.company.Department d)", + + serialize(select(department).from(department).where(department.employees.size().eq( + select(d.employees.size().max()).from(d) + ))) + ); + } + +/* "SELECT FROM " + Employee.class.getName() + " WHERE this.weeklyhours > " + + * "(SELECT AVG(e.weeklyhours) FROM this.department.employees e)"; */ + @Test + public void test2() { + assertEquals( + "SELECT FROM com.querydsl.jdo.models.company.Employee " + + "WHERE this.weeklyhours > " + + "(SELECT avg(e.weeklyhours) FROM this.department.employees e)", + + serialize(select(employee).from(employee).where(employee.weeklyhours.gt( + select(e.weeklyhours.avg()).from(employee.department.employees, e) + ))) + ); + } + +/* "SELECT FROM " + Employee.class.getName() + + * " WHERE this.weeklyhours > " + + * "(SELECT AVG(e.weeklyhours) FROM this.department.employees e " + + * " WHERE e.manager == this.manager)"; */ + @Test + public void test3() { + assertEquals( + "SELECT FROM com.querydsl.jdo.models.company.Employee " + + "WHERE this.weeklyhours > " + + "(SELECT avg(e.weeklyhours) FROM this.department.employees e WHERE e.manager == this.manager)", + + serialize(select(employee).from(employee).where(employee.weeklyhours.gt( + select(e.weeklyhours.avg()).from(employee.department.employees, e).where(e.manager.eq(employee.manager)) + ))) + ); + } +/* "SELECT FROM " + Employee.class.getName() + " WHERE this.weeklyhours > " + + * "(SELECT AVG(e.weeklyhours) FROM " + Employee.class.getName() + " e)"; */ + @Test + public void test4() { + assertEquals( + "SELECT FROM com.querydsl.jdo.models.company.Employee " + + "WHERE this.weeklyhours > " + + "(SELECT avg(e.weeklyhours) FROM com.querydsl.jdo.models.company.Employee e)", + + serialize(select(employee).from(employee).where(employee.weeklyhours.gt( + select(e.weeklyhours.avg()).from(e) + ))) + ); + } + +/* "SELECT FROM " + Employee.class.getName() + + * " WHERE this.weeklyhours == emp.weeklyhours && " + + * "emp.firstname == 'emp1First' VARIABLES Employee emp"; */ + @Test + public void test5() { + assertEquals( + "SELECT FROM com.querydsl.jdo.models.company.Employee " + + "WHERE this.weeklyhours == e.weeklyhours && this.firstName == a1 " + + "VARIABLES com.querydsl.jdo.models.company.Employee e " + + "PARAMETERS java.lang.String a1", + + serialize(select(employee).from(employee, e) + .where( + employee.weeklyhours.eq(e.weeklyhours), + employee.firstName.eq("emp1First") + )) + ); + } + +} diff --git a/querydsl-jdo/src/test/java/com/querydsl/jdo/test/domain/Book.java b/querydsl-jdo/src/test/java/com/querydsl/jdo/test/domain/Book.java new file mode 100644 index 0000000000..884fc7433f --- /dev/null +++ b/querydsl-jdo/src/test/java/com/querydsl/jdo/test/domain/Book.java @@ -0,0 +1,78 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jdo.test.domain; + +import java.util.Date; + +import javax.jdo.annotations.Inheritance; +import javax.jdo.annotations.InheritanceStrategy; +import javax.jdo.annotations.PersistenceCapable; + +/** + * Definition of a Book. Extends basic Product class. + */ +@PersistenceCapable +@Inheritance(strategy = InheritanceStrategy.NEW_TABLE) +public class Book extends Product { + private String author = null; + + private String isbn = null; + + private String publisher = null; + + protected Book() { + super(); + } + + public Book(String name, String description, double price, int amount, String author, + String isbn, String publisher) { + this(name, description, price, amount, author, isbn, publisher, new Date()); + } + + public Book(String name, String description, double price, int amount, String author, + String isbn, String publisher, Date date) { + super(name, description, price, amount, date); + this.author = author; + this.isbn = isbn; + this.publisher = publisher; + } + + public String getAuthor() { + return author; + } + + public String getIsbn() { + return isbn; + } + + public String getPublisher() { + return publisher; + } + + public void setAuthor(String author) { + this.author = author; + } + + public void setIsbn(String isbn) { + this.isbn = isbn; + } + + public void setPublisher(String publisher) { + this.publisher = publisher; + } + + public String toString() { + return "Book : " + author + " - " + getName(); + } +} diff --git a/querydsl-jdo/src/test/java/com/querydsl/jdo/test/domain/Product.java b/querydsl-jdo/src/test/java/com/querydsl/jdo/test/domain/Product.java new file mode 100644 index 0000000000..2c0be4fc7c --- /dev/null +++ b/querydsl-jdo/src/test/java/com/querydsl/jdo/test/domain/Product.java @@ -0,0 +1,122 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jdo.test.domain; + +import java.util.Date; + +import javax.jdo.annotations.Inheritance; +import javax.jdo.annotations.InheritanceStrategy; +import javax.jdo.annotations.PersistenceCapable; +import javax.jdo.annotations.Persistent; + +/** + * Definition of a Product Represents a product, and contains the key aspects of + * the item. + */ +@PersistenceCapable +@Inheritance(strategy = InheritanceStrategy.NEW_TABLE) +public class Product { + private String name = null; + + private String description = null; + + private double price = 0.0; + + private Date publicationDate; + + @Persistent + private java.sql.Date dateField; + + @Persistent + private java.sql.Time timeField; + + private int amount; + + public Product() { + } + + public Product(String name, String description, double price, int amount) { + this(name, description, price, amount, new Date()); + } + + public Product(String name, String description, double price, int amount, Date publicationDate) { + this.name = name; + this.description = description; + this.price = price; + this.amount = amount; + this.publicationDate = new Date(publicationDate.getTime()); + this.dateField = new java.sql.Date(publicationDate.getTime()); + this.timeField = new java.sql.Time(publicationDate.getTime()); + } + + public String getName() { + return name; + } + + public String getDescription() { + return description; + } + + public double getPrice() { + return price; + } + + public void setName(String name) { + this.name = name; + } + + public void setDescription(String description) { + this.description = description; + } + + public void setPrice(double price) { + this.price = price; + } + + public int getAmount() { + return amount; + } + + public void setAmount(int amount) { + this.amount = amount; + } + + public Date getPublicationDate() { + return publicationDate; + } + + public void setPublicationDate(Date publicationDate) { + this.publicationDate = new java.sql.Date(publicationDate.getTime()); + } + + public java.sql.Date getDateField() { + return new java.sql.Date(dateField.getTime()); + } + + public void setDateField(java.sql.Date dateField) { + this.dateField = new java.sql.Date(dateField.getTime()); + } + + public java.sql.Time getTimeField() { + return timeField; + } + + public void setTimeField(java.sql.Time timeField) { + this.timeField = timeField; + } + + public String toString() { + return "Product : " + name + " [" + description + "]"; + } +} diff --git a/querydsl-jdo/src/test/java/com/querydsl/jdo/test/domain/QBook.java b/querydsl-jdo/src/test/java/com/querydsl/jdo/test/domain/QBook.java new file mode 100644 index 0000000000..b3f96013d8 --- /dev/null +++ b/querydsl-jdo/src/test/java/com/querydsl/jdo/test/domain/QBook.java @@ -0,0 +1,60 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jdo.test.domain; + +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.PathMetadataFactory; +import com.querydsl.core.types.dsl.DateTimePath; +import com.querydsl.core.types.dsl.EntityPathBase; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.StringPath; + +/** + * QBook is a Querydsl query type for Book + * + */ +@SuppressWarnings("serial") +public class QBook extends EntityPathBase<com.querydsl.jdo.test.domain.Book> { + + public static final QBook book = new QBook("book"); + + public final StringPath author = createString("author"); + + public final StringPath description = createString("description"); + + public final StringPath isbn = createString("isbn"); + + public final StringPath name = createString("name"); + + public final StringPath publisher = createString("publisher"); + + public final DateTimePath<java.util.Date> publicationDate = createDateTime("publicationDate",java.util.Date.class); + + public final NumberPath<Integer> amount = createNumber("amount",Integer.class); + + public final NumberPath<Double> price = createNumber("price",Double.class); + + public QBook(String path) { + this(com.querydsl.jdo.test.domain.Book.class, path); + } + + public QBook(Class<? extends com.querydsl.jdo.test.domain.Book> cl, String path) { + super(cl, PathMetadataFactory.forVariable(path)); + } + + public QBook(PathMetadata metadata) { + super(com.querydsl.jdo.test.domain.Book.class, metadata); + } + +} diff --git a/querydsl-jdo/src/test/java/com/querydsl/jdo/test/domain/QProduct.java b/querydsl-jdo/src/test/java/com/querydsl/jdo/test/domain/QProduct.java new file mode 100644 index 0000000000..f3a9d13dc5 --- /dev/null +++ b/querydsl-jdo/src/test/java/com/querydsl/jdo/test/domain/QProduct.java @@ -0,0 +1,55 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jdo.test.domain; + +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.PathMetadataFactory; +import com.querydsl.core.types.dsl.*; + +/** + * QProduct is a Querydsl query type for Product + * + */ +@SuppressWarnings("serial") +public class QProduct extends EntityPathBase<com.querydsl.jdo.test.domain.Product> { + + public static final QProduct product = new QProduct("product"); + + public final StringPath description = createString("description"); + + public final StringPath name = createString("name"); + + public final DateTimePath<java.util.Date> publicationDate = createDateTime("publicationDate",java.util.Date.class); + + public final DatePath<java.sql.Date> dateField = createDate("dateField", java.sql.Date.class); + + public final TimePath<java.sql.Time> timeField = createTime("timeField", java.sql.Time.class); + + public final NumberPath<Integer> amount = createNumber("amount",Integer.class); + + public final NumberPath<Double> price = createNumber("price",Double.class); + + public QProduct(String path) { + this(com.querydsl.jdo.test.domain.Product.class, path); + } + + public QProduct(Class<? extends com.querydsl.jdo.test.domain.Product> cl, String path) { + super(cl, PathMetadataFactory.forVariable(path)); + } + + public QProduct(PathMetadata metadata) { + super(com.querydsl.jdo.test.domain.Product.class, metadata); + } + +} diff --git a/querydsl-jdo/src/test/java/com/querydsl/jdo/test/domain/QStore.java b/querydsl-jdo/src/test/java/com/querydsl/jdo/test/domain/QStore.java new file mode 100644 index 0000000000..344b2c3d1e --- /dev/null +++ b/querydsl-jdo/src/test/java/com/querydsl/jdo/test/domain/QStore.java @@ -0,0 +1,55 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jdo.test.domain; + +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.PathMetadataFactory; +import com.querydsl.core.types.dsl.*; + +/** + * QStore is a Querydsl query type for Store + * + */ +@SuppressWarnings("serial") +public class QStore extends EntityPathBase<com.querydsl.jdo.test.domain.Store> { + + public static final QStore store = new QStore("store"); + + public final StringPath name = createString("name"); + + public final MapPath<String, Product, QProduct> productsByName = this.<String, Product, QProduct>createMap("productsByName",String.class,Product.class,QProduct.class); + + public final ListPath<Product, QProduct> products = this.<Product, QProduct>createList("products",Product.class,QProduct.class, PathInits.DIRECT); + + public QProduct productsByName(String key) { + return new QProduct(PathMetadataFactory.forMapAccess(productsByName,key)); + } + + public QProduct productsByName(com.querydsl.core.types.Expression<String> key) { + return new QProduct(PathMetadataFactory.forMapAccess(productsByName,key)); + } + + public QStore(String path) { + this(Store.class, path); + } + + public QStore(Class<? extends Store> cl, String path) { + super(cl, PathMetadataFactory.forVariable(path)); + } + + public QStore(PathMetadata metadata) { + super(Store.class, metadata); + } + +} diff --git a/querydsl-jdo/src/test/java/com/querydsl/jdo/test/domain/Store.java b/querydsl-jdo/src/test/java/com/querydsl/jdo/test/domain/Store.java new file mode 100644 index 0000000000..b2951afb04 --- /dev/null +++ b/querydsl-jdo/src/test/java/com/querydsl/jdo/test/domain/Store.java @@ -0,0 +1,65 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jdo.test.domain; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.jdo.annotations.*; + +@PersistenceCapable +@Inheritance(strategy = InheritanceStrategy.NEW_TABLE) +@FetchGroups({ + @FetchGroup(name = "products", members = {@Persistent(name = "products")}) +}) +public class Store { + + private String name; + + @Join + @Element(types = Product.class) + private List<Product> products = new ArrayList<Product>(); + + @Join + @Key(types = String.class) + @Value(types = Product.class) + private Map<String,Product> productsByName = new HashMap<String,Product>(); + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Map<String, Product> getProductsByName() { + return productsByName; + } + + public void setProductsByName(Map<String, Product> productsByName) { + this.productsByName = productsByName; + } + + public List<Product> getProducts() { + return products; + } + + public void setProducts(List<Product> products) { + this.products = products; + } + +} diff --git a/querydsl-jdo/src/test/java/com/querydsl/jdo/test/domain/sql/SBook.java b/querydsl-jdo/src/test/java/com/querydsl/jdo/test/domain/sql/SBook.java new file mode 100644 index 0000000000..33ffd8f26a --- /dev/null +++ b/querydsl-jdo/src/test/java/com/querydsl/jdo/test/domain/sql/SBook.java @@ -0,0 +1,62 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jdo.test.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.BeanPath; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.StringPath; +import com.querydsl.sql.ForeignKey; +import com.querydsl.sql.PrimaryKey; +import com.querydsl.sql.RelationalPathBase; + + +/** + * SBook is a Querydsl query type for SBook + */ +//@Table(value="BOOK") +public class SBook extends RelationalPathBase<SBook> { + + private static final long serialVersionUID = -1566558053; + + public static final SBook book = new SBook("BOOK"); + + public final StringPath author = createString("AUTHOR"); + + public final NumberPath<Long> bookId = createNumber("BOOK_ID", Long.class); + + public final StringPath isbn = createString("ISBN"); + + public final StringPath publisher = createString("PUBLISHER"); + + public final PrimaryKey<SBook> sysIdx65 = createPrimaryKey(bookId); + + public final ForeignKey<SProduct> bookFk1 = new ForeignKey<SProduct>(this, bookId, "PRODUCT_ID"); + + public SBook(String variable) { + super(SBook.class, forVariable(variable), "", "BOOK"); + } + + public SBook(BeanPath<? extends SBook> entity) { + super(entity.getType(),entity.getMetadata(), "", "BOOK"); + } + + public SBook(PathMetadata metadata) { + super(SBook.class, metadata, "", "BOOK"); + } + +} + diff --git a/querydsl-jdo/src/test/java/com/querydsl/jdo/test/domain/sql/SProduct.java b/querydsl-jdo/src/test/java/com/querydsl/jdo/test/domain/sql/SProduct.java new file mode 100644 index 0000000000..8414405c58 --- /dev/null +++ b/querydsl-jdo/src/test/java/com/querydsl/jdo/test/domain/sql/SProduct.java @@ -0,0 +1,90 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jdo.test.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import java.sql.Date; +import java.sql.Time; + +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.*; +import com.querydsl.sql.ColumnMetadata; +import com.querydsl.sql.ForeignKey; +import com.querydsl.sql.PrimaryKey; +import com.querydsl.sql.RelationalPathBase; + + +/** + * SProduct is a Querydsl query type for SProduct + */ +//@Table(value="PRODUCT") +public class SProduct extends RelationalPathBase<SProduct> { + + private static final long serialVersionUID = -590374403; + + public static final SProduct product = new SProduct("PRODUCT"); + + public final NumberPath<Integer> amount = createNumber("AMOUNT", Integer.class); + + public final DatePath<Date> datefield = createDate("DATEFIELD", java.sql.Date.class); + + public final StringPath description = createString("DESCRIPTION"); + + public final StringPath name = createString("NAME"); + + public final NumberPath<Double> price = createNumber("PRICE", Double.class); + + public final NumberPath<Long> productId = createNumber("PRODUCT_ID", Long.class); + + public final DateTimePath<java.util.Date> publicationdate = createDateTime("PUBLICATIONDATE", java.util.Date.class); + + public final TimePath<Time> timefield = createTime("TIMEFIELD", java.sql.Time.class); + + public final PrimaryKey<SProduct> sysIdx47 = createPrimaryKey(productId); + + public final ForeignKey<SStoreProducts> _storeProductsFk2 = new ForeignKey<SStoreProducts>(this, productId, "PRODUCT_ID_EID"); + + public final ForeignKey<SBook> _bookFk1 = new ForeignKey<SBook>(this, productId, "BOOK_ID"); + + public final ForeignKey<SStoreProductsbyname> _storeProductsbynameFk2 = new ForeignKey<SStoreProductsbyname>(this, productId, "PRODUCT_ID_VID"); + + public SProduct(String variable) { + super(SProduct.class, forVariable(variable), "", "PRODUCT"); + addMetadata(); + } + + public SProduct(BeanPath<? extends SProduct> entity) { + super(entity.getType(),entity.getMetadata(), "", "PRODUCT"); + addMetadata(); + } + + public SProduct(PathMetadata metadata) { + super(SProduct.class, metadata, "", "PRODUCT"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(amount, ColumnMetadata.named("AMOUNT")); + addMetadata(datefield, ColumnMetadata.named("DATEFIELD")); + addMetadata(description, ColumnMetadata.named("DESCRIPTION")); + addMetadata(name, ColumnMetadata.named("NAME")); + addMetadata(price, ColumnMetadata.named("PRICE")); + addMetadata(productId, ColumnMetadata.named("PRODUCT_ID")); + addMetadata(publicationdate, ColumnMetadata.named("PUBLICATIONDATE")); + addMetadata(timefield, ColumnMetadata.named("TIMEFIELD")); + } + +} + diff --git a/querydsl-jdo/src/test/java/com/querydsl/jdo/test/domain/sql/SStore.java b/querydsl-jdo/src/test/java/com/querydsl/jdo/test/domain/sql/SStore.java new file mode 100644 index 0000000000..02f69c7c5a --- /dev/null +++ b/querydsl-jdo/src/test/java/com/querydsl/jdo/test/domain/sql/SStore.java @@ -0,0 +1,60 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jdo.test.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.BeanPath; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.StringPath; +import com.querydsl.sql.ForeignKey; +import com.querydsl.sql.PrimaryKey; +import com.querydsl.sql.RelationalPathBase; + + +/** + * SStore is a Querydsl query type for SStore + */ +//@Table(value="STORE") +public class SStore extends RelationalPathBase<SStore> { + + private static final long serialVersionUID = -1302810257; + + public static final SStore store = new SStore("STORE"); + + public final StringPath name = createString("NAME"); + + public final NumberPath<Long> storeId = createNumber("STORE_ID", Long.class); + + public final PrimaryKey<SStore> sysIdx51 = createPrimaryKey(storeId); + + public final ForeignKey<SStoreProductsbyname> _storeProductsbynameFk1 = new ForeignKey<SStoreProductsbyname>(this, storeId, "STORE_ID_OID"); + + public final ForeignKey<SStoreProducts> _storeProductsFk1 = new ForeignKey<SStoreProducts>(this, storeId, "STORE_ID_OID"); + + public SStore(String variable) { + super(SStore.class, forVariable(variable), "", "STORE"); + } + + public SStore(BeanPath<? extends SStore> entity) { + super(entity.getType(),entity.getMetadata(), "", "STORE"); + } + + public SStore(PathMetadata metadata) { + super(SStore.class, metadata, "", "STORE"); + } + +} + diff --git a/querydsl-jdo/src/test/java/com/querydsl/jdo/test/domain/sql/SStoreProducts.java b/querydsl-jdo/src/test/java/com/querydsl/jdo/test/domain/sql/SStoreProducts.java new file mode 100644 index 0000000000..9311cd6d2f --- /dev/null +++ b/querydsl-jdo/src/test/java/com/querydsl/jdo/test/domain/sql/SStoreProducts.java @@ -0,0 +1,61 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jdo.test.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.BeanPath; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.sql.ForeignKey; +import com.querydsl.sql.PrimaryKey; +import com.querydsl.sql.RelationalPathBase; + + +/** + * SStoreProducts is a Querydsl query type for SStoreProducts + */ +//@Table(value="STORE_PRODUCTS") +public class SStoreProducts extends RelationalPathBase<SStoreProducts> { + + private static final long serialVersionUID = 1019873267; + + public static final SStoreProducts storeProducts = new SStoreProducts("STORE_PRODUCTS"); + + public final NumberPath<Integer> idx = createNumber("IDX", Integer.class); + + public final NumberPath<Long> productIdEid = createNumber("PRODUCT_ID_EID", Long.class); + + public final NumberPath<Long> storeIdOid = createNumber("STORE_ID_OID", Long.class); + + public final PrimaryKey<SStoreProducts> sysIdx55 = createPrimaryKey(idx, storeIdOid); + + public final ForeignKey<SProduct> storeProductsFk2 = new ForeignKey<SProduct>(this, productIdEid, "PRODUCT_ID"); + + public final ForeignKey<SStore> storeProductsFk1 = new ForeignKey<SStore>(this, storeIdOid, "STORE_ID"); + + public SStoreProducts(String variable) { + super(SStoreProducts.class, forVariable(variable), "", "STORE_PRODUCTS"); + } + + public SStoreProducts(BeanPath<? extends SStoreProducts> entity) { + super(entity.getType(),entity.getMetadata(), "", "STORE_PRODUCTS"); + } + + public SStoreProducts(PathMetadata metadata) { + super(SStoreProducts.class, metadata, "", "STORE_PRODUCTS"); + } + +} + diff --git a/querydsl-jdo/src/test/java/com/querydsl/jdo/test/domain/sql/SStoreProductsbyname.java b/querydsl-jdo/src/test/java/com/querydsl/jdo/test/domain/sql/SStoreProductsbyname.java new file mode 100644 index 0000000000..a389c45f6e --- /dev/null +++ b/querydsl-jdo/src/test/java/com/querydsl/jdo/test/domain/sql/SStoreProductsbyname.java @@ -0,0 +1,62 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jdo.test.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.BeanPath; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.StringPath; +import com.querydsl.sql.ForeignKey; +import com.querydsl.sql.PrimaryKey; +import com.querydsl.sql.RelationalPathBase; + + +/** + * SStoreProductsbyname is a Querydsl query type for SStoreProductsbyname + */ +//@Table(value="STORE_PRODUCTSBYNAME") +public class SStoreProductsbyname extends RelationalPathBase<SStoreProductsbyname> { + + private static final long serialVersionUID = 764053781; + + public static final SStoreProductsbyname storeProductsbyname = new SStoreProductsbyname("STORE_PRODUCTSBYNAME"); + + public final StringPath key = createString("KEY"); + + public final NumberPath<Long> productIdVid = createNumber("PRODUCT_ID_VID", Long.class); + + public final NumberPath<Long> storeIdOid = createNumber("STORE_ID_OID", Long.class); + + public final PrimaryKey<SStoreProductsbyname> sysIdx53 = createPrimaryKey(key, storeIdOid); + + public final ForeignKey<SStore> storeProductsbynameFk1 = new ForeignKey<SStore>(this, storeIdOid, "STORE_ID"); + + public final ForeignKey<SProduct> storeProductsbynameFk2 = new ForeignKey<SProduct>(this, productIdVid, "PRODUCT_ID"); + + public SStoreProductsbyname(String variable) { + super(SStoreProductsbyname.class, forVariable(variable), "", "STORE_PRODUCTSBYNAME"); + } + + public SStoreProductsbyname(BeanPath<? extends SStoreProductsbyname> entity) { + super(entity.getType(),entity.getMetadata(), "", "STORE_PRODUCTSBYNAME"); + } + + public SStoreProductsbyname(PathMetadata metadata) { + super(SStoreProductsbyname.class, metadata, "", "STORE_PRODUCTSBYNAME"); + } + +} + diff --git a/querydsl-jdo/src/test/resources/datanucleus.properties b/querydsl-jdo/src/test/resources/datanucleus.properties index 44813ad81c..57ee19eff7 100644 --- a/querydsl-jdo/src/test/resources/datanucleus.properties +++ b/querydsl-jdo/src/test/resources/datanucleus.properties @@ -1,13 +1,16 @@ -javax.jdo.PersistenceManagerFactoryClass=org.datanucleus.api.jdo.JDOPersistenceManagerFactory - -javax.jdo.option.ConnectionDriverName=org.h2.Driver -javax.jdo.option.ConnectionURL=jdbc:h2:~/dbs/test -javax.jdo.option.ConnectionUserName=sa -javax.jdo.option.ConnectionPassword= -#javax.jdo.option.Mapping=h2 - -datanucleus.metadata.validate=false -datanucleus.autoCreateSchema=true -datanucleus.autoCreateTables=true -datanucleus.validateTables=true -datanucleus.validateConstraints=true +javax.jdo.PersistenceManagerFactoryClass=org.datanucleus.api.jdo.JDOPersistenceManagerFactory + +javax.jdo.option.ConnectionDriverName=org.h2.Driver +javax.jdo.option.ConnectionURL=jdbc:h2:./target/test +javax.jdo.option.ConnectionUserName=sa +javax.jdo.option.ConnectionPassword= +#javax.jdo.option.Mapping=h2 + +datanucleus.metadata.validate=false +datanucleus.schema.autoCreateAll=true +datanucleus.schema.autoCreateDatabase=true +datanucleus.schema.autoCreateSchema=true +datanucleus.schema.autoCreateTables=true +datanucleus.schema.autoCreateColumns=true +datanucleus.schema.validateTables=true +datanucleus.schema.validateConstraints=true diff --git a/querydsl-jdo/src/test/resources/log4j.properties b/querydsl-jdo/src/test/resources/log4j.properties index b86a4715ee..a458916ee4 100644 --- a/querydsl-jdo/src/test/resources/log4j.properties +++ b/querydsl-jdo/src/test/resources/log4j.properties @@ -1,11 +1,11 @@ -### direct log messages to stdout ### -log4j.appender.stdout=org.apache.log4j.ConsoleAppender -#log4j.appender.stdout.Target=System.out -log4j.appender.stdout.layout=org.apache.log4j.PatternLayout -log4j.appender.stdout.layout.ConversionPattern=%5p [%d{yyyy-MM-dd HH:mm:ss}] (%F:%L) - %m%n - -### set log levels - for more verbose logging change 'info' to 'debug' ### - -log4j.rootLogger=WARN, stdout - -#log4j.logger.com.mysema.query.jdo=DEBUG +### direct log messages to stdout ### +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +#log4j.appender.stdout.Target=System.out +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%5p [%d{yyyy-MM-dd HH:mm:ss}] (%F:%L) - %m %X%n + +### set log levels - for more verbose logging change 'info' to 'debug' ### + +log4j.rootLogger=WARN, stdout + +#log4j.logger.com.querydsl.jdo=DEBUG diff --git a/querydsl-jdo/template.mf b/querydsl-jdo/template.mf deleted file mode 100644 index 6782ed012e..0000000000 --- a/querydsl-jdo/template.mf +++ /dev/null @@ -1,12 +0,0 @@ -Bundle-SymbolicName: com.mysema.querydsl.jdo -Bundle-Name: Querydsl JDO -Bundle-Vendor: Mysema -Bundle-ManifestVersion: 2 -Import-Template: - com.mysema.commons.lang.*;version="${mysema.lang.version}", - com.mysema.query.*;version="${project.version}", - javax.annotation.*;version="0", - javax.inject.*;version="0", - javax.jdo.*;version="[2.0.0,4.0.0)", - com.google.common.*;version="${guava.version}", - org.slf4j.*;version="${slf4j.version}" \ No newline at end of file diff --git a/querydsl-jpa-codegen/pom.xml b/querydsl-jpa-codegen/pom.xml index a04b06c41a..407d4aca5f 100644 --- a/querydsl-jpa-codegen/pom.xml +++ b/querydsl-jpa-codegen/pom.xml @@ -1,15 +1,15 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0" encoding="UTF-8"?> <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <modelVersion>4.0.0</modelVersion> <parent> - <groupId>com.mysema.querydsl</groupId> + <groupId>com.querydsl</groupId> <artifactId>querydsl-root</artifactId> - <version>3.4.1.BUILD-SNAPSHOT</version> - <relativePath>../querydsl-root/pom.xml</relativePath> + <version>5.1.0</version> + <relativePath>../pom.xml</relativePath> </parent> - <groupId>com.mysema.querydsl</groupId> + <groupId>com.querydsl</groupId> <artifactId>querydsl-jpa-codegen</artifactId> <name>Querydsl - JPA Codegen support</name> <description>JPA Codegen support for Querydsl</description> @@ -21,13 +21,13 @@ <developerConnection>${project.checkout}</developerConnection> <url>${project.githubpage}</url> </scm> - - <properties> - <hibernate.version>4.1.7.Final</hibernate.version> - <hibernate.validator.version>4.3.0.Final</hibernate.validator.version> - </properties> - - <dependencies> + + <dependencies> + <dependency> + <groupId>org.jetbrains</groupId> + <artifactId>annotations</artifactId> + <scope>provided</scope> + </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> @@ -43,45 +43,45 @@ </exclusion> </exclusions> <scope>provided</scope> - </dependency> - <dependency> - <groupId>org.hibernate</groupId> - <artifactId>hibernate-entitymanager</artifactId> - <version>${hibernate.version}</version> - <scope>provided</scope> </dependency> <dependency> - <groupId>org.hibernate</groupId> + <groupId>org.hibernate.validator</groupId> <artifactId>hibernate-validator</artifactId> <version>${hibernate.validator.version}</version> <scope>provided</scope> - <exclusions> + <exclusions> <exclusion> - <groupId>org.slf4j</groupId> - <artifactId>slf4j-api</artifactId> + <artifactId>jboss-logging</artifactId> + <groupId>org.jboss.logging</groupId> </exclusion> - </exclusions> + </exclusions> </dependency> <dependency> - <groupId>org.hibernate.javax.persistence</groupId> - <artifactId>hibernate-jpa-2.0-api</artifactId> - <version>1.0.0.Final</version> - <scope>compile</scope> + <groupId>jakarta.persistence</groupId> + <artifactId>jakarta.persistence-api</artifactId> + <version>2.2.3</version> + <scope>provided</scope> </dependency> <dependency> - <groupId>com.mysema.querydsl</groupId> + <groupId>com.querydsl</groupId> <artifactId>querydsl-codegen</artifactId> <version>${project.version}</version> </dependency> <dependency> - <groupId>com.mysema.querydsl</groupId> + <groupId>com.querydsl</groupId> + <artifactId>querydsl-sql</artifactId> + <version>${project.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>com.querydsl</groupId> <artifactId>querydsl-jpa</artifactId> <version>${project.version}</version> - </dependency> + </dependency> <dependency> - <groupId>com.mysema.querydsl</groupId> + <groupId>com.querydsl</groupId> <artifactId>querydsl-jpa</artifactId> <version>${project.version}</version> <scope>test</scope> @@ -89,7 +89,7 @@ </dependency> <dependency> - <groupId>com.mysema.querydsl</groupId> + <groupId>com.querydsl</groupId> <artifactId>querydsl-core</artifactId> <version>${project.version}</version> <scope>test</scope> @@ -99,28 +99,46 @@ <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> - <version>${h2.version}</version> <scope>test</scope> - </dependency> - - <dependency> - <groupId>org.slf4j</groupId> - <artifactId>slf4j-api</artifactId> </dependency> - <dependency> - <groupId>org.slf4j</groupId> - <artifactId>slf4j-log4j12</artifactId> - </dependency> </dependencies> <build> - <plugins> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-jar-plugin</artifactId> + <configuration> + <archive> + <manifestEntries> + <Automatic-Module-Name>com.querydsl.jpa.codegen</Automatic-Module-Name> + </manifestEntries> + </archive> + </configuration> + </plugin> + <plugin> + <groupId>org.eclipse.transformer</groupId> + <artifactId>org.eclipse.transformer.maven</artifactId> + <version>0.2.0</version> + <executions> + <execution> + <id>jakarta-ee</id> + <goals> + <goal>run</goal> + </goals> + <phase>package</phase> + <configuration> + <classifier>jakarta</classifier> + </configuration> + </execution> + </executions> + </plugin> <plugin> - <groupId>com.springsource.bundlor</groupId> - <artifactId>com.springsource.bundlor.maven</artifactId> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> </plugin> </plugins> </build> -</project> +</project> diff --git a/querydsl-jpa-codegen/src/main/java/com/mysema/query/jpa/codegen/Constants.java b/querydsl-jpa-codegen/src/main/java/com/mysema/query/jpa/codegen/Constants.java deleted file mode 100644 index 1bb386ede2..0000000000 --- a/querydsl-jpa-codegen/src/main/java/com/mysema/query/jpa/codegen/Constants.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa.codegen; - -import java.util.List; - -import com.google.common.collect.ImmutableList; - -/** - * Constants defines keywords used in Hibernate - * - * @author tiwe - * - */ -public final class Constants { - - public static final List<String> keywords = ImmutableList.of( - "ABS","ALL","AND","ANY","AS","ASC","AVG","BETWEEN", - "BIT_LENGTH[51]","BOTH","BY","CASE","CHAR_LENGTH", - "CHARACTER_LENGTH","CLASS", - "COALESCE","CONCAT","COUNT","CURRENT_DATE","CURRENT_TIME", - "CURRENT_TIMESTAMP", - "DELETE","DESC","DISTINCT","ELSE","EMPTY","END","ENTRY", - "ESCAPE","EXISTS","FALSE","FETCH", - "FROM","GROUP","HAVING","IN","INDEX","INNER","IS","JOIN", - "KEY","LEADING","LEFT","LENGTH","LIKE", - "LOCATE","LOWER","MAX","MEMBER","MIN","MOD","NEW","NOT", - "NULL","NULLIF","OBJECT","OF","OR", - "ORDER","OUTER","POSITION","SELECT","SET","SIZE","SOME", - "SQRT","SUBSTRING","SUM","THEN", - "TRAILING","TRIM","TRUE","TYPE","UNKNOWN","UPDATE","UPPER", - "VALUE","WHEN","WHERE"); - - private Constants() {} - -} diff --git a/querydsl-jpa-codegen/src/main/java/com/mysema/query/jpa/codegen/HibernateDomainExporter.java b/querydsl-jpa-codegen/src/main/java/com/mysema/query/jpa/codegen/HibernateDomainExporter.java deleted file mode 100644 index 7bcd8045e3..0000000000 --- a/querydsl-jpa-codegen/src/main/java/com/mysema/query/jpa/codegen/HibernateDomainExporter.java +++ /dev/null @@ -1,290 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa.codegen; - -import java.io.File; -import java.io.IOException; -import java.lang.reflect.AnnotatedElement; -import java.nio.charset.Charset; -import java.util.Iterator; - -import javax.xml.stream.XMLStreamException; - -import org.hibernate.MappingException; -import org.hibernate.cfg.Configuration; -import org.hibernate.mapping.Component; -import org.hibernate.mapping.KeyValue; -import org.hibernate.mapping.ManyToOne; -import org.hibernate.mapping.MappedSuperclass; -import org.hibernate.mapping.OneToMany; -import org.hibernate.mapping.PersistentClass; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.mysema.codegen.model.SimpleType; -import com.mysema.codegen.model.Type; -import com.mysema.codegen.model.TypeCategory; -import com.mysema.query.codegen.EntityType; -import com.mysema.query.codegen.Property; -import com.mysema.query.codegen.SerializerConfig; -import com.mysema.query.codegen.SimpleSerializerConfig; - -/** - * HibernateDomainExporter exports Hibernate XML configuration files to Querydsl expression types - * - * @author tiwe - * - */ -public class HibernateDomainExporter extends AbstractDomainExporter{ - - private static final Logger logger = LoggerFactory.getLogger(HibernateDomainExporter.class); - - private final Configuration configuration; - - /** - * Create a new HibernateDomainExporter instance - * - * @param targetFolder - * @param configuration - */ - public HibernateDomainExporter(File targetFolder, Configuration configuration) { - this("Q", "", targetFolder, SimpleSerializerConfig.DEFAULT, configuration, - Charset.defaultCharset()); - } - - /** - * Create a new HibernateDomainExporter instance - * - * @param namePrefix - * @param targetFolder - * @param configuration - */ - public HibernateDomainExporter(String namePrefix, File targetFolder, Configuration configuration) { - this(namePrefix, "", targetFolder, SimpleSerializerConfig.DEFAULT, configuration, - Charset.defaultCharset()); - } - - /** - * Create a new HibernateDomainExporter instance - * - * @param namePrefix - * @param targetFolder - * @param configuration - * @param charset - */ - public HibernateDomainExporter(String namePrefix, File targetFolder, Configuration configuration, - Charset charset) { - this(namePrefix, "", targetFolder, SimpleSerializerConfig.DEFAULT, configuration, charset); - } - - /** - * Create a new HibernateDomainExporter instance - * - * @param namePrefix - * @param nameSuffix - * @param targetFolder - * @param configuration - */ - public HibernateDomainExporter(String namePrefix, String nameSuffix, File targetFolder, - Configuration configuration) { - this(namePrefix, nameSuffix, targetFolder, SimpleSerializerConfig.DEFAULT, configuration, - Charset.defaultCharset()); - } - - /** - * Create a new HibernateDomainExporter instance - * - * @param namePrefix - * @param targetFolder - * @param serializerConfig - * @param configuration - */ - public HibernateDomainExporter(String namePrefix, File targetFolder, - SerializerConfig serializerConfig, Configuration configuration) { - this(namePrefix, "", targetFolder, serializerConfig, configuration, Charset.defaultCharset()); - } - - /** - * Create a new HibernateDomainExporter instance - * - * @param namePrefix - * @param targetFolder - * @param serializerConfig - * @param configuration - * @param charset - */ - public HibernateDomainExporter(String namePrefix, File targetFolder, - SerializerConfig serializerConfig, Configuration configuration, Charset charset) { - this(namePrefix, "", targetFolder, serializerConfig, configuration, charset); - } - - /** - * Create a new HibernateDomainExporter instance - * - * @param namePrefix - * @param nameSuffix - * @param targetFolder - * @param serializerConfig - * @param configuration - * @param charset - */ - public HibernateDomainExporter(String namePrefix, String nameSuffix, File targetFolder, - SerializerConfig serializerConfig, Configuration configuration, Charset charset) { - super(namePrefix, nameSuffix, targetFolder, serializerConfig, charset); - configuration.buildMappings(); - this.configuration = configuration; - } - - @Override - protected void collectTypes() throws IOException, XMLStreamException, ClassNotFoundException, - NoSuchMethodException { - // super classes - Iterator<?> superClassMappings = configuration.getMappedSuperclassMappings(); - while (superClassMappings.hasNext()) { - MappedSuperclass msc = (MappedSuperclass)superClassMappings.next(); - EntityType entityType = createSuperType(msc.getMappedClass()); - if (msc.getDeclaredIdentifierProperty() != null) { - handleProperty(entityType, msc.getMappedClass(), msc.getDeclaredIdentifierProperty()); - } - Iterator<?> properties = msc.getDeclaredPropertyIterator(); - while (properties.hasNext()) { - handleProperty(entityType, msc.getMappedClass(), (org.hibernate.mapping.Property) properties.next()); - } - } - - // entity classes - Iterator<?> classMappings = configuration.getClassMappings(); - while (classMappings.hasNext()) { - PersistentClass pc = (PersistentClass)classMappings.next(); - EntityType entityType = createEntityType(pc.getMappedClass()); - if (pc.getDeclaredIdentifierProperty() != null) { - handleProperty(entityType, pc.getMappedClass(), pc.getDeclaredIdentifierProperty()); - } else if (!pc.isInherited() && pc.hasIdentifierProperty()) { - logger.info(entityType.toString() + pc.getIdentifierProperty()); - handleProperty(entityType, pc.getMappedClass(), pc.getIdentifierProperty()); - } else if (pc.getIdentifier() != null) { - KeyValue identifier = pc.getIdentifier(); - if (identifier instanceof Component) { - Component component = (Component)identifier; - Iterator<?> properties = component.getPropertyIterator(); - if (component.isEmbedded()) { - while (properties.hasNext()) { - handleProperty(entityType, pc.getMappedClass(), (org.hibernate.mapping.Property) properties.next()); - } - } else { - String name = component.getNodeName(); - Class<?> clazz = component.getType().getReturnedClass(); - Type propertyType = getType(pc.getMappedClass(), clazz, name); - AnnotatedElement annotated = getAnnotatedElement(pc.getMappedClass(), name); - Property property = createProperty(entityType, name, propertyType, annotated); - entityType.addProperty(property); - // handle component properties - EntityType embeddedType = createEmbeddableType(propertyType); - while (properties.hasNext()) { - handleProperty(embeddedType, clazz, (org.hibernate.mapping.Property) properties.next()); - } - } - } - // TODO handle other KeyValue subclasses such as Any, DependentValue and ToOne - } - Iterator<?> properties = pc.getDeclaredPropertyIterator(); - while (properties.hasNext()) { - handleProperty(entityType, pc.getMappedClass(), (org.hibernate.mapping.Property) properties.next()); - } - } - } - - private void handleProperty(EntityType entityType, Class<?> cl, org.hibernate.mapping.Property p) - throws NoSuchMethodException, ClassNotFoundException { - if (p.isBackRef()) { - return; - } - Class<?> clazz = Object.class; - try { - clazz = p.getType().getReturnedClass(); - } catch (MappingException e) { - // ignore - } - Type propertyType = getType(cl, clazz, p.getName()); - try { - propertyType = getPropertyType(p, propertyType); - } catch (MappingException e) { - // ignore - } - - AnnotatedElement annotated = getAnnotatedElement(cl, p.getName()); - propertyType = getTypeOverride(propertyType, annotated); - if (propertyType == null) { - return; - } - - if (p.isComposite()) { - EntityType embeddedType = createEmbeddableType(propertyType); - Iterator<?> properties = ((Component)p.getValue()).getPropertyIterator(); - while (properties.hasNext()) { - handleProperty(embeddedType, embeddedType.getJavaClass(), (org.hibernate.mapping.Property)properties.next()); - } - propertyType = embeddedType; - } else if (propertyType.getCategory() == TypeCategory.ENTITY || p.getValue() instanceof ManyToOne) { - propertyType = createEntityType(propertyType); - } else if (propertyType.getCategory() == TypeCategory.CUSTOM) { - propertyType = createEmbeddableType(propertyType); - } else if (p.getValue() instanceof org.hibernate.mapping.Collection) { - org.hibernate.mapping.Collection collection = (org.hibernate.mapping.Collection)p.getValue(); - if (collection.getElement() instanceof OneToMany) { - String entityName = ((OneToMany)collection.getElement()).getReferencedEntityName(); - if (entityName != null) { - if (collection.isMap()) { - Type keyType = typeFactory.get(Class.forName(propertyType.getParameters().get(0).getFullName())); - Type valueType = typeFactory.get(Class.forName(entityName)); - propertyType = new SimpleType(propertyType, keyType, valueType); - } else { - Type componentType = typeFactory.get(Class.forName(entityName)); - propertyType = new SimpleType(propertyType, componentType); - } - } - } else if (collection.getElement() instanceof Component) { - Component component = (Component)collection.getElement(); - Class<?> embeddedClass = Class.forName(component.getComponentClassName()); - EntityType embeddedType = createEmbeddableType(embeddedClass); - Iterator<?> properties = component.getPropertyIterator(); - while (properties.hasNext()) { - handleProperty(embeddedType, embeddedClass, (org.hibernate.mapping.Property)properties.next()); - } - } - } - - Property property = createProperty(entityType, p.getName(), propertyType, annotated); - entityType.addProperty(property); - } - - private Type getPropertyType(org.hibernate.mapping.Property p, Type propertyType) { - switch (propertyType.getCategory()) { - case DATE: - case TIME: - case DATETIME: - String type = p.getType().getName(); - if ("time".equals(type)) { - propertyType = propertyType.as(TypeCategory.TIME); - } else if ("date".equals(type)) { - propertyType = propertyType.as(TypeCategory.DATE); - } else if ("timestamp".equals(type)) { - propertyType = propertyType.as(TypeCategory.DATETIME); - } - default: - } - return propertyType; - } - -} diff --git a/querydsl-jpa-codegen/src/main/java/com/mysema/query/jpa/codegen/JPADomainExporter.java b/querydsl-jpa-codegen/src/main/java/com/mysema/query/jpa/codegen/JPADomainExporter.java deleted file mode 100644 index bd7c53e345..0000000000 --- a/querydsl-jpa-codegen/src/main/java/com/mysema/query/jpa/codegen/JPADomainExporter.java +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Copyright 2013, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa.codegen; - -import java.io.File; -import java.io.IOException; -import java.lang.reflect.AnnotatedElement; -import java.nio.charset.Charset; -import java.util.Map; - -import javax.persistence.Temporal; -import javax.persistence.metamodel.Attribute; -import javax.persistence.metamodel.EmbeddableType; -import javax.persistence.metamodel.ManagedType; -import javax.persistence.metamodel.MapAttribute; -import javax.persistence.metamodel.MappedSuperclassType; -import javax.persistence.metamodel.Metamodel; -import javax.persistence.metamodel.PluralAttribute; -import javax.xml.stream.XMLStreamException; - -import org.hibernate.MappingException; - -import com.google.common.collect.Maps; -import com.mysema.codegen.model.SimpleType; -import com.mysema.codegen.model.Type; -import com.mysema.codegen.model.TypeCategory; -import com.mysema.query.codegen.EntityType; -import com.mysema.query.codegen.Property; -import com.mysema.query.codegen.SerializerConfig; -import com.mysema.query.codegen.SimpleSerializerConfig; - -/** - * JPADomainExporter exports JPA 2 metamodels to Querydsl expression types - * - * @author tiwe - * - */ -public class JPADomainExporter extends AbstractDomainExporter { - - private final Metamodel configuration; - - /** - * Create a new JPADomainExporter instance - * - * @param targetFolder - * @param configuration - */ - public JPADomainExporter(File targetFolder, Metamodel configuration) { - this("Q", "", targetFolder, SimpleSerializerConfig.DEFAULT, configuration, - Charset.defaultCharset()); - } - - /** - * Create a new JPADomainExporter instance - * - * @param namePrefix - * @param targetFolder - * @param configuration - */ - public JPADomainExporter(String namePrefix, File targetFolder, Metamodel configuration) { - this(namePrefix, "", targetFolder, SimpleSerializerConfig.DEFAULT, configuration, - Charset.defaultCharset()); - } - - /** - * Create a new JPADomainExporter instance - * - * @param namePrefix - * @param targetFolder - * @param configuration - * @param charset - */ - public JPADomainExporter(String namePrefix, File targetFolder, Metamodel configuration, - Charset charset) { - this(namePrefix, "", targetFolder, SimpleSerializerConfig.DEFAULT, configuration, charset); - } - - /** - * Create a new JPADomainExporter instance - * - * @param namePrefix - * @param nameSuffix - * @param targetFolder - * @param configuration - */ - public JPADomainExporter(String namePrefix, String nameSuffix, File targetFolder, - Metamodel configuration) { - this(namePrefix, nameSuffix, targetFolder, SimpleSerializerConfig.DEFAULT, configuration, - Charset.defaultCharset()); - } - - /** - * Create a new JPADomainExporter instance - * - * @param namePrefix - * @param targetFolder - * @param serializerConfig - * @param configuration - */ - public JPADomainExporter(String namePrefix, File targetFolder, - SerializerConfig serializerConfig, Metamodel configuration) { - this(namePrefix, "", targetFolder, serializerConfig, configuration, Charset.defaultCharset()); - } - - /** - * Create a new JPADomainExporter instance - * - * @param namePrefix - * @param targetFolder - * @param serializerConfig - * @param configuration - * @param charset - */ - public JPADomainExporter(String namePrefix, File targetFolder, - SerializerConfig serializerConfig, Metamodel configuration, Charset charset) { - this(namePrefix, "", targetFolder, serializerConfig, configuration, charset); - } - - /** - * Create a new JPADomainExporter instance - * - * @param namePrefix - * @param nameSuffix - * @param targetFolder - * @param serializerConfig - * @param configuration - * @param charset - */ - public JPADomainExporter(String namePrefix, String nameSuffix, File targetFolder, - SerializerConfig serializerConfig, Metamodel configuration, Charset charset) { - super(namePrefix, nameSuffix, targetFolder, serializerConfig, charset); - this.configuration = configuration; - } - - @Override - protected void collectTypes() throws IOException, XMLStreamException, ClassNotFoundException, - NoSuchMethodException { - - Map<ManagedType<?>, EntityType> types = Maps.newHashMap(); - for (ManagedType<?> managedType : configuration.getManagedTypes()) { - if (managedType instanceof MappedSuperclassType) { - types.put(managedType, createSuperType(managedType.getJavaType())); - } else if (managedType instanceof javax.persistence.metamodel.EntityType) { - types.put(managedType, createEntityType(managedType.getJavaType())); - } else if (managedType instanceof EmbeddableType) { - types.put(managedType, createEmbeddableType(managedType.getJavaType())); - } else { - throw new IllegalArgumentException("Unknown type " + managedType); - } - } - - // handle properties - for (Map.Entry<ManagedType<?>, EntityType> entry : types.entrySet()) { - EntityType entityType = entry.getValue(); - for (Attribute<?,?> attribute : entry.getKey().getDeclaredAttributes()) { - handleProperty(entityType, entityType.getJavaClass(), attribute); - } - } - - } - - private void handleProperty(EntityType entityType, Class<?> cl, Attribute<?,?> p) - throws NoSuchMethodException, ClassNotFoundException { - Class<?> clazz = Object.class; - try { - clazz = p.getJavaType(); - } catch (MappingException e) { - // ignore - } - Type propertyType = getType(cl, clazz, p.getName()); - - AnnotatedElement annotated = getAnnotatedElement(cl, p.getName()); - propertyType = getTypeOverride(propertyType, annotated); - if (propertyType == null) { - return; - } - - if (p.isCollection()) { - if (p instanceof MapAttribute) { - MapAttribute<?,?,?> map = (MapAttribute<?,?,?>)p; - Type keyType = typeFactory.get(map.getKeyJavaType()); - Type valueType = typeFactory.get(map.getElementType().getJavaType()); - valueType = getPropertyType(p, valueType); - propertyType = new SimpleType(propertyType, keyType, valueType); - } else { - Type valueType = typeFactory.get(((PluralAttribute<?,?,?>)p).getElementType().getJavaType()); - valueType = getPropertyType(p, valueType); - propertyType = new SimpleType(propertyType, valueType); - } - } else { - propertyType = getPropertyType(p, propertyType); - } - - Property property = createProperty(entityType, p.getName(), propertyType, annotated); - entityType.addProperty(property); - } - - private Type getPropertyType(Attribute<?, ?> p, Type propertyType) { - Temporal temporal = ((AnnotatedElement)p.getJavaMember()).getAnnotation(Temporal.class); - if (temporal != null) { - switch (temporal.value()) { - case DATE: propertyType = propertyType.as(TypeCategory.DATE); break; - case TIME: propertyType = propertyType.as(TypeCategory.TIME); break; - case TIMESTAMP: propertyType = propertyType.as(TypeCategory.DATETIME); break; - } - } - return propertyType; - } - -} diff --git a/querydsl-jpa-codegen/src/main/java/com/mysema/query/jpa/codegen/AbstractDomainExporter.java b/querydsl-jpa-codegen/src/main/java/com/querydsl/jpa/codegen/AbstractDomainExporter.java similarity index 77% rename from querydsl-jpa-codegen/src/main/java/com/mysema/query/jpa/codegen/AbstractDomainExporter.java rename to querydsl-jpa-codegen/src/main/java/com/querydsl/jpa/codegen/AbstractDomainExporter.java index fa37b4121a..7f9cfb7cb1 100644 --- a/querydsl-jpa-codegen/src/main/java/com/mysema/query/jpa/codegen/AbstractDomainExporter.java +++ b/querydsl-jpa-codegen/src/main/java/com/querydsl/jpa/codegen/AbstractDomainExporter.java @@ -1,5 +1,5 @@ /* - * Copyright 2013, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,83 +11,71 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.jpa.codegen; +package com.querydsl.jpa.codegen; + +import com.querydsl.codegen.*; +import com.querydsl.codegen.utils.CodeWriter; +import com.querydsl.codegen.utils.JavaWriter; +import com.querydsl.codegen.utils.model.Type; +import com.querydsl.codegen.utils.model.TypeCategory; +import com.querydsl.core.QueryException; +import com.querydsl.core.annotations.Config; +import com.querydsl.core.annotations.PropertyType; +import com.querydsl.core.annotations.QueryInit; +import com.querydsl.core.annotations.QueryType; +import com.querydsl.core.util.Annotations; +import com.querydsl.core.util.ReflectionUtils; +import org.jetbrains.annotations.Nullable; +import javax.persistence.Embeddable; +import javax.persistence.Entity; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.Writer; -import java.lang.annotation.Annotation; import java.lang.reflect.AnnotatedElement; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.nio.charset.Charset; import java.util.Arrays; import java.util.Collections; +import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; - -import javax.annotation.Nullable; -import javax.persistence.Embeddable; -import javax.persistence.Entity; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; -import com.mysema.codegen.CodeWriter; -import com.mysema.codegen.JavaWriter; -import com.mysema.codegen.model.Type; -import com.mysema.codegen.model.TypeCategory; -import com.mysema.query.QueryException; -import com.mysema.query.annotations.PropertyType; -import com.mysema.query.annotations.QueryInit; -import com.mysema.query.annotations.QueryType; -import com.mysema.query.codegen.CodegenModule; -import com.mysema.query.codegen.EmbeddableSerializer; -import com.mysema.query.codegen.EntitySerializer; -import com.mysema.query.codegen.EntityType; -import com.mysema.query.codegen.Property; -import com.mysema.query.codegen.QueryTypeFactory; -import com.mysema.query.codegen.Serializer; -import com.mysema.query.codegen.SerializerConfig; -import com.mysema.query.codegen.Supertype; -import com.mysema.query.codegen.SupertypeSerializer; -import com.mysema.query.codegen.TypeFactory; -import com.mysema.query.codegen.TypeMappings; -import com.mysema.util.Annotations; -import com.mysema.util.ReflectionUtils; +import java.util.function.Function; +import java.util.logging.Level; +import java.util.logging.Logger; /** - * AbstractDomainExporter is a common supertype for DomainExporters + * {@code AbstractDomainExporter} is a common supertype for domain exporters * * @author tiwe * */ public abstract class AbstractDomainExporter { - private static final Logger logger = LoggerFactory.getLogger(HibernateDomainExporter.class); + private static final Logger logger = Logger.getLogger(AbstractDomainExporter.class.getName()); private final File targetFolder; - private final Map<Class<?>, EntityType> allTypes = Maps.newHashMap(); + private final Map<Class<?>, EntityType> allTypes = new HashMap<>(); - private final Map<Class<?>, EntityType> entityTypes = Maps.newHashMap(); + private final Map<Class<?>, EntityType> entityTypes = new HashMap<>(); - private final Map<Class<?>, EntityType> embeddableTypes = Maps.newHashMap(); + private final Map<Class<?>, EntityType> embeddableTypes = new HashMap<>(); - private final Map<Class<?>, EntityType> superTypes = Maps.newHashMap(); + private final Map<Class<?>, EntityType> superTypes = new HashMap<>(); + + private final Map<Class<?>, SerializerConfig> typeToConfig = new HashMap<>(); private final Set<EntityType> serialized = new HashSet<EntityType>(); @SuppressWarnings("unchecked") - protected final TypeFactory typeFactory = new TypeFactory(Arrays.<Class<? extends Annotation>>asList(Entity.class, + protected final TypeFactory typeFactory = new TypeFactory(Arrays.asList(Entity.class, javax.persistence.MappedSuperclass.class, Embeddable.class)); private final QueryTypeFactory queryTypeFactory; @@ -106,13 +94,9 @@ public abstract class AbstractDomainExporter { private final Set<File> generatedFiles = new HashSet<File>(); - /** - * @param namePrefix - * @param nameSuffix - * @param targetFolder - * @param serializerConfig - * @param charset - */ + private Function<EntityType, String> variableNameFunction; + + @SuppressWarnings("unchecked") public AbstractDomainExporter(String namePrefix, String nameSuffix, File targetFolder, SerializerConfig serializerConfig, Charset charset) { this.targetFolder = targetFolder; @@ -122,11 +106,13 @@ public AbstractDomainExporter(String namePrefix, String nameSuffix, File targetF module.bind(CodegenModule.PREFIX, namePrefix); module.bind(CodegenModule.SUFFIX, nameSuffix); module.bind(CodegenModule.KEYWORDS, Constants.keywords); + module.loadExtensions(); this.queryTypeFactory = module.get(QueryTypeFactory.class); this.typeMappings = module.get(TypeMappings.class); this.embeddableSerializer = module.get(EmbeddableSerializer.class); this.entitySerializer = module.get(EntitySerializer.class); this.supertypeSerializer = module.get(SupertypeSerializer.class); + this.variableNameFunction = module.get(Function.class, CodegenModule.VARIABLE_NAME_FUNCTION_CLASS); } /** @@ -143,7 +129,7 @@ public void execute() throws IOException { } // go through supertypes - Set<Supertype> additions = Sets.newHashSet(); + Set<Supertype> additions = new HashSet<>(); for (Map.Entry<Class<?>, EntityType> entry : allTypes.entrySet()) { EntityType entityType = entry.getValue(); if (entityType.getSuperType() != null && !allTypes.containsKey(entityType.getSuperType().getType().getJavaClass())) { @@ -206,6 +192,7 @@ private EntityType createEntityType(Class<?> cl, Map<Class<?>, EntityType> type return allTypes.get(cl); } else { EntityType type = typeFactory.getEntityType(cl); + registerConfig(type); typeMappings.register(type, queryTypeFactory.create(type)); if (!cl.getSuperclass().equals(Object.class)) { type.addSupertype(new Supertype(typeFactory.get(cl.getSuperclass(), cl.getGenericSuperclass()))); @@ -225,7 +212,8 @@ protected EntityType createEntityType(Type type, Map<Class<?>, EntityType> type if (allTypes.containsKey(key)) { return allTypes.get(key); } else { - EntityType entityType = new EntityType(type); + EntityType entityType = new EntityType(type, variableNameFunction); + registerConfig(entityType); typeMappings.register(entityType, queryTypeFactory.create(entityType)); Class<?> superClass = key.getSuperclass(); if (entityType.getSuperType() == null && superClass != null && !superClass.equals(Object.class)) { @@ -237,6 +225,17 @@ protected EntityType createEntityType(Type type, Map<Class<?>, EntityType> type } } + private void registerConfig(EntityType entityType) { + Class<?> key = entityType.getJavaClass(); + Config config = key.getAnnotation(Config.class); + if (config == null && key.getPackage() != null) { + config = key.getPackage().getAnnotation(Config.class); + } + if (config != null) { + typeToConfig.put(key, SimpleSerializerConfig.getConfig(config)); + } + } + @Nullable protected Type getTypeOverride(Type propertyType, AnnotatedElement annotated) { if (annotated.isAnnotationPresent(QueryType.class)) { @@ -252,9 +251,9 @@ protected Type getTypeOverride(Type propertyType, AnnotatedElement annotated) { protected Property createProperty(EntityType entityType, String propertyName, Type propertyType, AnnotatedElement annotated) { - List<String> inits = Collections.<String>emptyList(); + List<String> inits = Collections.emptyList(); if (annotated.isAnnotationPresent(QueryInit.class)) { - inits = ImmutableList.copyOf(annotated.getAnnotation(QueryInit.class).value()); + inits = Collections.unmodifiableList(Arrays.asList(annotated.getAnnotation(QueryInit.class).value())); } return new Property(entityType, propertyName, propertyType, inits); } @@ -319,18 +318,19 @@ private void serialize(Map<Class<?>, EntityType> types, Serializer serializer) t private void write(Serializer serializer, String path, EntityType type) throws IOException { File targetFile = new File(targetFolder, path); generatedFiles.add(targetFile); - Writer w = writerFor(targetFile); - try{ + try (Writer w = writerFor(targetFile)) { CodeWriter writer = new JavaWriter(w); - serializer.serialize(type, serializerConfig, writer); - }finally{ - w.close(); + if (typeToConfig.containsKey(type.getJavaClass())) { + serializer.serialize(type, typeToConfig.get(type.getJavaClass()), writer); + } else { + serializer.serialize(type, serializerConfig, writer); + } } } private Writer writerFor(File file) { if (!file.getParentFile().exists() && !file.getParentFile().mkdirs()) { - logger.error("Folder " + file.getParent() + " could not be created"); + logger.log(Level.WARNING, "Folder " + file.getParent() + " could not be created"); } try { return new OutputStreamWriter(new FileOutputStream(file), charset); @@ -339,6 +339,14 @@ private Writer writerFor(File file) { } } + protected Type normalize(Type first, Type second) { + if (first.getFullName().equals(second.getFullName())) { + return first; + } else { + return second; + } + } + public void setUnknownAsEntity(boolean unknownAsEntity) { typeFactory.setUnknownAsEntity(unknownAsEntity); } diff --git a/querydsl-jpa-codegen/src/main/java/com/querydsl/jpa/codegen/Constants.java b/querydsl-jpa-codegen/src/main/java/com/querydsl/jpa/codegen/Constants.java new file mode 100644 index 0000000000..246c641369 --- /dev/null +++ b/querydsl-jpa-codegen/src/main/java/com/querydsl/jpa/codegen/Constants.java @@ -0,0 +1,47 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.codegen; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +/** + * Constants defines keywords used in Hibernate + * + * @author tiwe + * + */ +final class Constants { + + public static final List<String> keywords = Collections.unmodifiableList(Arrays.asList( + "ABS", "ALL", "AND", "ANY", "AS", "ASC", "AVG", "BETWEEN", + "BIT_LENGTH[51]", "BOTH", "BY", "CASE", "CHAR_LENGTH", + "CHARACTER_LENGTH", "CLASS", + "COALESCE", "CONCAT", "COUNT", "CURRENT_DATE", "CURRENT_TIME", + "CURRENT_TIMESTAMP", + "DELETE", "DESC", "DISTINCT", "ELSE", "EMPTY", "END", "ENTRY", + "ESCAPE", "EXISTS", "FALSE", "FETCH", + "FROM", "GROUP", "HAVING", "IN", "INDEX", "INNER", "IS", "JOIN", + "KEY", "LEADING", "LEFT", "LENGTH", "LIKE", + "LOCATE", "LOWER", "MAX", "MEMBER", "MIN", "MOD", "NEW", "NOT", + "NULL", "NULLIF", "OBJECT", "OF", "OR", + "ORDER", "OUTER", "POSITION", "SELECT", "SET", "SIZE", "SOME", + "SQRT", "SUBSTRING", "SUM", "THEN", + "TRAILING", "TRIM", "TRUE", "TYPE", "UNKNOWN", "UPDATE", "UPPER", + "VALUE", "WHEN", "WHERE")); + + private Constants() { } + +} diff --git a/querydsl-jpa-codegen/src/main/java/com/querydsl/jpa/codegen/JPADomainExporter.java b/querydsl-jpa-codegen/src/main/java/com/querydsl/jpa/codegen/JPADomainExporter.java new file mode 100644 index 0000000000..e6c8bc14cd --- /dev/null +++ b/querydsl-jpa-codegen/src/main/java/com/querydsl/jpa/codegen/JPADomainExporter.java @@ -0,0 +1,218 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.codegen; + +import java.io.File; +import java.io.IOException; +import java.lang.reflect.AnnotatedElement; +import java.nio.charset.Charset; +import java.util.HashMap; +import java.util.Map; + +import javax.persistence.Temporal; +import javax.persistence.metamodel.*; +import javax.xml.stream.XMLStreamException; + +import org.hibernate.MappingException; + +import com.querydsl.codegen.utils.model.SimpleType; +import com.querydsl.codegen.utils.model.Type; +import com.querydsl.codegen.utils.model.TypeCategory; +import com.querydsl.codegen.EntityType; +import com.querydsl.codegen.Property; +import com.querydsl.codegen.SerializerConfig; +import com.querydsl.codegen.SimpleSerializerConfig; + +/** + * {@code JPADomainExporter} exports JPA 2 metamodels to Querydsl expression types + * + * @author tiwe + * + */ +public class JPADomainExporter extends AbstractDomainExporter { + + private final Metamodel metamodel; + + /** + * Create a new JPADomainExporter instance + * + * @param targetFolder target folder + * @param metamodel metamodel + */ + public JPADomainExporter(File targetFolder, Metamodel metamodel) { + this("Q", "", targetFolder, SimpleSerializerConfig.DEFAULT, metamodel, + Charset.defaultCharset()); + } + + /** + * Create a new JPADomainExporter instance + * + * @param namePrefix name prefix (default: Q) + * @param targetFolder target folder + * @param metamodel metamodel + */ + public JPADomainExporter(String namePrefix, File targetFolder, Metamodel metamodel) { + this(namePrefix, "", targetFolder, SimpleSerializerConfig.DEFAULT, metamodel, + Charset.defaultCharset()); + } + + /** + * Create a new JPADomainExporter instance + * + * @param namePrefix name prefix (default: Q) + * @param targetFolder target folder + * @param metamodel metamodel + * @param charset charset (default: system charset) + */ + public JPADomainExporter(String namePrefix, File targetFolder, Metamodel metamodel, + Charset charset) { + this(namePrefix, "", targetFolder, SimpleSerializerConfig.DEFAULT, metamodel, charset); + } + + /** + * Create a new JPADomainExporter instance + * + * @param namePrefix name prefix (default: Q) + * @param nameSuffix name suffix + * @param targetFolder target folder + * @param metamodel metamodel + */ + public JPADomainExporter(String namePrefix, String nameSuffix, File targetFolder, + Metamodel metamodel) { + this(namePrefix, nameSuffix, targetFolder, SimpleSerializerConfig.DEFAULT, metamodel, + Charset.defaultCharset()); + } + + /** + * Create a new JPADomainExporter instance + * + * @param namePrefix name prefix (default: Q) + * @param targetFolder target folder + * @param serializerConfig serializer config + * @param metamodel metamodel + */ + public JPADomainExporter(String namePrefix, File targetFolder, + SerializerConfig serializerConfig, Metamodel metamodel) { + this(namePrefix, "", targetFolder, serializerConfig, metamodel, Charset.defaultCharset()); + } + + /** + * Create a new JPADomainExporter instance + * + * @param namePrefix name prefix (default: Q) + * @param targetFolder target folder + * @param serializerConfig serializer config + * @param metamodel metamodel + * @param charset charset (default: system charset) + */ + public JPADomainExporter(String namePrefix, File targetFolder, + SerializerConfig serializerConfig, Metamodel metamodel, Charset charset) { + this(namePrefix, "", targetFolder, serializerConfig, metamodel, charset); + } + + /** + * Create a new JPADomainExporter instance + * + * @param namePrefix name prefix (default: Q) + * @param nameSuffix name suffix (default: empty) + * @param targetFolder target folder + * @param serializerConfig serializer config + * @param metamodel metamodel + * @param charset charset (default: system charset) + */ + public JPADomainExporter(String namePrefix, String nameSuffix, File targetFolder, + SerializerConfig serializerConfig, Metamodel metamodel, Charset charset) { + super(namePrefix, nameSuffix, targetFolder, serializerConfig, charset); + this.metamodel = metamodel; + } + + @Override + protected void collectTypes() throws IOException, XMLStreamException, ClassNotFoundException, + NoSuchMethodException { + + Map<ManagedType<?>, EntityType> types = new HashMap<>(); + for (ManagedType<?> managedType : metamodel.getManagedTypes()) { + if (managedType instanceof MappedSuperclassType) { + types.put(managedType, createSuperType(managedType.getJavaType())); + } else if (managedType instanceof javax.persistence.metamodel.EntityType) { + types.put(managedType, createEntityType(managedType.getJavaType())); + } else if (managedType instanceof EmbeddableType) { + types.put(managedType, createEmbeddableType(managedType.getJavaType())); + } else { + throw new IllegalArgumentException("Unknown type " + managedType); + } + } + + // handle properties + for (Map.Entry<ManagedType<?>, EntityType> entry : types.entrySet()) { + EntityType entityType = entry.getValue(); + for (Attribute<?,?> attribute : entry.getKey().getDeclaredAttributes()) { + handleProperty(entityType, entityType.getJavaClass(), attribute); + } + } + + } + + private void handleProperty(EntityType entityType, Class<?> cl, Attribute<?,?> p) + throws NoSuchMethodException, ClassNotFoundException { + Class<?> clazz = Object.class; + try { + clazz = p.getJavaType(); + } catch (MappingException e) { + // ignore + } + Type propertyType = getType(cl, clazz, p.getName()); + + AnnotatedElement annotated = getAnnotatedElement(cl, p.getName()); + propertyType = getTypeOverride(propertyType, annotated); + if (propertyType == null) { + return; + } + + if (p.isCollection()) { + if (p instanceof MapAttribute) { + MapAttribute<?,?,?> map = (MapAttribute<?,?,?>) p; + Type keyType = typeFactory.get(map.getKeyJavaType()); + Type valueType = typeFactory.get(map.getElementType().getJavaType()); + valueType = getPropertyType(p, valueType); + propertyType = new SimpleType(propertyType, + normalize(propertyType.getParameters().get(0), keyType), + normalize(propertyType.getParameters().get(1), valueType)); + } else { + Type valueType = typeFactory.get(((PluralAttribute<?,?,?>) p).getElementType().getJavaType()); + valueType = getPropertyType(p, valueType); + propertyType = new SimpleType(propertyType, + normalize(propertyType.getParameters().get(0), valueType)); + } + } else { + propertyType = getPropertyType(p, propertyType); + } + + Property property = createProperty(entityType, p.getName(), propertyType, annotated); + entityType.addProperty(property); + } + + private Type getPropertyType(Attribute<?, ?> p, Type propertyType) { + Temporal temporal = ((AnnotatedElement) p.getJavaMember()).getAnnotation(Temporal.class); + if (temporal != null) { + switch (temporal.value()) { + case DATE: propertyType = propertyType.as(TypeCategory.DATE); break; + case TIME: propertyType = propertyType.as(TypeCategory.TIME); break; + case TIMESTAMP: propertyType = propertyType.as(TypeCategory.DATETIME); break; + } + } + return propertyType; + } + +} diff --git a/querydsl-jpa-codegen/src/main/java/com/querydsl/jpa/codegen/ant/AntJPADomainExporter.java b/querydsl-jpa-codegen/src/main/java/com/querydsl/jpa/codegen/ant/AntJPADomainExporter.java new file mode 100644 index 0000000000..4c8f95a597 --- /dev/null +++ b/querydsl-jpa-codegen/src/main/java/com/querydsl/jpa/codegen/ant/AntJPADomainExporter.java @@ -0,0 +1,163 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.codegen.ant; + +import java.io.File; +import java.io.IOException; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; +import javax.persistence.metamodel.Metamodel; + +import com.querydsl.jpa.codegen.JPADomainExporter; + +/** + * {@code AntJPADomainExporter} exports JPA 2 metamodels to Querydsl expression types + * + * @author 200003548 + */ +public class AntJPADomainExporter { + + /** + * Additional property to use when creating the JPA entity manager factory + */ + public static class Property { + private String name; + private String value; + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + public String getValue() { + return value; + } + public void setValue(String value) { + this.value = value; + } + } + + /** + * Set of additional properties to use when creating the JPA entity manager factory + */ + public static class Configuration { + private Map<String, String> properties = new HashMap<String, String>(); + public Map<String, String> getProperties() { + return properties; + } + public void addConfiguredProperty(Property property) { + properties.put(property.getName(), property.getValue()); + } + } + + /** + * Set of additional properties to use when creating the JPA entity manager factory + * (no default - not required) + */ + private Configuration configuration; + + /** + * Name prefix for generated query types (default: "Q") + */ + private String namePrefix = "Q"; + + /** + * Name suffix for generated query types (default: "") + */ + private String nameSuffix = ""; + + /** + * Target folder in which to generate query types (no default - required) + */ + private String targetFolder; + + /** + * Name of persistence unit from which to generate query types (no default - required) + */ + private String persistenceUnitName; + + private Set<File> generatedFiles = Collections.emptySet(); + + public Configuration getConfiguration() { + return configuration; + } + + public void addConfiguration(Configuration configuration) { + this.configuration = configuration; + } + + public String getNamePrefix() { + return namePrefix; + } + + public void setNamePrefix(String namePrefix) { + this.namePrefix = namePrefix; + } + + public String getNameSuffix() { + return nameSuffix; + } + + public void setNameSuffix(String nameSuffix) { + this.nameSuffix = nameSuffix; + } + + public String getTargetFolder() { + return targetFolder; + } + + public void setTargetFolder(String targetFolder) { + this.targetFolder = targetFolder; + } + + public String getPersistenceUnitName() { + return persistenceUnitName; + } + + public void setPersistenceUnitName(String persistenceUnitName) { + this.persistenceUnitName = persistenceUnitName; + } + + public Set<File> getGeneratedFiles() { + return generatedFiles; + } + + /** + * Exports the named persistence unit's metamodel to Querydsl query types. Expects to be + * called by Ant via name convention using a method with signature public void execute(). + */ + public void execute() { + // We can assume we have the named persistence unit and its mapping file in our classpath, + // but we may have to allow some properties in that persistence unit to be overridden before + // we can successfully get that persistence unit's metamodel. + Map<String, String> properties = (configuration != null) ? configuration.getProperties() : null; + EntityManagerFactory emf = Persistence.createEntityManagerFactory(persistenceUnitName, properties); + + // Now we can get the persistence unit's metamodel and export it to Querydsl query types. + Metamodel configuration = emf.getMetamodel(); + JPADomainExporter exporter = new JPADomainExporter(namePrefix, nameSuffix, new File(targetFolder), configuration); + try { + exporter.execute(); + generatedFiles = exporter.getGeneratedFiles(); + } catch (IOException e) { + throw new RuntimeException("Error in JPADomainExporter", e); + } + } + +} diff --git a/querydsl-jpa-codegen/src/main/java/com/querydsl/jpa/codegen/ant/package-info.java b/querydsl-jpa-codegen/src/main/java/com/querydsl/jpa/codegen/ant/package-info.java new file mode 100644 index 0000000000..0e20b664d2 --- /dev/null +++ b/querydsl-jpa-codegen/src/main/java/com/querydsl/jpa/codegen/ant/package-info.java @@ -0,0 +1,18 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ + +/** + * ANT integration for JPA code generation + */ +package com.querydsl.jpa.codegen.ant; diff --git a/querydsl-jpa-codegen/src/main/java/com/querydsl/jpa/codegen/package-info.java b/querydsl-jpa-codegen/src/main/java/com/querydsl/jpa/codegen/package-info.java new file mode 100644 index 0000000000..fedf81fd27 --- /dev/null +++ b/querydsl-jpa-codegen/src/main/java/com/querydsl/jpa/codegen/package-info.java @@ -0,0 +1,18 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ + +/** + * JPA and Hibernate model based code generation + */ +package com.querydsl.jpa.codegen; diff --git a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/GenericExporterTest.java b/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/GenericExporterTest.java deleted file mode 100644 index 5d03a6889e..0000000000 --- a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/GenericExporterTest.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.mysema.query.jpa; - -import java.io.File; - -import org.junit.Test; - -import com.mysema.query.codegen.GenericExporter; - -public class GenericExporterTest { - - @Test - public void test() { - GenericExporter exporter = new GenericExporter(); - exporter.setTargetFolder(new File("target/" + GenericExporterTest.class.getSimpleName())); - exporter.export(getClass().getPackage()); - } - -} diff --git a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/codegen/HibernateDomainExporterTest.java b/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/codegen/HibernateDomainExporterTest.java deleted file mode 100644 index f080b29152..0000000000 --- a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/codegen/HibernateDomainExporterTest.java +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa.codegen; - -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import org.hibernate.cfg.Configuration; -import org.junit.Test; - -import com.google.common.base.Charsets; -import com.google.common.io.Files; -import com.mysema.query.annotations.Config; -import com.mysema.query.codegen.SerializerConfig; -import com.mysema.query.codegen.SimpleSerializerConfig; -import com.mysema.query.jpa.domain.Domain; -import com.mysema.query.jpa.domain2.Domain2; -import com.mysema.util.FileUtils; - -public class HibernateDomainExporterTest { - - private final SerializerConfig serializerConfig = SimpleSerializerConfig.getConfig(Domain.class - .getPackage().getAnnotation(Config.class)); - - @Test - public void Execute_MyEntity() throws IOException { - FileUtils.delete(new File("target/gen6")); - File myEntity = new File("src/test/resources/entity.hbm.xml"); - Configuration config = new Configuration(); - config.addFile(myEntity); - HibernateDomainExporter exporter = new HibernateDomainExporter("Q", - new File("target/gen6"), config); - exporter.execute(); - - File targetFile = new File("target/gen6/com/mysema/query/jpa/codegen/QMyEntity.java"); - assertContains(targetFile, "StringPath pk1", "StringPath pk2", "StringPath prop1"); - } - - @Test - public void Execute_Contact() throws IOException { - FileUtils.delete(new File("target/gen1")); - File contact = new File("src/test/resources/contact.hbm.xml"); - Configuration config = new Configuration(); - config.addFile(contact); - HibernateDomainExporter exporter = new HibernateDomainExporter("Q", - new File("target/gen1"), config); - exporter.execute(); - - File targetFile = new File("target/gen1/com/mysema/query/jpa/domain2/QContact.java"); - assertContains(targetFile, "StringPath email", "StringPath firstName", - "NumberPath<Long> id", "StringPath lastName"); - } - - @Test - public void Execute_Contact_with_Suffix() throws IOException { - FileUtils.delete(new File("target/gen1")); - File contact = new File("src/test/resources/contact.hbm.xml"); - Configuration config = new Configuration(); - config.addFile(contact); - HibernateDomainExporter exporter = new HibernateDomainExporter("", "Type", new File( - "target/gen1"), config); - exporter.execute(); - - File targetFile = new File("target/gen1/com/mysema/query/jpa/domain2/ContactType.java"); - assertContains(targetFile, "StringPath email", "StringPath firstName", - "NumberPath<Long> id", "StringPath lastName"); - } - - @Test - public void Execute_Contact2() throws IOException { - FileUtils.delete(new File("target/gen2")); - File contact = new File("src/test/resources/contact2.hbm.xml"); - Configuration config = new Configuration(); - config.addFile(contact); - HibernateDomainExporter exporter = new HibernateDomainExporter("Q", - new File("target/gen2"), config); - exporter.execute(); - - File targetFile = new File("target/gen2/com/mysema/query/jpa/domain2/QContact.java"); - assertContains(targetFile, "StringPath email", "StringPath firstName", - "NumberPath<Long> id", "StringPath lastName"); - } - - @Test - public void Execute_Multiple() throws IOException { - FileUtils.delete(new File("target/gen3")); - Configuration config = new Configuration(); - for (Class<?> cl : Domain.classes) { - config.addAnnotatedClass(cl); - } - HibernateDomainExporter exporter = new HibernateDomainExporter("Q", - new File("target/gen3"), serializerConfig, config); - exporter.execute(); - - List<String> failures = new ArrayList<String>(); - for (File file : new File("target/gen3/com/mysema/query/jpa/domain").listFiles()) { - String result1 = Files.toString(file, Charsets.UTF_8); - String result2 = Files - .toString( - new File( - "../querydsl-jpa/target/generated-test-sources/java/com/mysema/query/jpa/domain", - file.getName()), Charsets.UTF_8); - if (!result1.equals(result2)) { - System.err.println(file.getName()); - failures.add(file.getName()); - } - } - - if (!failures.isEmpty()) { - fail("Failed with " + failures.size() + " failures"); - } - - } - - @Test - public void Execute_Multiple2() throws IOException { - FileUtils.delete(new File("target/gen4")); - Configuration config = new Configuration(); - for (Class<?> cl : Domain2.classes) { - config.addAnnotatedClass(cl); - } - HibernateDomainExporter exporter = new HibernateDomainExporter("Q", - new File("target/gen4"), serializerConfig, config); - exporter.execute(); - - List<String> failures = new ArrayList<String>(); - for (File file : new File("target/gen4/com/mysema/query/jpa/domain2").listFiles()) { - String result1 = Files.toString(file, Charsets.UTF_8); - String result2 = Files - .toString( - new File( - "../querydsl-jpa/target/generated-test-sources/java/com/mysema/query/jpa/domain2", - file.getName()), Charsets.UTF_8); - if (!result1.equals(result2)) { - System.err.println(file.getName()); - failures.add(file.getName()); - } - } - - if (!failures.isEmpty()) { - fail("Failed with " + failures.size() + " failures"); - } - - } - - @Test - public void Execute_Store() throws IOException { - FileUtils.delete(new File("target/gen5")); - File contact = new File("src/test/resources/store.hbm.xml"); - Configuration config = new Configuration(); - config.addFile(contact); - HibernateDomainExporter exporter = new HibernateDomainExporter("Q", - new File("target/gen5"), config); - exporter.execute(); - - File targetFile = new File("target/gen5/com/mysema/query/jpa/domain3/QStore.java"); - assertContains(targetFile, "StringPath code", "StringPath address"); - - targetFile = new File("target/gen5/com/mysema/query/jpa/domain3/QHardwareStore.java"); - assertContains(targetFile, "StringPath code = _super.code;", "StringPath address"); - } - - private static void assertContains(File file, String... strings) throws IOException { - assertTrue(file.getPath() + " doesn't exist", file.exists()); - String result = Files.toString(file, Charsets.UTF_8); - for (String str : strings) { - assertTrue(str + " was not contained", result.contains(str)); - } - } - -} diff --git a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/codegen/JPADomainExporterTest.java b/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/codegen/JPADomainExporterTest.java deleted file mode 100644 index e53586e1ee..0000000000 --- a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/codegen/JPADomainExporterTest.java +++ /dev/null @@ -1,225 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa.codegen; - -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.List; -import java.util.Properties; - -import javax.persistence.metamodel.Metamodel; - -import org.hibernate.SessionFactory; -import org.hibernate.cfg.Configuration; -import org.hibernate.ejb.metamodel.MetamodelImpl; -import org.hibernate.engine.spi.SessionFactoryImplementor; -import org.hibernate.service.ServiceRegistry; -import org.hibernate.service.ServiceRegistryBuilder; -import org.junit.Ignore; -import org.junit.Test; - -import com.google.common.base.Charsets; -import com.google.common.io.Files; -import com.mysema.query.annotations.Config; -import com.mysema.query.codegen.SerializerConfig; -import com.mysema.query.codegen.SimpleSerializerConfig; -import com.mysema.query.jpa.domain.Domain; -import com.mysema.query.jpa.domain2.Domain2; -import com.mysema.util.FileUtils; - -public class JPADomainExporterTest { - - private static Properties props = new Properties(); - - static { - try { - InputStream is = JPADomainExporterTest.class.getResourceAsStream("/h2.properties"); - props.load(is); - } catch (IOException e) { - throw new RuntimeException(e.getMessage(), e); - } - } - - private final SerializerConfig serializerConfig = SimpleSerializerConfig.getConfig(Domain.class - .getPackage().getAnnotation(Config.class)); - - - private Metamodel convert(Configuration config) { - ServiceRegistry serviceRegistry = new ServiceRegistryBuilder() - .applySettings(props) - .buildServiceRegistry(); - - config.setProperties(props); - config.buildMappings(); - SessionFactory sessionFactory = config.buildSessionFactory(serviceRegistry); - return MetamodelImpl.buildMetamodel(config.getClassMappings(), - (SessionFactoryImplementor) sessionFactory, true); - } - - @Test - @Ignore // FIXME - public void Execute_MyEntity() throws IOException { - FileUtils.delete(new File("target/jpagen6")); - File myEntity = new File("src/test/resources/entity.hbm.xml"); - Configuration config = new Configuration(); - config.addFile(myEntity); - JPADomainExporter exporter = new JPADomainExporter("Q", - new File("target/jpagen6"), convert(config)); - exporter.execute(); - - File targetFile = new File("target/jpagen6/com/mysema/query/jpa/codegen/QMyEntity.java"); - assertContains(targetFile, "StringPath pk1", "StringPath pk2", "StringPath prop1"); - } - - @Test - public void Execute_Contact() throws IOException { - FileUtils.delete(new File("target/jpagen1")); - File contact = new File("src/test/resources/contact.hbm.xml"); - Configuration config = new Configuration(); - config.addFile(contact); - JPADomainExporter exporter = new JPADomainExporter("Q", - new File("target/jpagen1"), convert(config)); - exporter.execute(); - - File targetFile = new File("target/jpagen1/com/mysema/query/jpa/domain2/QContact.java"); - assertContains(targetFile, "StringPath email", "StringPath firstName", - "NumberPath<Long> id", "StringPath lastName"); - } - - @Test - public void Execute_Contact_with_Suffix() throws IOException { - FileUtils.delete(new File("target/jpagen1")); - File contact = new File("src/test/resources/contact.hbm.xml"); - Configuration config = new Configuration(); - config.addFile(contact); - JPADomainExporter exporter = new JPADomainExporter("", "Type", new File( - "target/jpagen1"), convert(config)); - exporter.execute(); - - File targetFile = new File("target/jpagen1/com/mysema/query/jpa/domain2/ContactType.java"); - assertContains(targetFile, "StringPath email", "StringPath firstName", - "NumberPath<Long> id", "StringPath lastName"); - } - - @Test - public void Execute_Contact2() throws IOException { - FileUtils.delete(new File("target/jpagen2")); - File contact = new File("src/test/resources/contact2.hbm.xml"); - Configuration config = new Configuration(); - config.addFile(contact); - JPADomainExporter exporter = new JPADomainExporter("Q", - new File("target/jpagen2"), convert(config)); - exporter.execute(); - - File targetFile = new File("target/jpagen2/com/mysema/query/jpa/domain2/QContact.java"); - assertContains(targetFile, "StringPath email", "StringPath firstName", - "NumberPath<Long> id", "StringPath lastName"); - } - - @Test - public void Execute_Multiple() throws IOException { - FileUtils.delete(new File("target/jpagen3")); - Configuration config = new Configuration(); - for (Class<?> cl : Domain.classes) { - config.addAnnotatedClass(cl); - } - JPADomainExporter exporter = new JPADomainExporter("Q", - new File("target/jpagen3"), serializerConfig, convert(config)); - exporter.execute(); - - List<String> failures = new ArrayList<String>(); - for (File file : new File("target/jpagen3/com/mysema/query/jpa/domain").listFiles()) { - String result1 = Files.toString(file, Charsets.UTF_8); - String result2 = Files - .toString( - new File( - "../querydsl-jpa/target/generated-test-sources/java/com/mysema/query/jpa/domain", - file.getName()), Charsets.UTF_8); - if (!result1.equals(result2)) { - System.err.println(file.getName()); - failures.add(file.getName()); - } - } - - failures.remove("QCalendar.java"); // FIXME - - if (!failures.isEmpty()) { - fail("Failed with " + failures.size() + " failures"); - } - - } - - @Test - public void Execute_Multiple2() throws IOException { - FileUtils.delete(new File("target/jpagen4")); - Configuration config = new Configuration(); - for (Class<?> cl : Domain2.classes) { - config.addAnnotatedClass(cl); - } - JPADomainExporter exporter = new JPADomainExporter("Q", - new File("target/jpagen4"), serializerConfig, convert(config)); - exporter.execute(); - - List<String> failures = new ArrayList<String>(); - for (File file : new File("target/jpagen4/com/mysema/query/jpa/domain2").listFiles()) { - String result1 = Files.toString(file, Charsets.UTF_8); - String result2 = Files - .toString( - new File( - "../querydsl-jpa/target/generated-test-sources/java/com/mysema/query/jpa/domain2", - file.getName()), Charsets.UTF_8); - if (!result1.equals(result2)) { - System.err.println(file.getName()); - failures.add(file.getName()); - } - } - - if (!failures.isEmpty()) { - fail("Failed with " + failures.size() + " failures"); - } - - } - - @Test - @Ignore // FIXME - public void Execute_Store() throws IOException { - FileUtils.delete(new File("target/jpagen5")); - File contact = new File("src/test/resources/store.hbm.xml"); - Configuration config = new Configuration(); - config.addFile(contact); - JPADomainExporter exporter = new JPADomainExporter("Q", - new File("target/jpagen5"), convert(config)); - exporter.execute(); - - File targetFile = new File("target/jpagen5/com/mysema/query/jpa/domain3/QStore.java"); - assertContains(targetFile, "StringPath code", "StringPath address"); - - targetFile = new File("target/jpagen5/com/mysema/query/jpa/domain3/QHardwareStore.java"); - assertContains(targetFile, "StringPath code = _super.code;", "StringPath address"); - } - - private static void assertContains(File file, String... strings) throws IOException { - assertTrue(file.getPath() + " doesn't exist", file.exists()); - String result = Files.toString(file, Charsets.UTF_8); - for (String str : strings) { - assertTrue(str + " was not contained", result.contains(str)); - } - } - -} diff --git a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/codegen/MyEntity.java b/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/codegen/MyEntity.java deleted file mode 100644 index 4ed1ed05aa..0000000000 --- a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/codegen/MyEntity.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.mysema.query.jpa.codegen; - - -public class MyEntity { - - private String pk1, pk2, prop1; - - public String getPk1() { - return pk1; - } - - public void setPk1(String pk1) { - this.pk1 = pk1; - } - - public String getPk2() { - return pk2; - } - - public void setPk2(String pk2) { - this.pk2 = pk2; - } - - public String getProp1() { - return prop1; - } - - public void setProp1(String prop1) { - this.prop1 = prop1; - } - - -} diff --git a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain10/CustomType.java b/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain10/CustomType.java deleted file mode 100644 index 9c9c719d01..0000000000 --- a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain10/CustomType.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.mysema.query.jpa.domain10; - - -public class CustomType { - - String property; - -} diff --git a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain10/DomainExporterTest.java b/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain10/DomainExporterTest.java deleted file mode 100644 index 2252b4fbe4..0000000000 --- a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain10/DomainExporterTest.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.mysema.query.jpa.domain10; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import java.io.File; -import java.io.IOException; - -import org.hibernate.cfg.Configuration; -import org.junit.Test; - -import com.mysema.query.jpa.codegen.HibernateDomainExporter; -import com.mysema.util.FileUtils; - -public class DomainExporterTest { - - @Test - public void Execute() throws IOException { - File gen = new File("target/" + getClass().getSimpleName()); - FileUtils.delete(gen); - Configuration config = new Configuration(); - config.addFile(new File("src/test/resources/com/mysema/query/jpa/domain10/domain.hbm.xml")); - HibernateDomainExporter exporter = new HibernateDomainExporter("Q", gen, config); - exporter.execute(); - - assertTrue(new File(gen, "com/mysema/query/jpa/domain10/QEntity.java").exists()); - assertFalse(new File(gen, "com/mysema/query/jpa/domain10/QCustomType.java").exists()); - - } - -} diff --git a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain10/Entity.java b/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain10/Entity.java deleted file mode 100644 index 446f958884..0000000000 --- a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain10/Entity.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.mysema.query.jpa.domain10; - -public class Entity { - - String id; - - CustomType custom; - -} diff --git a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain11/DomainExporterTest.java b/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain11/DomainExporterTest.java deleted file mode 100644 index 85a6d9644f..0000000000 --- a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain11/DomainExporterTest.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.mysema.query.jpa.domain11; - -import static org.junit.Assert.*; - -import java.io.File; -import java.io.IOException; - -import org.hibernate.cfg.Configuration; -import org.junit.Test; - -import com.google.common.base.Charsets; -import com.google.common.io.Files; -import com.mysema.query.jpa.codegen.HibernateDomainExporter; -import com.mysema.util.FileUtils; - -public class DomainExporterTest { - - @Test - public void Execute() throws IOException { - File gen = new File("target/" + getClass().getSimpleName()); - FileUtils.delete(gen); - Configuration config = new Configuration(); - config.addFile(new File("src/test/resources/com/mysema/query/jpa/domain11/domain.hbm.xml")); - HibernateDomainExporter exporter = new HibernateDomainExporter("Q", gen, config); - exporter.execute(); - - assertTrue(new File(gen, "com/mysema/query/jpa/domain11/QOtherthing.java").exists()); - assertTrue(new File(gen, "com/mysema/query/jpa/domain11/QSomething.java").exists()); - - String str = Files.toString(new File(gen, "com/mysema/query/jpa/domain11/QOtherthing.java"), Charsets.UTF_8); - assertTrue(str.contains("QSomething")); - - str = Files.toString(new File(gen, "com/mysema/query/jpa/domain11/QSomething.java"), Charsets.UTF_8); - assertTrue(str.contains("id")); - } - -} diff --git a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain11/ISomething.java b/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain11/ISomething.java deleted file mode 100644 index ef4150673f..0000000000 --- a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain11/ISomething.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.mysema.query.jpa.domain11; - -public interface ISomething { - -} diff --git a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain11/Otherthing.java b/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain11/Otherthing.java deleted file mode 100644 index d27c95195a..0000000000 --- a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain11/Otherthing.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.mysema.query.jpa.domain11; - -public class Otherthing { - - String id; - - ISomething property; - -} \ No newline at end of file diff --git a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain11/Something.java b/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain11/Something.java deleted file mode 100644 index dabeb47dfc..0000000000 --- a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain11/Something.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.mysema.query.jpa.domain11; - -public class Something implements ISomething { - - String id; -} diff --git a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain12/DomainExporterTest.java b/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain12/DomainExporterTest.java deleted file mode 100644 index ac792c2e2e..0000000000 --- a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain12/DomainExporterTest.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.mysema.query.jpa.domain12; - -import static org.junit.Assert.assertTrue; - -import java.io.File; -import java.io.IOException; - -import org.hibernate.cfg.Configuration; -import org.junit.Test; - -import com.mysema.query.jpa.codegen.HibernateDomainExporter; -import com.mysema.util.FileUtils; - -public class DomainExporterTest { - - @Test - public void Execute() throws IOException { - File gen = new File("target/" + getClass().getSimpleName()); - FileUtils.delete(gen); - Configuration config = new Configuration(); - config.addFile(new File("src/test/resources/com/mysema/query/jpa/domain12/domain.hbm.xml")); - HibernateDomainExporter exporter = new HibernateDomainExporter("Q", gen, config); - exporter.execute(); - - assertTrue(new File(gen, "com/mysema/query/jpa/domain12/QEntity.java").exists()); - assertTrue(new File(gen, "com/mysema/query/jpa/domain12/QSupertype.java").exists()); - } - -} diff --git a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain12/Entity.java b/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain12/Entity.java deleted file mode 100644 index 3babb46e26..0000000000 --- a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain12/Entity.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.mysema.query.jpa.domain12; - -public class Entity extends Supertype { - - String id; - - Entity entity; - -} diff --git a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain12/Supertype.java b/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain12/Supertype.java deleted file mode 100644 index 69986c7224..0000000000 --- a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain12/Supertype.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.mysema.query.jpa.domain12; - -public class Supertype { - - String property; -} diff --git a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain13/DomainExporterTest.java b/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain13/DomainExporterTest.java deleted file mode 100644 index ed4c20241a..0000000000 --- a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain13/DomainExporterTest.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.mysema.query.jpa.domain13; - -import static org.junit.Assert.assertTrue; - -import java.io.File; -import java.io.IOException; - -import org.hibernate.cfg.Configuration; -import org.junit.Test; - -import com.mysema.query.jpa.codegen.HibernateDomainExporter; -import com.mysema.util.FileUtils; - -public class DomainExporterTest { - - @Test - public void Execute() throws IOException { - File gen = new File("target/" + getClass().getSimpleName()); - FileUtils.delete(gen); - Configuration config = new Configuration(); - config.addFile(new File("src/test/resources/com/mysema/query/jpa/domain13/domain.hbm.xml")); - HibernateDomainExporter exporter = new HibernateDomainExporter("Q", gen, config); - exporter.execute(); - - assertTrue(new File(gen, "com/mysema/query/jpa/domain13/QEntity.java").exists()); - } - -} diff --git a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain13/Entity.java b/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain13/Entity.java deleted file mode 100644 index e1c6154b9d..0000000000 --- a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain13/Entity.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.mysema.query.jpa.domain13; - -class Entity { - String id; - - Status status; -} diff --git a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain13/Status.java b/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain13/Status.java deleted file mode 100644 index 1c8409f07f..0000000000 --- a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain13/Status.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.mysema.query.jpa.domain13; - -public enum Status { - BUSY, AVAILABLE; -} diff --git a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain14/DomainExporterTest.java b/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain14/DomainExporterTest.java deleted file mode 100644 index c37c8bdaf9..0000000000 --- a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain14/DomainExporterTest.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.mysema.query.jpa.domain14; - -import static org.junit.Assert.assertTrue; - -import java.io.File; -import java.io.IOException; - -import org.hibernate.cfg.Configuration; -import org.junit.Test; - -import com.mysema.query.jpa.codegen.HibernateDomainExporter; -import com.mysema.util.FileUtils; - -public class DomainExporterTest { - - @Test - public void Execute() throws IOException { - File gen = new File("target/" + getClass().getSimpleName()); - FileUtils.delete(gen); - Configuration config = new Configuration(); - config.addFile(new File("src/test/resources/com/mysema/query/jpa/domain14/domain.hbm.xml")); - HibernateDomainExporter exporter = new HibernateDomainExporter("Q", gen, config); - exporter.execute(); - - assertTrue(new File(gen, "com/mysema/query/jpa/domain14/QSiCZuCapiRechtMapping.java").exists()); - assertTrue(new File(gen, "com/mysema/query/jpa/domain14/QMappingID.java").exists()); - } - -} diff --git a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain14/MappingID.java b/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain14/MappingID.java deleted file mode 100644 index dac7633174..0000000000 --- a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain14/MappingID.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.mysema.query.jpa.domain14; - -import java.io.Serializable; - -public class MappingID implements Serializable { - - private static final long serialVersionUID = -4623004134095871109L; - private short systemID; - - private int capiID; - - public MappingID() { - // Default-Konstruktor wird vom Hinernate Criteria-API verwendet - } - - public MappingID(short systemID, int capiID) { - this.capiID = capiID; - this.systemID = systemID; - } - - public short getSystemID() { - return systemID; - } - - public int getCapiID() { - return capiID; - } -} \ No newline at end of file diff --git a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain14/SiCZuCapiRechtMapping.java b/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain14/SiCZuCapiRechtMapping.java deleted file mode 100644 index b74794d59c..0000000000 --- a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain14/SiCZuCapiRechtMapping.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.mysema.query.jpa.domain14; - -public abstract class SiCZuCapiRechtMapping { - - private MappingID id; - - public void setId(MappingID id) { - this.id = id; - } - - public int getSystemID() { - return id.getSystemID(); - } - - public int getCapiPID() { - return id.getCapiID(); - } -} \ No newline at end of file diff --git a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain15/DomainExporterTest.java b/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain15/DomainExporterTest.java deleted file mode 100644 index 6681b2a0bd..0000000000 --- a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain15/DomainExporterTest.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.mysema.query.jpa.domain15; - -import static org.junit.Assert.assertTrue; - -import java.io.File; -import java.io.IOException; - -import org.hibernate.cfg.Configuration; -import org.junit.Test; - -import com.mysema.query.jpa.codegen.HibernateDomainExporter; -import com.mysema.util.FileUtils; - -public class DomainExporterTest { - - @Test - public void Execute() throws IOException { - File gen = new File("target/" + getClass().getSimpleName()); - FileUtils.delete(gen); - Configuration config = new Configuration(); - config.addFile(new File("src/test/resources/com/mysema/query/jpa/domain15/domain.hbm.xml")); - HibernateDomainExporter exporter = new HibernateDomainExporter("Q", gen, config); - exporter.execute(); - - assertTrue(new File(gen, "com/mysema/query/jpa/domain15/QEntity.java").exists()); - assertTrue(new File(gen, "com/mysema/query/jpa/domain15/QEntity2.java").exists()); - assertTrue(new File(gen, "com/mysema/query/jpa/domain15/QSuperclass.java").exists()); - - } - -} diff --git a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain15/Entity.java b/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain15/Entity.java deleted file mode 100644 index 0131b51f7a..0000000000 --- a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain15/Entity.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.mysema.query.jpa.domain15; - -import com.mysema.query.annotations.QueryEntity; - -@QueryEntity -public class Entity extends Superclass<String> { - -} diff --git a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain15/Entity2.java b/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain15/Entity2.java deleted file mode 100644 index dad7b094b9..0000000000 --- a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain15/Entity2.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.mysema.query.jpa.domain15; - -import com.mysema.query.annotations.QueryEntity; - -@QueryEntity -public class Entity2 extends Superclass<Integer> { - -} diff --git a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain15/Superclass.java b/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain15/Superclass.java deleted file mode 100644 index 83369488e5..0000000000 --- a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain15/Superclass.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.mysema.query.jpa.domain15; - -import java.util.List; - -import com.mysema.query.annotations.QuerySupertype; - -@QuerySupertype -public class Superclass<T> { - - Long id; - - List<T> values; - - List<? extends T> values2; - -} diff --git a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain16/Custom.java b/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain16/Custom.java deleted file mode 100644 index 1d044120f9..0000000000 --- a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain16/Custom.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.mysema.query.jpa.domain16; - -public class Custom { - -} diff --git a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain16/Custom2.java b/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain16/Custom2.java deleted file mode 100644 index fae9f71eab..0000000000 --- a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain16/Custom2.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.mysema.query.jpa.domain16; - -public class Custom2 { - -} diff --git a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain16/Custom3.java b/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain16/Custom3.java deleted file mode 100644 index be472f5e41..0000000000 --- a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain16/Custom3.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.mysema.query.jpa.domain16; - -public class Custom3 { - -} diff --git a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain16/DomainExporterTest.java b/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain16/DomainExporterTest.java deleted file mode 100644 index 59eeff152d..0000000000 --- a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain16/DomainExporterTest.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.mysema.query.jpa.domain16; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import java.io.File; -import java.io.IOException; - -import org.hibernate.cfg.Configuration; -import org.junit.Test; - -import com.mysema.query.jpa.codegen.HibernateDomainExporter; -import com.mysema.util.FileUtils; - -public class DomainExporterTest { - - @Test - public void Execute() throws IOException { - File gen = new File("target/" + getClass().getSimpleName()); - FileUtils.delete(gen); - Configuration config = new Configuration(); - config.addFile(new File("src/test/resources/com/mysema/query/jpa/domain16/domain.hbm.xml")); - HibernateDomainExporter exporter = new HibernateDomainExporter("Q", gen, config); - exporter.execute(); - - assertTrue(new File(gen, "com/mysema/query/jpa/domain16/QEntity.java").exists()); - assertFalse(new File(gen, "com/mysema/query/jpa/domain16/QCustom.java").exists()); - assertTrue(new File(gen, "com/mysema/query/jpa/domain16/QCustom2.java").exists()); - assertFalse(new File(gen, "com/mysema/query/jpa/domain16/QCustom3.java").exists()); - - } - -} diff --git a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain16/Entity.java b/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain16/Entity.java deleted file mode 100644 index bd8af9787c..0000000000 --- a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain16/Entity.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.mysema.query.jpa.domain16; - -import com.mysema.query.annotations.PropertyType; -import com.mysema.query.annotations.QueryType; - -public class Entity { - - private Long id; - - @QueryType(PropertyType.SIMPLE) - private Custom custom; - - @QueryType(PropertyType.ENTITY) - private Custom2 custom2; - - private Custom3 custom3; - - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public Custom getCustom() { - return custom; - } - - public void setCustom(Custom custom) { - this.custom = custom; - } - - public Custom2 getCustom2() { - return custom2; - } - - public void setCustom2(Custom2 custom2) { - this.custom2 = custom2; - } - - public Custom3 getCustom3() { - return custom3; - } - - public void setCustom3(Custom3 custom3) { - this.custom3 = custom3; - } - -} diff --git a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain5/Contact.java b/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain5/Contact.java deleted file mode 100644 index e4a4334653..0000000000 --- a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain5/Contact.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.mysema.query.jpa.domain5; - -public abstract class Contact { - - private Long id; - - private String value; - - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public String getValue() { - return value; - } - - public void setValue(String value) { - this.value = value; - } - -} \ No newline at end of file diff --git a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain5/Customer.java b/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain5/Customer.java deleted file mode 100644 index 5c4e4afda7..0000000000 --- a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain5/Customer.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.mysema.query.jpa.domain5; - - -public class Customer extends Person<CustomerContact, CustomerHistory> { - -} \ No newline at end of file diff --git a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain5/CustomerContact.java b/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain5/CustomerContact.java deleted file mode 100644 index 0678eb177e..0000000000 --- a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain5/CustomerContact.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.mysema.query.jpa.domain5; - -public class CustomerContact extends Contact { -} \ No newline at end of file diff --git a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain5/CustomerHistory.java b/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain5/CustomerHistory.java deleted file mode 100644 index a844fde7ae..0000000000 --- a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain5/CustomerHistory.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.mysema.query.jpa.domain5; - -public class CustomerHistory extends HistoryEntity { -} \ No newline at end of file diff --git a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain5/DomainExporterTest.java b/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain5/DomainExporterTest.java deleted file mode 100644 index 709c567991..0000000000 --- a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain5/DomainExporterTest.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.mysema.query.jpa.domain5; - -import static org.junit.Assert.assertTrue; - -import java.io.File; -import java.io.IOException; -import java.util.Arrays; - -import org.hibernate.cfg.Configuration; -import org.junit.Test; - -import com.google.common.base.Charsets; -import com.google.common.io.Files; -import com.mysema.query.jpa.codegen.HibernateDomainExporter; -import com.mysema.util.FileUtils; - -public class DomainExporterTest { - - @Test - public void Execute() throws IOException { - File gen = new File("target/" + getClass().getSimpleName()); - FileUtils.delete(gen); - Configuration config = new Configuration(); - for (String res : Arrays.asList("Customer.hbm.xml", - "CustomerContact.hbm.xml", - "CustomerHistory.hbm.xml")) { - config.addFile(new File("src/test/resources/com/mysema/query/jpa/domain5/" + res)); - } - HibernateDomainExporter exporter = new HibernateDomainExporter("Q", gen, config); - exporter.execute(); - - File targetFile = new File(gen, "com/mysema/query/jpa/domain5/QCustomer.java"); - assertContains(targetFile, "SetPath<CustomerContact, QCustomerContact>", - "SetPath<CustomerHistory, QCustomerHistory>"); - } - - - private static void assertContains(File file, String... strings) throws IOException { - assertTrue(file.getPath() + " doesn't exist", file.exists()); - String result = Files.toString(file, Charsets.UTF_8); - for (String str : strings) { - assertTrue(str + " was not contained", result.contains(str)); - } - } - -} diff --git a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain5/HistoryEntity.java b/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain5/HistoryEntity.java deleted file mode 100644 index f4e38b2811..0000000000 --- a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain5/HistoryEntity.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.mysema.query.jpa.domain5; - -public class HistoryEntity { - - private Long id; - - private String description; - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - - -} \ No newline at end of file diff --git a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain5/Person.java b/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain5/Person.java deleted file mode 100644 index c6155f8747..0000000000 --- a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain5/Person.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.mysema.query.jpa.domain5; - -import java.util.HashSet; -import java.util.Set; - - -public class Person<T extends Contact, H extends HistoryEntity> { - - private Long id; - - private Set<T> contacts = new HashSet<T>(); - - private Set<H> history = new HashSet<H>(); - - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public Set<T> getContacts() { - return contacts; - } - - public void setContacts(Set<T> contacts) { - this.contacts = contacts; - } - - public Set<H> getHistory() { - return history; - } - - public void setHistory(Set<H> history) { - this.history = history; - } - - -} \ No newline at end of file diff --git a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain6/Contact.java b/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain6/Contact.java deleted file mode 100644 index bf9b839e29..0000000000 --- a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain6/Contact.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.mysema.query.jpa.domain6; - -import java.util.List; - -public class Contact { - - private long id; - private String name; - private List<PhoneNumber> phoneNumbers; - - public long getId() { - return id; - } - - public void setId(long id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public List<PhoneNumber> getPhoneNumbers() { - return phoneNumbers; - } - - public void setPhoneNumbers(List<PhoneNumber> phoneNumbers) { - this.phoneNumbers = phoneNumbers; - } -} \ No newline at end of file diff --git a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain6/DomainExporterTest.java b/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain6/DomainExporterTest.java deleted file mode 100644 index 2c1a5e76f7..0000000000 --- a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain6/DomainExporterTest.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.mysema.query.jpa.domain6; - -import static org.junit.Assert.assertTrue; - -import java.io.File; -import java.io.IOException; - -import org.hibernate.cfg.Configuration; -import org.junit.Test; - -import com.google.common.base.Charsets; -import com.google.common.io.Files; -import com.mysema.query.jpa.codegen.HibernateDomainExporter; -import com.mysema.util.FileUtils; - -public class DomainExporterTest { - - @Test - public void Execute() throws IOException { - File gen = new File("target/" + getClass().getSimpleName()); - FileUtils.delete(gen); - Configuration config = new Configuration(); - config.addFile(new File("src/test/resources/com/mysema/query/jpa/domain6/Contact.hbm.xml")); - HibernateDomainExporter exporter = new HibernateDomainExporter("Q", gen, config); - exporter.execute(); - - File targetFile = new File(gen, "com/mysema/query/jpa/domain6/QContact.java"); - assertContains(targetFile, "ListPath<PhoneNumber, QPhoneNumber> phoneNumbers"); - - targetFile = new File(gen, "com/mysema/query/jpa/domain6/QPhoneNumber.java"); - assertContains(targetFile, "QPhoneNumber extends BeanPath<PhoneNumber>", - "StringPath number = createString(\"number\")"); - } - - private static void assertContains(File file, String... strings) throws IOException { - assertTrue(file.getPath() + " doesn't exist", file.exists()); - String result = Files.toString(file, Charsets.UTF_8); - for (String str : strings) { - assertTrue(str + " was not contained", result.contains(str)); - } - } - -} diff --git a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain6/PhoneNumber.java b/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain6/PhoneNumber.java deleted file mode 100644 index f0cb7fae91..0000000000 --- a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain6/PhoneNumber.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.mysema.query.jpa.domain6; - -public class PhoneNumber { - - private String type; - private String number; - - public String getNumber() { - return number; - } - - public void setNumber(String number) { - this.number = number; - } - - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } -} \ No newline at end of file diff --git a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain7/A.java b/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain7/A.java deleted file mode 100644 index 3729373db9..0000000000 --- a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain7/A.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.mysema.query.jpa.domain7; - -import java.util.ArrayList; -import java.util.List; - -public class A { - - public int id; - - public List<B> b = new ArrayList<B>(); - -} diff --git a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain7/B.java b/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain7/B.java deleted file mode 100644 index 292a8d192d..0000000000 --- a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain7/B.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.mysema.query.jpa.domain7; - -import java.util.ArrayList; -import java.util.List; - -public class B { - - public int id; - - public List<C> c = new ArrayList<C>(); - - public A a; - -} diff --git a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain7/C.java b/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain7/C.java deleted file mode 100644 index 47bc9beab6..0000000000 --- a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain7/C.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.mysema.query.jpa.domain7; - -public class C { - - public int id; - - public B b; - -} \ No newline at end of file diff --git a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain7/DomainExporterTest.java b/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain7/DomainExporterTest.java deleted file mode 100644 index 498eb2d17a..0000000000 --- a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain7/DomainExporterTest.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.mysema.query.jpa.domain7; - -import static org.junit.Assert.assertTrue; - -import java.io.File; -import java.io.IOException; - -import org.hibernate.cfg.Configuration; -import org.junit.Test; - -import com.mysema.query.jpa.codegen.HibernateDomainExporter; -import com.mysema.util.FileUtils; - -public class DomainExporterTest { - - @Test - public void Execute() throws IOException { - File gen = new File("target/" + getClass().getSimpleName()); - FileUtils.delete(gen); - Configuration config = new Configuration(); - config.addFile(new File("src/test/resources/com/mysema/query/jpa/domain7/domain.hbm.xml")); - HibernateDomainExporter exporter = new HibernateDomainExporter("Q", gen, config); - exporter.execute(); - - assertTrue(new File(gen, "com/mysema/query/jpa/domain7/QA.java").exists()); - assertTrue(new File(gen, "com/mysema/query/jpa/domain7/QB.java").exists()); - assertTrue(new File(gen, "com/mysema/query/jpa/domain7/QC.java").exists()); - } - -} diff --git a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain8/A.java b/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain8/A.java deleted file mode 100644 index 313354ad39..0000000000 --- a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain8/A.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.mysema.query.jpa.domain8; - -public class A { - - String property1; - -} diff --git a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain8/B.java b/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain8/B.java deleted file mode 100644 index be05b7ff21..0000000000 --- a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain8/B.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.mysema.query.jpa.domain8; - -public class B extends A { - - Long id; - - String property2; -} diff --git a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain8/DomainExporterTest.java b/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain8/DomainExporterTest.java deleted file mode 100644 index 79b59b9fd1..0000000000 --- a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain8/DomainExporterTest.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.mysema.query.jpa.domain8; - -import static org.junit.Assert.assertTrue; - -import java.io.File; -import java.io.IOException; - -import org.hibernate.cfg.Configuration; -import org.junit.Test; - -import com.mysema.query.jpa.codegen.HibernateDomainExporter; -import com.mysema.util.FileUtils; - -public class DomainExporterTest { - - @Test - public void Execute() throws IOException { - File gen = new File("target/" + getClass().getSimpleName()); - FileUtils.delete(gen); - Configuration config = new Configuration(); - config.addFile(new File("src/test/resources/com/mysema/query/jpa/domain8/domain.hbm.xml")); - HibernateDomainExporter exporter = new HibernateDomainExporter("Q", gen, config); - exporter.execute(); - - assertTrue(new File(gen, "com/mysema/query/jpa/domain8/QA.java").exists()); - assertTrue(new File(gen, "com/mysema/query/jpa/domain8/QB.java").exists()); - } - -} diff --git a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain9/DomainExporterTest.java b/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain9/DomainExporterTest.java deleted file mode 100644 index 0ffd9c9be5..0000000000 --- a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain9/DomainExporterTest.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.mysema.query.jpa.domain9; - -import java.io.File; -import java.io.IOException; - -import org.hibernate.cfg.Configuration; -import org.junit.Test; - -import com.mysema.query.jpa.codegen.HibernateDomainExporter; -import com.mysema.util.FileUtils; - -public class DomainExporterTest { - - @Test - public void Execute() throws IOException { - File gen = new File("target/" + getClass().getSimpleName()); - FileUtils.delete(gen); - Configuration config = new Configuration(); - config.addFile(new File("src/test/resources/com/mysema/query/jpa/domain9/domain.hbm.xml")); - HibernateDomainExporter exporter = new HibernateDomainExporter("Q", gen, config); - exporter.execute(); - } - -} diff --git a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain9/EigentumPersonRechtsgueltig.java b/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain9/EigentumPersonRechtsgueltig.java deleted file mode 100644 index 08b0b00b62..0000000000 --- a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain9/EigentumPersonRechtsgueltig.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.mysema.query.jpa.domain9; - -public abstract class EigentumPersonRechtsgueltig { - - String id; - -} diff --git a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain9/EigentumPersonRechtsgueltigSnapshot.java b/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain9/EigentumPersonRechtsgueltigSnapshot.java deleted file mode 100644 index 6bc5aa0c44..0000000000 --- a/querydsl-jpa-codegen/src/test/java/com/mysema/query/jpa/domain9/EigentumPersonRechtsgueltigSnapshot.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.mysema.query.jpa.domain9; - -public class EigentumPersonRechtsgueltigSnapshot extends EigentumPersonRechtsgueltig { - -} \ No newline at end of file diff --git a/querydsl-jpa-codegen/src/test/java/com/querydsl/jpa/codegen/JPADomainExporterTest.java b/querydsl-jpa-codegen/src/test/java/com/querydsl/jpa/codegen/JPADomainExporterTest.java new file mode 100644 index 0000000000..cb59ea901f --- /dev/null +++ b/querydsl-jpa-codegen/src/test/java/com/querydsl/jpa/codegen/JPADomainExporterTest.java @@ -0,0 +1,63 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.codegen; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertFalse; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Properties; +import java.util.Set; + +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ErrorCollector; +import org.junit.rules.TemporaryFolder; + +public class JPADomainExporterTest { + + @Rule + public TemporaryFolder folder = new TemporaryFolder(); + + @Rule + public ErrorCollector errors = new ErrorCollector(); + + @Test + public void test() throws IOException { + EntityManagerFactory emf = Persistence.createEntityManagerFactory("h2", new Properties()); + Path outputFolder = folder.getRoot().toPath(); + JPADomainExporter exporter = new JPADomainExporter(outputFolder.toFile(), emf.getMetamodel()); + exporter.execute(); + + File origRoot = new File("../querydsl-jpa/target/generated-test-sources/java"); + Set<File> files = exporter.getGeneratedFiles(); + assertFalse(files.isEmpty()); + for (File file : files) { + Path relativeFile = outputFolder.relativize(file.toPath()); + Path origFile = origRoot.toPath().resolve(relativeFile); + String reference = new String(Files.readAllBytes(origFile), StandardCharsets.UTF_8); + String content = new String(Files.readAllBytes(file.toPath()), StandardCharsets.UTF_8); + errors.checkThat("Mismatch for " + file.getPath(), content, is(equalTo(reference))); + } + } + +} diff --git a/querydsl-jpa-codegen/src/test/java/com/querydsl/jpa/codegen/ant/AntJPADomainExporterTest.java b/querydsl-jpa-codegen/src/test/java/com/querydsl/jpa/codegen/ant/AntJPADomainExporterTest.java new file mode 100644 index 0000000000..f8396a8fe8 --- /dev/null +++ b/querydsl-jpa-codegen/src/test/java/com/querydsl/jpa/codegen/ant/AntJPADomainExporterTest.java @@ -0,0 +1,49 @@ +package com.querydsl.jpa.codegen.ant; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertFalse; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Set; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ErrorCollector; +import org.junit.rules.TemporaryFolder; + +public class AntJPADomainExporterTest { + + @Rule + public TemporaryFolder folder = new TemporaryFolder(); + + @Rule + public ErrorCollector errors = new ErrorCollector(); + + @Test + public void test() throws IOException { + AntJPADomainExporter exporter = new AntJPADomainExporter(); + exporter.setNamePrefix("Q"); + exporter.setNameSuffix(""); + Path outputFolder = folder.getRoot().toPath(); + exporter.setTargetFolder(outputFolder.toFile().getAbsolutePath()); + exporter.setPersistenceUnitName("h2"); + exporter.execute(); + + File origRoot = new File("../querydsl-jpa/target/generated-test-sources/java"); + Set<File> files = exporter.getGeneratedFiles(); + assertFalse(files.isEmpty()); + for (File file : files) { + Path relativeFile = outputFolder.relativize(file.toPath()); + Path origFile = origRoot.toPath().resolve(relativeFile); + String reference = new String(java.nio.file.Files.readAllBytes(origFile), StandardCharsets.UTF_8); + String content = new String(Files.readAllBytes(file.toPath()), StandardCharsets.UTF_8); + errors.checkThat("Mismatch for " + file.getPath(), content, is(equalTo(reference))); + } + } + +} diff --git a/querydsl-jpa-codegen/src/test/resources/com/mysema/query/jpa/domain10/domain.hbm.xml b/querydsl-jpa-codegen/src/test/resources/com/mysema/query/jpa/domain10/domain.hbm.xml deleted file mode 100644 index 3ff1b00de0..0000000000 --- a/querydsl-jpa-codegen/src/test/resources/com/mysema/query/jpa/domain10/domain.hbm.xml +++ /dev/null @@ -1,15 +0,0 @@ -<?xml version="1.0"?> -<!DOCTYPE hibernate-mapping PUBLIC - "-//Hibernate/Hibernate Mapping DTD 3.0//EN" - "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> -<hibernate-mapping package="com.mysema.query.jpa.domain10"> - - <class name="Entity" table="Entity" mutable="false"> - - <id name="id" type="string" length="40"/> - - <property name="custom" type="object"/> - - </class> - -</hibernate-mapping> \ No newline at end of file diff --git a/querydsl-jpa-codegen/src/test/resources/com/mysema/query/jpa/domain11/domain.hbm.xml b/querydsl-jpa-codegen/src/test/resources/com/mysema/query/jpa/domain11/domain.hbm.xml deleted file mode 100644 index 40f62b43f3..0000000000 --- a/querydsl-jpa-codegen/src/test/resources/com/mysema/query/jpa/domain11/domain.hbm.xml +++ /dev/null @@ -1,22 +0,0 @@ -<?xml version="1.0"?> -<!DOCTYPE hibernate-mapping PUBLIC - "-//Hibernate/Hibernate Mapping DTD 3.0//EN" - "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> - -<hibernate-mapping default-access="field" package="com.mysema.query.jpa.domain11"> - <class name="Otherthing" table="Otherthing"> - <id name="id" type="string" length="40"/> - - <many-to-one name="property" class="Something" lazy="false" - fetch="join"> - <column name="SOMETHING_ID" length="40" /> - </many-to-one> - - </class> - - <class name="Something" table="Something"> - <id name="id" type="string" length="40"/> - - </class> - -</hibernate-mapping> \ No newline at end of file diff --git a/querydsl-jpa-codegen/src/test/resources/com/mysema/query/jpa/domain12/domain.hbm.xml b/querydsl-jpa-codegen/src/test/resources/com/mysema/query/jpa/domain12/domain.hbm.xml deleted file mode 100644 index 30b532309e..0000000000 --- a/querydsl-jpa-codegen/src/test/resources/com/mysema/query/jpa/domain12/domain.hbm.xml +++ /dev/null @@ -1,18 +0,0 @@ -<?xml version="1.0"?> -<!DOCTYPE hibernate-mapping PUBLIC - "-//Hibernate/Hibernate Mapping DTD 3.0//EN" - "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> - -<hibernate-mapping default-access="field" package="com.mysema.query.jpa.domain12"> - <class name="Entity" table="Entity"> - <id name="id" type="string" length="40"/> - - <property name="property" type="string"/> - - <many-to-one name="entity" class="Entity" lazy="false" fetch="join"> - <column name="SOMETHING_ID" length="40" /> - </many-to-one> - - </class> - -</hibernate-mapping> \ No newline at end of file diff --git a/querydsl-jpa-codegen/src/test/resources/com/mysema/query/jpa/domain13/domain.hbm.xml b/querydsl-jpa-codegen/src/test/resources/com/mysema/query/jpa/domain13/domain.hbm.xml deleted file mode 100644 index 19dffc8fda..0000000000 --- a/querydsl-jpa-codegen/src/test/resources/com/mysema/query/jpa/domain13/domain.hbm.xml +++ /dev/null @@ -1,18 +0,0 @@ -<?xml version="1.0"?> -<!DOCTYPE hibernate-mapping PUBLIC - "-//Hibernate/Hibernate Mapping DTD 3.0//EN" - "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> - -<hibernate-mapping default-access="field" package="com.mysema.query.jpa.domain13"> - <class name="Entity"> - <id name="id"> - <generator class="native"/> - </id> - - <property name="status"> - <type name="org.hibernate.type.EnumType"> - <param name="enumClass">com.mysema.query.jpa.domain13.Status</param> - </type> - </property> - </class> -</hibernate-mapping> \ No newline at end of file diff --git a/querydsl-jpa-codegen/src/test/resources/com/mysema/query/jpa/domain14/domain.hbm.xml b/querydsl-jpa-codegen/src/test/resources/com/mysema/query/jpa/domain14/domain.hbm.xml deleted file mode 100644 index f0475c0cde..0000000000 --- a/querydsl-jpa-codegen/src/test/resources/com/mysema/query/jpa/domain14/domain.hbm.xml +++ /dev/null @@ -1,17 +0,0 @@ -<?xml version="1.0"?> -<!DOCTYPE hibernate-mapping PUBLIC - "-//Hibernate/Hibernate Mapping DTD 3.0//EN" - "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> - -<hibernate-mapping package="com.mysema.query.jpa.domain14" default-access="field"> - - <class name="SiCZuCapiRechtMapping"> - - <composite-id name="id" class="MappingID"> - <key-property name="capiID"/> - <key-property name="systemID"/> - </composite-id> - - </class> - -</hibernate-mapping> \ No newline at end of file diff --git a/querydsl-jpa-codegen/src/test/resources/com/mysema/query/jpa/domain15/domain.hbm.xml b/querydsl-jpa-codegen/src/test/resources/com/mysema/query/jpa/domain15/domain.hbm.xml deleted file mode 100644 index fb9537b380..0000000000 --- a/querydsl-jpa-codegen/src/test/resources/com/mysema/query/jpa/domain15/domain.hbm.xml +++ /dev/null @@ -1,30 +0,0 @@ -<?xml version="1.0"?> -<!DOCTYPE hibernate-mapping PUBLIC - "-//Hibernate/Hibernate Mapping DTD 3.0//EN" - "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> - -<hibernate-mapping package="com.mysema.query.jpa.domain15" default-access="field"> - - <class name="Superclass"> - <id name="id"> - <generator class="native"/> - </id> - <property name="values"/> - <property name="values2"/> - </class> - - <class name="Entity"> - <id name="id"> - <generator class="native"/> - </id> - <property name="values"/> - <property name="values2"/> - </class> - - <class name="Entity2"> - <id name="id"> - <generator class="native"/> - </id> - </class> - -</hibernate-mapping> \ No newline at end of file diff --git a/querydsl-jpa-codegen/src/test/resources/com/mysema/query/jpa/domain16/domain.hbm.xml b/querydsl-jpa-codegen/src/test/resources/com/mysema/query/jpa/domain16/domain.hbm.xml deleted file mode 100644 index 672d3347d8..0000000000 --- a/querydsl-jpa-codegen/src/test/resources/com/mysema/query/jpa/domain16/domain.hbm.xml +++ /dev/null @@ -1,17 +0,0 @@ -<?xml version="1.0"?> -<!DOCTYPE hibernate-mapping PUBLIC - "-//Hibernate/Hibernate Mapping DTD 3.0//EN" - "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> - -<hibernate-mapping package="com.mysema.query.jpa.domain16" default-access="field"> - - <class name="Entity"> - <id name="id"> - <generator class="native"/> - </id> - <property name="custom"/> - <property name="custom2"/> - <property name="custom3"/> - </class> - -</hibernate-mapping> \ No newline at end of file diff --git a/querydsl-jpa-codegen/src/test/resources/com/mysema/query/jpa/domain5/Customer.hbm.xml b/querydsl-jpa-codegen/src/test/resources/com/mysema/query/jpa/domain5/Customer.hbm.xml deleted file mode 100644 index 2b5303f7d0..0000000000 --- a/querydsl-jpa-codegen/src/test/resources/com/mysema/query/jpa/domain5/Customer.hbm.xml +++ /dev/null @@ -1,22 +0,0 @@ -<?xml version="1.0"?> -<!DOCTYPE hibernate-mapping PUBLIC - "-//Hibernate/Hibernate Mapping DTD 3.0//EN" - "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> -<hibernate-mapping package="com.mysema.query.jpa.domain5" default-lazy="false"> - <class name="Customer" table="customer"> - - <id name="id" column="id"> - <generator class="identity"/> - </id> - - <set name="contacts" cascade="all-delete-orphan" order-by="value" fetch="join"> - <key column="customer_id"/> - <one-to-many class="CustomerContact"/> - </set> - <set name="history" cascade="all-delete-orphan" order-by="creationDate DESC" fetch="select" lazy="true"> - <key column="customer_id"/> - <one-to-many class="CustomerHistory"/> - </set> - - </class> -</hibernate-mapping> \ No newline at end of file diff --git a/querydsl-jpa-codegen/src/test/resources/com/mysema/query/jpa/domain5/CustomerContact.hbm.xml b/querydsl-jpa-codegen/src/test/resources/com/mysema/query/jpa/domain5/CustomerContact.hbm.xml deleted file mode 100644 index 2bf759fdc5..0000000000 --- a/querydsl-jpa-codegen/src/test/resources/com/mysema/query/jpa/domain5/CustomerContact.hbm.xml +++ /dev/null @@ -1,15 +0,0 @@ -<?xml version="1.0"?> -<!DOCTYPE hibernate-mapping PUBLIC - "-//Hibernate/Hibernate Mapping DTD 3.0//EN" - "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> -<hibernate-mapping package="com.mysema.query.jpa.domain5" default-lazy="false"> - <class name="CustomerContact" table="customer_contact"> - - <id name="id" column="id"> - <generator class="identity"/> - </id> - - <property name="value"/> - - </class> -</hibernate-mapping> \ No newline at end of file diff --git a/querydsl-jpa-codegen/src/test/resources/com/mysema/query/jpa/domain5/CustomerHistory.hbm.xml b/querydsl-jpa-codegen/src/test/resources/com/mysema/query/jpa/domain5/CustomerHistory.hbm.xml deleted file mode 100644 index f24609dd0a..0000000000 --- a/querydsl-jpa-codegen/src/test/resources/com/mysema/query/jpa/domain5/CustomerHistory.hbm.xml +++ /dev/null @@ -1,15 +0,0 @@ -<?xml version="1.0"?> -<!DOCTYPE hibernate-mapping PUBLIC - "-//Hibernate/Hibernate Mapping DTD 3.0//EN" - "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> -<hibernate-mapping package="com.mysema.query.jpa.domain5" default-lazy="false"> - <class name="CustomerHistory" table="customer_history"> - - <id name="id" column="id"> - <generator class="identity"/> - </id> - - <property name="description" type="text"/> - - </class> -</hibernate-mapping> \ No newline at end of file diff --git a/querydsl-jpa-codegen/src/test/resources/com/mysema/query/jpa/domain6/Contact.hbm.xml b/querydsl-jpa-codegen/src/test/resources/com/mysema/query/jpa/domain6/Contact.hbm.xml deleted file mode 100644 index c54f660d43..0000000000 --- a/querydsl-jpa-codegen/src/test/resources/com/mysema/query/jpa/domain6/Contact.hbm.xml +++ /dev/null @@ -1,20 +0,0 @@ -<?xml version="1.0"?> -<!DOCTYPE hibernate-mapping PUBLIC - "-//Hibernate/Hibernate Mapping DTD 3.0//EN" - "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> -<hibernate-mapping package="com.mysema.query.jpa.domain6" default-lazy="false"> - <class name="Contact" table="CONTACT" mutable="false"> - <id name="id" column="ID"> - <generator class="increment" /> - </id> - <property name="name" column="name" not-null="true" /> - <list name="phoneNumbers" table="CONTACT_PHONE_NUMBER" lazy="false"> - <key column="CONTACT_ID"/> - <list-index column="INDEX" base="0"/> - <composite-element class="PhoneNumber"> - <property name="type"/> - <property name="number" /> - </composite-element> - </list> - </class> -</hibernate-mapping> \ No newline at end of file diff --git a/querydsl-jpa-codegen/src/test/resources/com/mysema/query/jpa/domain7/domain.hbm.xml b/querydsl-jpa-codegen/src/test/resources/com/mysema/query/jpa/domain7/domain.hbm.xml deleted file mode 100644 index 7088c06fb4..0000000000 --- a/querydsl-jpa-codegen/src/test/resources/com/mysema/query/jpa/domain7/domain.hbm.xml +++ /dev/null @@ -1,39 +0,0 @@ -<?xml version="1.0"?> -<!DOCTYPE hibernate-mapping PUBLIC - "-//Hibernate/Hibernate Mapping DTD 3.0//EN" - "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> -<hibernate-mapping package="com.mysema.query.jpa.domain7"> - <class name="A" table="A"> - <id access="field" name="id" type="int" column="A_ID" length="4"> - <generator class="sequence"><param name="sequence">a_id_seq</param></generator> - </id> - <list access="field" name="b" lazy="true" inverse="false"> - <key column="A_ID" not-null="true" unique="true" /> - <index column="B_IDX" /> - <one-to-many class="B" /> - </list> - </class> - - <class name="B" table="B"> - <id access="field" name="id" type="int" column="B_ID" length="4"> - <generator class="sequence"><param name="sequence">b_id_seq</param></generator> - </id> - <list access="field" name="c" lazy="true" inverse="false"> - <key column="B_ID" not-null="true" unique="true" /> - <index column="C_IDX" /> - <one-to-many class="C" /> - </list> - <many-to-one access="field" name="a" class="A" - foreign-key="FK_B_A" column="A_ID" insert="false" update="false" - not-null="true" /> - </class> - - <class name="C" table="C"> - <id access="field" name="id" type="int" column="C_ID" length="4"> - <generator class="sequence"><param name="sequence">c_id_seq</param></generator> - </id> - <many-to-one access="field" name="b" class="B" - foreign-key="FK_C_B" column="B_ID" insert="false" update="false" - not-null="true" /> - </class> -</hibernate-mapping> \ No newline at end of file diff --git a/querydsl-jpa-codegen/src/test/resources/com/mysema/query/jpa/domain8/domain.hbm.xml b/querydsl-jpa-codegen/src/test/resources/com/mysema/query/jpa/domain8/domain.hbm.xml deleted file mode 100644 index e6fdd7b958..0000000000 --- a/querydsl-jpa-codegen/src/test/resources/com/mysema/query/jpa/domain8/domain.hbm.xml +++ /dev/null @@ -1,15 +0,0 @@ -<?xml version="1.0"?> -<!DOCTYPE hibernate-mapping PUBLIC - "-//Hibernate/Hibernate Mapping DTD 3.0//EN" - "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> -<hibernate-mapping package="com.mysema.query.jpa.domain8"> - - <class name="B" table="B"> - <id access="field" name="id" type="int" column="B_ID" length="4"> - <generator class="sequence"><param name="sequence">b_id_seq</param></generator> - </id> - <property name="property1" column="property1" not-null="true" /> - <property name="property2" column="property2" not-null="true" /> - </class> - -</hibernate-mapping> \ No newline at end of file diff --git a/querydsl-jpa-codegen/src/test/resources/com/mysema/query/jpa/domain9/domain.hbm.xml b/querydsl-jpa-codegen/src/test/resources/com/mysema/query/jpa/domain9/domain.hbm.xml deleted file mode 100644 index 73b0dbd0f8..0000000000 --- a/querydsl-jpa-codegen/src/test/resources/com/mysema/query/jpa/domain9/domain.hbm.xml +++ /dev/null @@ -1,13 +0,0 @@ -<?xml version="1.0"?> -<!DOCTYPE hibernate-mapping PUBLIC - "-//Hibernate/Hibernate Mapping DTD 3.0//EN" - "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> -<hibernate-mapping package="com.mysema.query.jpa.domain9"> - - <class name="EigentumPersonRechtsgueltigSnapshot" table="EigentumPersonRechtsgueltigSS" mutable="false"> - - <id name="id" type="string" length="40"/> - - </class> - -</hibernate-mapping> \ No newline at end of file diff --git a/querydsl-jpa-codegen/src/test/resources/contact.hbm.xml b/querydsl-jpa-codegen/src/test/resources/contact.hbm.xml deleted file mode 100644 index bbe23fcf41..0000000000 --- a/querydsl-jpa-codegen/src/test/resources/contact.hbm.xml +++ /dev/null @@ -1,19 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> -<hibernate-mapping package="com.mysema.query.jpa.domain2"> - <class name="Contact" table="CONTACT"> - <id name="id" type="long" column="ID" > - <generator class="assigned"/> - </id> - - <property name="firstName"> - <column name="FIRSTNAME" /> - </property> - <property name="lastName"> - <column name="LASTNAME"/> - </property> - <property name="email"> - <column name="EMAIL"/> - </property> - </class> -</hibernate-mapping> \ No newline at end of file diff --git a/querydsl-jpa-codegen/src/test/resources/contact2.hbm.xml b/querydsl-jpa-codegen/src/test/resources/contact2.hbm.xml deleted file mode 100644 index 5d84dc2f6d..0000000000 --- a/querydsl-jpa-codegen/src/test/resources/contact2.hbm.xml +++ /dev/null @@ -1,19 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> -<hibernate-mapping> - <class name="com.mysema.query.jpa.domain2.Contact" table="CONTACT"> - <id name="id" type="long" column="ID" > - <generator class="assigned"/> - </id> - - <property name="firstName"> - <column name="FIRSTNAME" /> - </property> - <property name="lastName"> - <column name="LASTNAME"/> - </property> - <property name="email"> - <column name="EMAIL"/> - </property> - </class> -</hibernate-mapping> \ No newline at end of file diff --git a/querydsl-jpa-codegen/src/test/resources/entity.hbm.xml b/querydsl-jpa-codegen/src/test/resources/entity.hbm.xml deleted file mode 100644 index e6c1a9789a..0000000000 --- a/querydsl-jpa-codegen/src/test/resources/entity.hbm.xml +++ /dev/null @@ -1,11 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> -<hibernate-mapping> - <class name="com.mysema.query.jpa.codegen.MyEntity" table="MY_TABLE"> - <composite-id> - <key-property name="pk1" column="PK1"/> - <key-property name="pk2" column="PK2"/> - </composite-id> - <property name="prop1" column="PROP1"/> - </class> -</hibernate-mapping> \ No newline at end of file diff --git a/querydsl-jpa-codegen/src/test/resources/h2.properties b/querydsl-jpa-codegen/src/test/resources/h2.properties deleted file mode 100644 index 8ebdf759ad..0000000000 --- a/querydsl-jpa-codegen/src/test/resources/h2.properties +++ /dev/null @@ -1,9 +0,0 @@ -hibernate.dialect=org.hibernate.dialect.H2Dialect -hibernate.connection.driver_class=org.h2.Driver -hibernate.connection.url=jdbc:h2:mem: -hibernate.connection.username=sa -hibernate.connection.password= - -#hibernate.show_sql=true -hibernate.flushMode=FLUSH_AUTO -hibernate.hbm2ddl.auto=create-drop \ No newline at end of file diff --git a/querydsl-jpa-codegen/src/test/resources/hibernate.cfg.xml b/querydsl-jpa-codegen/src/test/resources/hibernate.cfg.xml deleted file mode 100644 index eb1c3b8cf2..0000000000 --- a/querydsl-jpa-codegen/src/test/resources/hibernate.cfg.xml +++ /dev/null @@ -1,12 +0,0 @@ -<?xml version='1.0' encoding='utf-8'?> -<!DOCTYPE hibernate-configuration PUBLIC -"-//Hibernate/Hibernate Configuration DTD//EN" -"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> - -<hibernate-configuration> -<session-factory> - <property name="hibernate.dialect">com.mysema.query.jpa.support.ExtendedDerbyDialect</property> - <property name="hibernate.connection.driver_class">org.apache.derby.jdbc.EmbeddedDriver</property> - <property name="hibernate.connection.url">jdbc:derby:target/derbydb;create=true</property> -</session-factory> -</hibernate-configuration> diff --git a/querydsl-jpa-codegen/src/test/resources/store.hbm.xml b/querydsl-jpa-codegen/src/test/resources/store.hbm.xml deleted file mode 100644 index 09cf3dfd0e..0000000000 --- a/querydsl-jpa-codegen/src/test/resources/store.hbm.xml +++ /dev/null @@ -1,52 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> -<hibernate-mapping> - - <class name="com.mysema.query.jpa.domain3.Store" table="STORE" discriminator-value="S"> - -<!-- - <discriminator column="subclass" type="character"/> - --> - <id name="code" type="java.lang.String" column="CODE"> - <generator class="assigned"/> - </id> - - <property name="name"> - <column name="NAME"/> - </property> - - <property name="address"> - <column name="ADDRESS"/> - </property> - - <property name="city"> - <column name="CITY"/> - </property> - - <property name="phoneDetails"> - <column name="PHONE_DETAILS" length="30"/> - </property> - - <property name="faxDetails"> - <column name="FAX_DETAILS" length="30"/> - </property> - - <property name="zipCode"> - <column name="ZIP_CODE" length="15"/> - </property> - - <property name="chainCode"> - <column name="CHAIN_CODE"/> - </property> - - <subclass name="com.mysema.query.jpa.domain3.HardwareStore" discriminator-value="D"> - - <property name="storeCode"> - <column name="STORE_CODE"/> - </property> - - </subclass> - - </class> - -</hibernate-mapping> \ No newline at end of file diff --git a/querydsl-jpa-codegen/template.mf b/querydsl-jpa-codegen/template.mf deleted file mode 100644 index 3ec0530f3e..0000000000 --- a/querydsl-jpa-codegen/template.mf +++ /dev/null @@ -1,16 +0,0 @@ -Bundle-SymbolicName: com.mysema.querydsl.jpa.codegen -Bundle-Name: Querydsl JPA Codegen -Bundle-Vendor: Mysema -Bundle-ManifestVersion: 2 -Import-Template: - com.mysema.codegen.*;version="${codegen.version}", - com.mysema.commons.lang.*;version="${mysema.lang.version}", - com.mysema.query.*;version="${project.version}", - com.mysema.util.*;version="${project.version}", - javax.annotation.*;version="0", - javax.inject.*;version="0", - javax.persistence.*;version="[2.0.0,2.1.0)", - javax.xml.stream.*;version="0", - org.hibernate.*;version="${hibernate.version}", - org.slf4j.*;version="${slf4j.version}", - com.google.common.*;version="${guava.version}" \ No newline at end of file diff --git a/querydsl-jpa/README.md b/querydsl-jpa/README.md index edbd3c3887..01e9bfafcb 100644 --- a/querydsl-jpa/README.md +++ b/querydsl-jpa/README.md @@ -6,47 +6,53 @@ The JPA module provides integration with the JPA 2 persistence API. Add the following dependencies to your Maven project : - <dependency> - <groupId>com.mysema.querydsl</groupId> - <artifactId>querydsl-apt</artifactId> - <version>${querydsl.version}</version> - <scope>provided</scope> - </dependency> - - <dependency> - <groupId>com.mysema.querydsl</groupId> - <artifactId>querydsl-jpa</artifactId> - <version>${querydsl.version}</version> - </dependency> - - <dependency> - <groupId>org.slf4j</groupId> - <artifactId>slf4j-log4j12</artifactId> - <version>1.6.1</version> - </dependency> +```XML +<dependency> + <groupId>com.querydsl</groupId> + <artifactId>querydsl-jpa</artifactId> + <version>${querydsl.version}</version> +</dependency> +``` And now, configure the Maven APT plugin : - <plugin> - <groupId>com.mysema.maven</groupId> - <artifactId>apt-maven-plugin</artifactId> - <version>1.0.6</version> - <executions> - <execution> - <goals> - <goal>process</goal> - </goals> - <configuration> - <outputDirectory>target/generated-sources/java</outputDirectory> - <processor>com.mysema.query.apt.jpa.JPAAnnotationProcessor</processor> - </configuration> - </execution> - </executions> - </plugin> +```XML +<project> + <build> + <plugins> + ... + <plugin> + <groupId>com.mysema.maven</groupId> + <artifactId>apt-maven-plugin</artifactId> + <version>1.1.3</version> + <executions> + <execution> + <goals> + <goal>process</goal> + </goals> + <configuration> + <outputDirectory>target/generated-sources/java</outputDirectory> + <processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor> + </configuration> + </execution> + </executions> + <dependencies> + <dependency> + <groupId>com.querydsl</groupId> + <artifactId>querydsl-apt</artifactId> + <version>${querydsl.version}</version> + </dependency> + </dependencies> + </plugin> + ... + </plugins> + </build> +</project> +``` The JPAAnnotationProcessor finds domain types annotated with the javax.persistence.Entity annotation and generates query types for them. -If you use Hibernate annotations in your domain types you should use the APT processor com.mysema.query.apt.hibernate.HibernateAnnotationProcessor instead. +If you use Hibernate annotations in your domain types you should use the APT processor com.querydsl.apt.hibernate.HibernateAnnotationProcessor instead. Run clean install and you will get your Query types generated into target/generated-sources/java. @@ -58,10 +64,13 @@ Now you are able to construct JPQL query instances and instances of the query do Querying with Querydsl JPA is as simple as this : - QCustomer customer = QCustomer.customer; - JPAQuery query = new JPAQuery(entityManager); - Customer bob = query.from(customer) - .where(customer.firstName.eq("Bob")) - .uniqueResult(customer); - -For more information on the Querydsl JPA module visit the reference documentation http://www.querydsl.com/static/querydsl/latest/reference/html/ch02.html#jpa_integration \ No newline at end of file +```JAVA +QCustomer customer = QCustomer.customer; +JPAQuery<?> query = new JPAQuery<Void>(entityManager); +Customer bob = query.select(customer) + .from(customer) + .where(customer.firstName.eq("Bob")) + .fetchOne(); +``` + +For more information on the Querydsl JPA module visit the reference documentation http://www.querydsl.com/static/querydsl/latest/reference/html/ch02.html#jpa_integration diff --git a/querydsl-jpa/etc/features.txt b/querydsl-jpa/etc/features.txt index 29a368482a..3255735ef4 100644 --- a/querydsl-jpa/etc/features.txt +++ b/querydsl-jpa/etc/features.txt @@ -1,39 +1,39 @@ -* mathematical operators +, -, *, / - -* binary comparison operators =, >=, <=, <>, !=, like - -* logical operations and, or, not - -* Parentheses ( ), indicating grouping - -* in, not in, between, is null, is not null, is empty, is not empty, member of and not member of - -* "Simple" case, case ... when ... then ... else ... end, and "searched" case, case when ... then ... else ... end - -* string concatenation ...||... or concat(...,...) - -* current_date(), current_time(), current_timestamp() - -* second(...), minute(...), hour(...), day(...), month(...), year(...), - -* Any function or operator defined by EJB-QL 3.0: substring(), trim(), lower(), upper(), length(), locate(), abs(), sqrt(), bit_length(), mod() - -* coalesce() and nullif() - -* str() for converting numeric or temporal values to a readable string - -* cast(... as ...), where the second argument is the name of a Hibernate type, and extract(... from ...) if ANSI cast() and extract() is supported by the underlying database - -* the HQL index() function, that applies to aliases of a joined indexed collection - -* HQL functions that take collection-valued path expressions: size(), minelement(), maxelement(), minindex(), maxindex(), along with the special elements() and indices functions which may be quantified using some, all, exists, any, in. - -* Any database-supported SQL scalar function like sign(), trunc(), rtrim(), sin() - -* JDBC-style positional parameters ? - -* named parameters :name, :start_date, :x1 - -* SQL literals 'foo', 69, 6.66E+2, '1970-01-01 10:00:01.0' - +* mathematical operators +, -, *, / + +* binary comparison operators =, >=, <=, <>, !=, like + +* logical operations and, or, not + +* Parentheses ( ), indicating grouping + +* in, not in, between, is null, is not null, is empty, is not empty, member of and not member of + +* "Simple" case, case ... when ... then ... else ... end, and "searched" case, case when ... then ... else ... end + +* string concatenation ...||... or concat(...,...) + +* current_date(), current_time(), current_timestamp() + +* second(...), minute(...), hour(...), day(...), month(...), year(...), + +* Any function or operator defined by EJB-QL 3.0: substring(), trim(), lower(), upper(), length(), locate(), abs(), sqrt(), bit_length(), mod() + +* coalesce() and nullif() + +* str() for converting numeric or temporal values to a readable string + +* cast(... as ...), where the second argument is the name of a Hibernate type, and extract(... from ...) if ANSI cast() and extract() is supported by the underlying database + +* the HQL index() function, that applies to aliases of a joined indexed collection + +* HQL functions that take collection-valued path expressions: size(), minelement(), maxelement(), minindex(), maxindex(), along with the special elements() and indices functions which may be quantified using some, all, exists, any, in. + +* Any database-supported SQL scalar function like sign(), trunc(), rtrim(), sin() + +* JDBC-style positional parameters ? + +* named parameters :name, :start_date, :x1 + +* SQL literals 'foo', 69, 6.66E+2, '1970-01-01 10:00:01.0' + * Java public static final constants eg.Color.TABBY \ No newline at end of file diff --git a/querydsl-jpa/etc/precedence.txt b/querydsl-jpa/etc/precedence.txt index fad0e18475..b857f7096a 100644 --- a/querydsl-jpa/etc/precedence.txt +++ b/querydsl-jpa/etc/precedence.txt @@ -1,40 +1,40 @@ -BINARY, COLLATE -!, -NOT -- (unary minus), -~ (unary bit inversion) -^ -*, -/, -DIV, -%, -MOD --, -+ -<<, ->> -& -| -=, -<=>, ->=, ->, -<=, -<, -<>, -!=, -IS, -LIKE, -REGEXP, -IN -BETWEEN, -CASE, -WHEN, -THEN, -ELSE -&&, -AND -||, -OR, -XOR +BINARY, COLLATE +!, +NOT +- (unary minus), +~ (unary bit inversion) +^ +*, +/, +DIV, +%, +MOD +-, ++ +<<, +>> +& +| +=, +<=>, +>=, +>, +<=, +<, +<>, +!=, +IS, +LIKE, +REGEXP, +IN +BETWEEN, +CASE, +WHEN, +THEN, +ELSE +&&, +AND +||, +OR, +XOR := \ No newline at end of file diff --git a/querydsl-jpa/pom.xml b/querydsl-jpa/pom.xml index 5b0fea7725..75a8232314 100644 --- a/querydsl-jpa/pom.xml +++ b/querydsl-jpa/pom.xml @@ -1,15 +1,15 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0" encoding="UTF-8"?> <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <modelVersion>4.0.0</modelVersion> <parent> - <groupId>com.mysema.querydsl</groupId> + <groupId>com.querydsl</groupId> <artifactId>querydsl-root</artifactId> - <version>3.4.1.BUILD-SNAPSHOT</version> - <relativePath>../querydsl-root/pom.xml</relativePath> + <version>5.1.0</version> + <relativePath>../pom.xml</relativePath> </parent> - <groupId>com.mysema.querydsl</groupId> + <groupId>com.querydsl</groupId> <artifactId>querydsl-jpa</artifactId> <name>Querydsl - JPA support</name> <description>JPA support for Querydsl</description> @@ -23,12 +23,15 @@ </scm> <properties> - <hibernate.version>4.3.5.Final</hibernate.version> - <hibernate.validator.version>4.3.1.Final</hibernate.validator.version> - <eclipselink.version>2.5.1</eclipselink.version> + <osgi.import.package>javax.persistence.*;version="[1.1,3)",${osgi.import.package.root}</osgi.import.package> </properties> - <dependencies> + <dependencies> + <dependency> + <groupId>org.jetbrains</groupId> + <artifactId>annotations</artifactId> + <scope>provided</scope> + </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> @@ -43,69 +46,93 @@ <artifactId>asm</artifactId> </exclusion> </exclusions> - <scope>provided</scope> - </dependency> - <dependency> - <groupId>org.hibernate</groupId> - <artifactId>hibernate-entitymanager</artifactId> - <version>${hibernate.version}</version> + <optional>true</optional> <scope>provided</scope> </dependency> + <dependency> - <groupId>org.hibernate</groupId> - <artifactId>hibernate-validator</artifactId> - <version>${hibernate.validator.version}</version> - <scope>provided</scope> - <exclusions> - <exclusion> - <groupId>org.slf4j</groupId> - <artifactId>slf4j-api</artifactId> - </exclusion> - </exclusions> - </dependency> - - <dependency> - <groupId>org.hibernate.javax.persistence</groupId> - <artifactId>hibernate-jpa-2.1-api</artifactId> - <version>1.0.0.Final</version> + <groupId>jakarta.persistence</groupId> + <artifactId>jakarta.persistence-api</artifactId> <scope>provided</scope> </dependency> <dependency> - <groupId>com.mysema.querydsl</groupId> + <groupId>com.querydsl</groupId> <artifactId>querydsl-core</artifactId> <version>${project.version}</version> - </dependency> + </dependency> <dependency> - <groupId>com.mysema.querydsl</groupId> + <groupId>com.querydsl</groupId> <artifactId>querydsl-apt</artifactId> <version>${project.version}</version> <scope>provided</scope> </dependency> <dependency> - <groupId>com.mysema.querydsl</groupId> + <groupId>com.querydsl</groupId> <artifactId>querydsl-sql</artifactId> <version>${project.version}</version> <scope>compile</scope> <optional>true</optional> - </dependency> - + </dependency> + + <!-- test --> <dependency> - <groupId>org.slf4j</groupId> - <artifactId>slf4j-api</artifactId> + <groupId>org.hibernate.validator</groupId> + <artifactId>hibernate-validator</artifactId> + <version>${hibernate.validator.version}</version> + <scope>test</scope> </dependency> <dependency> - <groupId>org.slf4j</groupId> - <artifactId>slf4j-log4j12</artifactId> - </dependency> - - <!-- test --> - + <groupId>javax.validation</groupId> + <artifactId>validation-api</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>joda-time</groupId> + <artifactId>joda-time</artifactId> + <version>${jodatime.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>cglib</groupId> + <artifactId>cglib</artifactId> + <version>${cglib.version}</version> + <scope>test</scope> + <exclusions> + <exclusion> + <groupId>org.ow2.asm</groupId> + <artifactId>asm</artifactId> + </exclusion> + <exclusion> + <groupId>org.ow2.asm</groupId> + <artifactId>asm-commons</artifactId> + </exclusion> + </exclusions> + </dependency> + <dependency> + <groupId>org.ow2.asm</groupId> + <artifactId>asm</artifactId> + <version>${asm.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.ow2.asm</groupId> + <artifactId>asm-commons</artifactId> + <version>${asm.version}</version> + <scope>test</scope> + </dependency> <dependency> <groupId>org.eclipse.persistence</groupId> <artifactId>eclipselink</artifactId> <version>${eclipselink.version}</version> + <exclusions> + <exclusion> + <artifactId>validation-api</artifactId> + <groupId>javax.validation</groupId> + </exclusion> + </exclusions> + <optional>true</optional> <scope>provided</scope> </dependency> @@ -114,6 +141,12 @@ <artifactId>postgresql</artifactId> <version>${postgresql.version}</version> <scope>test</scope> + <exclusions> + <exclusion> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-simple</artifactId> + </exclusion> + </exclusions> </dependency> <!-- @@ -143,12 +176,6 @@ </exclusion> </exclusions> </dependency> - <dependency> - <groupId>com.jolbox</groupId> - <artifactId>bonecp</artifactId> - <version>0.7.1.RELEASE</version> - <scope>test</scope> - </dependency> <dependency> <groupId>org.hsqldb</groupId> @@ -160,7 +187,6 @@ <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> - <version>${h2.version}</version> <scope>test</scope> </dependency> @@ -170,6 +196,12 @@ <version>${derby.version}</version> <scope>test</scope> </dependency> + <dependency> + <groupId>org.apache.derby</groupId> + <artifactId>derbytools</artifactId> + <version>${derby.version}</version> + <scope>test</scope> + </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> @@ -177,26 +209,32 @@ <scope>test</scope> </dependency> <dependency> - <groupId>net.sourceforge.jtds</groupId> - <artifactId>jtds</artifactId> - <version>${jtds.version}</version> + <groupId>com.microsoft.sqlserver</groupId> + <artifactId>mssql-jdbc</artifactId> + <version>${mssql.version}</version> <scope>test</scope> </dependency> <dependency> - <groupId>com.oracle</groupId> - <artifactId>ojdbc6</artifactId> + <groupId>com.oracle.database.jdbc</groupId> + <artifactId>ojdbc8</artifactId> <version>${oracle.version}</version> <scope>test</scope> </dependency> <dependency> - <groupId>com.mysema.querydsl</groupId> + <groupId>com.querydsl</groupId> <artifactId>querydsl-core</artifactId> <version>${project.version}</version> <scope>test</scope> <type>test-jar</type> </dependency> - + + <dependency> + <groupId>io.github.classgraph</groupId> + <artifactId>classgraph</artifactId> + <scope>test</scope> + </dependency> + <dependency> <groupId>jdepend</groupId> <artifactId>jdepend</artifactId> @@ -210,8 +248,8 @@ <plugins> <plugin> - <groupId>com.springsource.bundlor</groupId> - <artifactId>com.springsource.bundlor.maven</artifactId> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> </plugin> <plugin> @@ -219,7 +257,7 @@ <artifactId>maven-jar-plugin</artifactId> <executions> <execution> - <id>apt</id> + <id>apt</id> <goals> <goal>jar</goal> </goals> @@ -235,7 +273,14 @@ </goals> </execution> </executions> - </plugin> + <configuration> + <archive> + <manifestEntries> + <Automatic-Module-Name>com.querydsl.jpa</Automatic-Module-Name> + </manifestEntries> + </archive> + </configuration> + </plugin> <plugin> <artifactId>maven-source-plugin</artifactId> <executions> @@ -246,8 +291,24 @@ </goals> </execution> </executions> - </plugin> - + </plugin> + <plugin> + <groupId>org.eclipse.transformer</groupId> + <artifactId>org.eclipse.transformer.maven</artifactId> + <version>0.2.0</version> + <executions> + <execution> + <id>jakarta-ee</id> + <goals> + <goal>run</goal> + </goals> + <phase>package</phase> + <configuration> + <classifier>jakarta</classifier> + </configuration> + </execution> + </executions> + </plugin> <plugin> <artifactId>maven-assembly-plugin</artifactId> <executions> @@ -280,6 +341,10 @@ <name>derby.stream.error.file</name> <value>target/derby.log</value> </property> + <property> + <name>org.jboss.logging.provider</name> + <value>slf4j</value> + </property> </systemProperties> </configuration> <executions> @@ -297,7 +362,7 @@ </property> </systemProperties> <includes> - <include>com/mysema/query/PackageVerification.java</include> + <include>com/querydsl/jpa/PackageVerification.java</include> </includes> </configuration> </execution> @@ -315,14 +380,14 @@ </goals> <configuration> <outputDirectory>target/generated-test-sources/java</outputDirectory> - <processor>com.mysema.query.apt.hibernate.HibernateAnnotationProcessor</processor> + <processor>com.querydsl.apt.hibernate.HibernateAnnotationProcessor</processor> <logOnlyOnError>true</logOnlyOnError> </configuration> </execution> </executions> </plugin> <plugin> - <groupId>com.mysema.querydsl</groupId> + <groupId>com.querydsl</groupId> <artifactId>querydsl-maven-plugin</artifactId> <version>${project.version}</version> <!-- @@ -337,7 +402,7 @@ <configuration> <jdbcDriver>org.apache.derby.jdbc.EmbeddedDriver</jdbcDriver> <jdbcUrl>jdbc:derby:target/derbydb;create=true</jdbcUrl> - <packageName>com.mysema.query.jpa.domain.sql</packageName> + <packageName>com.querydsl.jpa.domain.sql</packageName> <targetFolder>src/test/java</targetFolder> <namePrefix>S</namePrefix> <imports> @@ -350,10 +415,32 @@ <groupId>org.apache.derby</groupId> <artifactId>derby</artifactId> <version>${derby.version}</version> - </dependency> + </dependency> + <dependency> + <groupId>org.apache.derby</groupId> + <artifactId>derbytools</artifactId> + <version>${derby.version}</version> + </dependency> </dependencies> </plugin> </plugins> </build> -</project> + <profiles> + <profile> + <id>java-11</id> + <activation> + <jdk>[11,)</jdk> + </activation> + <dependencies> + <dependency> + <groupId>javax.annotation</groupId> + <artifactId>javax.annotation-api</artifactId> + <version>1.3.2</version> + <scope>provided</scope> + </dependency> + </dependencies> + </profile> + </profiles> + +</project> diff --git a/querydsl-jpa/src/apt-hibernate/META-INF/services/javax.annotation.processing.Processor b/querydsl-jpa/src/apt-hibernate/META-INF/services/javax.annotation.processing.Processor index 4f7291436b..bb12f8599e 100644 --- a/querydsl-jpa/src/apt-hibernate/META-INF/services/javax.annotation.processing.Processor +++ b/querydsl-jpa/src/apt-hibernate/META-INF/services/javax.annotation.processing.Processor @@ -1 +1 @@ -com.mysema.query.apt.hibernate.HibernateAnnotationProcessor \ No newline at end of file +com.querydsl.apt.hibernate.HibernateAnnotationProcessor \ No newline at end of file diff --git a/querydsl-jpa/src/apt/META-INF/services/javax.annotation.processing.Processor b/querydsl-jpa/src/apt/META-INF/services/javax.annotation.processing.Processor index 4774bfb506..720345c294 100644 --- a/querydsl-jpa/src/apt/META-INF/services/javax.annotation.processing.Processor +++ b/querydsl-jpa/src/apt/META-INF/services/javax.annotation.processing.Processor @@ -1 +1 @@ -com.mysema.query.apt.jpa.JPAAnnotationProcessor \ No newline at end of file +com.querydsl.apt.jpa.JPAAnnotationProcessor \ No newline at end of file diff --git a/querydsl-jpa/src/main/assembly-hibernate.xml b/querydsl-jpa/src/main/assembly-hibernate.xml index 49405bfd89..cec7aa7c90 100644 --- a/querydsl-jpa/src/main/assembly-hibernate.xml +++ b/querydsl-jpa/src/main/assembly-hibernate.xml @@ -21,18 +21,16 @@ <unpack>true</unpack> <excludes> <exclude>cglib:cglib</exclude> - <exclude>com.mysema.querydsl:querydsl-sql</exclude> - <exclude>com.mysema.querydsl:querydsl-jpa</exclude> - <exclude>org.slf4j:slf4j-api</exclude> - <exclude>org.slf4j:slf4j-log4j12</exclude> + <exclude>com.querydsl:querydsl-sql</exclude> + <exclude>com.querydsl:querydsl-jpa</exclude> </excludes> </dependencySet> <dependencySet> <unpack>true</unpack> <scope>provided</scope> <includes> - <include>com.mysema.querydsl:*</include> - <include>com.mysema.codegen:*</include> + <include>com.querydsl:*</include> + <include>com.querydsl.codegen.utils:*</include> <include>org.hibernate:hibernate-core</include> <include>org.hibernate.javax.persistence:*</include> </includes> diff --git a/querydsl-jpa/src/main/assembly.xml b/querydsl-jpa/src/main/assembly.xml index df3483aa98..24669eba05 100644 --- a/querydsl-jpa/src/main/assembly.xml +++ b/querydsl-jpa/src/main/assembly.xml @@ -27,18 +27,16 @@ <unpack>true</unpack> <excludes> <exclude>cglib:cglib</exclude> - <exclude>com.mysema.querydsl:querydsl-sql</exclude> - <exclude>com.mysema.querydsl:querydsl-jpa</exclude> - <exclude>org.slf4j:slf4j-api</exclude> - <exclude>org.slf4j:slf4j-log4j12</exclude> + <exclude>com.querydsl:querydsl-sql</exclude> + <exclude>com.querydsl:querydsl-jpa</exclude> </excludes> </dependencySet> <dependencySet> <unpack>true</unpack> <scope>provided</scope> <includes> - <include>com.mysema.querydsl:*</include> - <include>com.mysema.codegen:*</include> + <include>com.querydsl:*</include> + <include>com.querydsl.codegen.utils:*</include> <include>org.hibernate.javax.persistence:*</include> </includes> </dependencySet> diff --git a/querydsl-jpa/src/main/java/com/mysema/query/jpa/AbstractJPASubQuery.java b/querydsl-jpa/src/main/java/com/mysema/query/jpa/AbstractJPASubQuery.java deleted file mode 100644 index b32254377e..0000000000 --- a/querydsl-jpa/src/main/java/com/mysema/query/jpa/AbstractJPASubQuery.java +++ /dev/null @@ -1,254 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa; - -import com.mysema.query.DefaultQueryMetadata; -import com.mysema.query.JoinExpression; -import com.mysema.query.JoinType; -import com.mysema.query.QueryMetadata; -import com.mysema.query.support.DetachableQuery; -import com.mysema.query.types.CollectionExpression; -import com.mysema.query.types.EntityPath; -import com.mysema.query.types.MapExpression; -import com.mysema.query.types.Path; -import com.mysema.query.types.Predicate; -import com.mysema.query.types.query.NumberSubQuery; -import com.mysema.query.types.template.NumberTemplate; - -/** - * Abstract superclass for SubQuery implementations - * - * @author tiwe - * - * @param <Q> concrete subtype - */ -public class AbstractJPASubQuery<Q extends AbstractJPASubQuery<Q>> extends DetachableQuery<Q> implements JPQLSubQuery { - - private final JPAQueryMixin<Q> queryMixin; - - public AbstractJPASubQuery() { - this(new DefaultQueryMetadata().noValidate()); - } - - @SuppressWarnings("unchecked") - public AbstractJPASubQuery(QueryMetadata metadata) { - super(new JPAQueryMixin<Q>(metadata)); - super.queryMixin.setSelf((Q)this); - this.queryMixin = (JPAQueryMixin<Q>) super.queryMixin; - } - - @Override - public NumberSubQuery<Long> count() { - StringBuilder count = new StringBuilder(); - for (JoinExpression join : queryMixin.getMetadata().getJoins()) { - if (join.getType() == JoinType.DEFAULT) { - count.append(count.length() == 0 ? "count(" : ", "); - count.append(join.getTarget().toString()); - } - } - count.append(")"); - return unique(NumberTemplate.create(Long.class, count.toString())); - } - - public Q from(EntityPath<?> o) { - return queryMixin.from(o); - } - - @Override - public Q from(EntityPath<?>... o) { - return queryMixin.from(o); - } - - @Override - public <P> Q fullJoin(CollectionExpression<?,P> target) { - return queryMixin.fullJoin(target); - } - - @Override - public <P> Q fullJoin(CollectionExpression<?,P> target, Path<P> alias) { - return queryMixin.fullJoin(target, alias); - } - - @Override - public <P> Q fullJoin(EntityPath<P> target) { - return queryMixin.fullJoin(target); - } - - @Override - public <P> Q fullJoin(EntityPath<P> target, Path<P> alias) { - return queryMixin.fullJoin(target, alias); - } - - @Override - public <P> Q fullJoin(MapExpression<?,P> target) { - return queryMixin.fullJoin(target); - } - - @Override - public <P> Q fullJoin(MapExpression<?,P> target, Path<P> alias) { - return queryMixin.fullJoin(target, alias); - } - - @Override - public <P> Q innerJoin(CollectionExpression<?,P> target) { - return queryMixin.innerJoin(target); - } - - @Override - public <P> Q innerJoin(CollectionExpression<?,P> target, Path<P> alias) { - return queryMixin.innerJoin(target, alias); - } - - @Override - public <P> Q innerJoin(EntityPath<P> target) { - return queryMixin.innerJoin(target); - } - - @Override - public <P> Q innerJoin(EntityPath<P> target, Path<P> alias) { - return queryMixin.innerJoin(target, alias); - } - - @Override - public <P> Q innerJoin(MapExpression<?,P> target) { - return queryMixin.innerJoin(target); - } - - @Override - public <P> Q innerJoin(MapExpression<?,P> target, Path<P> alias) { - return queryMixin.innerJoin(target, alias); - } - - @Override - public <P> Q join(CollectionExpression<?,P> target) { - return queryMixin.join(target); - } - - @Override - public <P> Q join(CollectionExpression<?,P> target, Path<P> alias) { - return queryMixin.join(target, alias); - } - - @Override - public <P> Q join(EntityPath<P> target) { - return queryMixin.join(target); - } - - @Override - public <P> Q join(EntityPath<P> target, Path<P> alias) { - return queryMixin.join(target, alias); - } - - @Override - public <P> Q join(MapExpression<?,P> target) { - return queryMixin.join(target); - } - - @Override - public <P> Q join(MapExpression<?,P> target, Path<P> alias) { - return queryMixin.join(target, alias); - } - - @Override - public <P> Q leftJoin(CollectionExpression<?,P> target) { - return queryMixin.leftJoin(target); - } - - @Override - public <P> Q leftJoin(CollectionExpression<?,P> target, Path<P> alias) { - return queryMixin.leftJoin(target, alias); - } - - @Override - public <P> Q leftJoin(EntityPath<P> target) { - return queryMixin.leftJoin(target); - } - - @Override - public <P> Q leftJoin(EntityPath<P> target, Path<P> alias) { - return queryMixin.leftJoin(target, alias); - } - - @Override - public <P> Q leftJoin(MapExpression<?,P> target) { - return queryMixin.leftJoin(target); - } - - @Override - public <P> Q leftJoin(MapExpression<?,P> target, Path<P> alias) { - return queryMixin.leftJoin(target, alias); - } - - @Override - public <P> Q rightJoin(CollectionExpression<?,P> target) { - return queryMixin.rightJoin(target); - } - - @Override - public <P> Q rightJoin(CollectionExpression<?,P> target, Path<P> alias) { - return queryMixin.rightJoin(target, alias); - } - - @Override - public <P> Q rightJoin(EntityPath<P> target) { - return queryMixin.rightJoin(target); - } - - @Override - public <P> Q rightJoin(EntityPath<P> target, Path<P> alias) { - return queryMixin.rightJoin(target, alias); - } - - @Override - public <P> Q rightJoin(MapExpression<?,P> target) { - return queryMixin.rightJoin(target); - } - - @Override - public <P> Q rightJoin(MapExpression<?,P> target, Path<P> alias) { - return queryMixin.rightJoin(target, alias); - } - - public Q on(Predicate condition) { - return queryMixin.on(condition); - } - - @Override - public Q on(Predicate... conditions) { - return queryMixin.on(conditions); - } - - @Override - public Q limit(long l) { - throw new UnsupportedOperationException("JPQL doesn't support limit on subqueries"); - } - - @Override - public Q offset(long o) { - throw new UnsupportedOperationException("JPQL doesn't support offset on subqueries"); - } - - @Override - public String toString() { - if (!queryMixin.getMetadata().getJoins().isEmpty()) { - JPQLSerializer serializer = new JPQLSerializer(JPQLTemplates.DEFAULT, null); - serializer.setStrict(false); - serializer.serialize(queryMixin.getMetadata(), false, null); - return serializer.toString().trim(); - } else { - return super.toString(); - } - } - -} diff --git a/querydsl-jpa/src/main/java/com/mysema/query/jpa/AbstractSQLQuery.java b/querydsl-jpa/src/main/java/com/mysema/query/jpa/AbstractSQLQuery.java deleted file mode 100644 index f253c24d2e..0000000000 --- a/querydsl-jpa/src/main/java/com/mysema/query/jpa/AbstractSQLQuery.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa; - -import com.mysema.query.QueryMetadata; -import com.mysema.query.sql.Configuration; -import com.mysema.query.sql.ProjectableSQLQuery; -import com.mysema.query.support.QueryMixin; -import com.mysema.query.types.EntityPath; -import com.mysema.query.types.Expression; -import com.mysema.query.types.Operation; -import com.mysema.query.types.TemplateExpression; - -import javax.persistence.Entity; - -/** - * Abstract super class for SQLQuery implementation for JPA and Hibernate - * - * @author tiwe - * - * @param <Q> concrete subtype - */ -public abstract class AbstractSQLQuery<Q extends AbstractSQLQuery<Q>> extends ProjectableSQLQuery<Q> { - - private static final class NativeQueryMixin<T> extends QueryMixin<T> { - private NativeQueryMixin(QueryMetadata metadata) { - super(metadata, false); - } - - @Override - public <RT> Expression<RT> convert(Expression<RT> expr, boolean forOrder) { - return Conversions.convertForNativeQuery(super.convert(expr, forOrder)); - } - } - - @SuppressWarnings("unchecked") - public AbstractSQLQuery(QueryMetadata metadata, Configuration configuration) { - super(new NativeQueryMixin<Q>(metadata), configuration); - this.queryMixin.setSelf((Q) this); - } - - protected boolean isEntityExpression(Expression<?> expr) { - return expr instanceof EntityPath || expr.getType().isAnnotationPresent(Entity.class); - } - - protected Expression<?> extractEntityExpression(Expression<?> expr) { - if (expr instanceof Operation) { - return ((Operation<?>)expr).getArg(0); - } else if (expr instanceof TemplateExpression) { - return (Expression<?>) ((TemplateExpression<?>)expr).getArg(0); - } else { - return expr; - } - } - -} diff --git a/querydsl-jpa/src/main/java/com/mysema/query/jpa/Conversions.java b/querydsl-jpa/src/main/java/com/mysema/query/jpa/Conversions.java deleted file mode 100644 index 02d73bb13e..0000000000 --- a/querydsl-jpa/src/main/java/com/mysema/query/jpa/Conversions.java +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright 2012, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa; - -import java.util.List; - -import javax.persistence.Entity; - -import com.google.common.collect.Lists; -import com.mysema.query.sql.RelationalPath; -import com.mysema.query.sql.SQLOps; -import com.mysema.query.support.EnumConversion; -import com.mysema.query.support.NumberConversion; -import com.mysema.query.support.NumberConversions; -import com.mysema.query.types.EntityPath; -import com.mysema.query.types.Expression; -import com.mysema.query.types.ExpressionUtils; -import com.mysema.query.types.FactoryExpression; -import com.mysema.query.types.FactoryExpressionUtils; -import com.mysema.query.types.Operation; -import com.mysema.query.types.OperationImpl; -import com.mysema.query.types.Ops; -import com.mysema.query.types.Path; - -/** - * Conversions provides module specific projection conversion functionality - * - * @author tiwe - * - */ -public final class Conversions { - - public static <RT> Expression<RT> convert(Expression<RT> expr) { - if (isAggSumWithConversion(expr) || isCountAggConversion(expr)) { - return new NumberConversion<RT>(expr); - } else if (expr instanceof FactoryExpression) { - FactoryExpression<RT> factorye = (FactoryExpression<RT>)expr; - for (Expression<?> e : factorye.getArgs()) { - if (isAggSumWithConversion(e) || isCountAggConversion(expr)) { - return new NumberConversions<RT>(factorye); - } - } - } - return expr; - } - - private static boolean isEntityPathAndNeedsWrapping(Expression<?> expr) { - if ((expr instanceof Path && expr.getType().isAnnotationPresent(Entity.class)) || - (expr instanceof EntityPath && !RelationalPath.class.isInstance(expr))) { - Path<?> path = (Path<?>)expr; - if (path.getMetadata().getParent() == null) { - return true; - } - } - return false; - } - - private static <RT> FactoryExpression<RT> createEntityPathConversions(FactoryExpression<RT> factorye) { - List<Expression<?>> conversions = Lists.newArrayList(); - for (Expression<?> e : factorye.getArgs()) { - if (isEntityPathAndNeedsWrapping(e)) { - conversions.add(OperationImpl.create(e.getType(), SQLOps.ALL, e)); - } else { - conversions.add(e); - } - } - return FactoryExpressionUtils.wrap(factorye, conversions); - } - - public static <RT> Expression<RT> convertForNativeQuery(Expression<RT> expr) { - if (isEntityPathAndNeedsWrapping(expr)) { - return OperationImpl.create(expr.getType(), SQLOps.ALL, expr); - } else if (Number.class.isAssignableFrom(expr.getType())) { - return new NumberConversion<RT>(expr); - } else if (Enum.class.isAssignableFrom(expr.getType())) { - return new EnumConversion<RT>(expr); - } else if (expr instanceof FactoryExpression) { - FactoryExpression<RT> factorye = (FactoryExpression<RT>)expr; - boolean numberConversions = false; - boolean hasEntityPath = false; - for (Expression<?> e : factorye.getArgs()) { - if (isEntityPathAndNeedsWrapping(e)) { - hasEntityPath = true; - } else if (Number.class.isAssignableFrom(e.getType())) { - numberConversions = true; - } else if (Enum.class.isAssignableFrom(e.getType())) { - numberConversions = true; - } - } - if (hasEntityPath) { - factorye = createEntityPathConversions(factorye); - } - if (numberConversions) { - factorye = new NumberConversions<RT>(factorye); - } - return factorye; - } - return expr; - } - - private static boolean isAggSumWithConversion(Expression<?> expr) { - expr = ExpressionUtils.extract(expr); - if (expr instanceof Operation) { - Operation<?> operation = (Operation<?>)expr; - Class<?> type = operation.getType(); - if (type.equals(Float.class) || type.equals(Integer.class) || type.equals(Long.class) - || type.equals(Short.class) || type.equals(Byte.class)) { - if (operation.getOperator() == Ops.AggOps.SUM_AGG) { - return true; - } else { - for (Expression<?> e : operation.getArgs()) { - if (isAggSumWithConversion(e)) { - return true; - } - } - } - } - } - return false; - } - - private static boolean isCountAggConversion(Expression<?> expr) { - expr = ExpressionUtils.extract(expr); - if (expr instanceof Operation) { - Operation<?> operation = (Operation<?>)expr; - return operation.getOperator() == Ops.AggOps.COUNT_AGG; - } - return false; - } - - private Conversions() {} - -} diff --git a/querydsl-jpa/src/main/java/com/mysema/query/jpa/DefaultQueryHandler.java b/querydsl-jpa/src/main/java/com/mysema/query/jpa/DefaultQueryHandler.java deleted file mode 100644 index f8072dce02..0000000000 --- a/querydsl-jpa/src/main/java/com/mysema/query/jpa/DefaultQueryHandler.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2013, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa; - -import java.util.Iterator; - -import javax.annotation.Nullable; -import javax.persistence.Query; - -import com.mysema.commons.lang.CloseableIterator; -import com.mysema.commons.lang.IteratorAdapter; -import com.mysema.query.types.FactoryExpression; - -/** - * @author tiwe - * - */ -public final class DefaultQueryHandler implements QueryHandler { - - public static final QueryHandler DEFAULT = new DefaultQueryHandler(); - - @Override - public void addEntity(Query query, String alias, Class<?> type) { - // do nothing - } - - @Override - public void addScalar(Query query, String alias, Class<?> type) { - // do nothing - } - - @Override - public boolean createNativeQueryTyped() { - return true; - } - - @Override - public <T> CloseableIterator<T> iterate(Query query, @Nullable final FactoryExpression<?> projection) { - Iterator<T> iterator = query.getResultList().iterator(); - if (projection != null) { - return new TransformingIterator<T>(iterator, projection); - } else { - return new IteratorAdapter<T>(iterator); - } - } - - @Override - public boolean transform(Query query, FactoryExpression<?> projection) { - return false; - } - - @Override - public boolean wrapEntityProjections() { - return false; - } - - private DefaultQueryHandler() {} - - -} diff --git a/querydsl-jpa/src/main/java/com/mysema/query/jpa/EclipseLinkHandler.java b/querydsl-jpa/src/main/java/com/mysema/query/jpa/EclipseLinkHandler.java deleted file mode 100644 index 0dc1a1cf07..0000000000 --- a/querydsl-jpa/src/main/java/com/mysema/query/jpa/EclipseLinkHandler.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2013, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa; - -import java.io.Closeable; -import java.io.IOException; -import java.util.Iterator; - -import javax.persistence.Query; - -import org.eclipse.persistence.config.QueryHints; -import org.eclipse.persistence.config.ResultSetType; -import org.eclipse.persistence.jpa.JpaQuery; -import org.eclipse.persistence.queries.Cursor; - -import com.mysema.commons.lang.CloseableIterator; -import com.mysema.commons.lang.IteratorAdapter; -import com.mysema.query.types.FactoryExpression; - -/** - * - * @author tiwe - * - */ -public class EclipseLinkHandler implements QueryHandler { - - @Override - public void addEntity(Query query, String alias, Class<?> type) { - // do nothing - } - - @Override - public void addScalar(Query query, String alias, Class<?> type) { - // do nothing - } - - @Override - public boolean createNativeQueryTyped() { - return true; - } - - @Override - public <T> CloseableIterator<T> iterate(Query query, FactoryExpression<?> projection) { - Iterator<T> iterator = null; - Closeable closeable = null; - if (query instanceof JpaQuery) { - JpaQuery<T> elQuery = (JpaQuery<T>) query; - elQuery.setHint(QueryHints.RESULT_SET_TYPE, ResultSetType.ForwardOnly); - elQuery.setHint(QueryHints.SCROLLABLE_CURSOR, true); - final Cursor cursor = elQuery.getResultCursor(); - closeable = new Closeable() { - @Override - public void close() throws IOException { - cursor.close(); - } - }; - iterator = cursor; - } else { - iterator = query.getResultList().iterator(); - } - if (projection != null) { - return new TransformingIterator<T>(iterator, closeable, projection); - } else { - return new IteratorAdapter<T>(iterator, closeable); - } - } - - @Override - public boolean transform(Query query, FactoryExpression<?> projection) { - return false; - } - - @Override - public boolean wrapEntityProjections() { - return false; - } - -} diff --git a/querydsl-jpa/src/main/java/com/mysema/query/jpa/EclipseLinkTemplates.java b/querydsl-jpa/src/main/java/com/mysema/query/jpa/EclipseLinkTemplates.java deleted file mode 100644 index e1131e1ff3..0000000000 --- a/querydsl-jpa/src/main/java/com/mysema/query/jpa/EclipseLinkTemplates.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa; - -import java.math.BigDecimal; -import java.math.BigInteger; -import java.util.Map; - -import com.google.common.collect.ImmutableMap; -import com.mysema.query.types.Ops; - -/** - * EclipseLinkTemplates extends JPQLTemplates with EclipseLink specific extensions - * - * @author tiwe - * - */ -public class EclipseLinkTemplates extends JPQLTemplates { - - private static final QueryHandler QUERY_HANDLER; - - static { - QueryHandler instance; - try { - instance = (QueryHandler) Class.forName("com.mysema.query.jpa.EclipseLinkHandler").newInstance(); - } catch (NoClassDefFoundError e) { - instance = DefaultQueryHandler.DEFAULT; - } catch (Exception e) { - instance = DefaultQueryHandler.DEFAULT; - } - QUERY_HANDLER = instance; - } - - - public static final EclipseLinkTemplates DEFAULT = new EclipseLinkTemplates(); - - private final Map<Class<?>, String> typeNames; - - public EclipseLinkTemplates() { - this(DEFAULT_ESCAPE); - } - - public EclipseLinkTemplates(char escape) { - super(escape, QUERY_HANDLER); - - ImmutableMap.Builder<Class<?>, String> builder = ImmutableMap.builder(); - builder.put(Short.class, "short"); - builder.put(Integer.class, "integer"); - builder.put(Long.class, "bigint"); - builder.put(BigInteger.class, "bigint"); - builder.put(Float.class, "float"); - builder.put(Double.class, "double"); - builder.put(BigDecimal.class, "double"); - typeNames = builder.build(); - - add(Ops.CHAR_AT, "substring({0},{1}+1,1)"); - add(JPQLOps.CAST, "cast({0} {1s})"); - add(Ops.STRING_CAST, "cast({0} varchar(255))"); - add(Ops.NUMCAST, "cast({0} {1s})"); - - // datetime - add(Ops.DateTimeOps.MILLISECOND, "extract(microsecond from {0})"); - add(Ops.DateTimeOps.SECOND, "extract(second from {0})"); - add(Ops.DateTimeOps.MINUTE, "extract(minute from {0})"); - add(Ops.DateTimeOps.HOUR, "extract(hour from {0})"); - add(Ops.DateTimeOps.DAY_OF_MONTH, "extract(day from {0})"); - add(Ops.DateTimeOps.MONTH, "extract(month from {0})"); - add(Ops.DateTimeOps.YEAR, "extract(year from {0})"); - } - - @Override - public String getTypeForCast(Class<?> cl) { - return typeNames.get(cl); - } - - @Override - public boolean isPathInEntitiesSupported() { - return false; - } - - @Override - public boolean isSelect1Supported() { - return true; - } - - -} diff --git a/querydsl-jpa/src/main/java/com/mysema/query/jpa/HQLTemplates.java b/querydsl-jpa/src/main/java/com/mysema/query/jpa/HQLTemplates.java deleted file mode 100644 index 77b255616a..0000000000 --- a/querydsl-jpa/src/main/java/com/mysema/query/jpa/HQLTemplates.java +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa; - -import java.math.BigDecimal; -import java.math.BigInteger; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; -import java.util.Map; - -import com.google.common.collect.ImmutableMap; -import com.mysema.query.types.Operator; -import com.mysema.query.types.Ops; -import com.mysema.query.types.PathType; - -/** - * HQLTemplates extends JPQLTemplates with Hibernate specific extensions - * - * @author tiwe - * - */ -public class HQLTemplates extends JPQLTemplates { - - private static final QueryHandler QUERY_HANDLER; - - static { - QueryHandler instance; - try { - instance = (QueryHandler) Class.forName("com.mysema.query.jpa.HibernateHandler").newInstance(); - } catch (NoClassDefFoundError e) { - instance = DefaultQueryHandler.DEFAULT; - } catch (Exception e) { - instance = DefaultQueryHandler.DEFAULT; - } - QUERY_HANDLER = instance; - } - - private static final List<Operator<?>> wrapElements = Arrays.<Operator<?>> asList( - Ops.QuantOps.ALL, - Ops.QuantOps.ANY, - Ops.QuantOps.AVG_IN_COL, - Ops.EXISTS); - - public static final HQLTemplates DEFAULT = new HQLTemplates(); - - private final Map<Class<?>, String> typeNames; - - public HQLTemplates() { - this(DEFAULT_ESCAPE); - } - - public HQLTemplates(char escape) { - super(escape, QUERY_HANDLER); - - ImmutableMap.Builder<Class<?>, String> builder = ImmutableMap.builder(); - builder.put(Byte.class, "byte"); - builder.put(Short.class, "short"); - builder.put(Integer.class, "integer"); - builder.put(Long.class, "long"); - builder.put(BigInteger.class, "big_integer"); - builder.put(Float.class, "float"); - builder.put(Double.class, "double"); - builder.put(BigDecimal.class, "big_decimal"); - typeNames = builder.build(); - - // TODO : remove this when Hibernate supports type(alias) - add(Ops.INSTANCE_OF, "{0}.class = {1}"); - // TODO : remove this when Hibernate supports type(alias) - add(JPQLOps.TYPE, "{0}.class"); - // TODO : remove this when Hibernate supports member of properly - add(JPQLOps.MEMBER_OF, "{0} in elements({1})"); - add(JPQLOps.NOT_MEMBER_OF, "{0} not in elements({1})"); - - // path types - for (PathType type : new PathType[] { - PathType.LISTVALUE, - PathType.MAPVALUE, - PathType.MAPVALUE_CONSTANT }) { - add(type, "{0}[{1}]"); - } - add(PathType.LISTVALUE_CONSTANT, "{0}[{1s}]"); - add(PathType.COLLECTION_ANY, "any elements({0})"); - - add(Ops.CONTAINS_KEY, "{1} in indices({0})"); - add(Ops.CONTAINS_VALUE, "{1} in elements({0})"); - } - - @Override - public boolean wrapElements(Operator<?> operator) { - return wrapElements.contains(operator); - } - - @Override - public boolean isTypeAsString() { - return true; - } - - @Override - public String getTypeForCast(Class<?> cl) { - return typeNames.get(cl); - } - - @Override - public String getExistsProjection() { - return "1"; - } - - @Override - public boolean isSelect1Supported() { - // TODO return true, when JPQLTemplates becomes standard - return false; - } - - @Override - public boolean isEnumInPathSupported() { - // related : http://opensource.atlassian.com/projects/hibernate/browse/HHH-5159 - return false; - } - - @Override - public boolean wrapConstant(Object constant) { - // related : https://hibernate.onjira.com/browse/HHH-6913 - Class<?> type = constant.getClass(); - return type.isArray() || Collection.class.isAssignableFrom(type); - } - - @Override - public boolean isWithForOn() { - return true; - } - -} diff --git a/querydsl-jpa/src/main/java/com/mysema/query/jpa/HibernateHandler.java b/querydsl-jpa/src/main/java/com/mysema/query/jpa/HibernateHandler.java deleted file mode 100644 index a3e5ab9549..0000000000 --- a/querydsl-jpa/src/main/java/com/mysema/query/jpa/HibernateHandler.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa; - -import java.util.Iterator; - -import javax.persistence.Query; - -import org.hibernate.SQLQuery; -import org.hibernate.ScrollMode; -import org.hibernate.ScrollableResults; -import org.hibernate.ejb.HibernateQuery; -import org.hibernate.transform.ResultTransformer; - -import com.mysema.commons.lang.CloseableIterator; -import com.mysema.commons.lang.IteratorAdapter; -import com.mysema.query.types.FactoryExpression; - -/** - * @author tiwe - * - */ -public class HibernateHandler implements QueryHandler { - - @Override - public void addEntity(Query query, String alias, Class<?> type) { - if (query instanceof HibernateQuery) { - org.hibernate.Query hibernateQuery = ((HibernateQuery)query).getHibernateQuery(); - if (hibernateQuery instanceof SQLQuery) { - ((SQLQuery)hibernateQuery).addEntity(alias, type); - } - } - } - - @Override - public void addScalar(Query query, String alias, Class<?> type) { - if (query instanceof HibernateQuery) { - org.hibernate.Query hibernateQuery = ((HibernateQuery)query).getHibernateQuery(); - if (hibernateQuery instanceof SQLQuery) { - ((SQLQuery)hibernateQuery).addScalar(alias); - } - } - } - - @Override - public boolean createNativeQueryTyped() { - return false; - } - - @Override - public <T> CloseableIterator<T> iterate(Query query, FactoryExpression<?> projection) { - if (query instanceof HibernateQuery) { - HibernateQuery hQuery = (HibernateQuery)query; - ScrollableResults results = hQuery.getHibernateQuery().scroll(ScrollMode.FORWARD_ONLY); - CloseableIterator<T> iterator = new ScrollableResultsIterator<T>(results); - if (projection != null) { - iterator = new TransformingIterator<T>(iterator, projection); - } - return iterator; - } else { - Iterator<T> iterator = query.getResultList().iterator(); - if (projection != null) { - return new TransformingIterator<T>(iterator, projection); - } else { - return new IteratorAdapter<T>(iterator); - } - } - } - - @Override - public boolean transform(Query query, FactoryExpression<?> projection) { - if (query instanceof HibernateQuery) { - ResultTransformer transformer = new FactoryExpressionTransformer(projection); - ((HibernateQuery)query).getHibernateQuery().setResultTransformer(transformer); - return true; - } else { - return false; - } - } - - @Override - public boolean wrapEntityProjections() { - return true; - } - -} diff --git a/querydsl-jpa/src/main/java/com/mysema/query/jpa/JPACollectionAnyVisitor.java b/querydsl-jpa/src/main/java/com/mysema/query/jpa/JPACollectionAnyVisitor.java deleted file mode 100644 index 812b510448..0000000000 --- a/querydsl-jpa/src/main/java/com/mysema/query/jpa/JPACollectionAnyVisitor.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa; - -import java.util.UUID; - -import javax.persistence.Entity; - -import com.mysema.query.support.CollectionAnyVisitor; -import com.mysema.query.support.Context; -import com.mysema.query.types.EntityPath; -import com.mysema.query.types.ExpressionUtils; -import com.mysema.query.types.Ops; -import com.mysema.query.types.Path; -import com.mysema.query.types.PathMetadataFactory; -import com.mysema.query.types.Predicate; -import com.mysema.query.types.PredicateOperation; -import com.mysema.query.types.ToStringVisitor; -import com.mysema.query.types.path.EntityPathBase; - -/** - * JPACollectionAnyVisitor extends the {@link CollectionAnyVisitor} class with module specific - * extensions - * - * @author tiwe - * - */ -public final class JPACollectionAnyVisitor extends CollectionAnyVisitor { - - public static final JPACollectionAnyVisitor DEFAULT = new JPACollectionAnyVisitor(); - - @SuppressWarnings("unchecked") - @Override - protected Predicate exists(Context c, Predicate condition) { - JPASubQuery query = new JPASubQuery(); - for (int i = 0; i < c.paths.size(); i++) { - Path<?> child = c.paths.get(i).getMetadata().getParent(); - EntityPath<Object> replacement = (EntityPath<Object>) c.replacements.get(i); - if (c.paths.get(i).getType().isAnnotationPresent(Entity.class)) { - query.from(replacement); - query.where(PredicateOperation.create(Ops.IN, replacement, child)); - } else { - // join via parent - Path<?> parent = child.getMetadata().getParent(); - String prefix = parent.accept(ToStringVisitor.DEFAULT, TEMPLATES).replace('.', '_'); - String suffix = UUID.randomUUID().toString().replace("-", "").substring(0,5); - EntityPathBase<Object> newParent = new EntityPathBase<Object>(parent.getType(), prefix + suffix); - EntityPath<Object> newChild = new EntityPathBase<Object>(child.getType(), - PathMetadataFactory.forProperty(newParent, child.getMetadata().getName())); - query.from(newParent).innerJoin(newChild, replacement); - query.where(ExpressionUtils.eq(newParent, parent)); - } - } - c.clear(); - query.where(condition); - return query.exists(); - } - - private JPACollectionAnyVisitor() {} - -} diff --git a/querydsl-jpa/src/main/java/com/mysema/query/jpa/JPACommonQuery.java b/querydsl-jpa/src/main/java/com/mysema/query/jpa/JPACommonQuery.java deleted file mode 100644 index 5f979d64e1..0000000000 --- a/querydsl-jpa/src/main/java/com/mysema/query/jpa/JPACommonQuery.java +++ /dev/null @@ -1,348 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa; - -import com.mysema.query.Query; -import com.mysema.query.types.CollectionExpression; -import com.mysema.query.types.EntityPath; -import com.mysema.query.types.MapExpression; -import com.mysema.query.types.Path; -import com.mysema.query.types.Predicate; - -/** - * JPACommonQuery is a common interface for queries and subqueries of this module - * - * @author tiwe - * - * @param <Q> - */ -public interface JPACommonQuery<Q extends JPACommonQuery<Q>> extends Query<Q> { - - /** - * Set the sources of this query - * - * @param sources - * @return - */ - Q from(EntityPath<?>... sources); - - /** - * Create a inner join with the given target. - * Use fetch() to add the fetch parameter to this join. - * - * - * @param <P> - * @param target - * @return - */ - <P> Q innerJoin(EntityPath<P> target); - - /** - * Create a inner join with the given target and alias. - * - * @param <P> - * @param target - * @param alias - * @return - */ - <P> Q innerJoin(EntityPath<P> target, Path<P> alias); - - /** - * Create a inner join with the given target. - * Use fetch() to add the fetch parameter to this join. - * - * @param <P> - * @param target - * @return - */ - <P> Q innerJoin(CollectionExpression<?, P> target); - - /** - * Create a inner join with the given target and alias. - * - * @param <P> - * @param target - * @param alias - * @return - */ - <P> Q innerJoin(CollectionExpression<?,P> target, Path<P> alias); - - /** - * Create a inner join with the given target. - * Use fetch() to add the fetch parameter to this join. - * - * @param <P> - * @param target - * @return - */ - <P> Q innerJoin(MapExpression<?, P> target); - - /** - * Create a inner join with the given target and alias. - * - * @param <P> - * @param target - * @param alias - * @return - */ - <P> Q innerJoin(MapExpression<?, P> target, Path<P> alias); - - /** - * Create a join with the given target. - * Use fetch() to add the fetch parameter to this join. - * - * @param <P> - * @param target - * @return - */ - <P> Q join(EntityPath<P> target); - - /** - * Create a join with the given target and alias. - * - * @param <P> - * @param target - * @param alias - * @return - */ - <P> Q join(EntityPath<P> target, Path<P> alias); - - /** - * Create a join with the given target. - * Use fetch() to add the fetch parameter to this join. - * - * @param <P> - * @param target - * @return - */ - <P> Q join(CollectionExpression<?,P> target); - - /** - * @param <P> - * @param target - * @param alias - * @return - */ - <P> Q join(CollectionExpression<?,P> target, Path<P> alias); - - /** - * Create a join with the given target. - * Use fetch() to add the fetch parameter to this join. - * - * @param <P> - * @param target - * @return - */ - <P> Q join(MapExpression<?, P> target); - - /** - * Create a join with the given target and alias. - * - * @param <P> - * @param target - * @param alias - * @return - */ - <P> Q join(MapExpression<?, P> target, Path<P> alias); - - /** - * Create a left join with the given target. - * Use fetch() to add the fetch parameter to this join. - * - * @param <P> - * @param target - * @return - */ - <P> Q leftJoin(EntityPath<P> target); - - /** - * Create a left join with the given target and alias. - * - * @param <P> - * @param target - * @param alias - * @return - */ - <P> Q leftJoin(EntityPath<P> target, Path<P> alias); - - /** - * Create a left join with the given target. - * Use fetch() to add the fetch parameter to this join. - * - * @param <P> - * @param target - * @return - */ - <P> Q leftJoin(CollectionExpression<?,P> target); - - /** - * Create a left join with the given target and alias. - * - * @param <P> - * @param target - * @param alias - * @return - */ - <P> Q leftJoin(CollectionExpression<?,P> target, Path<P> alias); - - /** - * Create a left join with the given target. - * Use fetch() to add the fetch parameter to this join. - * - * @param <P> - * @param target - * @return - */ - <P> Q leftJoin(MapExpression<?, P> target); - - /** - * Create a left join with the given target and alias. - * - * @param <P> - * @param target - * @param alias - * @return - */ - <P> Q leftJoin(MapExpression<?, P> target, Path<P> alias); - - /** - * Create a right join with the given target. - * Use fetch() to add the fetch parameter to this join. - * - * @param <P> - * @param target - * @return - */ - <P> Q rightJoin(EntityPath<P> target); - - /** - * Create a right join with the given target and alias. - * - * @param <P> - * @param target - * @param alias - * @return - */ - <P> Q rightJoin(EntityPath<P> target, Path<P> alias); - - /** - * Create a right join with the given target. - * Use fetch() to add the fetch parameter to this join. - * - * @param <P> - * @param target - * @return - */ - <P> Q rightJoin(CollectionExpression<?,P> target); - - /** - * Create a right join with the given target and alias. - * - * @param <P> - * @param target - * @param alias - * @return - */ - <P> Q rightJoin(CollectionExpression<?,P> target, Path<P> alias); - - /** - * Create a right join with the given target. - * Use fetch() to add the fetch parameter to this join. - * - * @param <P> - * @param target - * @return - */ - <P> Q rightJoin(MapExpression<?, P> target); - - /** - * Create a right join with the given target and alias. - * - * @param <P> - * @param target - * @param alias - * @return - */ - <P> Q rightJoin(MapExpression<?, P> target, Path<P> alias); - - - /** - * Create a full join with the given target. - * Use fetch() to add the fetch parameter to this join. - * - * @param <P> - * @param target - * @return - */ - <P> Q fullJoin(EntityPath<P> target); - - /** - * Create a full join with the given target and alias. - * - * @param <P> - * @param target - * @param alias - * @return - */ - <P> Q fullJoin(EntityPath<P> target, Path<P> alias); - - /** - * Create a full join with the given target. - * Use fetch() to add the fetch parameter to this join. - * - * @param <P> - * @param target - * @return - */ - <P> Q fullJoin(CollectionExpression<?,P> target); - - /** - * Create a full join with the given target and alias. - * - * @param <P> - * @param target - * @param alias - * @return - */ - <P> Q fullJoin(CollectionExpression<?,P> target, Path<P> alias); - - /** - * Create a full join with the given target. - * Use fetch() to add the fetch parameter to this join. - * - * @param <P> - * @param target - * @return - */ - <P> Q fullJoin(MapExpression<?, P> target); - - /** - * Create a full join with the given target and alias. - * - * @param <P> - * @param target - * @param alias - * @return - */ - <P> Q fullJoin(MapExpression<?, P> target, Path<P> alias); - - /** - * Add join conditions to the last added join - * - * @param condition - * @return - */ - Q on(Predicate... condition); - -} diff --git a/querydsl-jpa/src/main/java/com/mysema/query/jpa/JPAExpressions.java b/querydsl-jpa/src/main/java/com/mysema/query/jpa/JPAExpressions.java deleted file mode 100644 index 3df05e29fe..0000000000 --- a/querydsl-jpa/src/main/java/com/mysema/query/jpa/JPAExpressions.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa; - -import com.mysema.query.types.CollectionExpression; -import com.mysema.query.types.EntityPath; -import com.mysema.query.types.Expression; -import com.mysema.query.types.Ops; -import com.mysema.query.types.expr.ComparableExpression; -import com.mysema.query.types.expr.ComparableOperation; -import com.mysema.query.types.expr.StringExpression; -import com.mysema.query.types.expr.StringOperation; - -/** - * JPAExpressions provides factory methods for JPQL specific operations - * elements. - * - * @author tiwe - */ -@SuppressWarnings("unchecked") -public final class JPAExpressions { - - /** - * Get the avg(col) expression - * - * @param col - * @return - */ - public static <A extends Comparable<? super A>> ComparableExpression<A> avg(CollectionExpression<?,A> col) { - return ComparableOperation.create((Class)col.getParameter(0), Ops.QuantOps.AVG_IN_COL, (Expression<?>)col); - } - - /** - * Get the max(col) expression - * - * @param left - * @return - */ - public static <A extends Comparable<? super A>> ComparableExpression<A> max(CollectionExpression<?,A> left) { - return ComparableOperation.create((Class)left.getParameter(0), Ops.QuantOps.MAX_IN_COL, (Expression<?>)left); - } - - /** - * Get the min(col) expression - * - * @param left - * @return - */ - public static <A extends Comparable<? super A>> ComparableExpression<A> min(CollectionExpression<?,A> left) { - return ComparableOperation.create((Class)left.getParameter(0), Ops.QuantOps.MIN_IN_COL, (Expression<?>)left); - } - - /** - * Get the type(path) expression - * - * @param path - * @return - */ - public static StringExpression type(EntityPath<?> path) { - return StringOperation.create(JPQLOps.TYPE, path); - } - - private JPAExpressions() {} - -} diff --git a/querydsl-jpa/src/main/java/com/mysema/query/jpa/JPAQueryBase.java b/querydsl-jpa/src/main/java/com/mysema/query/jpa/JPAQueryBase.java deleted file mode 100644 index 323bf6aea8..0000000000 --- a/querydsl-jpa/src/main/java/com/mysema/query/jpa/JPAQueryBase.java +++ /dev/null @@ -1,236 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa; - -import com.mysema.query.QueryMetadata; -import com.mysema.query.Tuple; -import com.mysema.query.support.ProjectableQuery; -import com.mysema.query.types.CollectionExpression; -import com.mysema.query.types.EntityPath; -import com.mysema.query.types.Expression; -import com.mysema.query.types.MapExpression; -import com.mysema.query.types.Path; -import com.mysema.query.types.Predicate; -import com.mysema.query.types.template.NumberTemplate; - -/** - * JPAQueryBase is a base Query class for JPA queries - * - * @author tiwe - */ -public abstract class JPAQueryBase<Q extends JPAQueryBase<Q>> extends ProjectableQuery<Q> implements JPQLQuery { - - protected final JPAQueryMixin<Q> queryMixin; - - private final JPQLTemplates templates; - - @SuppressWarnings("unchecked") - public JPAQueryBase(QueryMetadata md, JPQLTemplates templates) { - super(new JPAQueryMixin<Q>(md)); - super.queryMixin.setSelf((Q) this); - this.queryMixin = (JPAQueryMixin<Q>) super.queryMixin; - this.templates = templates; - } - - protected JPQLTemplates getTemplates() { - return templates; - } - - protected abstract JPQLSerializer createSerializer(); - - protected JPQLSerializer serialize(boolean forCountRow) { - if (queryMixin.getMetadata().getJoins().isEmpty()) { - throw new IllegalArgumentException("No joins given"); - } - JPQLSerializer serializer = createSerializer(); - serializer.serialize(queryMixin.getMetadata(), forCountRow, null); - return serializer; - } - - protected void reset() { - queryMixin.getMetadata().reset(); - } - - @Override - public boolean exists() { - if (templates.isSelect1Supported()) { - return limit(1).singleResult(NumberTemplate.ONE) != null; - } else { - EntityPath<?> entityPath = (EntityPath<?>) queryMixin.getMetadata().getJoins().get(0).getTarget(); - return !limit(1).list(entityPath).isEmpty(); - } - } - - public Q fetch() { - return queryMixin.fetch(); - } - - public Q fetchAll() { - return queryMixin.fetchAll(); - } - - public Q from(EntityPath<?> arg) { - return queryMixin.from(arg); - } - - public Q from(EntityPath<?>... args) { - return queryMixin.from(args); - } - - public <P> Q fullJoin(CollectionExpression<?,P> target) { - return queryMixin.fullJoin(target); - } - - public <P> Q fullJoin(CollectionExpression<?,P> target, Path<P> alias) { - return queryMixin.fullJoin(target, alias); - } - - public <P> Q fullJoin(EntityPath<P> target) { - return queryMixin.fullJoin(target); - } - - public <P> Q fullJoin(EntityPath<P> target, Path<P> alias) { - return queryMixin.fullJoin(target, alias); - } - - public <P> Q fullJoin(MapExpression<?,P> target) { - return queryMixin.fullJoin(target); - } - - public <P> Q fullJoin(MapExpression<?,P> target, Path<P> alias) { - return queryMixin.fullJoin(target, alias); - } - - public <P> Q innerJoin(CollectionExpression<?,P> target) { - return queryMixin.innerJoin(target); - } - - public <P> Q innerJoin(CollectionExpression<?,P>target, Path<P> alias) { - return queryMixin.innerJoin(target, alias); - } - - public <P> Q innerJoin(EntityPath<P> target) { - return queryMixin.innerJoin(target); - } - - public <P> Q innerJoin(EntityPath<P> target, Path<P> alias) { - return queryMixin.innerJoin(target, alias); - } - - public <P> Q innerJoin(MapExpression<?,P> target) { - return queryMixin.innerJoin(target); - } - - public <P> Q innerJoin(MapExpression<?,P> target, Path<P> alias) { - return queryMixin.innerJoin(target, alias); - } - - public <P> Q join(CollectionExpression<?,P> target) { - return queryMixin.join(target); - } - - public <P> Q join(CollectionExpression<?,P> target, Path<P> alias) { - return queryMixin.join(target, alias); - } - - public <P> Q join(EntityPath<P> target) { - return queryMixin.join(target); - } - - public <P> Q join(EntityPath<P> target, Path<P> alias) { - return queryMixin.join(target, alias); - } - - public <P> Q join(MapExpression<?,P> target) { - return queryMixin.join(target); - } - - public <P> Q join(MapExpression<?,P> target, Path<P> alias) { - return queryMixin.join(target, alias); - } - - public <P> Q leftJoin(CollectionExpression<?,P> target) { - return queryMixin.leftJoin(target); - } - - public <P> Q leftJoin(CollectionExpression<?,P> target, Path<P> alias) { - return queryMixin.leftJoin(target, alias); - } - - public <P> Q leftJoin(EntityPath<P> target) { - return queryMixin.leftJoin(target); - } - - public <P> Q leftJoin(EntityPath<P> target, Path<P> alias) { - return queryMixin.leftJoin(target, alias); - } - - public <P> Q leftJoin(MapExpression<?,P> target) { - return queryMixin.leftJoin(target); - } - - public <P> Q leftJoin(MapExpression<?,P> target, Path<P> alias) { - return queryMixin.leftJoin(target, alias); - } - - public <P> Q rightJoin(CollectionExpression<?,P> target) { - return queryMixin.rightJoin(target); - } - - public <P> Q rightJoin(CollectionExpression<?,P> target, Path<P> alias) { - return queryMixin.rightJoin(target, alias); - } - - public <P> Q rightJoin(EntityPath<P> target) { - return queryMixin.rightJoin(target); - } - - public <P> Q rightJoin(EntityPath<P> target, Path<P> alias) { - return queryMixin.rightJoin(target, alias); - } - - public <P> Q rightJoin(MapExpression<?,P> target) { - return queryMixin.rightJoin(target); - } - - public <P> Q rightJoin(MapExpression<?,P> target, Path<P> alias) { - return queryMixin.rightJoin(target, alias); - } - - public Q on(Predicate condition) { - return queryMixin.on(condition); - } - - public Q on(Predicate... conditions) { - return queryMixin.on(conditions); - } - - @Override - public Tuple uniqueResult(Expression<?>... args) { - return uniqueResult(queryMixin.createProjection(args)); - } - - @Override - public String toString() { - JPQLSerializer serializer = serialize(false); - return serializer.toString().trim(); - } - - public QueryMetadata getMetadata() { - return queryMixin.getMetadata(); - } - - public abstract Q clone(); - -} diff --git a/querydsl-jpa/src/main/java/com/mysema/query/jpa/JPAQueryMixin.java b/querydsl-jpa/src/main/java/com/mysema/query/jpa/JPAQueryMixin.java deleted file mode 100644 index 15da7c814a..0000000000 --- a/querydsl-jpa/src/main/java/com/mysema/query/jpa/JPAQueryMixin.java +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa; - -import javax.persistence.Entity; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; -import com.mysema.query.JoinFlag; -import com.mysema.query.QueryMetadata; -import com.mysema.query.support.*; -import com.mysema.query.types.*; -import com.mysema.query.types.path.CollectionPathBase; - -/** - * JPAQueryMixin extends {@link QueryMixin} to support JPQL join construction - * - * @author tiwe - * - * @param <T> - */ -public class JPAQueryMixin<T> extends QueryMixin<T> { - - private final Set<Path<?>> paths = Sets.newHashSet(); - - private final Map<Expression<?>, Path<?>> aliases = Maps.newHashMap(); - - private ReplaceVisitor replaceVisitor; - - public static final JoinFlag FETCH = new JoinFlag("fetch "); - - public static final JoinFlag FETCH_ALL_PROPERTIES = new JoinFlag(" fetch all properties"); - - public JPAQueryMixin() {} - - public JPAQueryMixin(QueryMetadata metadata) { - super(metadata); - } - - public JPAQueryMixin(T self, QueryMetadata metadata) { - super(self, metadata); - } - - public T fetch() { - addJoinFlag(FETCH); - return getSelf(); - } - - public T fetchAll() { - addJoinFlag(FETCH_ALL_PROPERTIES); - return getSelf(); - } - - @Override - protected <D> Expression<D> createAlias(Expression<?> expr, Path<?> alias) { - aliases.put(expr, alias); - return super.createAlias(expr, alias); - } - - private boolean isEntityPath(Path<?> path) { - if (path instanceof CollectionPathBase) { - return isEntityPath((Path<?>) ((CollectionPathBase)path).any()); - } else { - return path instanceof EntityPath - || path.getType().isAnnotationPresent(Entity.class); - } - } - - private <T> Class<T> getElementTypeOrType(Path<T> path) { - if (path instanceof CollectionExpression) { - return ((CollectionExpression)path).getParameter(0); - } else { - return (Class<T>) path.getType(); - } - } - - private <T> Path<T> shorten(Path<T> path, List<Path<?>> paths) { - PathMetadata<?> metadata = path.getMetadata(); - if (metadata.isRoot() || paths.contains(path)) { - return path; - } else if (aliases.containsKey(path)) { - return (Path<T>) aliases.get(path); - } else if (metadata.getPathType() == PathType.COLLECTION_ANY) { - return (Path<T>) shorten(metadata.getParent(), paths); - } else if (!isEntityPath(path)) { - Path<?> parent = shorten(metadata.getParent(), paths); - if (parent.equals(metadata.getParent())) { - return path; - } else { - return new PathImpl<T>(path.getType(), - new PathMetadata(parent, metadata.getElement(), metadata.getPathType())); - } - } else if (metadata.getParent().getMetadata().isRoot()) { - Class<T> type = getElementTypeOrType(path); - Path<T> newPath = new PathImpl<T>(type, path.toString().replace('.', '_')); - leftJoin(path, newPath); - return newPath; - } else { - Class<T> type = getElementTypeOrType(path); - Path<?> parent = shorten(metadata.getParent(), paths); - Path<T> oldPath = new PathImpl<T>(path.getType(), - new PathMetadata(parent, metadata.getElement(), metadata.getPathType())); - Path<T> newPath = new PathImpl<T>(type, oldPath.toString().replace('.', '_')); - leftJoin(oldPath, newPath); - return newPath; - } - } - - private <T> Path<T> convertPathForOrder(Path<T> path) { - PathMetadata<?> metadata = path.getMetadata(); - // at least three levels - if (metadata.getParent() != null && !metadata.getParent().getMetadata().isRoot()) { - Set<Expression<?>> exprs = Sets.newHashSet(); - QueryMetadata md = getMetadata(); - exprs.addAll(md.getGroupBy()); - if (md.getWhere() != null) exprs.add(md.getWhere()); - if (md.getHaving() != null) exprs.add(md.getHaving()); - List<Path<?>> paths = Lists.newArrayList(); - // extract paths - PathsExtractor.DEFAULT.visit(exprs, paths); - - if (!paths.contains(path) && !paths.contains(metadata.getParent())) { - Path<?> shortened = shorten(metadata.getParent(), paths); - return new PathImpl<T>(path.getType(), - new PathMetadata(shortened, metadata.getElement(), metadata.getPathType())); - } else { - return path; - } - } else { - return path; - } - } - - @Override - public <RT> Expression<RT> convert(Expression<RT> expr, boolean forOrder) { - if (forOrder) { - if (expr instanceof Path) { - expr = convertPathForOrder((Path)expr); - } else { - if (replaceVisitor == null) { - replaceVisitor = new ReplaceVisitor() { - public Expression<?> visit(Path<?> expr, Void context) { - return convertPathForOrder(expr); - } - }; - } - expr = (Expression<RT>)expr.accept(replaceVisitor, null); - } - } - return Conversions.convert(super.convert(expr, forOrder)); - } - - @Override - protected Predicate normalize(Predicate predicate, boolean where) { - if (predicate != null) { - predicate = (Predicate) ExpressionUtils.extract(predicate); - } - if (predicate != null) { - // transform any usage - predicate = (Predicate) predicate.accept(JPACollectionAnyVisitor.DEFAULT, new Context()); - - // transform list access - Context context = new Context(); - predicate = (Predicate) predicate.accept(ListAccessVisitor.DEFAULT, context); - for (int i = 0; i < context.paths.size(); i++) { - Path<?> path = context.paths.get(i); - if (!paths.contains(path)) { - addCondition(context, i, path, where); - } - } - return predicate; - } else { - return null; - } - } - - @SuppressWarnings("unchecked") - private void addCondition(Context context, int i, Path<?> path, boolean where) { - paths.add(path); - EntityPath<?> alias = context.replacements.get(i); - leftJoin((Expression)path.getMetadata().getParent(), context.replacements.get(i)); - Expression index = OperationImpl.create(Integer.class, JPQLOps.INDEX, alias); - Object element = path.getMetadata().getElement(); - if (!(element instanceof Expression)) { - element = ConstantImpl.create(element); - } - Predicate condition = ExpressionUtils.eq(index, (Expression)element); - if (where) { - super.where(condition); - } else { - super.having(condition); - } - } - -} diff --git a/querydsl-jpa/src/main/java/com/mysema/query/jpa/JPASubQuery.java b/querydsl-jpa/src/main/java/com/mysema/query/jpa/JPASubQuery.java deleted file mode 100644 index 1b415bc305..0000000000 --- a/querydsl-jpa/src/main/java/com/mysema/query/jpa/JPASubQuery.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa; - -import com.mysema.query.QueryMetadata; - -/** - * JPASubQuery is a subquery class for JPA - * - * @author tiwe - * - */ -public final class JPASubQuery extends AbstractJPASubQuery<JPASubQuery> { - - public JPASubQuery() { - super(); - } - - public JPASubQuery(QueryMetadata metadata) { - super(metadata); - } - -} diff --git a/querydsl-jpa/src/main/java/com/mysema/query/jpa/JPQLOps.java b/querydsl-jpa/src/main/java/com/mysema/query/jpa/JPQLOps.java deleted file mode 100644 index 16d222879c..0000000000 --- a/querydsl-jpa/src/main/java/com/mysema/query/jpa/JPQLOps.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2013, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa; - -import com.mysema.query.types.Operator; -import com.mysema.query.types.OperatorImpl; - -/** - * @author tiwe - * - */ -public final class JPQLOps { - - private static final String NS = JPQLOps.class.getName(); - - public static final Operator<Object> TREAT = new OperatorImpl<Object>(NS, "TREAT"); - - public static final Operator<Integer> INDEX = new OperatorImpl<Integer>(NS, "INDEX"); - - public static final Operator<String> TYPE = new OperatorImpl<String>(NS, "TYPE"); - - public static final Operator<Object> CAST = new OperatorImpl<Object>(NS, "CAST"); - - public static final Operator<Boolean> MEMBER_OF = new OperatorImpl<Boolean>(NS, "MEMBER_OF"); - - public static final Operator<Boolean> NOT_MEMBER_OF = new OperatorImpl<Boolean>(NS, "NOT_MEMBER_OF"); - - private JPQLOps(){} -} diff --git a/querydsl-jpa/src/main/java/com/mysema/query/jpa/JPQLQuery.java b/querydsl-jpa/src/main/java/com/mysema/query/jpa/JPQLQuery.java deleted file mode 100644 index eab1cc2e16..0000000000 --- a/querydsl-jpa/src/main/java/com/mysema/query/jpa/JPQLQuery.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa; - -import com.mysema.query.Projectable; - -/** - * Query interface for JPQL queries - * - * @author tiwe - * - */ -public interface JPQLQuery extends JPACommonQuery<JPQLQuery>, Projectable { - - /** - * Add the "fetch" flag to the last defined join - * - * Mind that collection joins might result in duplicate rows and that "inner join fetch" - * will restrict your result set. - * - * @return - */ - JPQLQuery fetch(); - - /** - * Add the "fetch all properties" flag to the last defined join. - * @return - */ - JPQLQuery fetchAll(); - -} diff --git a/querydsl-jpa/src/main/java/com/mysema/query/jpa/JPQLQueryFactory.java b/querydsl-jpa/src/main/java/com/mysema/query/jpa/JPQLQueryFactory.java deleted file mode 100644 index dc0f56987d..0000000000 --- a/querydsl-jpa/src/main/java/com/mysema/query/jpa/JPQLQueryFactory.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2013, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa; - -import com.mysema.query.QueryFactory; -import com.mysema.query.dml.DeleteClause; -import com.mysema.query.dml.UpdateClause; -import com.mysema.query.types.EntityPath; - -/** - * Common interface for JPA related QueryFactory implementations - * - * @author tiwe - * - */ -public interface JPQLQueryFactory extends QueryFactory<JPQLQuery, JPQLSubQuery> { - - /** - * Create a new DELETE clause - * - * @param path - * @return - */ - DeleteClause<?> delete(EntityPath<?> path); - - /** - * Create a new Query with the given source - * - * @param from - * @return - */ - JPQLQuery from(EntityPath<?> from); - - /** - * Create a new UPDATE clause - * - * @param path - * @return - */ - UpdateClause<?> update(EntityPath<?> path); - -} \ No newline at end of file diff --git a/querydsl-jpa/src/main/java/com/mysema/query/jpa/JPQLSerializer.java b/querydsl-jpa/src/main/java/com/mysema/query/jpa/JPQLSerializer.java deleted file mode 100644 index b92feff66b..0000000000 --- a/querydsl-jpa/src/main/java/com/mysema/query/jpa/JPQLSerializer.java +++ /dev/null @@ -1,510 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.EnumMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import javax.annotation.Nullable; -import javax.persistence.DiscriminatorValue; -import javax.persistence.Entity; -import javax.persistence.EntityManager; -import javax.persistence.EnumType; -import javax.persistence.Enumerated; -import javax.persistence.PersistenceUnitUtil; -import javax.persistence.metamodel.EntityType; -import javax.persistence.metamodel.Metamodel; -import javax.persistence.metamodel.SingularAttribute; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; -import com.mysema.query.JoinExpression; -import com.mysema.query.JoinType; -import com.mysema.query.QueryMetadata; -import com.mysema.query.support.SerializerBase; -import com.mysema.query.types.*; -import com.mysema.util.MathUtils; - -/** - * JPQLSerializer serializes Querydsl expressions into JPQL syntax. - * - * @author tiwe - */ -public class JPQLSerializer extends SerializerBase<JPQLSerializer> { - - private static final Set<Operator<?>> NUMERIC = ImmutableSet.<Operator<?>>of( - Ops.ADD, Ops.SUB, Ops.MULT, Ops.DIV, - Ops.LT, Ops.LOE, Ops.GT, Ops.GOE, Ops.BETWEEN); - - private static final String COMMA = ", "; - - private static final String DELETE = "delete from "; - - private static final String FROM = "from "; - - private static final String GROUP_BY = "\ngroup by "; - - private static final String HAVING = "\nhaving "; - - private static final String ORDER_BY = "\norder by "; - - private static final String SELECT = "select "; - - private static final String SELECT_COUNT = "select count("; - - private static final String SELECT_COUNT_DISTINCT = "select count(distinct "; - - private static final String SELECT_DISTINCT = "select distinct "; - - private static final String SET = "\nset "; - - private static final String UPDATE = "update "; - - private static final String WHERE = "\nwhere "; - - private static final String WITH = " with "; - - private static final String ON = " on "; - - private static final Map<JoinType, String> joinTypes = new EnumMap<JoinType, String>(JoinType.class); - - private final JPQLTemplates templates; - - private final EntityManager entityManager; - - private boolean inProjection = false; - - static{ - joinTypes.put(JoinType.DEFAULT, COMMA); - joinTypes.put(JoinType.FULLJOIN, "\n full join "); - joinTypes.put(JoinType.INNERJOIN, "\n inner join "); - joinTypes.put(JoinType.JOIN, "\n inner join "); - joinTypes.put(JoinType.LEFTJOIN, "\n left join "); - joinTypes.put(JoinType.RIGHTJOIN, "\n right join "); - } - - private boolean wrapElements = false; - - public JPQLSerializer(JPQLTemplates templates) { - this(templates, null); - } - - public JPQLSerializer(JPQLTemplates templates, EntityManager em) { - super(templates); - this.templates = templates; - this.entityManager = em; - } - - private String getEntityName(Class<?> clazz) { - final Entity entityAnnotation = clazz.getAnnotation(Entity.class); - if (entityAnnotation != null && entityAnnotation.name().length() > 0) { - return entityAnnotation.name(); - } else if (clazz.getPackage() != null) { - String pn = clazz.getPackage().getName(); - return clazz.getName().substring(pn.length() + 1); - } else { - return clazz.getName(); - } - } - - private void handleJoinTarget(JoinExpression je) { - // type specifier - if (je.getTarget() instanceof EntityPath<?>) { - final EntityPath<?> pe = (EntityPath<?>) je.getTarget(); - if (pe.getMetadata().isRoot()) { - append(getEntityName(pe.getType())); - append(" "); - } - handle(je.getTarget()); - } else if (je.getTarget() instanceof Operation) { - Operation<?> op = (Operation)je.getTarget(); - if (op.getOperator() == Ops.ALIAS) { - boolean treat = false; - if (Collection.class.isAssignableFrom(op.getArg(0).getType())) { - if (op.getArg(0) instanceof CollectionExpression) { - Class<?> par = ((CollectionExpression)op.getArg(0)).getParameter(0); - treat = !par.equals(op.getArg(1).getType()); - } - } else if (Map.class.isAssignableFrom(op.getArg(0).getType())) { - if (op.getArg(0) instanceof MapExpression) { - Class<?> par = ((MapExpression)op.getArg(0)).getParameter(1); - treat = !par.equals(op.getArg(1).getType()); - } - } else { - treat = !op.getArg(0).getType().equals(op.getArg(1).getType()); - } - if (treat) { - Expression<?> entityName = ConstantImpl.create(getEntityName(op.getArg(1).getType())); - Expression<?> t = OperationImpl.create(op.getType(), JPQLOps.TREAT, op.getArg(0), entityName); - op = OperationImpl.create(op.getType(), Ops.ALIAS, t, op.getArg(1)); - } - } - handle(op); - } else { - handle(je.getTarget()); - } - } - - public void serialize(QueryMetadata metadata, boolean forCountRow, @Nullable String projection) { - final List<? extends Expression<?>> select = metadata.getProjection(); - final List<JoinExpression> joins = metadata.getJoins(); - final Predicate where = metadata.getWhere(); - final List<? extends Expression<?>> groupBy = metadata.getGroupBy(); - final Predicate having = metadata.getHaving(); - final List<OrderSpecifier<?>> orderBy = metadata.getOrderBy(); - - // select - boolean inProjectionOrig = inProjection; - inProjection = true; - if (projection != null) { - append(SELECT).append(projection).append("\n"); - - } else if (forCountRow) { - if (!metadata.isDistinct()) { - append(SELECT_COUNT); - } else { - append(SELECT_COUNT_DISTINCT); - } - if(!select.isEmpty()) { - if (select.get(0) instanceof FactoryExpression) { - handle(joins.get(0).getTarget()); - } else { - // TODO : make sure this works - handle(COMMA, select); - } - } else { - handle(joins.get(0).getTarget()); - } - append(")\n"); - - } else { - if (!metadata.isDistinct()) { - append(SELECT); - } else { - append(SELECT_DISTINCT); - } - if (!select.isEmpty()) { - handle(COMMA, select); - } else { - handle(metadata.getJoins().get(0).getTarget()); - } - append("\n"); - - } - inProjection = inProjectionOrig; - - // from - append(FROM); - serializeSources(forCountRow, joins); - - // where - if (where != null) { - append(WHERE).handle(where); - } - - // group by - if (!groupBy.isEmpty()) { - append(GROUP_BY).handle(COMMA, groupBy); - } - - // having - if (having != null) { - append(HAVING).handle(having); - } - - // order by - if (!orderBy.isEmpty() && !forCountRow) { - append(ORDER_BY); - boolean first = true; - for (final OrderSpecifier<?> os : orderBy) { - if (!first) { - append(COMMA); - } - handle(os.getTarget()); - append(os.getOrder() == Order.ASC ? " asc" : " desc"); - if (os.getNullHandling() == OrderSpecifier.NullHandling.NullsFirst) { - append(" nulls first"); - } else if (os.getNullHandling() == OrderSpecifier.NullHandling.NullsLast) { - append(" nulls last"); - } - first = false; - } - } - } - - public void serializeForDelete(QueryMetadata md) { - append(DELETE); - handleJoinTarget(md.getJoins().get(0)); - if (md.getWhere() != null) { - append(WHERE).handle(md.getWhere()); - } - } - - public void serializeForUpdate(QueryMetadata md) { - append(UPDATE); - handleJoinTarget(md.getJoins().get(0)); - append(SET); - handle(COMMA, md.getProjection()); - if (md.getWhere() != null) { - append(WHERE).handle(md.getWhere()); - } - } - - private void serializeSources(boolean forCountRow, List<JoinExpression> joins) { - for (int i = 0; i < joins.size(); i++) { - final JoinExpression je = joins.get(i); - if (i > 0) { - append(joinTypes.get(je.getType())); - } - if (je.hasFlag(JPAQueryMixin.FETCH) && !forCountRow) { - handle(JPAQueryMixin.FETCH); - } - handleJoinTarget(je); - // XXX Hibernate specific flag - if (je.hasFlag(JPAQueryMixin.FETCH_ALL_PROPERTIES) && !forCountRow) { - handle(JPAQueryMixin.FETCH_ALL_PROPERTIES); - } - - if (je.getCondition() != null) { - append(templates.isWithForOn() ? WITH : ON); - handle(je.getCondition()); - } - } - } - - @Override - public void visitConstant(Object constant) { - boolean wrap = templates.wrapConstant(constant); - if (wrap) { - append("("); - } - append("?"); - if (!getConstantToLabel().containsKey(constant)) { - final String constLabel = String.valueOf(getConstantToLabel().size()+1); - getConstantToLabel().put(constant, constLabel); - append(constLabel); - } else { - append(getConstantToLabel().get(constant)); - } - if (wrap) { - append(")"); - } - } - - @Override - public Void visit(ParamExpression<?> param, Void context) { - append("?"); - if (!getConstantToLabel().containsKey(param)) { - final String paramLabel = String.valueOf(getConstantToLabel().size()+1); - getConstantToLabel().put(param, paramLabel); - append(paramLabel); - } else { - append(getConstantToLabel().get(param)); - } - return null; - } - - @Override - public Void visit(SubQueryExpression<?> query, Void context) { - append("("); - serialize(query.getMetadata(), false, null); - append(")"); - return null; - } - - @Override - public Void visit(Path<?> expr, Void context) { - // only wrap a PathCollection, if it the pathType is PROPERTY - boolean wrap = wrapElements - && (Collection.class.isAssignableFrom(expr.getType()) || Map.class.isAssignableFrom(expr.getType())) - && expr.getMetadata().getPathType().equals(PathType.PROPERTY); - if (wrap) { - append("elements("); - } - super.visit(expr, context); - if (wrap) { - append(")"); - } - return null; - } - - @Override - @SuppressWarnings("unchecked") - protected void visitOperation(Class<?> type, Operator<?> operator, List<? extends Expression<?>> args) { - boolean old = wrapElements; - wrapElements = templates.wrapElements(operator); - - if (operator == Ops.EQ && args.get(1) instanceof Operation && - ((Operation)args.get(1)).getOperator() == Ops.QuantOps.ANY) { - args = ImmutableList.<Expression<?>>of(args.get(0), ((Operation)args.get(1)).getArg(0)); - visitOperation(type, Ops.IN, args); - - } else if (operator == Ops.NE && args.get(1) instanceof Operation && - ((Operation)args.get(1)).getOperator() == Ops.QuantOps.ANY) { - args = ImmutableList.<Expression<?>>of(args.get(0), ((Operation)args.get(1)).getArg(0)); - visitOperation(type, Ops.NOT_IN, args); - - } else if (operator == Ops.IN || operator == Ops.NOT_IN) { - if (args.get(1) instanceof Path) { - visitAnyInPath(type, operator, args); - } else if (args.get(0) instanceof Path && args.get(1) instanceof Constant) { - visitPathInCollection(type, operator, args); - } else { - super.visitOperation(type, operator, args); - } - - } else if (operator == Ops.INSTANCE_OF) { - visitInstanceOf(type, operator, args); - - } else if (operator == Ops.NUMCAST) { - visitNumCast(args); - - } else if (operator == Ops.EXISTS && args.get(0) instanceof SubQueryExpression) { - final SubQueryExpression subQuery = (SubQueryExpression) args.get(0); - append("exists ("); - serialize(subQuery.getMetadata(), false, templates.getExistsProjection()); - append(")"); - - } else if (operator == Ops.MATCHES || operator == Ops.MATCHES_IC) { - super.visitOperation(type, Ops.LIKE, - ImmutableList.of(args.get(0), ExpressionUtils.regexToLike((Expression<String>) args.get(1)))); - - } else if (operator == Ops.LIKE && args.get(1) instanceof Constant) { - final String escape = String.valueOf(templates.getEscapeChar()); - final String escaped = args.get(1).toString().replace(escape, escape + escape); - super.visitOperation(String.class, Ops.LIKE, - ImmutableList.of(args.get(0), ConstantImpl.create(escaped))); - - } else if (NUMERIC.contains(operator)) { - super.visitOperation(type, operator, normalizeNumericArgs(args)); - - } else { - super.visitOperation(type, operator, args); - } - - wrapElements = old; - } - - private void visitNumCast(List<? extends Expression<?>> args) { - final Class<?> targetType = (Class<?>) ((Constant<?>) args.get(1)).getConstant(); - final String typeName = templates.getTypeForCast(targetType); - visitOperation(targetType, JPQLOps.CAST, ImmutableList.of(args.get(0), ConstantImpl.create(typeName))); - } - - private void visitInstanceOf(Class<?> type, Operator<?> operator, - List<? extends Expression<?>> args) { - if (templates.isTypeAsString()) { - final List<Expression<?>> newArgs = new ArrayList<Expression<?>>(args); - final Class<?> cl = ((Class<?>) ((Constant<?>) newArgs.get(1)).getConstant()); - // use discriminator value instead of fqnm - if (cl.getAnnotation(DiscriminatorValue.class) != null) { - newArgs.set(1, ConstantImpl.create(cl.getAnnotation(DiscriminatorValue.class).value())); - } else { - newArgs.set(1, ConstantImpl.create(cl.getSimpleName())); - } - super.visitOperation(type, operator, newArgs); - } else { - super.visitOperation(type, operator, args); - } - } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - private void visitPathInCollection(Class<?> type, Operator<?> operator, - List<? extends Expression<?>> args) { - // NOTE turns entityPath in collection into entityPath.id in (collection of ids) - if (entityManager != null && !templates.isPathInEntitiesSupported() && args.get(0).getType().isAnnotationPresent(Entity.class)) { - Path<?> lhs = (Path<?>) args.get(0); - Constant<?> rhs = (Constant<?>) args.get(1); - final Metamodel metamodel = entityManager.getMetamodel(); - final PersistenceUnitUtil util = entityManager.getEntityManagerFactory().getPersistenceUnitUtil(); - final EntityType<?> entityType = metamodel.entity(args.get(0).getType()); - if (entityType.hasSingleIdAttribute()) { - SingularAttribute<?,?> id = getIdProperty(entityType); - // turn lhs into id path - lhs = new PathImpl(id.getJavaType(), lhs, id.getName()); - // turn rhs into id collection - Set ids = new HashSet(); - for (Object entity : (Collection<?>)rhs.getConstant()) { - ids.add(util.getIdentifier(entity)); - } - rhs = ConstantImpl.create(ids); - args = ImmutableList.of(lhs, rhs); - } - } - super.visitOperation(type, operator, args); - } - - @SuppressWarnings("rawtypes") - private SingularAttribute<?,?> getIdProperty(EntityType entity) { - final Set<SingularAttribute> singularAttributes = entity.getSingularAttributes(); - for (final SingularAttribute singularAttribute : singularAttributes) { - if (singularAttribute.isId()) { - return singularAttribute; - } - } - return null; - } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - private void visitAnyInPath(Class<?> type, Operator<?> operator, List<? extends Expression<?>> args) { - if (!templates.isEnumInPathSupported() && args.get(0) instanceof Constant && Enum.class.isAssignableFrom(args.get(0).getType())) { - final Enumerated enumerated = ((Path)args.get(1)).getAnnotatedElement().getAnnotation(Enumerated.class); - final Enum constant = (Enum)((Constant)args.get(0)).getConstant(); - if (enumerated == null || enumerated.value() == EnumType.ORDINAL) { - args = ImmutableList.of(ConstantImpl.create(constant.ordinal()), args.get(1)); - } else { - args = ImmutableList.of(ConstantImpl.create(constant.name()), args.get(1)); - } - } - super.visitOperation(type, - operator == Ops.IN ? JPQLOps.MEMBER_OF : JPQLOps.NOT_MEMBER_OF, - args); - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - private List<? extends Expression<?>> normalizeNumericArgs(List<? extends Expression<?>> args) { - boolean hasConstants = false; - Class<? extends Number> numType = null; - for (Expression<?> arg : args) { - if (Number.class.isAssignableFrom(arg.getType())) { - if (arg instanceof Constant) { - hasConstants = true; - } else { - numType = (Class<? extends Number>) arg.getType(); - } - } - } - if (hasConstants && numType != null) { - final List<Expression<?>> newArgs = new ArrayList<Expression<?>>(args.size()); - for (final Expression<?> arg : args) { - if (arg instanceof Constant && Number.class.isAssignableFrom(arg.getType()) - && !arg.getType().equals(numType)) { - final Number number = (Number) ((Constant)arg).getConstant(); - newArgs.add(ConstantImpl.create(MathUtils.cast(number, (Class)numType))); - } else { - newArgs.add(arg); - } - } - return newArgs; - } else { - return args; - } - } - -} diff --git a/querydsl-jpa/src/main/java/com/mysema/query/jpa/JPQLSubQuery.java b/querydsl-jpa/src/main/java/com/mysema/query/jpa/JPQLSubQuery.java deleted file mode 100644 index a3032829ab..0000000000 --- a/querydsl-jpa/src/main/java/com/mysema/query/jpa/JPQLSubQuery.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2013, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa; - -import com.mysema.query.Detachable; - -/** - * @author tiwe - * - */ -public interface JPQLSubQuery extends Detachable, JPACommonQuery<JPQLSubQuery>{ - -} diff --git a/querydsl-jpa/src/main/java/com/mysema/query/jpa/JPQLTemplates.java b/querydsl-jpa/src/main/java/com/mysema/query/jpa/JPQLTemplates.java deleted file mode 100644 index a2179d238e..0000000000 --- a/querydsl-jpa/src/main/java/com/mysema/query/jpa/JPQLTemplates.java +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa; - -import javax.annotation.Nullable; - -import com.mysema.query.types.Operator; -import com.mysema.query.types.Ops; -import com.mysema.query.types.PathType; -import com.mysema.query.types.Templates; - -/** - * JPQLTemplates extends {@link Templates} to provide operator patterns for JPQL - * serialization - * - * @author tiwe - * @see HQLTemplates - * @see EclipseLinkTemplates - */ -public class JPQLTemplates extends Templates { - - public static final char DEFAULT_ESCAPE = '!'; - - public static final JPQLTemplates DEFAULT = new JPQLTemplates(); - - private final QueryHandler queryHandler; - - protected JPQLTemplates() { - this(DEFAULT_ESCAPE, DefaultQueryHandler.DEFAULT); - } - - protected JPQLTemplates(char escape) { - this(escape, DefaultQueryHandler.DEFAULT); - } - - protected JPQLTemplates(char escape, QueryHandler queryHandler) { - super(escape); - this.queryHandler = queryHandler; - - add(Ops.CASE, "case {0} end"); - add(Ops.CASE_WHEN, "when {0} then {1} {2}", 0); - add(Ops.CASE_ELSE, "else {0}", 0); - - //CHECKSTYLE:OFF - // boolean - add(Ops.AND, "{0} and {1}", 36); - add(Ops.NOT, "not {0}", 3); - add(Ops.OR, "{0} or {1}", 38); - add(Ops.XNOR, "{0} xnor {1}", 39); - add(Ops.XOR, "{0} xor {1}", 39); - - // comparison - add(Ops.BETWEEN, "{0} between {1} and {2}", 30); - - // numeric - add(Ops.MathOps.SQRT, "sqrt({0})"); - add(Ops.MOD, "mod({0},{1})", 0); - - // various - add(Ops.NE, "{0} <> {1}", 25); - add(Ops.IS_NULL, "{0} is null", 26); - add(Ops.IS_NOT_NULL, "{0} is not null", 26); - add(JPQLOps.CAST, "cast({0} as {1s})"); - add(Ops.NUMCAST, "cast({0} as {1s})"); - - // collection - add(JPQLOps.MEMBER_OF, "{0} member of {1}"); - add(JPQLOps.NOT_MEMBER_OF, "{0} not member of {1}"); - - add(Ops.IN, "{0} in {1}"); - add(Ops.NOT_IN, "{0} not in {1}"); - add(Ops.COL_IS_EMPTY, "{0} is empty"); - add(Ops.COL_SIZE, "size({0})"); - add(Ops.ARRAY_SIZE, "size({0})"); - - // string - add(Ops.LIKE, "{0} like {1} escape '"+escape+"'",1); - add(Ops.CONCAT, "concat({0},{1})",0); - add(Ops.MATCHES, "{0} like {1} escape '"+escape+"'", 27); // TODO : support real regexes - add(Ops.MATCHES_IC, "{0} like {1} escape '"+escape+"'", 27); // TODO : support real regexes - add(Ops.LOWER, "lower({0})"); - add(Ops.SUBSTR_1ARG, "substring({0},{1s}+1)", 1); - add(Ops.SUBSTR_2ARGS, "substring({0},{1s}+1,{2s}-{1s})", 1); - add(Ops.TRIM, "trim({0})"); - add(Ops.UPPER, "upper({0})"); - add(Ops.EQ_IGNORE_CASE, "{0l} = {1l}"); - add(Ops.CHAR_AT, "cast(substring({0},{1s}+1,1) as char)"); - add(Ops.STRING_IS_EMPTY, "length({0}) = 0"); - - add(Ops.STRING_CONTAINS, "{0} like {%1%} escape '"+escape+"'"); - add(Ops.STRING_CONTAINS_IC, "{0l} like {%%1%%} escape '"+escape+"'"); - add(Ops.ENDS_WITH, "{0} like {%1} escape '"+escape+"'"); - add(Ops.ENDS_WITH_IC, "{0l} like {%%1} escape '"+escape+"'"); - add(Ops.STARTS_WITH, "{0} like {1%} escape '"+escape+"'"); - add(Ops.STARTS_WITH_IC, "{0l} like {1%%} escape '"+escape+"'"); - add(Ops.INDEX_OF, "locate({1},{0})-1"); - add(Ops.INDEX_OF_2ARGS, "locate({1},{0},{2s}+1)-1"); - - // date time - add(Ops.DateTimeOps.SYSDATE, "sysdate"); - add(Ops.DateTimeOps.CURRENT_DATE, "current_date"); - add(Ops.DateTimeOps.CURRENT_TIME, "current_time"); - add(Ops.DateTimeOps.CURRENT_TIMESTAMP, "current_timestamp"); - - add(Ops.DateTimeOps.MILLISECOND, "0"); // NOT supported in HQL - add(Ops.DateTimeOps.SECOND, "second({0})"); - add(Ops.DateTimeOps.MINUTE, "minute({0})"); - add(Ops.DateTimeOps.HOUR, "hour({0})"); - add(Ops.DateTimeOps.DAY_OF_MONTH, "day({0})"); - add(Ops.DateTimeOps.MONTH, "month({0})"); - add(Ops.DateTimeOps.YEAR, "year({0})"); - - add(Ops.DateTimeOps.YEAR_MONTH, "year({0}) * 100 + month({0})"); - - // path types - add(PathType.PROPERTY, "{0}.{1s}"); - add(PathType.VARIABLE, "{0s}"); - - // case for eq - add(Ops.CASE_EQ, "case {1} end"); - add(Ops.CASE_EQ_WHEN, "when {0} = {1} then {2} {3}"); - add(Ops.CASE_EQ_ELSE, "else {0}"); - - add(Ops.INSTANCE_OF, "type({0}) = {1}"); - add(JPQLOps.TYPE, "type({0})"); - add(JPQLOps.INDEX, "index({0})"); - add(JPQLOps.TREAT, "treat({0} as {1s})"); - - //CHECKSTYLE:ON - } - - public boolean wrapElements(Operator<?> operator) { - return false; - } - - public boolean isTypeAsString() { - // TODO : get rid of this when Hibernate supports type(alias) - return false; - } - - public String getTypeForCast(Class<?> cl) { - return cl.getSimpleName().toLowerCase(); - } - - public boolean isEnumInPathSupported() { - return true; - } - - public boolean isPathInEntitiesSupported() { - return true; - } - - public boolean isSelect1Supported() { - return false; - } - - @Nullable - public String getExistsProjection() { - return null; - } - - public boolean wrapConstant(Object constant) { - // related : https://hibernate.onjira.com/browse/HHH-6913 - return false; - } - - public boolean isWithForOn() { - return false; - } - - public QueryHandler getQueryHandler() { - return queryHandler; - } - -} diff --git a/querydsl-jpa/src/main/java/com/mysema/query/jpa/NativeSQLSerializer.java b/querydsl-jpa/src/main/java/com/mysema/query/jpa/NativeSQLSerializer.java deleted file mode 100644 index 76611e4dff..0000000000 --- a/querydsl-jpa/src/main/java/com/mysema/query/jpa/NativeSQLSerializer.java +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.mysema.query.QueryMetadata; -import com.mysema.query.sql.*; -import com.mysema.query.types.*; - -import java.util.*; - -/** - * NativeSQLSerializer extends the SQLSerializer class to extract referenced entity paths and change - * some serialization formats - * - * @author tiwe - * - */ -public final class NativeSQLSerializer extends SQLSerializer { - - private final Map<Expression<?>, String> aliases = Maps.newHashMap(); - - private final boolean wrapEntityProjections; - - public NativeSQLSerializer(Configuration configuration) { - this(configuration, false); - } - - public NativeSQLSerializer(Configuration configuration, boolean wrapEntityProjections) { - super(configuration); - this.wrapEntityProjections = wrapEntityProjections; - } - - private boolean isAlias(Expression<?> expr) { - return expr instanceof Operation && ((Operation<?>)expr).getOperator() == Ops.ALIAS; - } - - public Map<Expression<?>, String> getAliases() { - return aliases; - } - - private boolean isAllExpression(Expression<?> expr) { - if (expr instanceof Operation) { - return ((Operation<?>)expr).getOperator() == SQLOps.ALL; - } else if (expr instanceof TemplateExpression) { - return ((TemplateExpression<?>)expr).getTemplate().toString().equals("*"); - } else { - return false; - } - } - - @Override - public void serialize(QueryMetadata metadata, boolean forCountRow) { - // TODO get rid of this wrapping when Hibernate doesn't require unique aliases anymore - int size = metadata.getProjection().size(); - Expression<?>[] args = metadata.getProjection().toArray(new Expression<?>[size]); - boolean modified = false; - Set<String> used = new HashSet<String>(); - for (int i = 0; i < args.length; i++) { - if (args[i] instanceof Path) { - Path<?> path = (Path<?>)args[i]; - if (!used.add(path.getMetadata().getName())) { - String alias = "col__"+(i+1); - aliases.put(args[i], alias); - args[i] = ExpressionUtils.as(args[i], alias); - modified = true; - } else { - aliases.put(path, ColumnMetadata.getName(path)); - } - } else if (args[i] instanceof FactoryExpression) { - FactoryExpression<?> factoryExpr = (FactoryExpression<?>)args[i]; - List<Expression<?>> fargs = Lists.newArrayList(factoryExpr.getArgs()); - for (int j = 0; j < fargs.size(); j++) { - if (fargs.get(j) instanceof Path) { - Path<?> path = (Path<?>) fargs.get(j); - String columnName = ColumnMetadata.getName(path); - if (!used.add(columnName)) { - String alias = "col__"+(i+1)+"_"+(j+1); - aliases.put(path, alias); - fargs.set(j, ExpressionUtils.as(fargs.get(j), alias)); - } else { - aliases.put(path, columnName); - } - } else if (isAlias(fargs.get(j))) { - Operation<?> operation = (Operation<?>)fargs.get(j); - aliases.put(operation, operation.getArg(1).toString()); - } else if (!isAllExpression(fargs.get(j))) { - String alias = "col__"+(i+1)+"_"+(j+1); - aliases.put(fargs.get(j), alias); - fargs.set(j, ExpressionUtils.as(fargs.get(j), alias)); - } - } - args[i] = new QTuple(ImmutableList.copyOf(fargs)); - modified = true; - } else if (isAlias(args[i])) { - Operation<?> operation = (Operation<?>)args[i]; - aliases.put(operation, operation.getArg(1).toString()); - } else { - // https://github.com/mysema/querydsl/issues/80 - if (!isAllExpression(args[i])) { - String alias = "col__"+(i+1); - aliases.put(args[i], alias); - args[i] = ExpressionUtils.as(args[i], alias); - modified = true; - } - } - } - if (modified) { - metadata = metadata.clone(); - metadata.clearProjection(); - for (Expression<?> arg : args) { - metadata.addProjection(arg); - } - } - super.serialize(metadata, forCountRow); - } - - @Override - public void visitConstant(Object constant) { - if (constant instanceof Collection<?>) { - append("("); - boolean first = true; - for (Object element : ((Collection<?>)constant)) { - if (!first) { - append(", "); - } - visitConstant(element); - first = false; - } - append(")"); - } else if (!getConstantToLabel().containsKey(constant)) { - String constLabel = String.valueOf(getConstantToLabel().size() + 1); - getConstantToLabel().put(constant, constLabel); - append("?"+constLabel); - } else { - append("?"+getConstantToLabel().get(constant)); - } - } - - @Override - protected void visitOperation(Class<?> type, Operator<?> operator, List<? extends Expression<?>> args) { - if (operator == SQLOps.ALL - && !RelationalPath.class.isInstance(args.get(0)) - && wrapEntityProjections) { - append("{"); - super.visitOperation(type, operator, args); - append("}"); - } else { - super.visitOperation(type, operator, args); - } - } - -} diff --git a/querydsl-jpa/src/main/java/com/mysema/query/jpa/OpenJPATemplates.java b/querydsl-jpa/src/main/java/com/mysema/query/jpa/OpenJPATemplates.java deleted file mode 100644 index fbef17757a..0000000000 --- a/querydsl-jpa/src/main/java/com/mysema/query/jpa/OpenJPATemplates.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa; - -import com.mysema.query.types.Ops; -import com.mysema.query.types.PathType; - -/** - * OpenJPATemplates extends JPQLTemplates with OpenJPA specific extensions - * - * @author tiwe - * - */ -public class OpenJPATemplates extends JPQLTemplates{ - - public static final OpenJPATemplates DEFAULT = new OpenJPATemplates(); - - public OpenJPATemplates() { - this(DEFAULT_ESCAPE); - add(PathType.VARIABLE, "{0s}_"); - add(Ops.ALIAS, "{0} {1}"); - add(Ops.NEGATE, "-1 * {0}", 7); - } - - public OpenJPATemplates(char escape) { - super(escape); - } - -} diff --git a/querydsl-jpa/src/main/java/com/mysema/query/jpa/QueryHandler.java b/querydsl-jpa/src/main/java/com/mysema/query/jpa/QueryHandler.java deleted file mode 100644 index 705126e6eb..0000000000 --- a/querydsl-jpa/src/main/java/com/mysema/query/jpa/QueryHandler.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2013, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa; - -import javax.annotation.Nullable; -import javax.persistence.Query; - -import com.mysema.commons.lang.CloseableIterator; -import com.mysema.query.types.FactoryExpression; - -/** - * QueryHandler provides injection of provider specific functionality into the query logic - * - * @author tiwe - * - */ -public interface QueryHandler { - - /** - * @return - */ - boolean createNativeQueryTyped(); - - /** - * Iterate the results with the optional projection - * - * @param query - * @return - */ - <T> CloseableIterator<T> iterate(Query query, @Nullable FactoryExpression<?> projection); - - /** - * Add the given scalar to the given native query - * - * @param query - * @param alias - * @param type - */ - void addScalar(Query query, String alias, Class<?> type); - - /** - * Add the given entity to the given native query - * - * @param query - * @param alias - * @param type - */ - void addEntity(Query query, String alias, Class<?> type); - - /** - * Transform the results of the given query using the given factory expression - * - * @param query - * @param projection - * @return - */ - boolean transform(Query query, FactoryExpression<?> projection); - - /** - * @return - */ - boolean wrapEntityProjections(); - -} diff --git a/querydsl-jpa/src/main/java/com/mysema/query/jpa/hibernate/AbstractHibernateQuery.java b/querydsl-jpa/src/main/java/com/mysema/query/jpa/hibernate/AbstractHibernateQuery.java deleted file mode 100644 index f84eeb5299..0000000000 --- a/querydsl-jpa/src/main/java/com/mysema/query/jpa/hibernate/AbstractHibernateQuery.java +++ /dev/null @@ -1,447 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa.hibernate; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.annotation.Nullable; - -import org.hibernate.FlushMode; -import org.hibernate.LockMode; -import org.hibernate.Query; -import org.hibernate.ScrollMode; -import org.hibernate.ScrollableResults; -import org.hibernate.Session; -import org.hibernate.StatelessSession; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.mysema.commons.lang.CloseableIterator; -import com.mysema.query.DefaultQueryMetadata; -import com.mysema.query.NonUniqueResultException; -import com.mysema.query.QueryException; -import com.mysema.query.QueryMetadata; -import com.mysema.query.QueryModifiers; -import com.mysema.query.SearchResults; -import com.mysema.query.Tuple; -import com.mysema.query.jpa.FactoryExpressionTransformer; -import com.mysema.query.jpa.HQLTemplates; -import com.mysema.query.jpa.JPAQueryBase; -import com.mysema.query.jpa.JPQLSerializer; -import com.mysema.query.jpa.JPQLTemplates; -import com.mysema.query.jpa.ScrollableResultsIterator; -import com.mysema.query.types.Expression; -import com.mysema.query.types.FactoryExpression; -import com.mysema.query.types.FactoryExpressionUtils; -import com.mysema.query.types.Path; - -/** - * Abstract base class for Hibernate API based implementations of the JPQL interface - * - * @author tiwe - * - * @param <Q> - */ -public abstract class AbstractHibernateQuery<Q extends AbstractHibernateQuery<Q>> extends JPAQueryBase<Q> { - - private static final Logger logger = LoggerFactory.getLogger(HibernateQuery.class); - - @Nullable - protected Boolean cacheable, readOnly; - - @Nullable - protected String cacheRegion, comment; - - protected int fetchSize = 0; - - protected final Map<Path<?>,LockMode> lockModes = new HashMap<Path<?>,LockMode>(); - - @Nullable - protected FlushMode flushMode; - - private final SessionHolder session; - - protected int timeout = 0; - - public AbstractHibernateQuery(Session session) { - this(new DefaultSessionHolder(session), HQLTemplates.DEFAULT, new DefaultQueryMetadata()); - } - - public AbstractHibernateQuery(SessionHolder session, JPQLTemplates patterns, QueryMetadata metadata) { - super(metadata, patterns); - this.session = session; - } - - @Override - public long count() { - QueryModifiers modifiers = getMetadata().getModifiers(); - Query query = createQuery(modifiers, true); - reset(); - Long rv = (Long)query.uniqueResult(); - if (rv != null) { - return rv.longValue(); - } else { - throw new QueryException("Query returned null"); - } - } - - /** - * Expose the original Hibernate query for the given projection - * - * @param expr - * @return - */ - public Query createQuery(Expression<?> expr) { - queryMixin.addProjection(expr); - return createQuery(getMetadata().getModifiers(), false); - } - - /** - * Expose the original Hibernate query for the given projection - * - * @param expr1 - * @param expr2 - * @param rest - * @return - */ - public Query createQuery(Expression<?> expr1, Expression<?> expr2, Expression<?>... rest) { - queryMixin.addProjection(expr1); - queryMixin.addProjection(expr2); - queryMixin.addProjection(rest); - return createQuery(getMetadata().getModifiers(), false); - } - - /** - * Expose the original Hibernate query for the given projection - * - * @param args - * @return - */ - public Query createQuery(Expression<?>[] args) { - queryMixin.addProjection(args); - return createQuery(getMetadata().getModifiers(), false); - } - - private Query createQuery(@Nullable QueryModifiers modifiers, boolean forCount) { - JPQLSerializer serializer = serialize(forCount); - String queryString = serializer.toString(); - logQuery(queryString); - Query query = session.createQuery(queryString); - HibernateUtil.setConstants(query, serializer.getConstantToLabel(), getMetadata().getParams()); - if (fetchSize > 0) { - query.setFetchSize(fetchSize); - } - if (timeout > 0) { - query.setTimeout(timeout); - } - if (cacheable != null) { - query.setCacheable(cacheable); - } - if (cacheRegion != null) { - query.setCacheRegion(cacheRegion); - } - if (comment != null) { - query.setComment(comment); - } - if (readOnly != null) { - query.setReadOnly(readOnly); - } - for (Map.Entry<Path<?>, LockMode> entry : lockModes.entrySet()) { - query.setLockMode(entry.getKey().toString(), entry.getValue()); - } - if (flushMode != null) { - query.setFlushMode(flushMode); - } - - if (modifiers != null && modifiers.isRestricting()) { - Integer limit = modifiers.getLimitAsInteger(); - Integer offset = modifiers.getOffsetAsInteger(); - if (limit != null) { - query.setMaxResults(limit.intValue()); - } - if (offset != null) { - query.setFirstResult(offset.intValue()); - } - } - - // set transformer, if necessary - List<? extends Expression<?>> projection = getMetadata().getProjection(); - if (projection.size() == 1 && !forCount) { - Expression<?> expr = projection.get(0); - if (expr instanceof FactoryExpression<?>) { - query.setResultTransformer(new FactoryExpressionTransformer((FactoryExpression<?>) projection.get(0))); - } - } else if (!forCount) { - FactoryExpression<?> proj = FactoryExpressionUtils.wrap(projection); - if (proj != null) { - query.setResultTransformer(new FactoryExpressionTransformer(proj)); - } - } - return query; - } - - /** - * Return the query results as an <tt>Iterator</tt>.<br> - * <br> - * Entities returned as results are initialized on demand. The first - * SQL query returns identifiers only.<br> - */ - @Override - public CloseableIterator<Tuple> iterate(Expression<?>... args) { - return iterate(queryMixin.createProjection(args)); - } - - /** - * Return the query results as an <tt>Iterator</tt>. If the query - * contains multiple results pre row, the results are returned in - * an instance of <tt>Object[]</tt>.<br> - * <br> - * Entities returned as results are initialized on demand. The first - * SQL query returns identifiers only.<br> - */ - @Override - public <RT> CloseableIterator<RT> iterate(Expression<RT> projection) { - Query query = createQuery(projection); - reset(); - ScrollableResults results = query.scroll(ScrollMode.FORWARD_ONLY); - return new ScrollableResultsIterator<RT>(results); - } - - @Override - public List<Tuple> list(Expression<?>... args) { - return list(queryMixin.createProjection(args)); - } - - @Override - @SuppressWarnings("unchecked") - public <RT> List<RT> list(Expression<RT> expr) { - Query query = createQuery(expr); - reset(); - return query.list(); - } - - @Override - public SearchResults<Tuple> listResults(Expression<?>... args) { - return listResults(queryMixin.createProjection(args)); - } - - @Override - public <RT> SearchResults<RT> listResults(Expression<RT> expr) { - queryMixin.addProjection(expr); - Query countQuery = createQuery(null, true); - long total = (Long) countQuery.uniqueResult(); - try{ - if (total > 0) { - QueryModifiers modifiers = getMetadata().getModifiers(); - Query query = createQuery(modifiers, false); - @SuppressWarnings("unchecked") - List<RT> list = query.list(); - return new SearchResults<RT>(list, modifiers, total); - } else { - return SearchResults.emptyResults(); - } - }finally{ - reset(); - } - } - - protected void logQuery(String queryString) { - if (logger.isDebugEnabled()) { - logger.debug(queryString.replace('\n', ' ')); - } - } - - /** - * Return the query results as <tt>ScrollableResults</tt>. The - * scrollability of the returned results depends upon JDBC driver - * support for scrollable <tt>ResultSet</tt>s.<br> - * - * @param mode - * @param expr - * @return - */ - public ScrollableResults scroll(ScrollMode mode, Expression<?> expr) { - Query query = createQuery(expr); - reset(); - return query.scroll(mode); - } - - /** - * Return the query results as <tt>ScrollableResults</tt>. The - * scrollability of the returned results depends upon JDBC driver - * support for scrollable <tt>ResultSet</tt>s.<br> - * - * @param mode - * @param args - * @return - */ - public ScrollableResults scroll(ScrollMode mode, Expression<?>... args) { - Query query = createQuery(args); - reset(); - return query.scroll(mode); - } - - /** - * Enable caching of this query result set. - * @param cacheable Should the query results be cacheable? - */ - @SuppressWarnings("unchecked") - public Q setCacheable(boolean cacheable) { - this.cacheable = cacheable; - return (Q)this; - } - - /** - * Set the name of the cache region. - * @param cacheRegion the name of a query cache region, or <tt>null</tt> - * for the default query cache - */ - @SuppressWarnings("unchecked") - public Q setCacheRegion(String cacheRegion) { - this.cacheRegion = cacheRegion; - return (Q)this; - } - - /** - * Add a comment to the generated SQL. - * @param comment - * @return - */ - @SuppressWarnings("unchecked") - public Q setComment(String comment) { - this.comment = comment; - return (Q)this; - } - - /** - * Set a fetch size for the underlying JDBC query. - * @param fetchSize the fetch size - */ - @SuppressWarnings("unchecked") - public Q setFetchSize(int fetchSize) { - this.fetchSize = fetchSize; - return (Q)this; - } - - /** - * Set the lock mode for the given path. - */ - @SuppressWarnings("unchecked") - public Q setLockMode(Path<?> path, LockMode lockMode) { - lockModes.put(path, lockMode); - return (Q)this; - } - - /** - * Override the current session flush mode, just for this query. - */ - @SuppressWarnings("unchecked") - public Q setFlushMode(FlushMode flushMode) { - this.flushMode = flushMode; - return (Q)this; - } - - /** - * Entities retrieved by this query will be loaded in - * a read-only mode where Hibernate will never dirty-check - * them or make changes persistent. - * - */ - @SuppressWarnings("unchecked") - public Q setReadOnly(boolean readOnly) { - this.readOnly = readOnly; - return (Q)this; - } - - /** - * Set a timeout for the underlying JDBC query. - * @param timeout the timeout in seconds - */ - @SuppressWarnings("unchecked") - public Q setTimeout(int timeout) { - this.timeout = timeout; - return (Q)this; - } - - @Override - public Tuple uniqueResult(Expression<?>... args) { - return uniqueResult(queryMixin.createProjection(args)); - } - - @Override - @SuppressWarnings("unchecked") - public <RT> RT uniqueResult(Expression<RT> expr) { - queryMixin.addProjection(expr); - return (RT)uniqueResult(); - } - - private Object uniqueResult() { - QueryModifiers modifiers = getMetadata().getModifiers(); - Query query = createQuery(modifiers, false); - reset(); - try{ - return query.uniqueResult(); - } catch (org.hibernate.NonUniqueResultException e) { - throw new NonUniqueResultException(); - } - } - - protected JPQLSerializer createSerializer() { - return new JPQLSerializer(getTemplates()); - } - - protected void clone(Q query) { - cacheable = query.cacheable; - cacheRegion = query.cacheRegion; - fetchSize = query.fetchSize; - flushMode = query.flushMode; - lockModes.putAll(query.lockModes); - readOnly = query.readOnly; - timeout = query.timeout; - } - - protected abstract Q clone(SessionHolder sessionHolder); - - /** - * Clone the state of this query to a new instance with the given Session - * - * @param session - * @return - */ - public Q clone(Session session) { - return this.clone(new DefaultSessionHolder(session)); - } - - /** - * Clone the state of this query to a new instance with the given StatelessSession - * - * @param session - * @return - */ - public Q clone(StatelessSession session) { - return this.clone(new StatelessSessionHolder(session)); - } - - /** - * Clone the state of this query to a new instance - * - * @return - */ - public Q clone() { - return this.clone(this.session); - } - -} diff --git a/querydsl-jpa/src/main/java/com/mysema/query/jpa/hibernate/DefaultSessionHolder.java b/querydsl-jpa/src/main/java/com/mysema/query/jpa/hibernate/DefaultSessionHolder.java deleted file mode 100644 index 095e81f09e..0000000000 --- a/querydsl-jpa/src/main/java/com/mysema/query/jpa/hibernate/DefaultSessionHolder.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa.hibernate; - -import org.hibernate.Query; -import org.hibernate.SQLQuery; -import org.hibernate.Session; - -/** - * DefaultSessionHolder is the default implementation of the {@link SessionHolder} interface - * - * @author tiwe - * - */ -public class DefaultSessionHolder implements SessionHolder{ - - private final Session session; - - public DefaultSessionHolder(Session session) { - this.session = session; - } - - @Override - public Query createQuery(String queryString) { - return session.createQuery(queryString); - } - - @Override - public SQLQuery createSQLQuery(String queryString) { - return session.createSQLQuery(queryString); - } - -} diff --git a/querydsl-jpa/src/main/java/com/mysema/query/jpa/hibernate/HibernateDeleteClause.java b/querydsl-jpa/src/main/java/com/mysema/query/jpa/hibernate/HibernateDeleteClause.java deleted file mode 100644 index 9efae77656..0000000000 --- a/querydsl-jpa/src/main/java/com/mysema/query/jpa/hibernate/HibernateDeleteClause.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa.hibernate; - -import java.util.Map; - -import org.hibernate.Query; -import org.hibernate.Session; -import org.hibernate.StatelessSession; - -import com.mysema.query.DefaultQueryMetadata; -import com.mysema.query.JoinType; -import com.mysema.query.QueryMetadata; -import com.mysema.query.dml.DeleteClause; -import com.mysema.query.jpa.JPQLSerializer; -import com.mysema.query.jpa.HQLTemplates; -import com.mysema.query.jpa.JPQLTemplates; -import com.mysema.query.types.EntityPath; -import com.mysema.query.types.Predicate; - -/** - * DeleteClause implementation for Hibernate - * - * @author tiwe - * - */ -public class HibernateDeleteClause implements DeleteClause<HibernateDeleteClause> { - - private final QueryMetadata md = new DefaultQueryMetadata(); - - private final SessionHolder session; - - private final JPQLTemplates templates; - - public HibernateDeleteClause(Session session, EntityPath<?> entity) { - this(new DefaultSessionHolder(session), entity, HQLTemplates.DEFAULT); - } - - public HibernateDeleteClause(StatelessSession session, EntityPath<?> entity) { - this(new StatelessSessionHolder(session), entity, HQLTemplates.DEFAULT); - } - - public HibernateDeleteClause(Session session, EntityPath<?> entity, JPQLTemplates templates) { - this(new DefaultSessionHolder(session), entity, templates); - } - - public HibernateDeleteClause(SessionHolder session, EntityPath<?> entity, JPQLTemplates templates) { - this.session = session; - this.templates = templates; - md.addJoin(JoinType.DEFAULT, entity); - } - - @Override - public long execute() { - JPQLSerializer serializer = new JPQLSerializer(templates, null); - serializer.serializeForDelete(md); - Map<Object,String> constants = serializer.getConstantToLabel(); - - Query query = session.createQuery(serializer.toString()); - HibernateUtil.setConstants(query, constants, md.getParams()); - return query.executeUpdate(); - } - - @Override - public HibernateDeleteClause where(Predicate... o) { - for (Predicate p : o) { - md.addWhere(p); - } - return this; - } - - @Override - public String toString() { - JPQLSerializer serializer = new JPQLSerializer(templates, null); - serializer.serializeForDelete(md); - return serializer.toString(); - } - -} diff --git a/querydsl-jpa/src/main/java/com/mysema/query/jpa/hibernate/HibernateQuery.java b/querydsl-jpa/src/main/java/com/mysema/query/jpa/hibernate/HibernateQuery.java deleted file mode 100644 index 3b2005fc69..0000000000 --- a/querydsl-jpa/src/main/java/com/mysema/query/jpa/hibernate/HibernateQuery.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa.hibernate; - -import org.hibernate.Session; -import org.hibernate.StatelessSession; - -import com.mysema.query.DefaultQueryMetadata; -import com.mysema.query.QueryMetadata; -import com.mysema.query.jpa.HQLTemplates; -import com.mysema.query.jpa.JPQLTemplates; - -/** - * HibernateQuery is the default implementation of the JPQLQuery interface for Hibernate - * - * @author tiwe - * - */ -public final class HibernateQuery extends AbstractHibernateQuery<HibernateQuery> { - - /** - * Creates a detached query - * The query can be attached via the clone method - */ - public HibernateQuery() { - super(NoSessionHolder.DEFAULT, HQLTemplates.DEFAULT, new DefaultQueryMetadata()); - } - - /** - * Creates a new Session bound query - * - * @param session - */ - public HibernateQuery(Session session) { - super(new DefaultSessionHolder(session), HQLTemplates.DEFAULT, new DefaultQueryMetadata()); - } - - /** - * Creates a new Session bound query - * - * @param session - */ - public HibernateQuery(Session session, QueryMetadata metadata) { - super(new DefaultSessionHolder(session), HQLTemplates.DEFAULT, metadata); - } - - /** - * Creates a new Session bound query - * - * @param session - * @param templates - */ - public HibernateQuery(Session session, JPQLTemplates templates) { - super(new DefaultSessionHolder(session), templates, new DefaultQueryMetadata()); - } - - /** - * Creates a new Stateless session bound query - * - * @param session - */ - public HibernateQuery(StatelessSession session) { - super(new StatelessSessionHolder(session), HQLTemplates.DEFAULT, new DefaultQueryMetadata()); - } - - /** - * Creates a new Session bound query - * - * @param session - * @param templates - */ - public HibernateQuery(SessionHolder session, JPQLTemplates templates) { - super(session, templates, new DefaultQueryMetadata()); - } - - /** - * Creates a new Session bound query - * - * @param session - * @param templates - * @param metadata - */ - public HibernateQuery(SessionHolder session, JPQLTemplates templates, QueryMetadata metadata) { - super(session, templates, metadata); - } - - @Override - protected HibernateQuery clone(SessionHolder sessionHolder) { - HibernateQuery q = new HibernateQuery(sessionHolder, - getTemplates(), getMetadata().clone()); - q.clone(this); - return q; - } - -} diff --git a/querydsl-jpa/src/main/java/com/mysema/query/jpa/hibernate/HibernateQueryFactory.java b/querydsl-jpa/src/main/java/com/mysema/query/jpa/hibernate/HibernateQueryFactory.java deleted file mode 100644 index f916868cc9..0000000000 --- a/querydsl-jpa/src/main/java/com/mysema/query/jpa/hibernate/HibernateQueryFactory.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa.hibernate; - -import javax.inject.Provider; - -import org.hibernate.Session; - -import com.mysema.query.jpa.HQLTemplates; -import com.mysema.query.jpa.JPQLQueryFactory; -import com.mysema.query.jpa.JPQLTemplates; -import com.mysema.query.types.EntityPath; - -/** - * Factory class for query and DML clause creation - * - * @author tiwe - * - */ -public class HibernateQueryFactory implements JPQLQueryFactory { - - private final JPQLTemplates templates; - - private final Provider<Session> session; - - public HibernateQueryFactory(Provider<Session> session) { - this(HQLTemplates.DEFAULT, session); - } - - public HibernateQueryFactory(JPQLTemplates templates, Provider<Session> session) { - this.session = session; - this.templates = templates; - } - - public HibernateDeleteClause delete(EntityPath<?> path) { - return new HibernateDeleteClause(session.get(), path, templates); - } - - public HibernateQuery from(EntityPath<?> from) { - return query().from(from); - } - - public HibernateUpdateClause update(EntityPath<?> path) { - return new HibernateUpdateClause(session.get(), path, templates); - } - - public HibernateQuery query() { - return new HibernateQuery(session.get(), templates); - } - - public HibernateSubQuery subQuery() { - return new HibernateSubQuery(); - } -} diff --git a/querydsl-jpa/src/main/java/com/mysema/query/jpa/hibernate/HibernateSubQuery.java b/querydsl-jpa/src/main/java/com/mysema/query/jpa/hibernate/HibernateSubQuery.java deleted file mode 100644 index 31ccce3221..0000000000 --- a/querydsl-jpa/src/main/java/com/mysema/query/jpa/hibernate/HibernateSubQuery.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa.hibernate; - -import com.mysema.query.QueryMetadata; -import com.mysema.query.jpa.AbstractJPASubQuery; - -/** - * HibernateSubQuery is a subquery class for Hibernate - * - * @author tiwe - * - */ -public final class HibernateSubQuery extends AbstractJPASubQuery<HibernateSubQuery> { - - public HibernateSubQuery() { - super(); - } - - public HibernateSubQuery(QueryMetadata metadata) { - super(metadata); - } - -} diff --git a/querydsl-jpa/src/main/java/com/mysema/query/jpa/hibernate/HibernateUpdateClause.java b/querydsl-jpa/src/main/java/com/mysema/query/jpa/hibernate/HibernateUpdateClause.java deleted file mode 100644 index ab75428544..0000000000 --- a/querydsl-jpa/src/main/java/com/mysema/query/jpa/hibernate/HibernateUpdateClause.java +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa.hibernate; - -import java.util.List; -import java.util.Map; - -import org.hibernate.Query; -import org.hibernate.Session; -import org.hibernate.StatelessSession; - -import com.mysema.query.DefaultQueryMetadata; -import com.mysema.query.JoinType; -import com.mysema.query.QueryMetadata; -import com.mysema.query.dml.UpdateClause; -import com.mysema.query.jpa.HQLTemplates; -import com.mysema.query.jpa.JPQLSerializer; -import com.mysema.query.jpa.JPQLTemplates; -import com.mysema.query.types.EntityPath; -import com.mysema.query.types.Expression; -import com.mysema.query.types.ExpressionUtils; -import com.mysema.query.types.NullExpression; -import com.mysema.query.types.Path; -import com.mysema.query.types.Predicate; - -/** - * UpdateClause implementation for Hibernate - * - * @author tiwe - * - */ -public class HibernateUpdateClause implements - UpdateClause<HibernateUpdateClause> { - - private final QueryMetadata metadata = new DefaultQueryMetadata(); - - private final SessionHolder session; - - private final JPQLTemplates templates; - - public HibernateUpdateClause(Session session, EntityPath<?> entity) { - this(new DefaultSessionHolder(session), entity, HQLTemplates.DEFAULT); - } - - public HibernateUpdateClause(StatelessSession session, EntityPath<?> entity) { - this(new StatelessSessionHolder(session), entity, HQLTemplates.DEFAULT); - } - - public HibernateUpdateClause(Session session, EntityPath<?> entity, JPQLTemplates templates) { - this(new DefaultSessionHolder(session), entity, templates); - } - - public HibernateUpdateClause(SessionHolder session, EntityPath<?> entity, - JPQLTemplates templates) { - this.session = session; - this.templates = templates; - metadata.addJoin(JoinType.DEFAULT, entity); - } - - @Override - public long execute() { - JPQLSerializer serializer = new JPQLSerializer(templates, null); - serializer.serializeForUpdate(metadata); - Map<Object, String> constants = serializer.getConstantToLabel(); - - Query query = session.createQuery(serializer.toString()); - HibernateUtil.setConstants(query, constants, metadata.getParams()); - return query.executeUpdate(); - } - - @Override - public <T> HibernateUpdateClause set(Path<T> path, T value) { - if (value != null) { - metadata.addProjection(ExpressionUtils.eqConst(path, value)); - } else { - setNull(path); - } - return this; - } - - @Override - public <T> HibernateUpdateClause set(Path<T> path, Expression<? extends T> expression) { - if (expression != null) { - metadata.addProjection(ExpressionUtils.eq(path, expression)); - } else { - setNull(path); - } - return this; - } - - @Override - public <T> HibernateUpdateClause setNull(Path<T> path) { - metadata.addProjection(ExpressionUtils.eq(path, new NullExpression<T>(path.getType()))); - return this; - } - - @SuppressWarnings("unchecked") - @Override - public HibernateUpdateClause set(List<? extends Path<?>> paths, List<?> values) { - for (int i = 0; i < paths.size(); i++) { - if (values.get(i) != null) { - metadata.addProjection(ExpressionUtils.eqConst((Expression)paths.get(i), values.get(i))); - } else { - metadata.addProjection(ExpressionUtils.eq(((Expression)paths.get(i)), - new NullExpression(paths.get(i).getType()))); - } - - } - return this; - } - - @Override - public HibernateUpdateClause where(Predicate... o) { - for (Predicate p : o) { - metadata.addWhere(p); - } - return this; - } - - @Override - public String toString() { - JPQLSerializer serializer = new JPQLSerializer(templates, null); - serializer.serializeForUpdate(metadata); - return serializer.toString(); - } - - @Override - public boolean isEmpty() { - return metadata.getProjection().isEmpty(); - } - - -} diff --git a/querydsl-jpa/src/main/java/com/mysema/query/jpa/hibernate/HibernateUtil.java b/querydsl-jpa/src/main/java/com/mysema/query/jpa/hibernate/HibernateUtil.java deleted file mode 100644 index e6634b78b8..0000000000 --- a/querydsl-jpa/src/main/java/com/mysema/query/jpa/hibernate/HibernateUtil.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa.hibernate; - -import java.math.BigDecimal; -import java.math.BigInteger; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; - -import org.hibernate.Query; -import org.hibernate.type.BigDecimalType; -import org.hibernate.type.BigIntegerType; -import org.hibernate.type.ByteType; -import org.hibernate.type.DoubleType; -import org.hibernate.type.FloatType; -import org.hibernate.type.IntegerType; -import org.hibernate.type.LongType; -import org.hibernate.type.ShortType; -import org.hibernate.type.Type; - -import com.mysema.query.types.ParamExpression; -import com.mysema.query.types.ParamNotSetException; -import com.mysema.query.types.expr.Param; - -/** - * HibernateUtil provides static utility methods for Hibernate - * - * @author tiwe - * - */ -public final class HibernateUtil { - - private static final Map<Class<?>,Type> TYPES = new HashMap<Class<?>,Type>(); - - static{ - TYPES.put(Byte.class, new ByteType()); - TYPES.put(Short.class, new ShortType()); - TYPES.put(Integer.class, new IntegerType()); - TYPES.put(Long.class, new LongType()); - TYPES.put(BigInteger.class, new BigIntegerType()); - TYPES.put(Double.class, new DoubleType()); - TYPES.put(Float.class, new FloatType()); - TYPES.put(BigDecimal.class, new BigDecimalType()); - } - - private HibernateUtil() {} - - public static void setConstants(Query query, Map<Object,String> constants, - Map<ParamExpression<?>, Object> params) { - for (Map.Entry<Object, String> entry : constants.entrySet()) { - String key = entry.getValue(); - Object val = entry.getKey(); - if (Param.class.isInstance(val)) { - val = params.get(val); - if (val == null) { - throw new ParamNotSetException((Param<?>) entry.getKey()); - } - } - setValue(query, key, val); - } - } - - private static void setValue(Query query, String key, Object val) { - if (val instanceof Collection<?>) { - query.setParameterList(key, (Collection<?>) val); - } else if (val.getClass().isArray()) { - query.setParameterList(key, (Object[]) val); - } else if (TYPES.containsKey(val.getClass())) { - query.setParameter(key, val, TYPES.get(val.getClass())); - } else { - query.setParameter(key, val); - } - } -} diff --git a/querydsl-jpa/src/main/java/com/mysema/query/jpa/hibernate/NoSessionHolder.java b/querydsl-jpa/src/main/java/com/mysema/query/jpa/hibernate/NoSessionHolder.java deleted file mode 100644 index 8b53ff2ae5..0000000000 --- a/querydsl-jpa/src/main/java/com/mysema/query/jpa/hibernate/NoSessionHolder.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa.hibernate; - -import org.hibernate.Query; -import org.hibernate.SQLQuery; - -/** - * NoSessionHolder is a session holder for detached HibernateQuery usage - * - * @author tiwe - * - */ -public final class NoSessionHolder implements SessionHolder { - - public static final SessionHolder DEFAULT = new NoSessionHolder(); - - private NoSessionHolder() {} - - @Override - public Query createQuery(String queryString) { - throw new UnsupportedOperationException("No session in detached Query available"); - } - - @Override - public SQLQuery createSQLQuery(String queryString) { - throw new UnsupportedOperationException("No session in detached Query available"); - } - -} diff --git a/querydsl-jpa/src/main/java/com/mysema/query/jpa/hibernate/SessionHolder.java b/querydsl-jpa/src/main/java/com/mysema/query/jpa/hibernate/SessionHolder.java deleted file mode 100644 index e970a93814..0000000000 --- a/querydsl-jpa/src/main/java/com/mysema/query/jpa/hibernate/SessionHolder.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa.hibernate; - -import org.hibernate.Query; -import org.hibernate.SQLQuery; - -/** - * Abstraction for different Hibernate Session signatures - * - * @author tiwe - * - */ -public interface SessionHolder { - - /** - * Create a JPQL query for the given query string - * - * @param queryString - * @return - */ - Query createQuery(String queryString); - - /** - * Create an SQL query for the given query string - * - * @param queryString - * @return - */ - SQLQuery createSQLQuery(String queryString); - -} diff --git a/querydsl-jpa/src/main/java/com/mysema/query/jpa/hibernate/StatelessSessionHolder.java b/querydsl-jpa/src/main/java/com/mysema/query/jpa/hibernate/StatelessSessionHolder.java deleted file mode 100644 index 58170ad500..0000000000 --- a/querydsl-jpa/src/main/java/com/mysema/query/jpa/hibernate/StatelessSessionHolder.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa.hibernate; - -import org.hibernate.Query; -import org.hibernate.SQLQuery; -import org.hibernate.StatelessSession; - -/** - * SessionHolder implementation using StatelessSession - * - * @author tiwe - * - */ -public class StatelessSessionHolder implements SessionHolder{ - - private final StatelessSession session; - - public StatelessSessionHolder(StatelessSession session) { - this.session = session; - } - - @Override - public Query createQuery(String queryString) { - return session.createQuery(queryString); - } - - @Override - public SQLQuery createSQLQuery(String queryString) { - return session.createSQLQuery(queryString); - } - -} diff --git a/querydsl-jpa/src/main/java/com/mysema/query/jpa/hibernate/package-info.java b/querydsl-jpa/src/main/java/com/mysema/query/jpa/hibernate/package-info.java deleted file mode 100644 index fd0ca70fc7..0000000000 --- a/querydsl-jpa/src/main/java/com/mysema/query/jpa/hibernate/package-info.java +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ - -/** - * JPQL for Hibernate - */ -package com.mysema.query.jpa.hibernate; diff --git a/querydsl-jpa/src/main/java/com/mysema/query/jpa/hibernate/sql/AbstractHibernateSQLQuery.java b/querydsl-jpa/src/main/java/com/mysema/query/jpa/hibernate/sql/AbstractHibernateSQLQuery.java deleted file mode 100644 index 847b5cf860..0000000000 --- a/querydsl-jpa/src/main/java/com/mysema/query/jpa/hibernate/sql/AbstractHibernateSQLQuery.java +++ /dev/null @@ -1,275 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa.hibernate.sql; - -import javax.annotation.Nullable; -import java.util.List; -import java.util.Map; - -import com.mysema.commons.lang.CloseableIterator; -import com.mysema.query.*; -import com.mysema.query.NonUniqueResultException; -import com.mysema.query.jpa.AbstractSQLQuery; -import com.mysema.query.jpa.FactoryExpressionTransformer; -import com.mysema.query.jpa.NativeSQLSerializer; -import com.mysema.query.jpa.ScrollableResultsIterator; -import com.mysema.query.jpa.hibernate.DefaultSessionHolder; -import com.mysema.query.jpa.hibernate.HibernateUtil; -import com.mysema.query.jpa.hibernate.SessionHolder; -import com.mysema.query.jpa.hibernate.StatelessSessionHolder; -import com.mysema.query.sql.Configuration; -import com.mysema.query.sql.SQLSerializer; -import com.mysema.query.types.Expression; -import com.mysema.query.types.FactoryExpression; -import org.hibernate.Query; -import org.hibernate.*; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * AbstractHibernateSQLQuery is the base class for Hibernate Native SQL queries - * - * @author tiwe - * - * @param <Q> - */ -public abstract class AbstractHibernateSQLQuery<Q extends AbstractHibernateSQLQuery<Q>> extends AbstractSQLQuery<Q> { - - private static final Logger logger = LoggerFactory.getLogger(AbstractHibernateSQLQuery.class); - - protected Boolean cacheable, readOnly; - - protected String cacheRegion; - - protected int fetchSize = 0; - - private final SessionHolder session; - - protected int timeout = 0; - - public AbstractHibernateSQLQuery(Session session, Configuration conf) { - this(new DefaultSessionHolder(session), conf, new DefaultQueryMetadata()); - } - - public AbstractHibernateSQLQuery(StatelessSession session, Configuration conf) { - this(new StatelessSessionHolder(session), conf, new DefaultQueryMetadata()); - } - - public AbstractHibernateSQLQuery(SessionHolder session, Configuration conf, QueryMetadata metadata) { - super(metadata, conf); - this.session = session; - } - - public Query createQuery(Expression<?>... args) { - queryMixin.getMetadata().setValidate(false); - queryMixin.addProjection(args); - return createQuery(false); - } - - private Query createQuery(boolean forCount) { - NativeSQLSerializer serializer = (NativeSQLSerializer) serialize(forCount); - String queryString = serializer.toString(); - logQuery(queryString); - org.hibernate.SQLQuery query = session.createSQLQuery(queryString); - // set constants - HibernateUtil.setConstants(query, serializer.getConstantToLabel(), queryMixin.getMetadata().getParams()); - - if (!forCount) { - Map<Expression<?>, String> aliases = serializer.getAliases(); - // set entity paths - List<? extends Expression<?>> projection = queryMixin.getMetadata().getProjection(); - Expression<?> proj = projection.get(0); - if (proj instanceof FactoryExpression) { - for (Expression<?> expr : ((FactoryExpression<?>)proj).getArgs()) { - if (isEntityExpression(expr)) { - query.addEntity(extractEntityExpression(expr).toString(), expr.getType()); - } else if (aliases.containsKey(expr)) { - query.addScalar(aliases.get(expr)); - } - } - } else if (isEntityExpression(proj)) { - query.addEntity(extractEntityExpression(proj).toString(), proj.getType()); - } else if (aliases.containsKey(proj)) { - query.addScalar(aliases.get(proj)); - } - - // set result transformer, if projection is a FactoryExpression instance - if (projection.size() == 1 && proj instanceof FactoryExpression) { - query.setResultTransformer(new FactoryExpressionTransformer((FactoryExpression<?>) proj)); - } - } - - if (fetchSize > 0) { - query.setFetchSize(fetchSize); - } - if (timeout > 0) { - query.setTimeout(timeout); - } - if (cacheable != null) { - query.setCacheable(cacheable); - } - if (cacheRegion != null) { - query.setCacheRegion(cacheRegion); - } - if (readOnly != null) { - query.setReadOnly(readOnly); - } - return query; - } - - @Override - protected SQLSerializer createSerializer() { - return new NativeSQLSerializer(configuration, true); - } - - @SuppressWarnings("unchecked") - @Override - public <RT> List<RT> list(Expression<RT> projection) { - Query query = createQuery(projection); - reset(); - return query.list(); - } - - @Override - public <RT> CloseableIterator<RT> iterate(Expression<RT> projection) { - Query query = createQuery(projection); - reset(); - ScrollableResults results = query.scroll(ScrollMode.FORWARD_ONLY); - return new ScrollableResultsIterator<RT>(results); - } - - @Override - public <RT> SearchResults<RT> listResults(Expression<RT> projection) { - // TODO : handle entity projections as well - queryMixin.addProjection(projection); - Query query = createQuery(true); - long total = ((Number)query.uniqueResult()).longValue(); - if (total > 0) { - QueryModifiers modifiers = queryMixin.getMetadata().getModifiers(); - query = createQuery(false); - @SuppressWarnings("unchecked") - List<RT> list = query.list(); - reset(); - return new SearchResults<RT>(list, modifiers, total); - } else { - reset(); - return SearchResults.emptyResults(); - } - } - - protected void logQuery(String queryString) { - if (logger.isDebugEnabled()) { - logger.debug(queryString.replace('\n', ' ')); - } - } - - protected void reset() { - queryMixin.getMetadata().reset(); - } - - @SuppressWarnings("unchecked") - @Override - public <RT> RT uniqueResult(Expression<RT> expr) { - Query query = createQuery(expr); - return (RT)uniqueResult(query); - } - - @Nullable - private Object uniqueResult(Query query) { - reset(); - try{ - return query.uniqueResult(); - }catch (org.hibernate.NonUniqueResultException e) { - throw new NonUniqueResultException(); - } - } - - /** - * Enable caching of this query result set. - * @param cacheable Should the query results be cacheable? - */ - @SuppressWarnings("unchecked") - public Q setCacheable(boolean cacheable) { - this.cacheable = cacheable; - return (Q)this; - } - - /** - * Set the name of the cache region. - * @param cacheRegion the name of a query cache region, or <tt>null</tt> - * for the default query cache - */ - @SuppressWarnings("unchecked") - public Q setCacheRegion(String cacheRegion) { - this.cacheRegion = cacheRegion; - return (Q)this; - } - - /** - * Set a fetch size for the underlying JDBC query. - * @param fetchSize the fetch size - */ - @SuppressWarnings("unchecked") - public Q setFetchSize(int fetchSize) { - this.fetchSize = fetchSize; - return (Q)this; - } - - /** - * Entities retrieved by this query will be loaded in - * a read-only mode where Hibernate will never dirty-check - * them or make changes persistent. - * - */ - @SuppressWarnings("unchecked") - public Q setReadOnly(boolean readOnly) { - this.readOnly = readOnly; - return (Q)this; - } - - /** - * Set a timeout for the underlying JDBC query. - * @param timeout the timeout in seconds - */ - @SuppressWarnings("unchecked") - public Q setTimeout(int timeout) { - this.timeout = timeout; - return (Q)this; - } - - protected void clone(Q query) { - super.clone(query); - cacheable = query.cacheable; - cacheRegion = query.cacheRegion; - fetchSize = query.fetchSize; - readOnly = query.readOnly; - timeout = query.timeout; - } - - protected abstract Q clone(SessionHolder session); - - public Q clone(Session session) { - return this.clone(new DefaultSessionHolder(session)); - } - - public Q clone(StatelessSession statelessSession) { - return this.clone(new StatelessSessionHolder(statelessSession)); - } - - @Override - public Q clone() { - return this.clone(this.session); - } - -} diff --git a/querydsl-jpa/src/main/java/com/mysema/query/jpa/hibernate/sql/HibernateSQLQuery.java b/querydsl-jpa/src/main/java/com/mysema/query/jpa/hibernate/sql/HibernateSQLQuery.java deleted file mode 100644 index 697406976d..0000000000 --- a/querydsl-jpa/src/main/java/com/mysema/query/jpa/hibernate/sql/HibernateSQLQuery.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa.hibernate.sql; - -import com.mysema.query.QueryMetadata; -import com.mysema.query.jpa.hibernate.SessionHolder; -import com.mysema.query.sql.Configuration; -import com.mysema.query.sql.SQLTemplates; -import org.hibernate.Session; -import org.hibernate.StatelessSession; - -/** - * HibernateSQLQuery is an SQLQuery implementation that uses Hibernate's Native SQL functionality - * to execute queries - * - * @author tiwe - * - */ -public final class HibernateSQLQuery extends AbstractHibernateSQLQuery<HibernateSQLQuery> { - - public HibernateSQLQuery(Session session, SQLTemplates sqlTemplates) { - super(session, new Configuration(sqlTemplates)); - } - - public HibernateSQLQuery(Session session, Configuration conf) { - super(session, conf); - } - - public HibernateSQLQuery(StatelessSession session, SQLTemplates sqlTemplates) { - super(session, new Configuration(sqlTemplates)); - } - - public HibernateSQLQuery(StatelessSession session, Configuration conf) { - super(session, conf); - } - - public HibernateSQLQuery(SessionHolder session, SQLTemplates sqlTemplates, QueryMetadata metadata) { - super(session, new Configuration(sqlTemplates), metadata); - } - - public HibernateSQLQuery(SessionHolder session, Configuration conf, QueryMetadata metadata) { - super(session, conf, metadata); - } - - @Override - protected HibernateSQLQuery clone(SessionHolder sessionHolder) { - HibernateSQLQuery q = new HibernateSQLQuery(sessionHolder, configuration, getMetadata().clone()); - q.clone(this); - return q; - } - -} diff --git a/querydsl-jpa/src/main/java/com/mysema/query/jpa/hibernate/sql/package-info.java b/querydsl-jpa/src/main/java/com/mysema/query/jpa/hibernate/sql/package-info.java deleted file mode 100644 index 77abe8bb29..0000000000 --- a/querydsl-jpa/src/main/java/com/mysema/query/jpa/hibernate/sql/package-info.java +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ - -package com.mysema.query.jpa.hibernate.sql; - diff --git a/querydsl-jpa/src/main/java/com/mysema/query/jpa/impl/AbstractJPAQuery.java b/querydsl-jpa/src/main/java/com/mysema/query/jpa/impl/AbstractJPAQuery.java deleted file mode 100644 index d499c6288e..0000000000 --- a/querydsl-jpa/src/main/java/com/mysema/query/jpa/impl/AbstractJPAQuery.java +++ /dev/null @@ -1,347 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa.impl; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import javax.annotation.Nullable; -import javax.persistence.EntityManager; -import javax.persistence.FlushModeType; -import javax.persistence.LockModeType; -import javax.persistence.Query; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.common.collect.HashMultimap; -import com.google.common.collect.Multimap; -import com.mysema.commons.lang.CloseableIterator; -import com.mysema.query.DefaultQueryMetadata; -import com.mysema.query.NonUniqueResultException; -import com.mysema.query.QueryMetadata; -import com.mysema.query.QueryModifiers; -import com.mysema.query.SearchResults; -import com.mysema.query.Tuple; -import com.mysema.query.jpa.JPAQueryBase; -import com.mysema.query.jpa.JPQLSerializer; -import com.mysema.query.jpa.JPQLTemplates; -import com.mysema.query.jpa.QueryHandler; -import com.mysema.query.types.Expression; -import com.mysema.query.types.FactoryExpression; -import com.mysema.query.types.FactoryExpressionUtils; - -/** - * Abstract base class for JPA API based implementations of the JPQLQuery interface - * - * @author tiwe - * - * @param <Q> - */ -public abstract class AbstractJPAQuery<Q extends AbstractJPAQuery<Q>> extends JPAQueryBase<Q> { - - private static final Logger logger = LoggerFactory.getLogger(JPAQuery.class); - - protected final Multimap<String,Object> hints = HashMultimap.create(); - - protected final EntityManager entityManager; - - protected final QueryHandler queryHandler; - - @Nullable - protected LockModeType lockMode; - - @Nullable - protected FlushModeType flushMode; - - @Nullable - protected FactoryExpression<?> projection; - - public AbstractJPAQuery(EntityManager em) { - this(em, JPAProvider.getTemplates(em), new DefaultQueryMetadata()); - } - - public AbstractJPAQuery(EntityManager em, JPQLTemplates templates, QueryMetadata metadata) { - super(metadata, templates); - this.queryHandler = templates.getQueryHandler(); - this.entityManager = em; - } - - @Override - public long count() { - Query query = createQuery(null, true); - reset(); - return (Long) query.getSingleResult(); - } - - /** - * Expose the original JPA query for the given projection - * - * @param expr - * @return - */ - public Query createQuery(Expression<?> expr) { - queryMixin.addProjection(expr); - return createQuery(getMetadata().getModifiers(), false); - } - - /** - * Expose the original JPA query for the given projection - * - * @param expr - * @return - */ - public Query createQuery(Expression<?> expr1, Expression<?> expr2, Expression<?>... rest) { - queryMixin.addProjection(expr1); - queryMixin.addProjection(expr2); - queryMixin.addProjection(rest); - return createQuery(getMetadata().getModifiers(), false); - } - - /** - * Expose the original JPA query for the given projection - * - * @param args - * @return - */ - public Query createQuery(Expression<?>[] args) { - queryMixin.addProjection(args); - return createQuery(getMetadata().getModifiers(), false); - } - - private Query createQuery(@Nullable QueryModifiers modifiers, boolean forCount) { - JPQLSerializer serializer = serialize(forCount); - String queryString = serializer.toString(); - logQuery(queryString); - Query query = entityManager.createQuery(queryString); - JPAUtil.setConstants(query, serializer.getConstantToLabel(), getMetadata().getParams()); - if (modifiers != null && modifiers.isRestricting()) { - Integer limit = modifiers.getLimitAsInteger(); - Integer offset = modifiers.getOffsetAsInteger(); - if (limit != null) { - query.setMaxResults(limit.intValue()); - } - if (offset != null) { - query.setFirstResult(offset.intValue()); - } - } - if (lockMode != null) { - query.setLockMode(lockMode); - } - if (flushMode != null) { - query.setFlushMode(flushMode); - } - - for (Map.Entry<String, Object> entry : hints.entries()) { - query.setHint(entry.getKey(), entry.getValue()); - } - - // set transformer, if necessary and possible - List<? extends Expression<?>> projection = getMetadata().getProjection(); - - FactoryExpression<?> wrapped = projection.size() > 1 ? FactoryExpressionUtils.wrap(projection) : null; - - if (!forCount && ((projection.size() == 1 && projection.get(0) instanceof FactoryExpression) || wrapped != null)) { - Expression<?> expr = wrapped != null ? wrapped : projection.get(0); - - if (!queryHandler.transform(query, (FactoryExpression<?>)expr)) { - this.projection = (FactoryExpression<?>)projection.get(0); - if (wrapped != null) { - this.projection = wrapped; - getMetadata().clearProjection(); - getMetadata().addProjection(wrapped); - } - } - } - - return query; - } - - /** - * Transforms results using FactoryExpression if ResultTransformer can't be used - * - * @param query - * @return - */ - private List<?> getResultList(Query query) { - // TODO : use lazy list here? - if (projection != null) { - List<?> results = query.getResultList(); - List<Object> rv = new ArrayList<Object>(results.size()); - for (Object o : results) { - if (o != null) { - if (!o.getClass().isArray()) { - o = new Object[]{o}; - } - rv.add(projection.newInstance((Object[])o)); - } else { - rv.add(null); - } - } - return rv; - } else { - return query.getResultList(); - } - } - - /** - * Transforms results using FactoryExpression if ResultTransformer can't be used - * - * @param query - * @return - */ - @Nullable - private Object getSingleResult(Query query) { - if (projection != null) { - Object result = query.getSingleResult(); - if (result != null) { - if (!result.getClass().isArray()) { - result = new Object[]{result}; - } - return projection.newInstance((Object[])result); - } else { - return null; - } - } else { - return query.getSingleResult(); - } - } - - @Override - public CloseableIterator<Tuple> iterate(Expression<?>... args) { - return iterate(queryMixin.createProjection(args)); - } - - @Override - public <RT> CloseableIterator<RT> iterate(Expression<RT> expr) { - Query query = createQuery(expr); - return queryHandler.<RT>iterate(query, projection); - } - - @Override - public List<Tuple> list(Expression<?>... args) { - return list(queryMixin.createProjection(args)); - } - - @Override - @SuppressWarnings("unchecked") - public <RT> List<RT> list(Expression<RT> expr) { - Query query = createQuery(expr); - try { - return (List<RT>) getResultList(query); - } finally { - reset(); - } - } - - @Override - public SearchResults<Tuple> listResults(Expression<?>... args) { - return listResults(queryMixin.createProjection(args)); - } - - @Override - public <RT> SearchResults<RT> listResults(Expression<RT> expr) { - queryMixin.addProjection(expr); - Query countQuery = createQuery(null, true); - long total = (Long) countQuery.getSingleResult(); - if (total > 0) { - QueryModifiers modifiers = getMetadata().getModifiers(); - Query query = createQuery(modifiers, false); - @SuppressWarnings("unchecked") - List<RT> list = (List<RT>) getResultList(query); - reset(); - return new SearchResults<RT>(list, modifiers, total); - } else { - reset(); - return SearchResults.emptyResults(); - } - } - - protected void logQuery(String queryString) { - if (logger.isDebugEnabled()) { - logger.debug(queryString.replace('\n', ' ')); - } - } - - @Override - public <RT> RT uniqueResult(Expression<RT> expr) { - queryMixin.addProjection(expr); - return uniqueResult(); - } - - @Nullable - @SuppressWarnings("unchecked") - private <RT> RT uniqueResult() { - Query query = createQuery(getMetadata().getModifiers(), false); - try{ - return (RT) getSingleResult(query); - } catch(javax.persistence.NoResultException e) { - logger.trace(e.getMessage(),e); - return null; - } catch(javax.persistence.NonUniqueResultException e) { - throw new NonUniqueResultException(); - } finally { - reset(); - } - } - - @SuppressWarnings("unchecked") - public Q setLockMode(LockModeType lockMode) { - this.lockMode = lockMode; - return (Q)this; - } - - @SuppressWarnings("unchecked") - public Q setFlushMode(FlushModeType flushMode) { - this.flushMode = flushMode; - return (Q)this; - } - - @SuppressWarnings("unchecked") - public Q setHint(String name, Object value) { - hints.put(name, value); - return (Q)this; - } - - @Override - protected JPQLSerializer createSerializer() { - return new JPQLSerializer(getTemplates(), entityManager); - } - - protected void clone(Q query) { - projection = query.projection; - flushMode = query.flushMode; - hints.putAll(query.hints); - lockMode = query.lockMode; - } - - /** - * Clone the state of this query to a new instance with the given EntityManager - * - * @param entityManager - * @return - */ - public abstract Q clone(EntityManager entityManager); - - /** - * Clone the state of this query to a new instance - * - * @return - */ - public Q clone() { - return this.clone(this.entityManager); - } - -} diff --git a/querydsl-jpa/src/main/java/com/mysema/query/jpa/impl/JPADeleteClause.java b/querydsl-jpa/src/main/java/com/mysema/query/jpa/impl/JPADeleteClause.java deleted file mode 100644 index 6625e8dba6..0000000000 --- a/querydsl-jpa/src/main/java/com/mysema/query/jpa/impl/JPADeleteClause.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa.impl; - -import java.util.Map; - -import javax.persistence.EntityManager; -import javax.persistence.Query; - -import com.mysema.query.DefaultQueryMetadata; -import com.mysema.query.JoinType; -import com.mysema.query.QueryMetadata; -import com.mysema.query.dml.DeleteClause; -import com.mysema.query.jpa.JPQLSerializer; -import com.mysema.query.jpa.JPQLTemplates; -import com.mysema.query.types.EntityPath; -import com.mysema.query.types.Predicate; - -/** - * DeleteClause implementation for JPA - * - * @author tiwe - * - */ -public class JPADeleteClause implements DeleteClause<JPADeleteClause> { - - private final QueryMetadata metadata = new DefaultQueryMetadata(); - - private final EntityManager entityManager; - - private final JPQLTemplates templates; - - public JPADeleteClause(EntityManager em, EntityPath<?> entity) { - this(em, entity, JPAProvider.getTemplates(em)); - } - - public JPADeleteClause(EntityManager entityManager, EntityPath<?> entity, JPQLTemplates templates) { - this.entityManager = entityManager; - this.templates = templates; - metadata.addJoin(JoinType.DEFAULT, entity); - } - - @Override - public long execute() { - JPQLSerializer serializer = new JPQLSerializer(templates, entityManager); - serializer.serializeForDelete(metadata); - Map<Object,String> constants = serializer.getConstantToLabel(); - - Query query = entityManager.createQuery(serializer.toString()); - JPAUtil.setConstants(query, constants, metadata.getParams()); - return query.executeUpdate(); - } - - @Override - public JPADeleteClause where(Predicate... o) { - for (Predicate p : o) { - metadata.addWhere(p); - } - return this; - } - - @Override - public String toString() { - JPQLSerializer serializer = new JPQLSerializer(templates, entityManager); - serializer.serializeForDelete(metadata); - return serializer.toString(); - } - -} diff --git a/querydsl-jpa/src/main/java/com/mysema/query/jpa/impl/JPAProvider.java b/querydsl-jpa/src/main/java/com/mysema/query/jpa/impl/JPAProvider.java deleted file mode 100644 index a3f78070d3..0000000000 --- a/querydsl-jpa/src/main/java/com/mysema/query/jpa/impl/JPAProvider.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2012, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa.impl; - -import java.util.Map; - -import javax.persistence.EntityManager; - -import com.google.common.collect.Maps; -import com.mysema.query.jpa.BatooTemplates; -import com.mysema.query.jpa.DataNucleusTemplates; -import com.mysema.query.jpa.EclipseLinkTemplates; -import com.mysema.query.jpa.HQLTemplates; -import com.mysema.query.jpa.JPQLTemplates; -import com.mysema.query.jpa.OpenJPATemplates; - -/** - * JPAProvider provides detection of the JPA provider based on the EntityManager instance - * - * @author tiwe - * - */ -public final class JPAProvider { - - private static final Map<Class<?>, JPQLTemplates> mappings = Maps.newHashMap(); - - private static final Map<String, JPQLTemplates> templatesByName = Maps.newHashMap(); - - private static void addMapping(String className, JPQLTemplates templates) { - try { - mappings.put(Class.forName(className), templates); - } catch (Exception e) {} - } - - static { - addMapping("org.batoo.jpa.core.impl.manager.EntityManagerImpl", BatooTemplates.DEFAULT); - addMapping("org.hibernate.Session", HQLTemplates.DEFAULT); - addMapping("org.hibernate.ejb.HibernateEntityManager", HQLTemplates.DEFAULT); - addMapping("org.eclipse.persistence.jpa.JpaEntityManager", EclipseLinkTemplates.DEFAULT); - addMapping("org.apache.openjpa.persistence.OpenJPAEntityManager", OpenJPATemplates.DEFAULT); - addMapping("org.datanucleus.jpa.EntityManagerImpl", DataNucleusTemplates.DEFAULT); - addMapping("org.datanucleus.ObjectManager", DataNucleusTemplates.DEFAULT); - addMapping("org.datanucleus.ObjectManagerImpl", DataNucleusTemplates.DEFAULT); - - templatesByName.put("batoo", BatooTemplates.DEFAULT); - templatesByName.put("eclipselink", EclipseLinkTemplates.DEFAULT); - templatesByName.put("hibernate", HQLTemplates.DEFAULT); - templatesByName.put("openjpa", OpenJPATemplates.DEFAULT); - templatesByName.put("datanucleus", DataNucleusTemplates.DEFAULT); - } - - public static JPQLTemplates getTemplates(EntityManager em) { - // detect by delegate - for (Map.Entry<Class<?>, JPQLTemplates> entry : mappings.entrySet()) { - if (entry.getKey().isAssignableFrom(em.getDelegate().getClass())) { - return entry.getValue(); - } - } - // detect by properties - for (String key : em.getEntityManagerFactory().getProperties().keySet()) { - key = key.toLowerCase(); - for (Map.Entry<String, JPQLTemplates> entry : templatesByName.entrySet()) { - if (key.contains(entry.getKey())) { - return entry.getValue(); - } - } - } - return JPQLTemplates.DEFAULT; - } - - private JPAProvider() {} - -} diff --git a/querydsl-jpa/src/main/java/com/mysema/query/jpa/impl/JPAQuery.java b/querydsl-jpa/src/main/java/com/mysema/query/jpa/impl/JPAQuery.java deleted file mode 100644 index 0080370764..0000000000 --- a/querydsl-jpa/src/main/java/com/mysema/query/jpa/impl/JPAQuery.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa.impl; - -import javax.persistence.EntityManager; - -import com.mysema.query.DefaultQueryMetadata; -import com.mysema.query.QueryMetadata; -import com.mysema.query.jpa.JPQLTemplates; - -/** - * JPAQuery is the default implementation of the JPQLQuery interface for JPA - * - * @author tiwe - * - */ -public final class JPAQuery extends AbstractJPAQuery<JPAQuery> { - - /** - * Creates a new detached query - * The query can be attached via the clone method - */ - public JPAQuery() { - super(null, JPQLTemplates.DEFAULT, new DefaultQueryMetadata()); - } - - /** - * Creates a new EntityManager bound query - * - * @param em - */ - public JPAQuery(EntityManager em) { - super(em, JPAProvider.getTemplates(em), new DefaultQueryMetadata()); - } - - /** - * Creates a new EntityManager bound query - * - * @param em - */ - public JPAQuery(EntityManager em, QueryMetadata metadata) { - super(em, JPAProvider.getTemplates(em), metadata); - } - - /** - * Creates a new query - * - * @param em - * @param templates - */ - public JPAQuery(EntityManager em, JPQLTemplates templates) { - super(em, templates, new DefaultQueryMetadata()); - } - - /** - * Creates a new query - * - * @param em - * @param templates - * @param metadata - */ - public JPAQuery(EntityManager em, JPQLTemplates templates, QueryMetadata metadata) { - super(em, templates, metadata); - } - - public JPAQuery clone(EntityManager entityManager) { - JPAQuery q = new JPAQuery(entityManager, JPAProvider.getTemplates(entityManager), getMetadata().clone()); - q.clone(this); - return q; - } - -} diff --git a/querydsl-jpa/src/main/java/com/mysema/query/jpa/impl/JPAQueryFactory.java b/querydsl-jpa/src/main/java/com/mysema/query/jpa/impl/JPAQueryFactory.java deleted file mode 100644 index 795ea76e57..0000000000 --- a/querydsl-jpa/src/main/java/com/mysema/query/jpa/impl/JPAQueryFactory.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa.impl; - -import javax.annotation.Nullable; -import javax.inject.Provider; -import javax.persistence.EntityManager; - -import com.mysema.query.jpa.JPASubQuery; -import com.mysema.query.jpa.JPQLQueryFactory; -import com.mysema.query.jpa.JPQLTemplates; -import com.mysema.query.types.EntityPath; - -/** - * Factory class for query and DML clause creation - * - * @author tiwe - * - */ -public class JPAQueryFactory implements JPQLQueryFactory { - - @Nullable - private final JPQLTemplates templates; - - private final Provider<EntityManager> entityManager; - - public JPAQueryFactory(Provider<EntityManager> entityManager) { - this.entityManager = entityManager; - this.templates = null; - } - - public JPAQueryFactory(JPQLTemplates templates, Provider<EntityManager> entityManager) { - this.entityManager = entityManager; - this.templates = templates; - } - - @Override - public JPADeleteClause delete(EntityPath<?> path) { - if (templates != null) { - return new JPADeleteClause(entityManager.get(), path, templates); - } else { - return new JPADeleteClause(entityManager.get(), path); - } - } - - @Override - public JPAQuery from(EntityPath<?> from) { - return query().from(from); - } - - @Override - public JPAUpdateClause update(EntityPath<?> path) { - if (templates != null) { - return new JPAUpdateClause(entityManager.get(), path, templates); - } else { - return new JPAUpdateClause(entityManager.get(), path); - } - } - - @Override - public JPAQuery query() { - if (templates != null) { - return new JPAQuery(entityManager.get(), templates); - } else { - return new JPAQuery(entityManager.get()); - } - } - - @Override - public JPASubQuery subQuery() { - return new JPASubQuery(); - } - -} diff --git a/querydsl-jpa/src/main/java/com/mysema/query/jpa/impl/JPAUpdateClause.java b/querydsl-jpa/src/main/java/com/mysema/query/jpa/impl/JPAUpdateClause.java deleted file mode 100644 index 3f0b9eb489..0000000000 --- a/querydsl-jpa/src/main/java/com/mysema/query/jpa/impl/JPAUpdateClause.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa.impl; - -import java.util.List; -import java.util.Map; - -import javax.persistence.EntityManager; -import javax.persistence.Query; - -import com.mysema.query.DefaultQueryMetadata; -import com.mysema.query.JoinType; -import com.mysema.query.QueryMetadata; -import com.mysema.query.dml.UpdateClause; -import com.mysema.query.jpa.JPQLSerializer; -import com.mysema.query.jpa.JPQLTemplates; -import com.mysema.query.types.EntityPath; -import com.mysema.query.types.Expression; -import com.mysema.query.types.ExpressionUtils; -import com.mysema.query.types.NullExpression; -import com.mysema.query.types.Path; -import com.mysema.query.types.Predicate; - -/** - * UpdateClause implementation for JPA - * - * @author tiwe - * - */ -public class JPAUpdateClause implements UpdateClause<JPAUpdateClause> { - - private final QueryMetadata metadata = new DefaultQueryMetadata(); - - private final EntityManager entityManager; - - private final JPQLTemplates templates; - - public JPAUpdateClause(EntityManager em, EntityPath<?> entity) { - this(em, entity, JPAProvider.getTemplates(em)); - } - - public JPAUpdateClause(EntityManager em, EntityPath<?> entity, JPQLTemplates templates) { - this.entityManager = em; - this.templates = templates; - metadata.addJoin(JoinType.DEFAULT, entity); - } - - @Override - public long execute() { - JPQLSerializer serializer = new JPQLSerializer(templates, entityManager); - serializer.serializeForUpdate(metadata); - Map<Object,String> constants = serializer.getConstantToLabel(); - - Query query = entityManager.createQuery(serializer.toString()); - JPAUtil.setConstants(query, constants, metadata.getParams()); - return query.executeUpdate(); - } - - @Override - public <T> JPAUpdateClause set(Path<T> path, T value) { - if (value != null) { - metadata.addProjection(ExpressionUtils.eqConst(path, value)); - } else { - setNull(path); - } - return this; - } - - @Override - public <T> JPAUpdateClause set(Path<T> path, Expression<? extends T> expression) { - if (expression != null) { - metadata.addProjection(ExpressionUtils.eq(path, expression)); - } else { - setNull(path); - } - return this; - } - - @Override - public <T> JPAUpdateClause setNull(Path<T> path) { - metadata.addProjection(ExpressionUtils.eq(path, new NullExpression<T>(path.getType()))); - return this; - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - @Override - public JPAUpdateClause set(List<? extends Path<?>> paths, List<?> values) { - for (int i = 0; i < paths.size(); i++) { - if (values.get(i) != null) { - metadata.addProjection(ExpressionUtils.eqConst((Expression)paths.get(i), values.get(i))); - } else { - metadata.addProjection(ExpressionUtils.eq((Expression)paths.get(i), - new NullExpression(paths.get(i).getType()))); - } - } - return this; - } - - @Override - public JPAUpdateClause where(Predicate... o) { - for (Predicate p : o) { - metadata.addWhere(p); - } - return this; - } - - @Override - public String toString() { - JPQLSerializer serializer = new JPQLSerializer(templates, entityManager); - serializer.serializeForUpdate(metadata); - return serializer.toString(); - } - - @Override - public boolean isEmpty() { - return metadata.getProjection().isEmpty(); - } - -} diff --git a/querydsl-jpa/src/main/java/com/mysema/query/jpa/impl/JPAUtil.java b/querydsl-jpa/src/main/java/com/mysema/query/jpa/impl/JPAUtil.java deleted file mode 100644 index fdf68a86bf..0000000000 --- a/querydsl-jpa/src/main/java/com/mysema/query/jpa/impl/JPAUtil.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa.impl; - -import javax.persistence.Parameter; -import javax.persistence.Query; -import java.util.Map; - -import com.mysema.query.types.ParamExpression; -import com.mysema.query.types.ParamNotSetException; -import com.mysema.query.types.expr.Param; -import com.mysema.util.MathUtils; - -/** - * JPAUtil provides static utility methods for JPA - * - * @author tiwe - * - */ -public final class JPAUtil { - - private JPAUtil() {} - - public static void setConstants(Query query, Map<Object,String> constants, Map<ParamExpression<?>, Object> params) { - boolean hasParameters = !query.getParameters().isEmpty(); - for (Map.Entry<Object,String> entry : constants.entrySet()) { - String key = entry.getValue(); - Object val = entry.getKey(); - if (Param.class.isInstance(val)) { - val = params.get(val); - if (val == null) { - throw new ParamNotSetException((Param<?>) entry.getKey()); - } - } - if (hasParameters) { - Parameter parameter = query.getParameter(Integer.valueOf(key)); - Class parameterType = parameter != null ? parameter.getParameterType() : null; - if (parameterType != null && !parameterType.isInstance(val)) { - if (val instanceof Number && Number.class.isAssignableFrom(parameterType)) { - val = MathUtils.cast((Number) val, parameterType); - } - } - } - query.setParameter(Integer.valueOf(key), val); - } - } - -} diff --git a/querydsl-jpa/src/main/java/com/mysema/query/jpa/impl/package-info.java b/querydsl-jpa/src/main/java/com/mysema/query/jpa/impl/package-info.java deleted file mode 100644 index 71bb3c085a..0000000000 --- a/querydsl-jpa/src/main/java/com/mysema/query/jpa/impl/package-info.java +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ - -/** - * JPQL for JPA - */ -package com.mysema.query.jpa.impl; diff --git a/querydsl-jpa/src/main/java/com/mysema/query/jpa/package-info.java b/querydsl-jpa/src/main/java/com/mysema/query/jpa/package-info.java deleted file mode 100644 index a3ac57a349..0000000000 --- a/querydsl-jpa/src/main/java/com/mysema/query/jpa/package-info.java +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ - - -/** - * Query implementations for HQL and JPAQL - */ -package com.mysema.query.jpa; diff --git a/querydsl-jpa/src/main/java/com/mysema/query/jpa/sql/AbstractJPASQLQuery.java b/querydsl-jpa/src/main/java/com/mysema/query/jpa/sql/AbstractJPASQLQuery.java deleted file mode 100644 index 1ef72fab90..0000000000 --- a/querydsl-jpa/src/main/java/com/mysema/query/jpa/sql/AbstractJPASQLQuery.java +++ /dev/null @@ -1,324 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa.sql; - -import com.google.common.collect.HashMultimap; -import com.google.common.collect.Multimap; -import com.mysema.commons.lang.CloseableIterator; -import com.mysema.query.*; -import com.mysema.query.jpa.AbstractSQLQuery; -import com.mysema.query.jpa.NativeSQLSerializer; -import com.mysema.query.jpa.QueryHandler; -import com.mysema.query.jpa.impl.JPAProvider; -import com.mysema.query.jpa.impl.JPAUtil; -import com.mysema.query.sql.Configuration; -import com.mysema.query.sql.SQLSerializer; -import com.mysema.query.types.Expression; -import com.mysema.query.types.FactoryExpression; -import com.mysema.query.types.FactoryExpressionUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.annotation.Nullable; -import javax.persistence.EntityManager; -import javax.persistence.FlushModeType; -import javax.persistence.LockModeType; -import javax.persistence.Query; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -/** - * AbstractJPASQLQuery is the base class for JPA Native SQL queries - * - * @author tiwe - * - * @param <Q> - */ -public abstract class AbstractJPASQLQuery<Q extends AbstractJPASQLQuery<Q>> extends AbstractSQLQuery<Q> { - - private static final Logger logger = LoggerFactory.getLogger(AbstractJPASQLQuery.class); - - private final EntityManager entityManager; - - protected final Multimap<String,Object> hints = HashMultimap.create(); - - protected final QueryHandler queryHandler; - - @Nullable - protected LockModeType lockMode; - - @Nullable - protected FlushModeType flushMode; - - @Nullable - - protected FactoryExpression<?> projection; - - public AbstractJPASQLQuery(EntityManager em, Configuration configuration) { - this(em, configuration, new DefaultQueryMetadata().noValidate()); - } - - public AbstractJPASQLQuery(EntityManager em, Configuration configuration, QueryHandler queryHandler) { - this(em, configuration, queryHandler, new DefaultQueryMetadata().noValidate()); - } - - public AbstractJPASQLQuery(EntityManager em, Configuration configuration, QueryMetadata metadata) { - this(em, configuration, JPAProvider.getTemplates(em).getQueryHandler(), metadata); - } - - public AbstractJPASQLQuery(EntityManager em, Configuration configuration, QueryHandler queryHandler, QueryMetadata metadata) { - super(metadata, configuration); - this.entityManager = em; - this.queryHandler = queryHandler; - } - - public Query createQuery(Expression<?>... args) { - queryMixin.getMetadata().setValidate(false); - queryMixin.addProjection(args); - return createQuery(false); - } - - private Query createQuery(boolean forCount) { - NativeSQLSerializer serializer = (NativeSQLSerializer) serialize(forCount); - String queryString = serializer.toString(); - logQuery(queryString); - List<? extends Expression<?>> projection = queryMixin.getMetadata().getProjection(); - Query query; - - Expression<?> proj = projection.get(0); - if (!FactoryExpression.class.isAssignableFrom(proj.getClass()) && isEntityExpression(proj)) { - if (projection.size() == 1) { - if (queryHandler.createNativeQueryTyped()) { - query = entityManager.createNativeQuery(queryString, proj.getType()); - } else { - query = entityManager.createNativeQuery(queryString); - } - } else { - throw new IllegalArgumentException("Only single element entity projections are supported"); - } - - } else { - query = entityManager.createNativeQuery(queryString); - } - if (!forCount) { - Map<Expression<?>, String> aliases = serializer.getAliases(); - if (proj instanceof FactoryExpression) { - for (Expression<?> expr : ((FactoryExpression<?>)proj).getArgs()) { - if (isEntityExpression(expr)) { - queryHandler.addEntity(query, extractEntityExpression(expr).toString(), expr.getType()); - } else if (aliases.containsKey(expr)) { - queryHandler.addScalar(query, aliases.get(expr), expr.getType()); - } - } - } else if (isEntityExpression(proj)) { - queryHandler.addEntity(query, extractEntityExpression(proj).toString(), proj.getType()); - } else if (aliases.containsKey(proj)) { - queryHandler.addScalar(query, aliases.get(proj), proj.getType()); - } - } - - if (lockMode != null) { - query.setLockMode(lockMode); - } - if (flushMode != null) { - query.setFlushMode(flushMode); - } - - for (Map.Entry<String, Object> entry : hints.entries()) { - query.setHint(entry.getKey(), entry.getValue()); - } - - - // set constants - JPAUtil.setConstants(query, serializer.getConstantToLabel(), queryMixin.getMetadata().getParams()); - - FactoryExpression<?> wrapped = projection.size() > 1 ? FactoryExpressionUtils.wrap(projection) : null; - if ((projection.size() == 1 && projection.get(0) instanceof FactoryExpression) || wrapped != null) { - Expression<?> expr = wrapped != null ? wrapped : projection.get(0); - - if (!queryHandler.transform(query, (FactoryExpression<?>)expr)) { - this.projection = (FactoryExpression<?>)projection.get(0); - if (wrapped != null) { - this.projection = wrapped; - getMetadata().clearProjection(); - getMetadata().addProjection(wrapped); - } - } - } - - return query; - } - - @Override - protected SQLSerializer createSerializer() { - return new NativeSQLSerializer(configuration, queryHandler.wrapEntityProjections()); - } - - /** - * Transforms results using FactoryExpression if ResultTransformer can't be used - * - * @param query - * @return - */ - private List<?> getResultList(Query query) { - // TODO : use lazy list here? - if (projection != null) { - List<?> results = query.getResultList(); - List<Object> rv = new ArrayList<Object>(results.size()); - for (Object o : results) { - if (o != null) { - Object[] arr; - if (!o.getClass().isArray()) { - arr = new Object[]{o}; - } else { - arr = (Object[])o; - } - if (projection.getArgs().size() < arr.length) { - Object[] shortened = new Object[projection.getArgs().size()]; - System.arraycopy(arr, 0, shortened, 0, shortened.length); - arr = shortened; - } - rv.add(projection.newInstance(arr)); - } else { - rv.add(null); - } - } - return rv; - } else { - return query.getResultList(); - } - } - - /** - * Transforms results using FactoryExpression if ResultTransformer can't be used - * - * @param query - * @return - */ - @Nullable - private Object getSingleResult(Query query) { - if (projection != null) { - Object result = query.getSingleResult(); - if (result != null) { - if (!result.getClass().isArray()) { - result = new Object[]{result}; - } - return projection.newInstance((Object[])result); - } else { - return null; - } - } else { - return query.getSingleResult(); - } - } - - @SuppressWarnings("unchecked") - @Override - public <RT> List<RT> list(Expression<RT> projection) { - Query query = createQuery(projection); - return (List<RT>) getResultList(query); - } - - @Override - public <RT> CloseableIterator<RT> iterate(Expression<RT> expr) { - Query query = createQuery(expr); - return queryHandler.<RT>iterate(query, null); - } - - @Override - public <RT> SearchResults<RT> listResults(Expression<RT> projection) { - // TODO : handle entity projections as well - queryMixin.addProjection(projection); - Query query = createQuery(true); - long total = ((Number)query.getSingleResult()).longValue(); - if (total > 0) { - QueryModifiers modifiers = queryMixin.getMetadata().getModifiers(); - query = createQuery(false); - @SuppressWarnings("unchecked") - List<RT> list = (List<RT>) getResultList(query); - reset(); - return new SearchResults<RT>(list, modifiers, total); - } else { - reset(); - return SearchResults.emptyResults(); - } - } - - protected void logQuery(String queryString) { - if (logger.isDebugEnabled()) { - logger.debug(queryString.replace('\n', ' ')); - } - } - - protected void reset() { - queryMixin.getMetadata().reset(); - } - - @Override - @SuppressWarnings("unchecked") - public <RT> RT uniqueResult(Expression<RT> expr) { - Query query = createQuery(expr); - return (RT)uniqueResult(query); - } - - @Nullable - private Object uniqueResult(Query query) { - try{ - return getSingleResult(query); - } catch(javax.persistence.NoResultException e) { - logger.trace(e.getMessage(),e); - return null; - } catch(javax.persistence.NonUniqueResultException e) { - throw new NonUniqueResultException(); - } finally { - reset(); - } - } - - @SuppressWarnings("unchecked") - public Q setLockMode(LockModeType lockMode) { - this.lockMode = lockMode; - return (Q)this; - } - - @SuppressWarnings("unchecked") - public Q setFlushMode(FlushModeType flushMode) { - this.flushMode = flushMode; - return (Q)this; - } - - @SuppressWarnings("unchecked") - public Q setHint(String name, Object value) { - hints.put(name, value); - return (Q)this; - } - - @Override - protected void clone(Q query) { - super.clone(query); - flushMode = query.flushMode; - hints.putAll(query.hints); - lockMode = query.lockMode; - projection = query.projection; - } - - public abstract Q clone(EntityManager entityManager); - - @Override - public Q clone() { - return this.clone(this.entityManager); - } - -} diff --git a/querydsl-jpa/src/main/java/com/mysema/query/jpa/sql/JPASQLQuery.java b/querydsl-jpa/src/main/java/com/mysema/query/jpa/sql/JPASQLQuery.java deleted file mode 100644 index 8b1f611013..0000000000 --- a/querydsl-jpa/src/main/java/com/mysema/query/jpa/sql/JPASQLQuery.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa.sql; - -import com.mysema.query.QueryMetadata; -import com.mysema.query.jpa.QueryHandler; -import com.mysema.query.sql.Configuration; -import com.mysema.query.sql.SQLTemplates; - -import javax.persistence.EntityManager; - -/** - * JPASQLQuery is an SQLQuery implementation that uses JPA Native SQL functionality - * to execute queries - * - * @author tiwe - * - */ -public final class JPASQLQuery extends AbstractJPASQLQuery<JPASQLQuery> { - - public JPASQLQuery(EntityManager entityManager, SQLTemplates sqlTemplates) { - super(entityManager, new Configuration(sqlTemplates)); - } - - public JPASQLQuery(EntityManager entityManager, Configuration conf) { - super(entityManager, conf); - } - - public JPASQLQuery(EntityManager entityManager, Configuration conf, QueryHandler queryHandler) { - super(entityManager, conf, queryHandler); - } - - public JPASQLQuery(EntityManager entityManager, SQLTemplates sqlTemplates, QueryMetadata metadata) { - super(entityManager, new Configuration(sqlTemplates), metadata); - } - - public JPASQLQuery(EntityManager entityManager, Configuration conf, QueryMetadata metadata) { - super(entityManager, conf, metadata); - } - - public JPASQLQuery(EntityManager entityManager, Configuration conf, QueryHandler queryHandler, QueryMetadata metadata) { - super(entityManager, conf, queryHandler, metadata); - } - - @Override - public JPASQLQuery clone(EntityManager entityManager) { - JPASQLQuery q = new JPASQLQuery(entityManager, configuration, queryHandler, getMetadata().clone()); - q.clone(this); - return q; - } - -} diff --git a/querydsl-jpa/src/main/java/com/mysema/query/jpa/sql/package-info.java b/querydsl-jpa/src/main/java/com/mysema/query/jpa/sql/package-info.java deleted file mode 100644 index a106f7c961..0000000000 --- a/querydsl-jpa/src/main/java/com/mysema/query/jpa/sql/package-info.java +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ - -package com.mysema.query.jpa.sql; diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/AbstractSQLQuery.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/AbstractSQLQuery.java new file mode 100644 index 0000000000..1371a23607 --- /dev/null +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/AbstractSQLQuery.java @@ -0,0 +1,68 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import javax.persistence.Entity; + +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.support.QueryMixin; +import com.querydsl.core.types.EntityPath; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.Operation; +import com.querydsl.core.types.TemplateExpression; +import com.querydsl.sql.Configuration; +import com.querydsl.sql.ProjectableSQLQuery; + +/** + * Abstract super class for SQLQuery implementation for JPA and Hibernate + * + * @param <T> result type + * @param <Q> concrete subtype + * + * @author tiwe + */ +public abstract class AbstractSQLQuery<T, Q extends AbstractSQLQuery<T, Q>> extends ProjectableSQLQuery<T, Q> { + + private static final class NativeQueryMixin<T> extends QueryMixin<T> { + private NativeQueryMixin(QueryMetadata metadata) { + super(metadata, false); + } + + @Override + public <RT> Expression<RT> convert(Expression<RT> expr, Role role) { + return Conversions.convertForNativeQuery(super.convert(expr, role)); + } + } + + @SuppressWarnings("unchecked") + public AbstractSQLQuery(QueryMetadata metadata, Configuration configuration) { + super(new NativeQueryMixin<Q>(metadata), configuration); + this.queryMixin.setSelf((Q) this); + } + + protected boolean isEntityExpression(Expression<?> expr) { + return expr instanceof EntityPath || expr.getType().isAnnotationPresent(Entity.class); + } + + protected Expression<?> extractEntityExpression(Expression<?> expr) { + if (expr instanceof Operation) { + return ((Operation<?>) expr).getArg(0); + } else if (expr instanceof TemplateExpression) { + return (Expression<?>) ((TemplateExpression<?>) expr).getArg(0); + } else { + return expr; + } + } + +} diff --git a/querydsl-jpa/src/main/java/com/mysema/query/jpa/BatooTemplates.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/BatooTemplates.java similarity index 82% rename from querydsl-jpa/src/main/java/com/mysema/query/jpa/BatooTemplates.java rename to querydsl-jpa/src/main/java/com/querydsl/jpa/BatooTemplates.java index 32771f829d..5ef2178148 100644 --- a/querydsl-jpa/src/main/java/com/mysema/query/jpa/BatooTemplates.java +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/BatooTemplates.java @@ -1,5 +1,5 @@ /* - * Copyright 2012, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,11 +11,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.jpa; - -import com.mysema.query.types.Ops; +package com.querydsl.jpa; +import com.querydsl.core.types.Ops; +/** + * {@code BatooTemplates} extends {@link JPQLTemplates} with Batoo specific extensions + * + */ public class BatooTemplates extends JPQLTemplates { public static final BatooTemplates DEFAULT = new BatooTemplates(); diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/Conversions.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/Conversions.java new file mode 100644 index 0000000000..11cfd93771 --- /dev/null +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/Conversions.java @@ -0,0 +1,125 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import java.util.ArrayList; +import java.util.List; + +import javax.persistence.Entity; + +import com.querydsl.core.support.ConstantHidingExpression; +import com.querydsl.core.support.EnumConversion; +import com.querydsl.core.support.NumberConversion; +import com.querydsl.core.support.NumberConversions; +import com.querydsl.core.types.*; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.sql.RelationalPath; +import com.querydsl.sql.SQLOps; + +/** + * {@code Conversions} provides module specific projection conversion functionality + * + * @author tiwe + * + */ +public final class Conversions { + + public static <RT> Expression<RT> convert(Expression<RT> expr) { + if (expr instanceof FactoryExpression) { + FactoryExpression<RT> factoryExpr = (FactoryExpression<RT>) expr; + for (Expression<?> e: factoryExpr.getArgs()) { + if (needsConstantRemoval(e)) { + return convert(new ConstantHidingExpression<RT>(factoryExpr)); + } + } + for (Expression<?> e : factoryExpr.getArgs()) { + if (needsNumberConversion(e)) { + return new NumberConversions<RT>(factoryExpr); + } + } + } else if (needsNumberConversion(expr)) { + return new NumberConversion<RT>(expr); + } + return expr; + } + + private static boolean needsConstantRemoval(Expression<?> expr) { + expr = ExpressionUtils.extract(expr); + return expr instanceof Constant || expr.equals(Expressions.TRUE) || expr.equals(Expressions.FALSE) || + (expr instanceof Operation && ((Operation<?>) expr).getOperator() == Ops.ALIAS + && needsConstantRemoval(((Operation<?>) expr).getArg(0))); + } + + private static boolean needsNumberConversion(Expression<?> expr) { + expr = ExpressionUtils.extract(expr); + return Number.class.isAssignableFrom(expr.getType()) && !Path.class.isInstance(expr); + } + + private static boolean isEntityPathAndNeedsWrapping(Expression<?> expr) { + if ((expr instanceof Path && expr.getType().isAnnotationPresent(Entity.class)) || + (expr instanceof EntityPath && !RelationalPath.class.isInstance(expr))) { + Path<?> path = (Path<?>) expr; + if (path.getMetadata().getParent() == null) { + return true; + } + } + return false; + } + + private static <RT> FactoryExpression<RT> createEntityPathConversions(FactoryExpression<RT> factoryExpr) { + List<Expression<?>> conversions = new ArrayList<>(); + for (Expression<?> e : factoryExpr.getArgs()) { + if (isEntityPathAndNeedsWrapping(e)) { + conversions.add(ExpressionUtils.operation(e.getType(), SQLOps.ALL, e)); + } else { + conversions.add(e); + } + } + return FactoryExpressionUtils.wrap(factoryExpr, conversions); + } + + public static <RT> Expression<RT> convertForNativeQuery(Expression<RT> expr) { + if (isEntityPathAndNeedsWrapping(expr)) { + return ExpressionUtils.operation(expr.getType(), SQLOps.ALL, expr); + } else if (Number.class.isAssignableFrom(expr.getType())) { + return new NumberConversion<RT>(expr); + } else if (Enum.class.isAssignableFrom(expr.getType())) { + return new EnumConversion<RT>(expr); + } else if (expr instanceof FactoryExpression) { + FactoryExpression<RT> factoryExpr = (FactoryExpression<RT>) expr; + boolean numberConversions = false; + boolean hasEntityPath = false; + for (Expression<?> e : factoryExpr.getArgs()) { + if (isEntityPathAndNeedsWrapping(e)) { + hasEntityPath = true; + } else if (Number.class.isAssignableFrom(e.getType())) { + numberConversions = true; + } else if (Enum.class.isAssignableFrom(e.getType())) { + numberConversions = true; + } + } + if (hasEntityPath) { + factoryExpr = createEntityPathConversions(factoryExpr); + } + if (numberConversions) { + factoryExpr = new NumberConversions<RT>(factoryExpr); + } + return factoryExpr; + } + return expr; + } + + private Conversions() { } + +} diff --git a/querydsl-jpa/src/main/java/com/mysema/query/jpa/DataNucleusTemplates.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/DataNucleusTemplates.java similarity index 85% rename from querydsl-jpa/src/main/java/com/mysema/query/jpa/DataNucleusTemplates.java rename to querydsl-jpa/src/main/java/com/querydsl/jpa/DataNucleusTemplates.java index 1da0767a15..7a418ec7d6 100644 --- a/querydsl-jpa/src/main/java/com/mysema/query/jpa/DataNucleusTemplates.java +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/DataNucleusTemplates.java @@ -1,5 +1,5 @@ /* - * Copyright 2012, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,11 +11,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.jpa; - -import com.mysema.query.types.Ops; +package com.querydsl.jpa; +import com.querydsl.core.types.Ops; +/** + * {@code DataNucleusTemplates} extends {@link JPQLTemplates} with DataNucleus specific extensions + */ public class DataNucleusTemplates extends JPQLTemplates { public static final DataNucleusTemplates DEFAULT = new DataNucleusTemplates(); diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/DefaultQueryHandler.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/DefaultQueryHandler.java new file mode 100644 index 0000000000..c90e93c79d --- /dev/null +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/DefaultQueryHandler.java @@ -0,0 +1,84 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import java.util.Iterator; +import java.util.stream.Stream; + +import org.jetbrains.annotations.Nullable; +import javax.persistence.Query; + +import com.mysema.commons.lang.CloseableIterator; +import com.mysema.commons.lang.IteratorAdapter; +import com.querydsl.core.types.FactoryExpression; + +/** + * {@code DefaultQueryHandler} is the default implementation of the {@link QueryHandler} interface + * + * @author tiwe + * + */ +public final class DefaultQueryHandler implements QueryHandler { + + public static final QueryHandler DEFAULT = new DefaultQueryHandler(); + + @Override + public void addEntity(Query query, String alias, Class<?> type) { + // do nothing + } + + @Override + public void addScalar(Query query, String alias, Class<?> type) { + // do nothing + } + + @Override + public boolean createNativeQueryTyped() { + return true; + } + + @SuppressWarnings("unchecked") + @Override + public <T> CloseableIterator<T> iterate(Query query, @Nullable final FactoryExpression<?> projection) { + Iterator<T> iterator = query.getResultList().iterator(); + if (projection != null) { + return new TransformingIterator<T>(iterator, projection); + } else { + return new IteratorAdapter<T>(iterator); + } + } + + @Override + public <T> Stream<T> stream(Query query, @Nullable FactoryExpression<?> projection) { + final Stream resultStream = query.getResultStream(); + if (projection != null) { + return resultStream.map(element -> projection.newInstance((Object[]) (element.getClass().isArray() ? element : new Object[] {element}))); + } + return resultStream; + } + + @Override + public boolean transform(Query query, FactoryExpression<?> projection) { + return false; + } + + @Override + public boolean wrapEntityProjections() { + return false; + } + + private DefaultQueryHandler() { } + + +} diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/EclipseLinkHandler.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/EclipseLinkHandler.java new file mode 100644 index 0000000000..1c949da817 --- /dev/null +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/EclipseLinkHandler.java @@ -0,0 +1,123 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import java.io.Closeable; +import java.io.IOException; +import java.util.Iterator; +import java.util.stream.Stream; + +import javax.persistence.PersistenceException; +import javax.persistence.Query; + +import org.eclipse.persistence.config.HintValues; +import org.eclipse.persistence.config.QueryHints; +import org.eclipse.persistence.jpa.JpaQuery; +import org.eclipse.persistence.queries.Cursor; + +import com.mysema.commons.lang.CloseableIterator; +import com.mysema.commons.lang.IteratorAdapter; +import com.querydsl.core.types.FactoryExpression; +import org.jetbrains.annotations.Nullable; + +/** + * {@code EclipseLinkHandler} is the {@link QueryHandler} implementation for EclipseLink + * + * @author tiwe + * + */ +class EclipseLinkHandler implements QueryHandler { + + @Override + public void addEntity(Query query, String alias, Class<?> type) { + // do nothing + } + + @Override + public void addScalar(Query query, String alias, Class<?> type) { + // do nothing + } + + @Override + public boolean createNativeQueryTyped() { + return true; + } + + @SuppressWarnings("unchecked") + @Override + public <T> CloseableIterator<T> iterate(Query query, FactoryExpression<?> projection) { + boolean canUseCursor = false; + try { + canUseCursor = query.unwrap(Query.class) instanceof JpaQuery; + } catch (PersistenceException e) { } // can't unwrap, just ignore the exception + + Iterator<T> iterator = null; + Closeable closeable = null; + if (canUseCursor) { + query.setHint(QueryHints.CURSOR, HintValues.TRUE); + final Cursor cursor = (Cursor) query.getSingleResult(); + final int pageSize = cursor.getPageSize(); + closeable = new Closeable() { + @Override + public void close() throws IOException { + cursor.close(); + } + }; + iterator = new Iterator<T>() { + private int rowsSinceLastClear = 0; + + @Override + public boolean hasNext() { + return cursor.hasNext(); + } + + @Override + public T next() { + if (rowsSinceLastClear++ == pageSize) { + rowsSinceLastClear = 0; + cursor.clear(); + } + return (T) cursor.next(); + } + }; + } else { + iterator = query.getResultList().iterator(); + } + if (projection != null) { + return new TransformingIterator<T>(iterator, closeable, projection); + } else { + return new IteratorAdapter<T>(iterator, closeable); + } + } + + @Override + public <T> Stream<T> stream(Query query, @Nullable FactoryExpression<?> projection) { + final Stream resultStream = query.getResultStream(); + if (projection != null) { + return resultStream.map(element -> projection.newInstance((Object[]) (element.getClass().isArray() ? element : new Object[] {element}))); + } + return resultStream; + } + + @Override + public boolean transform(Query query, FactoryExpression<?> projection) { + return false; + } + + @Override + public boolean wrapEntityProjections() { + return false; + } + +} diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/EclipseLinkTemplates.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/EclipseLinkTemplates.java new file mode 100644 index 0000000000..5e1593986c --- /dev/null +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/EclipseLinkTemplates.java @@ -0,0 +1,98 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import com.querydsl.core.types.Ops; + +/** + * {@code EclipseLinkTemplates} extends {@link JPQLTemplates} with EclipseLink specific extensions + * + * @author tiwe + * + */ +public class EclipseLinkTemplates extends JPQLTemplates { + + private static final QueryHandler QUERY_HANDLER; + + static { + QueryHandler instance; + try { + instance = (QueryHandler) Class.forName("com.querydsl.jpa.EclipseLinkHandler").newInstance(); + } catch (NoClassDefFoundError | Exception e) { + instance = DefaultQueryHandler.DEFAULT; + } + QUERY_HANDLER = instance; + } + + + public static final EclipseLinkTemplates DEFAULT = new EclipseLinkTemplates(); + + private final Map<Class<?>, String> typeNames; + + public EclipseLinkTemplates() { + this(DEFAULT_ESCAPE); + } + + public EclipseLinkTemplates(char escape) { + super(escape, QUERY_HANDLER); + + Map<Class<?>, String> builder = new HashMap<>(); + builder.put(Short.class, "short"); + builder.put(Integer.class, "integer"); + builder.put(Long.class, "bigint"); + builder.put(BigInteger.class, "bigint"); + builder.put(Float.class, "float"); + builder.put(Double.class, "double"); + builder.put(BigDecimal.class, "double"); + typeNames = Collections.unmodifiableMap(builder); + + add(Ops.CHAR_AT, "substring({0},{1+'1'},1)"); + add(JPQLOps.CAST, "cast({0} {1s})"); + add(Ops.STRING_CAST, "trim(cast({0} char(128)))"); + add(Ops.NUMCAST, "cast({0} {1s})"); + + // datetime + add(Ops.DateTimeOps.MILLISECOND, "extract(millisecond from {0})"); + add(Ops.DateTimeOps.SECOND, "extract(second from {0})"); + add(Ops.DateTimeOps.MINUTE, "extract(minute from {0})"); + add(Ops.DateTimeOps.HOUR, "extract(hour from {0})"); + add(Ops.DateTimeOps.DAY_OF_WEEK, "extract(day_of_week from {0})"); + add(Ops.DateTimeOps.DAY_OF_MONTH, "extract(day from {0})"); + add(Ops.DateTimeOps.DAY_OF_YEAR, "extract(day_of_year from {0})"); + add(Ops.DateTimeOps.WEEK, "extract(week from {0})"); + add(Ops.DateTimeOps.MONTH, "extract(month from {0})"); + add(Ops.DateTimeOps.YEAR, "extract(year from {0})"); + + add(Ops.DateTimeOps.YEAR_MONTH, "extract(year from {0}) * 100 + extract(month from {0})"); + add(Ops.DateTimeOps.YEAR_WEEK, "extract(year from {0}) * 100 + extract(week from {0})"); + + } + + @Override + public String getTypeForCast(Class<?> cl) { + return typeNames.get(cl); + } + + @Override + public boolean isPathInEntitiesSupported() { + return false; + } + +} diff --git a/querydsl-jpa/src/main/java/com/mysema/query/jpa/FactoryExpressionTransformer.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/FactoryExpressionTransformer.java similarity index 84% rename from querydsl-jpa/src/main/java/com/mysema/query/jpa/FactoryExpressionTransformer.java rename to querydsl-jpa/src/main/java/com/querydsl/jpa/FactoryExpressionTransformer.java index 3476e8cfd4..631626a258 100644 --- a/querydsl-jpa/src/main/java/com/mysema/query/jpa/FactoryExpressionTransformer.java +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/FactoryExpressionTransformer.java @@ -1,5 +1,5 @@ /* - * Copyright 2011, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,16 +11,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.jpa; +package com.querydsl.jpa; import java.util.List; import org.hibernate.transform.ResultTransformer; -import com.mysema.query.types.FactoryExpression; +import com.querydsl.core.types.FactoryExpression; /** - * FactoryExpressionTransformer is a ResultTransformer implementation using FactoryExpression for transformation + * {@code FactoryExpressionTransformer} is a ResultTransformer implementation using + * FactoryExpression instances for transformation * * @author tiwe * diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/HQLTemplates.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/HQLTemplates.java new file mode 100644 index 0000000000..04b21ef0c4 --- /dev/null +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/HQLTemplates.java @@ -0,0 +1,123 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.querydsl.core.types.Operator; +import com.querydsl.core.types.Ops; + +/** + * HQLTemplates extends {@link JPQLTemplates} with Hibernate specific extensions + * + * @author tiwe + */ +public class HQLTemplates extends JPQLTemplates { + + private static final QueryHandler QUERY_HANDLER; + + static { + QueryHandler instance; + try { + instance = (QueryHandler) Class.forName("com.querydsl.jpa.HibernateHandler").newInstance(); + } catch (NoClassDefFoundError | Exception e) { + instance = DefaultQueryHandler.DEFAULT; + } + QUERY_HANDLER = instance; + } + + private static final List<Operator> wrapElements = Arrays.<Operator> asList( + Ops.QuantOps.ALL, + Ops.QuantOps.ANY, + Ops.QuantOps.AVG_IN_COL, + Ops.EXISTS); + + public static final HQLTemplates DEFAULT = new HQLTemplates(); + + private final Map<Class<?>, String> typeNames; + + public HQLTemplates() { + this(DEFAULT_ESCAPE); + } + + @SuppressWarnings("unchecked") + public HQLTemplates(char escape) { + super(escape, QUERY_HANDLER); + + Map<Class<?>, String> builder = new HashMap<>(); + builder.put(Byte.class, "byte"); + builder.put(Short.class, "short"); + builder.put(Integer.class, "integer"); + builder.put(Long.class, "long"); + builder.put(BigInteger.class, "big_integer"); + builder.put(Float.class, "float"); + builder.put(Double.class, "double"); + builder.put(BigDecimal.class, "big_decimal"); + typeNames = Collections.unmodifiableMap(builder); + + // add Hibernate Spatial mappings, if on classpath + try { + Class cl = Class.forName("com.querydsl.spatial.hibernate.HibernateSpatialSupport"); + add((Map) cl.getMethod("getSpatialOps").invoke(null)); + } catch (Exception e) { + // do nothing + } + } + + @Override + public boolean wrapElements(Operator operator) { + // For example: JPaIntegration.docoExamples98_12 + return wrapElements.contains(operator); + } + + @Override + public String getTypeForCast(Class<?> cl) { + String typeName = typeNames.get(cl); + if (typeName == null) { + return super.getTypeForCast(cl); + } + return typeName; + } + + @Override + public String getExistsProjection() { + // TODO Required / supported just for Hibernate? + return "1"; + } + + @Override + public boolean wrapConstant(Object constant) { + // related : https://hibernate.onjira.com/browse/HHH-6913 + Class<?> type = constant.getClass(); + return type.isArray() || Collection.class.isAssignableFrom(type); + } + + @Override + public boolean isWithForOn() { + return true; + } + + @Override + public boolean isCaseWithLiterals() { + return true; + } + +} diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/Hibernate5Templates.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/Hibernate5Templates.java new file mode 100644 index 0000000000..54191e652e --- /dev/null +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/Hibernate5Templates.java @@ -0,0 +1,32 @@ +package com.querydsl.jpa; + +/** + * Hibernate5Templates extends {@link JPQLTemplates} with Hibernate specific extensions + * + * @author Jan-Willem Gmelig Meyling + * + */ +public class Hibernate5Templates extends HQLTemplates { + + public static final Hibernate5Templates DEFAULT = new Hibernate5Templates(); + + public Hibernate5Templates() { + } + + public Hibernate5Templates(char escape) { + super(escape); + } + + @Override + public boolean wrapConstant(Object constant) { + // HHH-6913 is fixed in 5.0, default to JPA behaviour + return false; + } + + @Override + public boolean isWithForOn() { + // Hibernate supports the on-clause since 5.0, and the ON clause is actually mandatory for entity joins + return true; + } + +} diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/HibernateHandler.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/HibernateHandler.java new file mode 100644 index 0000000000..b47e4f2920 --- /dev/null +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/HibernateHandler.java @@ -0,0 +1,102 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import java.util.Iterator; +import java.util.stream.Stream; + +import javax.persistence.PersistenceException; +import javax.persistence.Query; + +import org.hibernate.ScrollMode; +import org.hibernate.ScrollableResults; +import org.hibernate.query.NativeQuery; +import org.hibernate.transform.ResultTransformer; + +import com.mysema.commons.lang.CloseableIterator; +import com.mysema.commons.lang.IteratorAdapter; +import com.querydsl.core.types.FactoryExpression; +import org.jetbrains.annotations.Nullable; + +/** + * {@code HibernateHandler} is the {@link QueryHandler} implementation for Hibernate + * + * @author tiwe + * + */ +public class HibernateHandler implements QueryHandler { + + @Override + public void addEntity(Query query, String alias, Class<?> type) { + query.unwrap(NativeQuery.class).addEntity(alias, type); + } + + @Override + public void addScalar(Query query, String alias, Class<?> type) { + query.unwrap(NativeQuery.class).addScalar(alias); + } + + @Override + public boolean createNativeQueryTyped() { + return false; + } + + @SuppressWarnings("unchecked") + @Override + public <T> CloseableIterator<T> iterate(Query query, FactoryExpression<?> projection) { + try { + org.hibernate.query.Query<?> unwrappedQuery = query.unwrap(org.hibernate.query.Query.class); + ScrollableResults results = unwrappedQuery.scroll(ScrollMode.FORWARD_ONLY); + CloseableIterator<T> iterator = new ScrollableResultsIterator<T>(results); + if (projection != null) { + iterator = new TransformingIterator<T>(iterator, projection); + } + return iterator; + } catch (PersistenceException e) { + Iterator<T> iterator = query.getResultList().iterator(); + if (projection != null) { + return new TransformingIterator<T>(iterator, projection); + } else { + return new IteratorAdapter<T>(iterator); + } + } + } + + @Override + @SuppressWarnings({"unchecked", "rawtypes"}) + public <T> Stream<T> stream(Query query, @Nullable FactoryExpression<?> projection) { + final Stream resultStream = query.getResultStream(); + if (projection != null) { + return resultStream.map(element -> projection.newInstance((Object[]) (element.getClass().isArray() ? element : new Object[] {element}))); + } + return resultStream; + } + + @Override + public boolean transform(Query query, FactoryExpression<?> projection) { + try { + ResultTransformer transformer = new FactoryExpressionTransformer(projection); + query.unwrap(org.hibernate.query.Query.class).setResultTransformer(transformer); + return true; + } catch (PersistenceException e) { + return false; + } + } + + @Override + public boolean wrapEntityProjections() { + return true; + } + +} diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/JPACollectionAnyVisitor.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/JPACollectionAnyVisitor.java new file mode 100644 index 0000000000..61b1e4e801 --- /dev/null +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/JPACollectionAnyVisitor.java @@ -0,0 +1,69 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import javax.persistence.Entity; + +import com.querydsl.core.JoinType; +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.support.CollectionAnyVisitor; +import com.querydsl.core.support.Context; +import com.querydsl.core.types.*; +import com.querydsl.core.types.dsl.EntityPathBase; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.SimplePath; + +/** + * {@code JPACollectionAnyVisitor} extends the {@link CollectionAnyVisitor} class with module specific + * extensions + * + * @author tiwe + * + */ +class JPACollectionAnyVisitor extends CollectionAnyVisitor { + + @SuppressWarnings("unchecked") + @Override + protected Predicate exists(Context c, Predicate condition) { + JPAQueryMixin<?> query = new JPAQueryMixin<Object>(); + query.setProjection(Expressions.ONE); + for (int i = 0; i < c.paths.size(); i++) { + Path<?> child = c.paths.get(i).getMetadata().getParent(); + EntityPath<Object> replacement = (EntityPath<Object>) c.replacements.get(i); + if (c.paths.get(i).getType().isAnnotationPresent(Entity.class)) { + query.addJoin(i == 0 ? JoinType.DEFAULT : JoinType.INNERJOIN, Expressions.as( + Expressions.listPath((Class) c.paths.get(i).getType(), SimplePath.class, + child.getMetadata()), replacement)); + } else { + // join via parent + Path<?> parent = child.getMetadata().getParent(); + EntityPathBase<Object> newParent = new EntityPathBase<Object>(parent.getType(), + ExpressionUtils.createRootVariable(parent, Math.abs(condition.hashCode()))); + EntityPath<Object> newChild = new EntityPathBase<Object>(child.getType(), + PathMetadataFactory.forProperty(newParent, child.getMetadata().getName())); + query.from(newParent); + query.addJoin(JoinType.INNERJOIN, Expressions.as(newChild, replacement)); + query.where(ExpressionUtils.eq(newParent, parent)); + } + } + c.clear(); + query.where(condition); + return ExpressionUtils.predicate(Ops.EXISTS, asExpression(query.getMetadata())); + } + + private Expression<?> asExpression(QueryMetadata metadata) { + return new SubQueryExpressionImpl<Object>(metadata.getProjection().getType(), metadata); + } + +} diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/JPAExpressions.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/JPAExpressions.java new file mode 100644 index 0000000000..2044e2a7f1 --- /dev/null +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/JPAExpressions.java @@ -0,0 +1,196 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import com.querydsl.core.Tuple; +import com.querydsl.core.types.CollectionExpression; +import com.querydsl.core.types.EntityPath; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.ExpressionException; +import com.querydsl.core.types.Ops; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.PathType; +import com.querydsl.core.types.dsl.BeanPath; +import com.querydsl.core.types.dsl.ComparableExpression; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.StringExpression; + +import javax.persistence.Entity; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.ParameterizedType; + +/** + * {@code JPAExpressions} provides factory methods for JPQL specific operations + * elements. + * + * @author tiwe + */ +@SuppressWarnings("unchecked") +public final class JPAExpressions { + + /** + * Create a new detached JPQLQuery instance with the given projection + * + * @param expr projection + * @param <T> + * @return select(expr) + */ + public static <T> JPQLQuery<T> select(Expression<T> expr) { + return new JPASubQuery<Void>().select(expr); + } + + /** + * Create a new detached JPQLQuery instance with the given projection + * + * @param exprs projection + * @return select(exprs) + */ + public static JPQLQuery<Tuple> select(Expression<?>... exprs) { + return new JPASubQuery<Void>().select(exprs); + } + + /** + * Create a new detached JPQLQuery instance with the given projection + * + * @param expr projection + * @param <T> + * @return select(distinct expr) + */ + public static <T> JPQLQuery<T> selectDistinct(Expression<T> expr) { + return new JPASubQuery<Void>().select(expr).distinct(); + } + + /** + * Create a new detached JPQLQuery instance with the given projection + * + * @param exprs projection + * @return select(distinct expr) + */ + public static JPQLQuery<Tuple> selectDistinct(Expression<?>... exprs) { + return new JPASubQuery<Void>().select(exprs).distinct(); + } + + /** + * Create a new detached JPQLQuery instance with the projection zero + * + * @return select(0) + */ + public static JPQLQuery<Integer> selectZero() { + return select(Expressions.ZERO); + } + + /** + * Create a new detached JPQLQuery instance with the projection one + * + * @return select(1) + */ + public static JPQLQuery<Integer> selectOne() { + return select(Expressions.ONE); + } + + /** + * Create a new detached JPQLQuery instance with the given projection + * + * @param expr projection and source + * @param <T> + * @return select(expr).from(expr) + */ + public static <T> JPQLQuery<T> selectFrom(EntityPath<T> expr) { + return select(expr).from(expr); + } + + /** + * Create a JPA 2.1 treated path. + * + * @param path The path to apply the treat operation on + * @param subtype subtype class + * @param <U> the subtype class + * @param <T> the expression type + * @return subtype instance with the same identity + */ + public static <U extends BeanPath<? extends T>, T> U treat(BeanPath<? extends T> path, Class<U> subtype) { + try { + Class<? extends T> entitySubType = getConcreteEntitySubType(subtype); + PathMetadata pathMetadata = new PathMetadata(path, getEntityName(entitySubType), PathType.TREATED_PATH); + return subtype.getConstructor(PathMetadata.class).newInstance(pathMetadata); + } catch (InstantiationException e) { + throw new ExpressionException(e.getMessage(), e); + } catch (IllegalAccessException e) { + throw new ExpressionException(e.getMessage(), e); + } catch (InvocationTargetException e) { + throw new ExpressionException(e.getMessage(), e); + } catch (NoSuchMethodException e) { + throw new ExpressionException(e.getMessage(), e); + } + } + + /** + * Create a avg(col) expression + * + * @param col collection + * @return avg(col) + */ + public static <A extends Comparable<? super A>> ComparableExpression<A> avg(CollectionExpression<?,A> col) { + return Expressions.comparableOperation((Class) col.getParameter(0), Ops.QuantOps.AVG_IN_COL, (Expression<?>) col); + } + + /** + * Create a max(col) expression + * + * @param left collection + * @return max(col) + */ + public static <A extends Comparable<? super A>> ComparableExpression<A> max(CollectionExpression<?,A> left) { + return Expressions.comparableOperation((Class) left.getParameter(0), Ops.QuantOps.MAX_IN_COL, (Expression<?>) left); + } + + /** + * Create a min(col) expression + * + * @param left collection + * @return min(col) + */ + public static <A extends Comparable<? super A>> ComparableExpression<A> min(CollectionExpression<?,A> left) { + return Expressions.comparableOperation((Class) left.getParameter(0), Ops.QuantOps.MIN_IN_COL, (Expression<?>) left); + } + + /** + * Create a type(path) expression + * + * @param path entity + * @return type(path) + */ + public static StringExpression type(EntityPath<?> path) { + return Expressions.stringOperation(JPQLOps.TYPE, path); + } + + private static String getEntityName(Class<?> clazz) { + final Entity entityAnnotation = clazz.getAnnotation(Entity.class); + if (entityAnnotation != null && entityAnnotation.name().length() > 0) { + return entityAnnotation.name(); + } else if (clazz.getPackage() != null) { + String pn = clazz.getPackage().getName(); + return clazz.getName().substring(pn.length() + 1); + } else { + return clazz.getName(); + } + } + + private static <U extends BeanPath<? extends T>, T> Class<? extends T> getConcreteEntitySubType(Class<U> subtype) { + return (Class<? extends T>) ((ParameterizedType) subtype.getGenericSuperclass()).getActualTypeArguments()[0]; + } + + private JPAExpressions() { } + +} diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/JPAListAccessVisitor.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/JPAListAccessVisitor.java new file mode 100644 index 0000000000..87ee9b2cfe --- /dev/null +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/JPAListAccessVisitor.java @@ -0,0 +1,91 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import java.util.HashMap; +import java.util.Map; + +import org.jetbrains.annotations.Nullable; + +import com.querydsl.core.JoinType; +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.support.ReplaceVisitor; +import com.querydsl.core.types.*; +import com.querydsl.core.types.dsl.Expressions; + +class JPAListAccessVisitor extends ReplaceVisitor<Void> { + + private final QueryMetadata metadata; + + private final Map<Expression<?>, Path<?>> aliases; + + private final Map<Path<?>, Path<?>> replacements = new HashMap<>(); + + JPAListAccessVisitor(QueryMetadata metadata, Map<Expression<?>, Path<?>> aliases) { + this.metadata = metadata; + this.aliases = aliases; + } + + @SuppressWarnings("unchecked") + @Override + public Expression<?> visit(Path<?> expr, @Nullable Void context) { + expr = (Path<?>) super.visit(expr, null); + PathMetadata pathMetadata = expr.getMetadata(); + if (pathMetadata.getPathType() == PathType.LISTVALUE + || pathMetadata.getPathType() == PathType.LISTVALUE_CONSTANT) { + Path<?> replacement = replacements.get(expr); + if (replacement == null) { + // join parent as path123 on index(path123) = ... + Path parent = shorten(pathMetadata.getParent(), true); + replacement = ExpressionUtils.path(expr.getType(), + ExpressionUtils.createRootVariable(parent, replacements.size())); + metadata.addJoin(JoinType.LEFTJOIN, ExpressionUtils.as(parent, replacement)); + metadata.addJoinCondition(ExpressionUtils.eq( + (Expression) Expressions.operation(Integer.class, JPQLOps.INDEX, replacement), + ExpressionUtils.toExpression(pathMetadata.getElement()))); + replacements.put(expr, replacement); + } + return replacement; + } else { + return super.visit(expr, context); + } + } + + /** + * Shorten the parent path to a length of max 2 elements + */ + private Path<?> shorten(Path<?> path, boolean outer) { + if (aliases.containsKey(path)) { + return aliases.get(path); + } else if (path.getMetadata().isRoot()) { + return path; + } else if (path.getMetadata().getParent().getMetadata().isRoot() && outer) { + return path; + } else { + Class<?> type = JPAQueryMixin.getElementTypeOrType(path); + Path<?> parent = shorten(path.getMetadata().getParent(), false); + Path oldPath = ExpressionUtils.path(path.getType(), + new PathMetadata(parent, path.getMetadata().getElement(), path.getMetadata().getPathType())); + if (oldPath.getMetadata().getParent().getMetadata().isRoot() && outer) { + return oldPath; + } else { + Path newPath = ExpressionUtils.path(type, ExpressionUtils.createRootVariable(oldPath)); + aliases.put(path, newPath); + metadata.addJoin(JoinType.LEFTJOIN, ExpressionUtils.as(oldPath, newPath)); + return newPath; + } + } + } + +} diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/JPAMapAccessVisitor.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/JPAMapAccessVisitor.java new file mode 100644 index 0000000000..a574e88625 --- /dev/null +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/JPAMapAccessVisitor.java @@ -0,0 +1,114 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import java.util.HashMap; +import java.util.Map; + +import org.jetbrains.annotations.Nullable; + +import com.querydsl.core.JoinType; +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.support.ReplaceVisitor; +import com.querydsl.core.types.*; +import com.querydsl.core.types.dsl.Expressions; + +class JPAMapAccessVisitor extends ReplaceVisitor<Void> { + + private final QueryMetadata metadata; + + private final Map<Expression<?>, Path<?>> aliases; + + private final Map<Path<?>, Path<?>> replacements = new HashMap<>(); + + JPAMapAccessVisitor(QueryMetadata metadata, Map<Expression<?>, Path<?>> aliases) { + this.metadata = metadata; + this.aliases = aliases; + } + + @SuppressWarnings("unchecked") + @Override + public Expression<?> visit(Operation<?> expr, @Nullable Void context) { + if (expr.getOperator() == Ops.CONTAINS_KEY) { + ParameterizedExpression map = (ParameterizedExpression<?>) expr.getArg(0); + Expression key = expr.getArg(1); + Path replacement = ExpressionUtils.path(map.getParameter(1), + ExpressionUtils.createRootVariable((Path<?>) map, Math.abs(expr.hashCode()))); + metadata.addJoin(JoinType.LEFTJOIN, ExpressionUtils.as(map, replacement)); + metadata.addJoinCondition(ExpressionUtils.eq( + Expressions.operation(map.getParameter(0), JPQLOps.KEY, replacement), + key)); + return ExpressionUtils.isNotNull(replacement); + } else if (expr.getOperator() == Ops.CONTAINS_VALUE) { + ParameterizedExpression<?> map = (ParameterizedExpression<?>) expr.getArg(0); + Expression<?> value = expr.getArg(1); + return Expressions.predicate(JPQLOps.MEMBER_OF, value, map); + } else { + return super.visit(expr, context); + } + } + + @SuppressWarnings("unchecked") + @Override + public Expression<?> visit(Path<?> expr, @Nullable Void context) { + expr = (Path<?>) super.visit(expr, null); + PathMetadata pathMetadata = expr.getMetadata(); + if (pathMetadata.getPathType() == PathType.MAPVALUE + || pathMetadata.getPathType() == PathType.MAPVALUE_CONSTANT) { + Path<?> replacement = replacements.get(expr); + if (replacement == null) { + // join parent as path123 on key(path123) = ... + Path parent = shorten(pathMetadata.getParent(), true); + ParameterizedExpression parExpr = (ParameterizedExpression) pathMetadata.getParent(); + replacement = ExpressionUtils.path(parExpr.getParameter(1), + ExpressionUtils.createRootVariable(parent, replacements.size())); + metadata.addJoin(JoinType.LEFTJOIN, ExpressionUtils.as(parent, replacement)); + metadata.addJoinCondition(ExpressionUtils.eq( + Expressions.operation(parExpr.getParameter(0), JPQLOps.KEY, replacement), + ExpressionUtils.toExpression(pathMetadata.getElement()))); + replacements.put(expr, replacement); + } + return replacement; + } else { + return super.visit(expr, context); + } + } + + /** + * Shorten the parent path to a length of max 2 elements + */ + private Path<?> shorten(Path<?> path, boolean outer) { + if (aliases.containsKey(path)) { + return aliases.get(path); + } else if (path.getMetadata().isRoot()) { + return path; + } else if (path.getMetadata().getParent().getMetadata().isRoot() && outer) { + return path; + } else { + Class<?> type = JPAQueryMixin.getElementTypeOrType(path); + Path<?> parent = shorten(path.getMetadata().getParent(), false); + Path oldPath = ExpressionUtils.path(path.getType(), + new PathMetadata(parent, path.getMetadata().getElement(), path.getMetadata().getPathType())); + if (oldPath.getMetadata().getParent().getMetadata().isRoot() && outer) { + return oldPath; + } else { + Path newPath = ExpressionUtils.path(type, ExpressionUtils.createRootVariable(oldPath)); + aliases.put(path, newPath); + metadata.addJoin(JoinType.LEFTJOIN, ExpressionUtils.as(oldPath, newPath)); + return newPath; + } + } + } + +} diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/JPAQueryBase.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/JPAQueryBase.java new file mode 100644 index 0000000000..ab84866658 --- /dev/null +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/JPAQueryBase.java @@ -0,0 +1,230 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.support.FetchableSubQueryBase; +import com.querydsl.core.types.*; +import com.querydsl.core.types.dsl.Expressions; + +/** + * {@code JPAQueryBase} is a base Query class for JPA queries + * + * @param <T> result type + * @param <Q> concrete subtype + * + * @author tiwe + */ +public abstract class JPAQueryBase<T, Q extends JPAQueryBase<T, Q>> extends FetchableSubQueryBase<T, Q> implements JPQLQuery<T> { + + protected final JPAQueryMixin<Q> queryMixin; + + private final JPQLTemplates templates; + + @SuppressWarnings("unchecked") + public JPAQueryBase(QueryMetadata md, JPQLTemplates templates) { + super(new JPAQueryMixin<Q>(md)); + super.queryMixin.setSelf((Q) this); + this.queryMixin = (JPAQueryMixin<Q>) super.queryMixin; + this.templates = templates; + } + + protected JPQLTemplates getTemplates() { + return templates; + } + + protected abstract JPQLSerializer createSerializer(); + + protected JPQLSerializer serialize(boolean forCountRow) { + return serialize(forCountRow, true); + } + + protected JPQLSerializer serialize(boolean forCountRow, boolean validate) { + if (validate) { + if (queryMixin.getMetadata().getJoins().isEmpty()) { + throw new IllegalArgumentException("No sources given"); + } + } + JPQLSerializer serializer = createSerializer(); + serializer.serialize(queryMixin.getMetadata(), forCountRow, null); + return serializer; + } + + protected abstract void reset(); + + @Override + public Q fetchJoin() { + return queryMixin.fetchJoin(); + } + + @Override + public Q fetchAll() { + return queryMixin.fetchAll(); + } + + public Q from(EntityPath<?> arg) { + return queryMixin.from(arg); + } + + @Override + public Q from(EntityPath<?>... args) { + return queryMixin.from(args); + } + + @SuppressWarnings("unchecked") + @Override + public <P> Q from(CollectionExpression<?,P> target, Path<P> alias) { + return (Q) queryMixin.from((Expression) Expressions.as((Path) target, alias)); + } + + @Override + public <P> Q innerJoin(CollectionExpression<?,P> target) { + return queryMixin.innerJoin(target); + } + + @Override + public <P> Q innerJoin(CollectionExpression<?,P>target, Path<P> alias) { + return queryMixin.innerJoin(target, alias); + } + + @Override + public <P> Q innerJoin(EntityPath<P> target) { + return queryMixin.innerJoin(target); + } + + @Override + public <P> Q innerJoin(EntityPath<P> target, Path<P> alias) { + return queryMixin.innerJoin(target, alias); + } + + @Override + public <P> Q innerJoin(MapExpression<?,P> target) { + return queryMixin.innerJoin(target); + } + + @Override + public <P> Q innerJoin(MapExpression<?,P> target, Path<P> alias) { + return queryMixin.innerJoin(target, alias); + } + + @Override + public <P> Q join(CollectionExpression<?,P> target) { + return queryMixin.join(target); + } + + @Override + public <P> Q join(CollectionExpression<?,P> target, Path<P> alias) { + return queryMixin.join(target, alias); + } + + @Override + public <P> Q join(EntityPath<P> target) { + return queryMixin.join(target); + } + + @Override + public <P> Q join(EntityPath<P> target, Path<P> alias) { + return queryMixin.join(target, alias); + } + + @Override + public <P> Q join(MapExpression<?,P> target) { + return queryMixin.join(target); + } + + @Override + public <P> Q join(MapExpression<?,P> target, Path<P> alias) { + return queryMixin.join(target, alias); + } + + @Override + public <P> Q leftJoin(CollectionExpression<?,P> target) { + return queryMixin.leftJoin(target); + } + + @Override + public <P> Q leftJoin(CollectionExpression<?,P> target, Path<P> alias) { + return queryMixin.leftJoin(target, alias); + } + + @Override + public <P> Q leftJoin(EntityPath<P> target) { + return queryMixin.leftJoin(target); + } + + @Override + public <P> Q leftJoin(EntityPath<P> target, Path<P> alias) { + return queryMixin.leftJoin(target, alias); + } + + @Override + public <P> Q leftJoin(MapExpression<?,P> target) { + return queryMixin.leftJoin(target); + } + + @Override + public <P> Q leftJoin(MapExpression<?,P> target, Path<P> alias) { + return queryMixin.leftJoin(target, alias); + } + + @Override + public <P> Q rightJoin(CollectionExpression<?,P> target) { + return queryMixin.rightJoin(target); + } + + @Override + public <P> Q rightJoin(CollectionExpression<?,P> target, Path<P> alias) { + return queryMixin.rightJoin(target, alias); + } + + @Override + public <P> Q rightJoin(EntityPath<P> target) { + return queryMixin.rightJoin(target); + } + + @Override + public <P> Q rightJoin(EntityPath<P> target, Path<P> alias) { + return queryMixin.rightJoin(target, alias); + } + + @Override + public <P> Q rightJoin(MapExpression<?,P> target) { + return queryMixin.rightJoin(target); + } + + @Override + public <P> Q rightJoin(MapExpression<?,P> target, Path<P> alias) { + return queryMixin.rightJoin(target, alias); + } + + public Q on(Predicate condition) { + return queryMixin.on(condition); + } + + @Override + public Q on(Predicate... conditions) { + return queryMixin.on(conditions); + } + + + @Override + public String toString() { + JPQLSerializer serializer = serialize(false, false); + return serializer.toString().trim(); + } + + @Override + public abstract Q clone(); + +} diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/JPAQueryMixin.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/JPAQueryMixin.java new file mode 100644 index 0000000000..ea494407a7 --- /dev/null +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/JPAQueryMixin.java @@ -0,0 +1,238 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.jetbrains.annotations.Nullable; +import javax.persistence.Entity; + +import com.querydsl.core.DefaultQueryMetadata; +import com.querydsl.core.JoinFlag; +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.support.Context; +import com.querydsl.core.support.PathsExtractor; +import com.querydsl.core.support.QueryMixin; +import com.querydsl.core.support.ReplaceVisitor; +import com.querydsl.core.types.*; +import com.querydsl.core.types.dsl.CollectionPathBase; + +/** + * {@code JPAQueryMixin} extends {@link QueryMixin} to support JPQL join construction + * + * @author tiwe + * + * @param <T> + */ +public class JPAQueryMixin<T> extends QueryMixin<T> { + + private final Set<Path<?>> paths = new HashSet<>(); + + private final Map<Expression<?>, Path<?>> aliases = new HashMap<>(); + + private final JPAMapAccessVisitor mapAccessVisitor; + + private final JPAListAccessVisitor listAccessVisitor; + + private final JPACollectionAnyVisitor collectionAnyVisitor; + + private final ReplaceVisitor<Void> replaceVisitor = new ReplaceVisitor<Void>() { + @Override + public Expression<?> visit(Path<?> expr, Void context) { + return convertPathForOrder(expr); + } + @Override + public Expression<?> visit(SubQueryExpression<?> expr, @Nullable Void context) { + // don't shorten paths inside subquery expressions + return expr; + } + }; + + + public static final JoinFlag FETCH = new JoinFlag("fetch "); + + public static final JoinFlag FETCH_ALL_PROPERTIES = new JoinFlag(" fetch all properties"); + + public JPAQueryMixin() { + this(null, new DefaultQueryMetadata()); + } + + public JPAQueryMixin(QueryMetadata metadata) { + this(null, metadata); + } + + public JPAQueryMixin(T self, QueryMetadata metadata) { + super(self, metadata); + mapAccessVisitor = new JPAMapAccessVisitor(metadata, aliases); + listAccessVisitor = new JPAListAccessVisitor(metadata, aliases); + collectionAnyVisitor = new JPACollectionAnyVisitor(); + } + + public T fetchJoin() { + addJoinFlag(FETCH); + return getSelf(); + } + + public T fetchAll() { + addJoinFlag(FETCH_ALL_PROPERTIES); + return getSelf(); + } + + @Override + protected <D> Expression<D> createAlias(Expression<?> expr, Path<D> alias) { + aliases.put(expr, alias); + return super.createAlias(expr, alias); + } + + static boolean isEntityPath(Path<?> path) { + if (path instanceof CollectionPathBase) { + return isEntityPath((Path<?>) ((CollectionPathBase) path).any()); + } else { + return path instanceof EntityPath + || path.getType().isAnnotationPresent(Entity.class); + } + } + + @SuppressWarnings("unchecked") + static <T> Class<T> getElementTypeOrType(Path<T> path) { + if (path instanceof CollectionExpression) { + return ((CollectionExpression) path).getParameter(0); + } else { + return (Class<T>) path.getType(); + } + } + + @SuppressWarnings("unchecked") + private <T> Path<T> shorten(Path<T> path, List<Path<?>> paths) { + PathMetadata metadata = path.getMetadata(); + if (metadata.isRoot() || paths.contains(path)) { + return path; + } else if (aliases.containsKey(path)) { + return (Path<T>) aliases.get(path); + } else if (metadata.getPathType() == PathType.COLLECTION_ANY) { + return (Path<T>) shorten(metadata.getParent(), paths); + } else if (!isEntityPath(path)) { + Path<?> parent = shorten(metadata.getParent(), paths); + if (parent.equals(metadata.getParent())) { + return path; + } else { + return ExpressionUtils.path(path.getType(), + new PathMetadata(parent, metadata.getElement(), metadata.getPathType())); + } + } else if (metadata.getParent().getMetadata().isRoot()) { + Class<T> type = getElementTypeOrType(path); + Path<T> newPath = ExpressionUtils.path(type, ExpressionUtils.createRootVariable(path)); + leftJoin(path, newPath); + return newPath; + } else { + Class<T> type = getElementTypeOrType(path); + Path<?> parent = shorten(metadata.getParent(), paths); + Path<T> oldPath = ExpressionUtils.path(path.getType(), + new PathMetadata(parent, metadata.getElement(), metadata.getPathType())); + Path<T> newPath = ExpressionUtils.path(type, ExpressionUtils.createRootVariable(oldPath)); + aliases.put(path, newPath); + leftJoin(oldPath, newPath); + return newPath; + } + } + + private <T> Path<T> convertPathForOrder(Path<T> path) { + PathMetadata metadata = path.getMetadata(); + // at least three levels + if (metadata.getParent() != null && !metadata.getParent().getMetadata().isRoot()) { + Set<Expression<?>> exprs = new HashSet<>(); + QueryMetadata md = getMetadata(); + exprs.addAll(md.getGroupBy()); + if (md.getProjection() != null) { + exprs.add(md.getProjection()); + } + if (md.getWhere() != null) { + exprs.add(md.getWhere()); + } + if (md.getHaving() != null) { + exprs.add(md.getHaving()); + } + List<Path<?>> paths = new ArrayList<>(); + // extract paths + PathsExtractor.DEFAULT.visit(exprs, paths); + + if (!paths.contains(path) && !paths.contains(metadata.getParent())) { + Path<?> shortened = shorten(metadata.getParent(), paths); + return ExpressionUtils.path(path.getType(), + new PathMetadata(shortened, metadata.getElement(), metadata.getPathType())); + } else { + return path; + } + } else { + return path; + } + } + + @SuppressWarnings("unchecked") + @Override + public <RT> Expression<RT> convert(Expression<RT> expr, Role role) { + expr = (Expression<RT>) expr.accept(mapAccessVisitor, null); + expr = (Expression<RT>) expr.accept(listAccessVisitor, null); + if (role == Role.ORDER_BY) { + if (expr instanceof Path) { + expr = convertPathForOrder((Path) expr); + } else { + expr = (Expression<RT>) expr.accept(replaceVisitor, null); + } + } + return Conversions.convert(super.convert(expr, role)); + } + + @Override + protected Predicate convert(Predicate predicate, Role role) { + if (predicate != null) { + predicate = (Predicate) ExpressionUtils.extract(predicate); + } + if (predicate != null) { + predicate = (Predicate) predicate.accept(mapAccessVisitor, null); + predicate = (Predicate) predicate.accept(listAccessVisitor, null); + } + if (predicate != null) { + // transform any usage + predicate = (Predicate) predicate.accept(collectionAnyVisitor, new Context()); + return predicate; + } else { + return null; + } + } + + @SuppressWarnings("unchecked") + private void addCondition(Context context, int i, Path<?> path, boolean where) { + paths.add(path); + EntityPath<?> alias = context.replacements.get(i); + leftJoin((Expression) path.getMetadata().getParent(), context.replacements.get(i)); + Expression index = ExpressionUtils.operation(Integer.class, JPQLOps.INDEX, alias); + Object element = path.getMetadata().getElement(); + if (!(element instanceof Expression)) { + element = ConstantImpl.create(element); + } + Predicate condition = ExpressionUtils.eq(index, (Expression) element); + if (where) { + super.where(condition); + } else { + super.having(condition); + } + } + +} diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/JPASubQuery.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/JPASubQuery.java new file mode 100644 index 0000000000..563accf253 --- /dev/null +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/JPASubQuery.java @@ -0,0 +1,85 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import com.mysema.commons.lang.CloseableIterator; +import com.querydsl.core.DefaultQueryMetadata; +import com.querydsl.core.NonUniqueResultException; +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.QueryResults; +import com.querydsl.core.Tuple; +import com.querydsl.core.types.Expression; + +class JPASubQuery<T> extends JPAQueryBase<T, JPASubQuery<T>> { + + JPASubQuery() { + super(new DefaultQueryMetadata(), JPQLTemplates.DEFAULT); + } + + JPASubQuery(QueryMetadata metadata) { + super(metadata, JPQLTemplates.DEFAULT); + } + + @Override + protected JPQLSerializer createSerializer() { + return new JPQLSerializer(getTemplates(), null); + } + + @Override + protected void reset() { + // do nothing + } + + @Override + public JPASubQuery<T> clone() { + return new JPASubQuery<T>(getMetadata().clone()); + } + + @Override + public <U> JPASubQuery<U> select(Expression<U> expr) { + queryMixin.setProjection(expr); + @SuppressWarnings("unchecked") // This is the new type + JPASubQuery<U> newType = (JPASubQuery<U>) this; + return newType; + } + + @Override + public JPASubQuery<Tuple> select(Expression<?>... exprs) { + queryMixin.setProjection(exprs); + @SuppressWarnings("unchecked") // This is the new type + JPASubQuery<Tuple> newType = (JPASubQuery<Tuple>) this; + return newType; + } + + @Override + public T fetchOne() throws NonUniqueResultException { + throw new UnsupportedOperationException(); + } + + @Override + public CloseableIterator<T> iterate() { + throw new UnsupportedOperationException(); + } + + @Override + public QueryResults<T> fetchResults() { + throw new UnsupportedOperationException(); + } + + @Override + public long fetchCount() { + throw new UnsupportedOperationException(); + } + +} diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/JPQLOps.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/JPQLOps.java new file mode 100644 index 0000000000..57c1c910c7 --- /dev/null +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/JPQLOps.java @@ -0,0 +1,44 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import com.querydsl.core.types.Operator; + +/** + * {@code JPQLOps} provides JPQL specific operators + * + * @author tiwe + * + */ +public enum JPQLOps implements Operator { + TREAT(Object.class), + INDEX(Integer.class), + TYPE(String.class), + CAST(Object.class), + MEMBER_OF(Boolean.class), + NOT_MEMBER_OF(Boolean.class), + KEY(Object.class), + VALUE(Object.class); + + private final Class<?> type; + + JPQLOps(Class<?> type) { + this.type = type; + } + + @Override + public Class<?> getType() { + return type; + } +} diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/JPQLQuery.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/JPQLQuery.java new file mode 100644 index 0000000000..34d3b71c24 --- /dev/null +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/JPQLQuery.java @@ -0,0 +1,321 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import com.querydsl.core.FetchableQuery; +import com.querydsl.core.Query; +import com.querydsl.core.Tuple; +import com.querydsl.core.support.ExtendedSubQuery; +import com.querydsl.core.types.*; + +/** + * Query interface for JPQL queries + * + * @param <T> result type + * + * @author tiwe + * + */ +public interface JPQLQuery<T> extends FetchableQuery<T, JPQLQuery<T>>, Query<JPQLQuery<T>>, ExtendedSubQuery<T> { + + /** + * Add sources to this query + * + * @param sources sources + * @return the current object + */ + JPQLQuery<T> from(EntityPath<?>... sources); + + /** + * Add a query source + * + * @param target collection + * @param alias alias + * @param <P> + * @return the current object + */ + <P> JPQLQuery<T> from(CollectionExpression<?,P> target, Path<P> alias); + + /** + * Create a inner join with the given target. + * Use fetchJoin() to add the fetchJoin parameter to this join. + * + * @param <P> + * @param target target + * @return the current object + */ + <P> JPQLQuery<T> innerJoin(EntityPath<P> target); + + /** + * Create a inner join with the given target and alias. + * + * @param <P> + * @param target target + * @param alias alias + * @return the current object + */ + <P> JPQLQuery<T> innerJoin(EntityPath<P> target, Path<P> alias); + + /** + * Create a inner join with the given target. + * Use fetchJoin() to add the fetchJoin parameter to this join. + * + * @param <P> + * @param target target + * @return the current object + */ + <P> JPQLQuery<T> innerJoin(CollectionExpression<?, P> target); + + /** + * Create a inner join with the given target and alias. + * + * @param <P> + * @param target target + * @param alias alias + * @return the current object + */ + <P> JPQLQuery<T> innerJoin(CollectionExpression<?,P> target, Path<P> alias); + + /** + * Create a inner join with the given target. + * Use fetchJoin() to add the fetchJoin parameter to this join. + * + * @param <P> + * @param target target + * @return the current object + */ + <P> JPQLQuery<T> innerJoin(MapExpression<?, P> target); + + /** + * Create a inner join with the given target and alias. + * + * @param <P> + * @param target target + * @param alias alias + * @return the current object + */ + <P> JPQLQuery<T> innerJoin(MapExpression<?, P> target, Path<P> alias); + + /** + * Create a join with the given target. + * Use fetchJoin() to add the fetchJoin parameter to this join. + * + * @param <P> + * @param target target + * @return the current object + */ + <P> JPQLQuery<T> join(EntityPath<P> target); + + /** + * Create a join with the given target and alias. + * + * @param <P> + * @param target target + * @param alias alias + * @return the current object + */ + <P> JPQLQuery<T> join(EntityPath<P> target, Path<P> alias); + + /** + * Create a join with the given target. + * Use fetchJoin() to add the fetchJoin parameter to this join. + * + * @param <P> + * @param target target + * @return the current object + */ + <P> JPQLQuery<T> join(CollectionExpression<?,P> target); + + /** + * Create a join with the given target + * Use fetchJoin() to add the fetchJoin parameter to this join + * + * @param <P> + * @param target target + * @param alias alias + * @return the current object + */ + <P> JPQLQuery<T> join(CollectionExpression<?,P> target, Path<P> alias); + + /** + * Create a join with the given target. + * Use fetchJoin() to add the fetchJoin parameter to this join. + * + * @param <P> + * @param target target + * @return the current object + */ + <P> JPQLQuery<T> join(MapExpression<?, P> target); + + /** + * Create a join with the given target and alias. + * + * @param <P> + * @param target target + * @param alias alias + * @return the current object + */ + <P> JPQLQuery<T> join(MapExpression<?, P> target, Path<P> alias); + + /** + * Create a left join with the given target. + * Use fetchJoin() to add the fetchJoin parameter to this join. + * + * @param <P> + * @param target target + * @return the current object + */ + <P> JPQLQuery<T> leftJoin(EntityPath<P> target); + + /** + * Create a left join with the given target and alias. + * + * @param <P> + * @param target target + * @param alias alias + * @return the current object + */ + <P> JPQLQuery<T> leftJoin(EntityPath<P> target, Path<P> alias); + + /** + * Create a left join with the given target. + * Use fetchJoin() to add the fetchJoin parameter to this join. + * + * @param <P> + * @param target target + * @return the current object + */ + <P> JPQLQuery<T> leftJoin(CollectionExpression<?,P> target); + + /** + * Create a left join with the given target and alias. + * + * @param <P> + * @param target target + * @param alias alias + * @return the current object + */ + <P> JPQLQuery<T> leftJoin(CollectionExpression<?,P> target, Path<P> alias); + + /** + * Create a left join with the given target. + * Use fetchJoin() to add the fetchJoin parameter to this join. + * + * @param <P> + * @param target target + * @return the current object + */ + <P> JPQLQuery<T> leftJoin(MapExpression<?, P> target); + + /** + * Create a left join with the given target and alias. + * + * @param <P> + * @param target target + * @param alias alias + * @return the current object + */ + <P> JPQLQuery<T> leftJoin(MapExpression<?, P> target, Path<P> alias); + + /** + * Create a right join with the given target. + * Use fetchJoin() to add the fetchJoin parameter to this join. + * + * @param <P> + * @param target target + * @return the current object + */ + <P> JPQLQuery<T> rightJoin(EntityPath<P> target); + + /** + * Create a right join with the given target and alias. + * + * @param <P> + * @param target target + * @param alias alias + * @return the current object + */ + <P> JPQLQuery<T> rightJoin(EntityPath<P> target, Path<P> alias); + + /** + * Create a right join with the given target. + * Use fetchJoin() to add the fetchJoin parameter to this join. + * + * @param <P> + * @param target target + * @return the current object + */ + <P> JPQLQuery<T> rightJoin(CollectionExpression<?,P> target); + + /** + * Create a right join with the given target and alias. + * + * @param <P> + * @param target target + * @param alias alias + * @return the current object + */ + <P> JPQLQuery<T> rightJoin(CollectionExpression<?,P> target, Path<P> alias); + + /** + * Create a right join with the given target. + * Use fetchJoin() to add the fetchJoin parameter to this join. + * + * @param <P> + * @param target target + * @return the current object + */ + <P> JPQLQuery<T> rightJoin(MapExpression<?, P> target); + + /** + * Create a right join with the given target and alias. + * + * @param <P> + * @param target target + * @param alias alias + * @return the current object + */ + <P> JPQLQuery<T> rightJoin(MapExpression<?, P> target, Path<P> alias); + + /** + * Add join conditions to the last added join + * + * @param condition join conditions + * @return the current object + */ + JPQLQuery<T> on(Predicate... condition); + + /** + * Add the "fetchJoin" flag to the last defined join + * + * Mind that collection joins might result in duplicate rows and that "inner join fetchJoin" + * will restrict your result set. + * + * @return the current object + */ + JPQLQuery<T> fetchJoin(); + + /** + * Add the "fetchJoin all properties" flag to the last defined join. + * @return the current object + */ + JPQLQuery<T> fetchAll(); + + @Override + <U> JPQLQuery<U> select(Expression<U> expr); + + @Override + JPQLQuery<Tuple> select(Expression<?>... exprs); + +} diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/JPQLQueryFactory.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/JPQLQueryFactory.java new file mode 100644 index 0000000000..4c18b87da1 --- /dev/null +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/JPQLQueryFactory.java @@ -0,0 +1,129 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import com.querydsl.core.QueryFactory; +import com.querydsl.core.Tuple; +import com.querydsl.core.dml.DeleteClause; +import com.querydsl.core.dml.InsertClause; +import com.querydsl.core.dml.UpdateClause; +import com.querydsl.core.types.EntityPath; +import com.querydsl.core.types.Expression; + +/** + * Common interface for JPA related QueryFactory implementations + * + * @author tiwe + * + */ +public interface JPQLQueryFactory extends QueryFactory<JPQLQuery<?>> { + + /** + * Create a new DELETE clause + * + * @param path entity to delete from + * @return delete clause + */ + DeleteClause<?> delete(EntityPath<?> path); + + /** + * Create a new JPQLQuery instance with the given projection + * + * @param expr projection + * @param <T> + * @return select(expr) + */ + <T> JPQLQuery<T> select(Expression<T> expr); + + /** + * Create a new JPQLQuery instance with the given projection + * + * @param exprs projection + * @return select(exprs) + */ + JPQLQuery<Tuple> select(Expression<?>... exprs); + + /** + * Create a new JPQLQuery instance with the given projection + * + * @param expr projection + * @param <T> + * @return select(distinct expr) + */ + <T> JPQLQuery<T> selectDistinct(Expression<T> expr); + + /** + * Create a new JPQLQuery instance with the given projection + * + * @param exprs projection + * @return select(distinct exprs) + */ + JPQLQuery<Tuple> selectDistinct(Expression<?>... exprs); + + /** + * Create a new JPQLQuery instance with the projection one + * + * @return select(1) + */ + JPQLQuery<Integer> selectOne(); + + /** + * Create a new JPQLQuery instance with the projection zero + * + * @return select(0) + */ + JPQLQuery<Integer> selectZero(); + + /** + * Create a new JPQLQuery instance with the given source and projection + * + * @param from projection and source + * @param <T> + * @return select(from).from(from) + */ + <T> JPQLQuery<T> selectFrom(EntityPath<T> from); + + /** + * Create a new Query with the given source + * + * @param from from + * @return from(from) + */ + JPQLQuery<?> from(EntityPath<?> from); + + /** + * Create a new Query with the given source + * + * @param from from + * @return from(from) + */ + JPQLQuery<?> from(EntityPath<?>... from); + + /** + * Create a new UPDATE clause + * + * @param path entity to update + * @return update clause + */ + UpdateClause<?> update(EntityPath<?> path); + + /** + * Create a new INSERT clause + * + * @param path entity to insert to + * @return insert clause + */ + InsertClause<?> insert(EntityPath<?> path); + +} \ No newline at end of file diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/JPQLSerializer.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/JPQLSerializer.java new file mode 100644 index 0000000000..06c0a1c759 --- /dev/null +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/JPQLSerializer.java @@ -0,0 +1,595 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import java.util.*; + +import org.jetbrains.annotations.Nullable; +import javax.persistence.*; +import javax.persistence.metamodel.EntityType; +import javax.persistence.metamodel.Metamodel; +import javax.persistence.metamodel.SingularAttribute; + +import com.querydsl.core.JoinExpression; +import com.querydsl.core.JoinType; +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.support.SerializerBase; +import com.querydsl.core.types.*; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.util.MathUtils; + +/** + * {@code JPQLSerializer} serializes Querydsl expressions into JPQL syntax. + * + * @author tiwe + */ +public class JPQLSerializer extends SerializerBase<JPQLSerializer> { + + private static final Set<? extends Operator> NUMERIC = Collections.unmodifiableSet(EnumSet.of( + Ops.ADD, Ops.SUB, Ops.MULT, Ops.DIV, + Ops.LT, Ops.LOE, Ops.GT, Ops.GOE, Ops.BETWEEN)); + + private static final Set<? extends Operator> CASE_OPS = Collections.unmodifiableSet(EnumSet.of( + Ops.CASE_EQ_ELSE, Ops.CASE_ELSE)); + + private static final String COMMA = ", "; + + private static final String DELETE = "delete from "; + + private static final String FROM = "from "; + + private static final String GROUP_BY = "\ngroup by "; + + private static final String HAVING = "\nhaving "; + + private static final String ORDER_BY = "\norder by "; + + private static final String SELECT = "select "; + + private static final String SELECT_COUNT = "select count("; + + private static final String SELECT_COUNT_DISTINCT = "select count(distinct "; + + private static final String SELECT_DISTINCT = "select distinct "; + + private static final String SET = "\nset "; + + private static final String UPDATE = "update "; + + private static final String INSERT = "insert into "; + + private static final String VALUES = "\nvalues "; + + private static final String WHERE = "\nwhere "; + + private static final String WITH = " with "; + + private static final String ON = " on "; + + private static final Map<JoinType, String> joinTypes = new EnumMap<JoinType, String>(JoinType.class); + + private final JPQLTemplates templates; + + private final EntityManager entityManager; + + private boolean inProjection = false; + + private boolean inCaseOperation = false; + + static { + joinTypes.put(JoinType.DEFAULT, COMMA); + joinTypes.put(JoinType.FULLJOIN, "\n full join "); + joinTypes.put(JoinType.INNERJOIN, "\n inner join "); + joinTypes.put(JoinType.JOIN, "\n inner join "); + joinTypes.put(JoinType.LEFTJOIN, "\n left join "); + joinTypes.put(JoinType.RIGHTJOIN, "\n right join "); + } + + private boolean wrapElements = false; + + public JPQLSerializer(JPQLTemplates templates) { + this(templates, null); + } + + public JPQLSerializer(JPQLTemplates templates, EntityManager em) { + super(templates); + this.templates = templates; + this.entityManager = em; + } + + private String getEntityName(Class<?> clazz) { + final Entity entityAnnotation = clazz.getAnnotation(Entity.class); + if (entityAnnotation != null && entityAnnotation.name().length() > 0) { + return entityAnnotation.name(); + } else if (clazz.getPackage() != null && clazz.getPackage().getName().length() > 0) { + String pn = clazz.getPackage().getName(); + return clazz.getName().substring(pn.length() + 1); + } else { + return clazz.getName(); + } + } + + private void handleJoinTarget(JoinExpression je) { + // type specifier + if (je.getTarget() instanceof EntityPath<?>) { + final EntityPath<?> pe = (EntityPath<?>) je.getTarget(); + if (pe.getMetadata().isRoot()) { + append(getEntityName(pe.getType())); + append(" "); + } + handle(je.getTarget()); + } else if (je.getTarget() instanceof Operation) { + Operation<?> op = (Operation) je.getTarget(); + if (op.getOperator() == Ops.ALIAS) { + boolean treat = false; + if (Collection.class.isAssignableFrom(op.getArg(0).getType())) { + if (op.getArg(0) instanceof CollectionExpression) { + Class<?> par = ((CollectionExpression) op.getArg(0)).getParameter(0); + treat = !par.equals(op.getArg(1).getType()); + } + } else if (Map.class.isAssignableFrom(op.getArg(0).getType())) { + if (op.getArg(0) instanceof MapExpression) { + Class<?> par = ((MapExpression) op.getArg(0)).getParameter(1); + treat = !par.equals(op.getArg(1).getType()); + } + } else { + treat = !op.getArg(0).getType().equals(op.getArg(1).getType()); + } + if (treat) { + Expression<?> entityName = ConstantImpl.create(getEntityName(op.getArg(1).getType())); + Expression<?> t = ExpressionUtils.operation(op.getType(), JPQLOps.TREAT, op.getArg(0), entityName); + op = ExpressionUtils.operation(op.getType(), Ops.ALIAS, t, op.getArg(1)); + } + } + handle(op); + } else { + handle(je.getTarget()); + } + } + + public void serialize(QueryMetadata metadata, boolean forCountRow, @Nullable String projection) { + final Expression<?> select = metadata.getProjection(); + final List<JoinExpression> joins = metadata.getJoins(); + final Predicate where = metadata.getWhere(); + final List<? extends Expression<?>> groupBy = metadata.getGroupBy(); + final Predicate having = metadata.getHaving(); + final List<OrderSpecifier<?>> orderBy = metadata.getOrderBy(); + + // select + boolean inProjectionOrig = inProjection; + inProjection = true; + if (projection != null) { + append(SELECT).append(projection).append("\n"); + + } else if (forCountRow) { + if (!groupBy.isEmpty()) { + append(SELECT_COUNT_DISTINCT); + handle(", ", groupBy); + } else { + if (!metadata.isDistinct()) { + append(SELECT_COUNT); + } else { + append(SELECT_COUNT_DISTINCT); + } + if (select != null) { + if (select instanceof FactoryExpression) { + handle(joins.get(0).getTarget()); + } else { + // TODO : make sure this works + handle(select); + } + } else { + handle(joins.get(0).getTarget()); + } + } + append(")\n"); + + } else if (select != null || !joins.isEmpty()) { + if (!metadata.isDistinct()) { + append(SELECT); + } else { + append(SELECT_DISTINCT); + } + if (select != null) { + handle(select); + } else { + handle(joins.get(0).getTarget()); + } + append("\n"); + + } + inProjection = inProjectionOrig; + + // from + if (!joins.isEmpty()) { + append(FROM); + serializeSources(forCountRow, joins); + } + + // where + if (where != null) { + append(WHERE).handle(where); + } + + // group by + if (!groupBy.isEmpty() && !forCountRow) { + append(GROUP_BY).handle(COMMA, groupBy); + } + + // having + if (having != null) { + append(HAVING).handle(having); + } + + // order by + if (!orderBy.isEmpty() && !forCountRow) { + append(ORDER_BY); + boolean first = true; + for (final OrderSpecifier<?> os : orderBy) { + if (!first) { + append(COMMA); + } + handle(os.getTarget()); + append(os.getOrder() == Order.ASC ? " asc" : " desc"); + if (os.getNullHandling() == OrderSpecifier.NullHandling.NullsFirst) { + append(" nulls first"); + } else if (os.getNullHandling() == OrderSpecifier.NullHandling.NullsLast) { + append(" nulls last"); + } + first = false; + } + } + } + + public void serializeForDelete(QueryMetadata md) { + append(DELETE); + handleJoinTarget(md.getJoins().get(0)); + if (md.getWhere() != null) { + append(WHERE).handle(md.getWhere()); + } + } + + private static String relativePathString(Expression<?> root, Path<?> path) { + StringBuilder pathString = new StringBuilder(path.getMetadata().getName().length()); + while (path.getMetadata().getParent() != null && !path.equals(root)) { + if (pathString.length() > 0) { + pathString.insert(0, '.'); + } + pathString.insert(0, path.getMetadata().getName()); + path = path.getMetadata().getParent(); + } + return pathString.toString(); + } + + public void serializeForInsert(QueryMetadata md, Collection<Path<?>> columns, List<Object> values, SubQueryExpression<?> query, Map<Path<?>, Expression<?>> inserts) { + append(INSERT); + final JoinExpression root = md.getJoins().get(0); + append(getEntityName(root.getTarget().getType())); + append(" ("); + boolean first = true; + for (Path<?> path : columns) { + if (!first) { + append(", "); + } + + append(relativePathString(root.getTarget(), path)); + first = false; + } + append(")\n"); + + if (values != null && values.size() > 0) { + append(VALUES); + append(" ("); + first = true; + for (Object value : values) { + if (!first) { + append(", "); + } + handle(value); + first = false; + } + append(")"); + } else if (inserts != null && inserts.entrySet().size() > 0) { + first = true; + for (Map.Entry<Path<?>, Expression<?>> entry : inserts.entrySet()) { + if (!first) { + append(", "); + } + handle(entry.getKey()); + append(" = "); + handle(entry.getValue()); + first = false; + } + } else { + serialize(query.getMetadata(), false, null); + } + } + + public void serializeForUpdate(QueryMetadata md, Map<Path<?>, Expression<?>> updates) { + append(UPDATE); + handleJoinTarget(md.getJoins().get(0)); + append(SET); + boolean first = true; + for (Map.Entry<Path<?>, Expression<?>> entry : updates.entrySet()) { + if (!first) { + append(", "); + } + handle(entry.getKey()); + append(" = "); + handle(entry.getValue()); + first = false; + } + if (md.getWhere() != null) { + append(WHERE).handle(md.getWhere()); + } + } + + private void serializeSources(boolean forCountRow, List<JoinExpression> joins) { + for (int i = 0; i < joins.size(); i++) { + final JoinExpression je = joins.get(i); + if (i > 0) { + append(joinTypes.get(je.getType())); + } + if (je.hasFlag(JPAQueryMixin.FETCH) && !forCountRow) { + handle(JPAQueryMixin.FETCH); + } + handleJoinTarget(je); + // XXX Hibernate specific flag + if (je.hasFlag(JPAQueryMixin.FETCH_ALL_PROPERTIES) && !forCountRow) { + handle(JPAQueryMixin.FETCH_ALL_PROPERTIES); + } + + if (je.getCondition() != null) { + append(templates.isWithForOn() ? WITH : ON); + handle(je.getCondition()); + } + } + } + + @Override + public void visitConstant(Object constant) { + if (inCaseOperation && templates.isCaseWithLiterals()) { + if (constant instanceof Collection) { + append("("); + boolean first = true; + for (Object o : (Collection) constant) { + if (!first) { + append(", "); + } + visitLiteral(o); + first = false; + } + append(")"); + } else { + visitLiteral(constant); + } + } else { + boolean wrap = templates.wrapConstant(constant); + if (wrap) { + append("("); + } + super.visitConstant(constant); + if (wrap) { + append(")"); + } + } + } + + public void visitLiteral(Object constant) { + append(templates.asLiteral(constant)); + } + + @Override + protected void serializeConstant(int parameterIndex, String constantLabel) { + append("?"); + append(Integer.toString(parameterIndex)); + } + + @Override + public Void visit(SubQueryExpression<?> query, Void context) { + append("("); + serialize(query.getMetadata(), false, null); + append(")"); + return null; + } + + @Override + public Void visit(Path<?> expr, Void context) { + // only wrap a PathCollection, if it the pathType is PROPERTY + boolean wrap = wrapElements + && (Collection.class.isAssignableFrom(expr.getType()) || Map.class.isAssignableFrom(expr.getType())) + && expr.getMetadata().getPathType().equals(PathType.PROPERTY); + if (wrap) { + append("elements("); + } + super.visit(expr, context); + if (wrap) { + append(")"); + } + return null; + } + + @Override + @SuppressWarnings("unchecked") + protected void visitOperation(Class<?> type, Operator operator, List<? extends Expression<?>> args) { + boolean oldInCaseOperation = inCaseOperation; + inCaseOperation = CASE_OPS.contains(operator); + boolean oldWrapElements = wrapElements; + wrapElements = templates.wrapElements(operator); + + if (operator == Ops.EQ && args.get(1) instanceof Operation && + ((Operation) args.get(1)).getOperator() == Ops.QuantOps.ANY) { + args = Arrays.<Expression<?>> asList(args.get(0), ((Operation) args.get(1)).getArg(0)); + visitOperation(type, Ops.IN, args); + + } else if (operator == Ops.NE && args.get(1) instanceof Operation && + ((Operation) args.get(1)).getOperator() == Ops.QuantOps.ANY) { + args = Arrays.<Expression<?>> asList(args.get(0), ((Operation) args.get(1)).getArg(0)); + visitOperation(type, Ops.NOT_IN, args); + + } else if (operator == Ops.IN || operator == Ops.NOT_IN) { + if (args.get(1) instanceof Path) { + visitAnyInPath(type, operator, args); + } else if (args.get(0) instanceof Path && args.get(1) instanceof Constant<?>) { + visitPathInCollection(type, operator, args); + } else { + super.visitOperation(type, operator, args); + } + + } else if (operator == Ops.NUMCAST) { + visitNumCast(args); + + } else if (operator == Ops.EXISTS && args.get(0) instanceof SubQueryExpression) { + final SubQueryExpression subQuery = (SubQueryExpression) args.get(0); + append("exists ("); + serialize(subQuery.getMetadata(), false, templates.getExistsProjection()); + append(")"); + + } else if (operator == Ops.MATCHES || operator == Ops.MATCHES_IC) { + super.visitOperation(type, Ops.LIKE, + Arrays.asList(args.get(0), ExpressionUtils.regexToLike((Expression<String>) args.get(1)))); + + } else if (operator == Ops.LIKE && args.get(1) instanceof Constant<?>) { + final String escape = String.valueOf(templates.getEscapeChar()); + final String escaped = args.get(1).toString().replace(escape, escape + escape); + super.visitOperation(String.class, Ops.LIKE, + Arrays.asList(args.get(0), ConstantImpl.create(escaped))); + + } else if (NUMERIC.contains(operator)) { + super.visitOperation(type, operator, normalizeNumericArgs(args)); + + } else if (operator == Ops.ALIAS) { + if (args.get(1) instanceof Path && !((Path<?>) args.get(1)).getMetadata().isRoot()) { + Path<?> path = (Path<?>) args.get(1); + args = Arrays.asList(args.get(0), + ExpressionUtils.path(path.getType(), path.getMetadata().getName())); + } + super.visitOperation(type, operator, args); + + } else { + try { + super.visitOperation(type, operator, args); + } catch (IllegalArgumentException e) { + if (operator.getClass().getName().endsWith("SQLOps")) { + throw new IllegalArgumentException(String.format("SQL Expressions like %s are not supported in JPQL - the query language for JPA. " + + "SQLExpressions.* can only be used in JPQL queries when these functions are registered as custom function in your ORM.%n" + + "\tTo fix this issue, you have three options:%n" + + "\t1) If you do want to use advanced, dialect specific, SQL functions within JPQL, make sure to make these functions available to " + + "your ORM through custom functions and register these with your JPATemplates instance.%n" + + "\t2) Use JPASQLQuery instead. This allows you to generate a pure SQL query based on your JPA metamodel.%n" + + "\t3) Consider using the Blaze-Persistence QueryDSL integration. Blaze-Persistence is an extension on top of " + + "JPA that makes various SQL specific functions like window functions available to JPQL.", operator.name()), e); + } else { + throw e; + } + } + } + + inCaseOperation = oldInCaseOperation; + wrapElements = oldWrapElements; + } + + private void visitNumCast(List<? extends Expression<?>> args) { + @SuppressWarnings("unchecked") //this is the second argument's type + Constant<Class<?>> rightArg = (Constant<Class<?>>) args.get(1); + + final Class<?> targetType = rightArg.getConstant(); + final String typeName = templates.getTypeForCast(targetType); + visitOperation(targetType, JPQLOps.CAST, Arrays.asList(args.get(0), ConstantImpl.create(typeName))); + } + + private void visitPathInCollection(Class<?> type, Operator operator, + List<? extends Expression<?>> args) { + Path<?> lhs = (Path<?>) args.get(0); + @SuppressWarnings("unchecked") + Constant<? extends Collection<?>> rhs = (Constant<? extends Collection<?>>) args.get(1); + if (rhs.getConstant().isEmpty()) { + operator = operator == Ops.IN ? Ops.EQ : Ops.NE; + args = Arrays.<Expression<?>> asList(Expressions.ONE, Expressions.TWO); + } else if (entityManager != null && !templates.isPathInEntitiesSupported() && args.get(0).getType().isAnnotationPresent(Entity.class)) { + final Metamodel metamodel = entityManager.getMetamodel(); + final PersistenceUnitUtil util = entityManager.getEntityManagerFactory().getPersistenceUnitUtil(); + final EntityType<?> entityType = metamodel.entity(args.get(0).getType()); + if (entityType.hasSingleIdAttribute()) { + SingularAttribute<?,?> id = getIdProperty(entityType); + // turn lhs into id path + lhs = ExpressionUtils.path(id.getJavaType(), lhs, id.getName()); + // turn rhs into id collection + Set<Object> ids = new HashSet<Object>(); + for (Object entity : rhs.getConstant()) { + ids.add(util.getIdentifier(entity)); + } + rhs = ConstantImpl.create(ids); + args = Arrays.asList(lhs, rhs); + } + } + + super.visitOperation(type, operator, args); + } + + @SuppressWarnings({"rawtypes", "unchecked"}) + private SingularAttribute<?,?> getIdProperty(EntityType entity) { + final Set<SingularAttribute> singularAttributes = entity.getSingularAttributes(); + for (final SingularAttribute singularAttribute : singularAttributes) { + if (singularAttribute.isId()) { + return singularAttribute; + } + } + return null; + } + + private void visitAnyInPath(Class<?> type, Operator operator, List<? extends Expression<?>> args) { + super.visitOperation(type, + operator == Ops.IN ? JPQLOps.MEMBER_OF : JPQLOps.NOT_MEMBER_OF, + args); + } + + @SuppressWarnings("unchecked") + private List<? extends Expression<?>> normalizeNumericArgs(List<? extends Expression<?>> args) { + //we do not yet let it produce these types + //we verify the types with isAssignableFrom() + @SuppressWarnings("unchecked") + List<? extends Expression<? extends Number>> potentialArgs = + (List<? extends Expression<? extends Number>>) args; + boolean hasConstants = false; + Class<? extends Number> numType = null; + for (Expression<? extends Number> arg : potentialArgs) { + if (Number.class.isAssignableFrom(arg.getType())) { + if (arg instanceof Constant<?>) { + hasConstants = true; + } else { + numType = arg.getType(); + } + } + } + if (hasConstants && numType != null) { + //now we do let the potentialArgs help us + final List<Expression<?>> newArgs = new ArrayList<Expression<?>>(args.size()); + for (final Expression<? extends Number> arg : potentialArgs) { + if (arg instanceof Constant<?> && Number.class.isAssignableFrom(arg.getType()) + && !arg.getType().equals(numType)) { + final Number number = ((Constant<? extends Number>) arg).getConstant(); + newArgs.add(ConstantImpl.create(MathUtils.cast(number, numType))); + } else { + newArgs.add(arg); + } + } + return newArgs; + } else { + //the types are all non-constants, or not Number expressions + return potentialArgs; + } + } + +} diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/JPQLTemplates.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/JPQLTemplates.java new file mode 100644 index 0000000000..8988a7d327 --- /dev/null +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/JPQLTemplates.java @@ -0,0 +1,234 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import java.util.Collections; +import java.util.EnumSet; +import java.util.Set; + +import org.jetbrains.annotations.Nullable; + +import com.querydsl.core.types.Operator; +import com.querydsl.core.types.Ops; +import com.querydsl.core.types.PathType; +import com.querydsl.core.types.Templates; + +/** + * {@code JPQLTemplates} extends {@link Templates} to provide operator patterns for JPQL + * serialization + * + * @author tiwe + * @see HQLTemplates + * @see EclipseLinkTemplates + */ +public class JPQLTemplates extends Templates { + + public static final char DEFAULT_ESCAPE = '!'; + + protected static final Set<? extends Operator> OTHER_LIKE_CASES + = Collections.unmodifiableSet(EnumSet.of(Ops.MATCHES, Ops.MATCHES_IC, + Ops.ENDS_WITH, Ops.ENDS_WITH_IC, + Ops.LIKE_IC, Ops.LIKE_ESCAPE_IC, + Ops.STARTS_WITH, Ops.STARTS_WITH_IC, + Ops.STRING_CONTAINS, Ops.STRING_CONTAINS_IC)); + + public static final JPQLTemplates DEFAULT = new JPQLTemplates(); + + private final QueryHandler queryHandler; + + protected JPQLTemplates() { + this(DEFAULT_ESCAPE, DefaultQueryHandler.DEFAULT); + } + + protected JPQLTemplates(char escape) { + this(escape, DefaultQueryHandler.DEFAULT); + } + + protected JPQLTemplates(char escape, QueryHandler queryHandler) { + super(escape); + this.queryHandler = queryHandler; + + setPrecedence(Precedence.COMPARISON, Ops.EQ, Ops.NE, Ops.EQ_IGNORE_CASE, + Ops.BETWEEN, Ops.COL_IS_EMPTY); + + // other like cases + setPrecedence(Precedence.COMPARISON, OTHER_LIKE_CASES); + + add(Ops.CASE, "case {0} end"); + add(Ops.CASE_WHEN, "when {0} then {1} {2}", 0); + add(Ops.CASE_ELSE, "else {0}", 0); + + //CHECKSTYLE:OFF + // boolean + add(Ops.AND, "{0} and {1}"); + add(Ops.NOT, "not {0}", Precedence.NOT); + add(Ops.OR, "{0} or {1}"); + add(Ops.XNOR, "{0} xnor {1}"); + add(Ops.XOR, "{0} xor {1}"); + + // comparison + add(Ops.BETWEEN, "{0} between {1} and {2}"); + + // numeric + add(Ops.MathOps.SQRT, "sqrt({0})"); + add(Ops.MOD, "mod({0},{1})", -1); + + // various + add(Ops.NE, "{0} <> {1}"); + add(Ops.IS_NULL, "{0} is null"); + add(Ops.IS_NOT_NULL, "{0} is not null"); + add(JPQLOps.CAST, "cast({0} as {1s})"); + add(Ops.NUMCAST, "cast({0} as {1s})"); + + // collection + add(JPQLOps.MEMBER_OF, "{0} member of {1}", Precedence.COMPARISON); + add(JPQLOps.NOT_MEMBER_OF, "{0} not member of {1}", Precedence.COMPARISON); + + add(Ops.IN, "{0} in {1}"); + add(Ops.NOT_IN, "{0} not in {1}"); + add(Ops.COL_IS_EMPTY, "{0} is empty"); + add(Ops.COL_SIZE, "size({0})"); + add(Ops.ARRAY_SIZE, "size({0})"); + + // string + add(Ops.LIKE, "{0} like {1} escape '" + escape + "'"); + add(Ops.CONCAT, "concat({0},{1})", -1); + add(Ops.MATCHES, "{0} like {1} escape '" + escape + "'"); // TODO : support real regexes + add(Ops.MATCHES_IC, "{0} like {1} escape '" + escape + "'"); // TODO : support real regexes + add(Ops.LOWER, "lower({0})"); + add(Ops.SUBSTR_1ARG, "substring({0},{1+'1's})"); + add(Ops.SUBSTR_2ARGS, "substring({0},{1+'1's},{2-1s})"); + add(Ops.TRIM, "trim({0})"); + add(Ops.UPPER, "upper({0})"); + add(Ops.EQ_IGNORE_CASE, "{0l} = {1l}"); + add(Ops.CHAR_AT, "cast(substring({0},{1+'1's},1) as char)", Precedence.ARITH_LOW); + add(Ops.STRING_IS_EMPTY, "length({0}) = 0"); + + add(Ops.STRING_CONTAINS, "{0} like {%1%} escape '" + escape + "'"); + add(Ops.STRING_CONTAINS_IC, "{0l} like {%%1%%} escape '" + escape + "'"); + add(Ops.ENDS_WITH, "{0} like {%1} escape '" + escape + "'"); + add(Ops.ENDS_WITH_IC, "{0l} like {%%1} escape '" + escape + "'"); + add(Ops.STARTS_WITH, "{0} like {1%} escape '" + escape + "'"); + add(Ops.STARTS_WITH_IC, "{0l} like {1%%} escape '" + escape + "'"); + add(Ops.INDEX_OF, "locate({1},{0})-1", Precedence.ARITH_LOW); + add(Ops.INDEX_OF_2ARGS, "locate({1},{0},{2+'1's})-1", Precedence.ARITH_LOW); + + // date time + add(Ops.DateTimeOps.SYSDATE, "sysdate"); + add(Ops.DateTimeOps.CURRENT_DATE, "current_date"); + add(Ops.DateTimeOps.CURRENT_TIME, "current_time"); + add(Ops.DateTimeOps.CURRENT_TIMESTAMP, "current_timestamp"); + + add(Ops.DateTimeOps.MILLISECOND, "0"); // NOT supported in HQL + add(Ops.DateTimeOps.SECOND, "second({0})"); + add(Ops.DateTimeOps.MINUTE, "minute({0})"); + add(Ops.DateTimeOps.HOUR, "hour({0})"); + add(Ops.DateTimeOps.DAY_OF_MONTH, "day({0})"); + add(Ops.DateTimeOps.MONTH, "month({0})"); + add(Ops.DateTimeOps.YEAR, "year({0})"); + + add(Ops.DateTimeOps.YEAR_MONTH, "year({0}) * 100 + month({0})", Precedence.ARITH_LOW); + add(Ops.DateTimeOps.YEAR_WEEK, "year({0}) * 100 + week({0})", Precedence.ARITH_LOW); + + // path types + add(PathType.PROPERTY, "{0}.{1s}"); + add(PathType.VARIABLE, "{0s}"); + add(PathType.TREATED_PATH, "treat({0} as {1s})"); + + // case for eq + add(Ops.CASE_EQ, "case {1} end"); + add(Ops.CASE_EQ_WHEN, "when {0} = {1} then {2} {3}", 0); + add(Ops.CASE_EQ_ELSE, "else {0}", 0); + + add(Ops.INSTANCE_OF, "type({0}) = {1}"); + add(JPQLOps.TYPE, "type({0})"); + add(JPQLOps.INDEX, "index({0})"); + add(JPQLOps.TREAT, "treat({0} as {1s})"); + add(JPQLOps.KEY, "key({0})"); + add(JPQLOps.VALUE, "value({0})"); + + //CHECKSTYLE:ON + } + + public boolean wrapElements(Operator operator) { + return false; + } + + public String getTypeForCast(Class<?> cl) { + return cl.getSimpleName().toLowerCase(); + } + + @Deprecated // kept for backwards compatibility + public boolean isEnumInPathSupported() { + return true; + } + + public boolean isPathInEntitiesSupported() { + return true; + } + + @Nullable + public String getExistsProjection() { + return null; + } + + public boolean wrapConstant(Object constant) { + // related : https://hibernate.onjira.com/browse/HHH-6913 + return false; + } + + public boolean isWithForOn() { + return false; + } + + public QueryHandler getQueryHandler() { + return queryHandler; + } + + public boolean isCaseWithLiterals() { + return false; + } + + public String asLiteral(Object constant) { + if (constant instanceof Boolean) { + return constant.toString(); + } else if (constant instanceof Number) { + return constant.toString(); + } else if (constant instanceof String) { + return "'" + escapeLiteral(constant.toString()) + "'"; + } else if (constant instanceof Enum) { + return constant.getClass().getName() + "." + ((Enum) constant).name(); + } else { + return "'" + constant.toString() + "'"; + } + } + + private String escapeLiteral(String str) { + StringBuilder builder = new StringBuilder(); + for (char ch : str.toCharArray()) { + if (ch == '\n') { + builder.append("\\n"); + continue; + } else if (ch == '\r') { + builder.append("\\r"); + continue; + } else if (ch == '\'') { + builder.append("''"); + continue; + } + builder.append(ch); + } + return builder.toString(); + } +} diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/NativeSQLSerializer.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/NativeSQLSerializer.java new file mode 100644 index 0000000000..6f2f24a57a --- /dev/null +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/NativeSQLSerializer.java @@ -0,0 +1,224 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.persistence.Column; +import javax.persistence.Table; + +import com.querydsl.core.JoinExpression; +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.types.*; +import com.querydsl.sql.*; + +/** + * {@code NativeSQLSerializer} extends {@link SQLSerializer} to extract referenced entity paths and change + * some serialization formats + * + * @author tiwe + * + */ +public final class NativeSQLSerializer extends SQLSerializer { + + private final Map<Expression<?>, List<String>> aliases = new HashMap<>(); + + private final boolean wrapEntityProjections; + + public NativeSQLSerializer(Configuration configuration) { + this(configuration, false); + } + + public NativeSQLSerializer(Configuration configuration, boolean wrapEntityProjections) { + super(configuration); + this.wrapEntityProjections = wrapEntityProjections; + } + + @Override + protected void appendAsColumnName(Path<?> path, boolean precededByDot) { + if (path.getAnnotatedElement().isAnnotationPresent(Column.class)) { + Column column = path.getAnnotatedElement().getAnnotation(Column.class); + if (!column.name().isEmpty()) { + append(getTemplates().quoteIdentifier(column.name(), precededByDot)); + } else { + super.appendAsColumnName(path, precededByDot); + } + } else { + super.appendAsColumnName(path, precededByDot); + } + } + + @Override + protected void handleJoinTarget(JoinExpression je) { + SQLTemplates templates = getTemplates(); + Class<?> type = je.getTarget().getType(); + if (type.isAnnotationPresent(Table.class) && templates.isSupportsAlias()) { + Table table = type.getAnnotation(Table.class); + boolean precededByDot; + if (!table.schema().isEmpty() && templates.isPrintSchema()) { + appendSchemaName(table.schema()); + append("."); + precededByDot = true; + } else { + precededByDot = false; + } + appendTableName(table.name(), precededByDot); + append(templates.getTableAlias()); + } + super.handleJoinTarget(je); + } + + private boolean isAlias(Expression<?> expr) { + return expr instanceof Operation && ((Operation<?>) expr).getOperator() == Ops.ALIAS; + } + + public Map<Expression<?>, List<String>> getAliases() { + return aliases; + } + + private boolean isAllExpression(Expression<?> expr) { + if (expr instanceof Operation) { + return ((Operation<?>) expr).getOperator() == SQLOps.ALL; + } else if (expr instanceof TemplateExpression) { + return ((TemplateExpression<?>) expr).getTemplate().toString().equals("*"); + } else { + return false; + } + } + + @Override + public void serialize(QueryMetadata metadata, boolean forCountRow) { + // TODO get rid of this wrapping when Hibernate doesn't require unique aliases anymore + boolean modified = false; + Set<String> used = new HashSet<String>(); + Expression<?> projection = metadata.getProjection(); + if (projection instanceof Path) { + Path<?> path = (Path<?>) projection; + if (!used.add(path.getMetadata().getName())) { + String alias = "col_1"; + aliases.computeIfAbsent(projection, NativeSQLSerializer::createArrayList).add(alias); + projection = ExpressionUtils.as(projection, alias); + modified = true; + } else if (path.getAnnotatedElement().isAnnotationPresent(Column.class)) { + Column column = path.getAnnotatedElement().getAnnotation(Column.class); + if (!column.name().isEmpty()) { + aliases.computeIfAbsent(projection, NativeSQLSerializer::createArrayList).add(column.name()); + } else { + aliases.computeIfAbsent(projection, NativeSQLSerializer::createArrayList).add(ColumnMetadata.getName(path)); + } + } else { + aliases.computeIfAbsent(projection, NativeSQLSerializer::createArrayList).add(ColumnMetadata.getName(path)); + } + } else if (projection instanceof FactoryExpression) { + FactoryExpression<?> factoryExpr = (FactoryExpression<?>) projection; + List<Expression<?>> fargs = new ArrayList<>(factoryExpr.getArgs()); + for (int j = 0; j < fargs.size(); j++) { + if (fargs.get(j) instanceof Path) { + Path<?> path = (Path<?>) fargs.get(j); + String columnName; + if (path.getAnnotatedElement().isAnnotationPresent(Column.class)) { + Column column = path.getAnnotatedElement().getAnnotation(Column.class); + if (!column.name().isEmpty()) { + columnName = column.name(); + } else { + columnName = ColumnMetadata.getName(path); + } + } else { + columnName = ColumnMetadata.getName(path); + } + if (!used.add(columnName)) { + String alias = "col_" + (j + 1); + aliases.computeIfAbsent(path, NativeSQLSerializer::createArrayList).add(alias); + fargs.set(j, ExpressionUtils.as(fargs.get(j), alias)); + } else { + aliases.computeIfAbsent(path, NativeSQLSerializer::createArrayList).add(columnName); + } + } else if (isAlias(fargs.get(j))) { + Operation<?> operation = (Operation<?>) fargs.get(j); + aliases.computeIfAbsent(operation, NativeSQLSerializer::createArrayList).add(operation.getArg(1).toString()); + } else if (!isAllExpression(fargs.get(j))) { + String alias = "col_" + (j + 1); + aliases.computeIfAbsent(fargs.get(j), NativeSQLSerializer::createArrayList).add(alias); + fargs.set(j, ExpressionUtils.as(fargs.get(j), alias)); + } + } + projection = Projections.tuple(new ArrayList<>(fargs)); + modified = true; + } else if (isAlias(projection)) { + Operation<?> operation = (Operation<?>) projection; + aliases.computeIfAbsent(operation, NativeSQLSerializer::createArrayList).add(operation.getArg(1).toString()); + } else { + // https://github.com/querydsl/querydsl/issues/80 + if (!isAllExpression(projection)) { + String alias = "col_1"; + aliases.computeIfAbsent(projection, NativeSQLSerializer::createArrayList).add(alias); + projection = ExpressionUtils.as(projection, alias); + modified = true; + } + } + if (modified) { + metadata = metadata.clone(); + metadata.setProjection(projection); + } + super.serialize(metadata, forCountRow); + } + + private static <T> ArrayList<T> createArrayList(Object key) { + return new ArrayList<T>(); + } + + @Override + public void visitConstant(Object constant) { + if (constant instanceof Collection<?>) { + append("("); + boolean first = true; + for (Object element : ((Collection<?>) constant)) { + if (!first) { + append(", "); + } + visitConstant(element); + first = false; + } + append(")"); + } else { + super.visitConstant(constant); + } + } + + @Override + protected void serializeConstant(int parameterIndex, String constantLabel) { + append("?"); + append(Integer.toString(parameterIndex)); + } + + @Override + protected void visitOperation(Class<?> type, Operator operator, List<? extends Expression<?>> args) { + if (operator == SQLOps.ALL + && !(args.get(0) instanceof RelationalPath) + && wrapEntityProjections) { + append("{"); + super.visitOperation(type, operator, args); + append("}"); + } else { + super.visitOperation(type, operator, args); + } + } + +} diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/OpenJPATemplates.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/OpenJPATemplates.java new file mode 100644 index 0000000000..15654a973e --- /dev/null +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/OpenJPATemplates.java @@ -0,0 +1,40 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import com.querydsl.core.types.Ops; +import com.querydsl.core.types.PathType; + +/** + * {@code OpenJPATemplates} extends {@link JPQLTemplates} with OpenJPA specific extensions + * + * @author tiwe + * + */ +public class OpenJPATemplates extends JPQLTemplates { + + public static final OpenJPATemplates DEFAULT = new OpenJPATemplates(); + + public OpenJPATemplates() { + this(DEFAULT_ESCAPE); + add(PathType.VARIABLE, "{0s}_"); + add(Ops.ALIAS, "{0} {1}"); + add(Ops.NEGATE, "-1 * {0}", 7); + } + + public OpenJPATemplates(char escape) { + super(escape); + } + +} diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/QueryHandler.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/QueryHandler.java new file mode 100644 index 0000000000..9001421b42 --- /dev/null +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/QueryHandler.java @@ -0,0 +1,89 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import org.jetbrains.annotations.Nullable; +import javax.persistence.Query; + +import com.mysema.commons.lang.CloseableIterator; +import com.querydsl.core.types.FactoryExpression; + +import java.util.stream.Stream; + +/** + * {@code QueryHandle}r provides injection of provider specific functionality into the query logic + * + * @author tiwe + * + */ +public interface QueryHandler { + + /** + * Return whether native queries should be created as typed queries + * + * @return whether native queries should be created as typed queries + */ + boolean createNativeQueryTyped(); + + /** + * Iterate the results with the optional projection + * + * @param query query + * @return iterator + */ + <T> CloseableIterator<T> iterate(Query query, @Nullable FactoryExpression<?> projection); + + /** + * Stream the results with the optional projection + * + * @param query query + * @return stream + */ + <T> Stream<T> stream(Query query, @Nullable FactoryExpression<?> projection); + + /** + * Add the given scalar to the given native query + * + * @param query query + * @param alias alias + * @param type type + */ + void addScalar(Query query, String alias, Class<?> type); + + /** + * Add the given entity to the given native query + * + * @param query query + * @param alias alias + * @param type type + */ + void addEntity(Query query, String alias, Class<?> type); + + /** + * Transform the results of the given query using the given factory expression + * + * @param query query + * @param projection projection + * @return true, if query as been modified + */ + boolean transform(Query query, FactoryExpression<?> projection); + + /** + * Return whether entity projections need to be wrapped + * + * @return whether entity projections need to be wrapped + */ + boolean wrapEntityProjections(); + +} diff --git a/querydsl-jpa/src/main/java/com/mysema/query/jpa/ScrollableResultsIterator.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/ScrollableResultsIterator.java similarity index 88% rename from querydsl-jpa/src/main/java/com/mysema/query/jpa/ScrollableResultsIterator.java rename to querydsl-jpa/src/main/java/com/querydsl/jpa/ScrollableResultsIterator.java index b8793a0644..d6f7087e99 100644 --- a/querydsl-jpa/src/main/java/com/mysema/query/jpa/ScrollableResultsIterator.java +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/ScrollableResultsIterator.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,18 +11,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.jpa; +package com.querydsl.jpa; import java.util.NoSuchElementException; -import javax.annotation.Nullable; +import org.jetbrains.annotations.Nullable; import org.hibernate.ScrollableResults; import com.mysema.commons.lang.CloseableIterator; /** - * ScrollableResultsIterator is an {@link CloseableIterator} adapter for ScrollableResults + * {@code ScrollableResultsIterator} is a {@link CloseableIterator} adapter for ScrollableResults * * @author tiwe * diff --git a/querydsl-jpa/src/main/java/com/mysema/query/jpa/TransformingIterator.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/TransformingIterator.java similarity index 83% rename from querydsl-jpa/src/main/java/com/mysema/query/jpa/TransformingIterator.java rename to querydsl-jpa/src/main/java/com/querydsl/jpa/TransformingIterator.java index e0df10158d..a6d2c8848c 100644 --- a/querydsl-jpa/src/main/java/com/mysema/query/jpa/TransformingIterator.java +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/TransformingIterator.java @@ -1,6 +1,6 @@ /* - * Copyright 2013, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,16 +11,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.jpa; +package com.querydsl.jpa; import java.io.Closeable; import java.io.IOException; import java.util.Iterator; import com.mysema.commons.lang.CloseableIterator; -import com.mysema.query.types.FactoryExpression; +import com.querydsl.core.types.FactoryExpression; /** + * {@code TransformingIterator} is a CloseableIterator adapter that transforms via a {@link FactoryExpression} instance + * * @author tiwe * * @param <T> @@ -28,28 +30,29 @@ public class TransformingIterator<T> implements CloseableIterator<T> { private final Iterator<T> iterator; - + private final Closeable closeable; - + private final FactoryExpression<?> projection; - + public TransformingIterator(Iterator<T> iterator, FactoryExpression<?> projection) { this.iterator = iterator; this.projection = projection; - this.closeable = iterator instanceof Closeable ? (Closeable)iterator : null; + this.closeable = iterator instanceof Closeable ? (Closeable) iterator : null; } - + public TransformingIterator(Iterator<T> iterator, Closeable closeable, FactoryExpression<?> projection) { this.iterator = iterator; this.projection = projection; this.closeable = closeable; } - + @Override public boolean hasNext() { return iterator.hasNext(); } + @SuppressWarnings("unchecked") @Override public T next() { Object result = iterator.next(); @@ -57,10 +60,10 @@ public T next() { if (!result.getClass().isArray()) { result = new Object[]{result}; } - return (T)projection.newInstance((Object[])result); + return (T) projection.newInstance((Object[]) result); } else { return null; - } + } } @Override @@ -76,8 +79,8 @@ public void close() { } catch (IOException e) { throw new RuntimeException(e.getMessage(), e); } - } + } } - + } diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/hibernate/AbstractHibernateQuery.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/hibernate/AbstractHibernateQuery.java new file mode 100644 index 0000000000..2039447174 --- /dev/null +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/hibernate/AbstractHibernateQuery.java @@ -0,0 +1,389 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.hibernate; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.stream.Stream; + +import org.jetbrains.annotations.Nullable; + +import org.hibernate.*; +import org.hibernate.query.Query; + +import com.mysema.commons.lang.CloseableIterator; +import com.querydsl.core.*; +import com.querydsl.core.NonUniqueResultException; +import com.querydsl.core.QueryException; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.FactoryExpression; +import com.querydsl.core.types.Path; +import com.querydsl.jpa.*; + +/** + * Abstract base class for Hibernate API based implementations of the JPQL interface + * + * @param <T> result type + * @param <Q> concrete subtype + * + * @author tiwe + */ +public abstract class AbstractHibernateQuery<T, Q extends AbstractHibernateQuery<T, Q>> extends JPAQueryBase<T, Q> { + + private static final Logger logger = Logger.getLogger(HibernateQuery.class.getName()); + + @Nullable + protected Boolean cacheable, readOnly; + + @Nullable + protected String cacheRegion, comment; + + protected int fetchSize = 0; + + protected final Map<Path<?>,LockMode> lockModes = new HashMap<Path<?>,LockMode>(); + + @Nullable + protected FlushMode flushMode; + + private final SessionHolder session; + + protected int timeout = 0; + + public AbstractHibernateQuery(Session session) { + this(new DefaultSessionHolder(session), HQLTemplates.DEFAULT, new DefaultQueryMetadata()); + } + + public AbstractHibernateQuery(SessionHolder session, JPQLTemplates patterns, QueryMetadata metadata) { + super(metadata, patterns); + this.session = session; + } + + @Override + public long fetchCount() { + QueryModifiers modifiers = getMetadata().getModifiers(); + try { + Query query = createQuery(modifiers, true); + Long rv = (Long) query.uniqueResult(); + if (rv != null) { + return rv; + } else { + throw new QueryException("Query returned null"); + } + } finally { + reset(); + } + } + + /** + * Expose the original Hibernate query for the given projection + * + * @return query + */ + public Query createQuery() { + return createQuery(getMetadata().getModifiers(), false); + } + + private Query createQuery(@Nullable QueryModifiers modifiers, boolean forCount) { + JPQLSerializer serializer = serialize(forCount); + String queryString = serializer.toString(); + logQuery(queryString); + Query query = session.createQuery(queryString); + HibernateUtil.setConstants(query, serializer.getConstants(), + getMetadata().getParams()); + if (fetchSize > 0) { + query.setFetchSize(fetchSize); + } + if (timeout > 0) { + query.setTimeout(timeout); + } + if (cacheable != null) { + query.setCacheable(cacheable); + } + if (cacheRegion != null) { + query.setCacheRegion(cacheRegion); + } + if (comment != null) { + query.setComment(comment); + } + if (readOnly != null) { + query.setReadOnly(readOnly); + } + for (Map.Entry<Path<?>, LockMode> entry : lockModes.entrySet()) { + query.setLockMode(entry.getKey().toString(), entry.getValue()); + } + if (flushMode != null) { + query.setFlushMode(flushMode); + } + + if (modifiers != null && modifiers.isRestricting()) { + Integer limit = modifiers.getLimitAsInteger(); + Integer offset = modifiers.getOffsetAsInteger(); + if (limit != null) { + query.setMaxResults(limit); + } + if (offset != null) { + query.setFirstResult(offset); + } + } + + // set transformer, if necessary + Expression<?> projection = getMetadata().getProjection(); + if (!forCount && projection instanceof FactoryExpression) { + query.setResultTransformer(new FactoryExpressionTransformer((FactoryExpression<?>) projection)); + } + return query; + } + + + /** + * Return the query results as an {@code Iterator}. If the query + * contains multiple results pre row, the results are returned in + * an instance of {@code Object[]}.<br> + * <br> + * Entities returned as results are initialized on demand. The first + * SQL query returns identifiers only.<br> + */ + @Override + public CloseableIterator<T> iterate() { + try { + Query query = createQuery(); + ScrollableResults results = query.scroll(ScrollMode.FORWARD_ONLY); + return new ScrollableResultsIterator<T>(results); + } finally { + reset(); + } + } + + @Override + public Stream<T> stream() { + try { + Query query = createQuery(); + return query.getResultStream(); + } finally { + reset(); + } + } + + @Override + @SuppressWarnings("unchecked") + public List<T> fetch() { + try { + return createQuery().list(); + } finally { + reset(); + } + } + + @Override + public QueryResults<T> fetchResults() { + try { + Query countQuery = createQuery(null, true); + long total = (Long) countQuery.uniqueResult(); + + if (total > 0) { + QueryModifiers modifiers = getMetadata().getModifiers(); + Query query = createQuery(modifiers, false); + @SuppressWarnings("unchecked") + List<T> list = query.list(); + return new QueryResults<T>(list, modifiers, total); + } else { + return QueryResults.emptyResults(); + } + } finally { + reset(); + } + } + + protected void logQuery(String queryString) { + if (logger.isLoggable(Level.FINE)) { + String normalizedQuery = queryString.replace('\n', ' '); + logger.fine(normalizedQuery); + } + } + + @Override + protected void reset() { + } + + /** + * Return the query results as {@code ScrollableResults}. The + * scrollability of the returned results depends upon JDBC driver + * support for scrollable {@code ResultSet}s.<br> + * + * @param mode scroll mode + * @return scrollable results + */ + public ScrollableResults scroll(ScrollMode mode) { + try { + return createQuery().scroll(mode); + } finally { + reset(); + } + } + + /** + * Enable caching of this query result set. + * @param cacheable Should the query results be cacheable? + */ + @SuppressWarnings("unchecked") + public Q setCacheable(boolean cacheable) { + this.cacheable = cacheable; + return (Q) this; + } + + /** + * Set the name of the cache region. + * @param cacheRegion the name of a query cache region, or {@code null} + * for the default query cache + */ + @SuppressWarnings("unchecked") + public Q setCacheRegion(String cacheRegion) { + this.cacheRegion = cacheRegion; + return (Q) this; + } + + /** + * Add a comment to the generated SQL. + * @param comment comment + * @return the current object + */ + @SuppressWarnings("unchecked") + public Q setComment(String comment) { + this.comment = comment; + return (Q) this; + } + + /** + * Set a fetchJoin size for the underlying JDBC query. + * @param fetchSize the fetchJoin size + * @return the current object + */ + @SuppressWarnings("unchecked") + public Q setFetchSize(int fetchSize) { + this.fetchSize = fetchSize; + return (Q) this; + } + + /** + * Set the lock mode for the given path. + * @return the current object + */ + @SuppressWarnings("unchecked") + public Q setLockMode(Path<?> path, LockMode lockMode) { + lockModes.put(path, lockMode); + return (Q) this; + } + + /** + * Override the current session flush mode, just for this query. + * @return the current object + */ + @SuppressWarnings("unchecked") + public Q setFlushMode(FlushMode flushMode) { + this.flushMode = flushMode; + return (Q) this; + } + + /** + * Entities retrieved by this query will be loaded in + * a read-only mode where Hibernate will never dirty-check + * them or make changes persistent. + * + * @return the current object + * + */ + @SuppressWarnings("unchecked") + public Q setReadOnly(boolean readOnly) { + this.readOnly = readOnly; + return (Q) this; + } + + /** + * Set a timeout for the underlying JDBC query. + * @param timeout the timeout in seconds + * @return the current object + */ + @SuppressWarnings("unchecked") + public Q setTimeout(int timeout) { + this.timeout = timeout; + return (Q) this; + } + + @SuppressWarnings("unchecked") + @Override + public T fetchOne() throws NonUniqueResultException { + try { + QueryModifiers modifiers = getMetadata().getModifiers(); + Query query = createQuery(modifiers, false); + try { + return (T) query.uniqueResult(); + } catch (org.hibernate.NonUniqueResultException e) { + throw new NonUniqueResultException(e); + } + } finally { + reset(); + } + } + + @Override + protected JPQLSerializer createSerializer() { + return new JPQLSerializer(getTemplates()); + } + + protected void clone(Q query) { + cacheable = query.cacheable; + cacheRegion = query.cacheRegion; + fetchSize = query.fetchSize; + flushMode = query.flushMode; + lockModes.putAll(query.lockModes); + readOnly = query.readOnly; + timeout = query.timeout; + } + + protected abstract Q clone(SessionHolder sessionHolder); + + /** + * Clone the state of this query to a new instance with the given Session + * + * @param session session + * @return cloned query + */ + public Q clone(Session session) { + return this.clone(new DefaultSessionHolder(session)); + } + + /** + * Clone the state of this query to a new instance with the given StatelessSession + * + * @param session session + * @return cloned query + */ + public Q clone(StatelessSession session) { + return this.clone(new StatelessSessionHolder(session)); + } + + /** + * Clone the state of this query to a new instance + * + * @return closed query + */ + @Override + public Q clone() { + return this.clone(this.session); + } + +} diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/hibernate/DefaultSessionHolder.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/hibernate/DefaultSessionHolder.java new file mode 100644 index 0000000000..9fa9e49fd5 --- /dev/null +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/hibernate/DefaultSessionHolder.java @@ -0,0 +1,44 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.hibernate; + +import org.hibernate.query.Query; +import org.hibernate.query.NativeQuery; +import org.hibernate.Session; + +/** + * {@code DefaultSessionHolder} is the default implementation of the {@link SessionHolder} interface + * + * @author tiwe + * + */ +public class DefaultSessionHolder implements SessionHolder { + + private final Session session; + + public DefaultSessionHolder(Session session) { + this.session = session; + } + + @Override + public Query<?> createQuery(String queryString) { + return session.createQuery(queryString); + } + + @Override + public NativeQuery<?> createSQLQuery(String queryString) { + return session.createSQLQuery(queryString); + } + +} diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/hibernate/HibernateDeleteClause.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/hibernate/HibernateDeleteClause.java new file mode 100644 index 0000000000..efc563fec4 --- /dev/null +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/hibernate/HibernateDeleteClause.java @@ -0,0 +1,105 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.hibernate; + +import com.querydsl.core.JoinType; +import com.querydsl.core.dml.DeleteClause; +import com.querydsl.core.support.QueryMixin; +import com.querydsl.core.types.EntityPath; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.Predicate; +import com.querydsl.jpa.HQLTemplates; +import com.querydsl.jpa.JPAQueryMixin; +import com.querydsl.jpa.JPQLSerializer; +import com.querydsl.jpa.JPQLTemplates; +import org.hibernate.LockMode; +import org.hibernate.Session; +import org.hibernate.StatelessSession; +import org.hibernate.query.Query; + +import java.util.HashMap; +import java.util.Map; + +/** + * DeleteClause implementation for Hibernate + * + * @author tiwe + * + */ +public class HibernateDeleteClause implements DeleteClause<HibernateDeleteClause> { + + private final QueryMixin<?> queryMixin = new JPAQueryMixin<Void>(); + + private final SessionHolder session; + + private final JPQLTemplates templates; + + private final Map<Path<?>,LockMode> lockModes = new HashMap<Path<?>,LockMode>(); + + public HibernateDeleteClause(Session session, EntityPath<?> entity) { + this(new DefaultSessionHolder(session), entity, HQLTemplates.DEFAULT); + } + + public HibernateDeleteClause(StatelessSession session, EntityPath<?> entity) { + this(new StatelessSessionHolder(session), entity, HQLTemplates.DEFAULT); + } + + public HibernateDeleteClause(Session session, EntityPath<?> entity, JPQLTemplates templates) { + this(new DefaultSessionHolder(session), entity, templates); + } + + public HibernateDeleteClause(SessionHolder session, EntityPath<?> entity, JPQLTemplates templates) { + this.session = session; + this.templates = templates; + queryMixin.addJoin(JoinType.DEFAULT, entity); + } + + @Override + public long execute() { + JPQLSerializer serializer = new JPQLSerializer(templates, null); + serializer.serializeForDelete(queryMixin.getMetadata()); + + Query query = session.createQuery(serializer.toString()); + for (Map.Entry<Path<?>, LockMode> entry : lockModes.entrySet()) { + query.setLockMode(entry.getKey().toString(), entry.getValue()); + } + HibernateUtil.setConstants(query, serializer.getConstants(), queryMixin.getMetadata().getParams()); + return query.executeUpdate(); + } + + @Override + public HibernateDeleteClause where(Predicate... o) { + for (Predicate p : o) { + queryMixin.where(p); + } + return this; + } + + /** + * Set the lock mode for the given path. + */ + @SuppressWarnings("unchecked") + public HibernateDeleteClause setLockMode(Path<?> path, LockMode lockMode) { + lockModes.put(path, lockMode); + return this; + } + + @Override + public String toString() { + JPQLSerializer serializer = new JPQLSerializer(templates, null); + serializer.serializeForDelete(queryMixin.getMetadata()); + return serializer.toString(); + } + +} diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/hibernate/HibernateInsertClause.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/hibernate/HibernateInsertClause.java new file mode 100644 index 0000000000..9a9dd9af63 --- /dev/null +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/hibernate/HibernateInsertClause.java @@ -0,0 +1,165 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.hibernate; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import org.hibernate.LockMode; +import org.hibernate.query.Query; +import org.hibernate.Session; +import org.hibernate.StatelessSession; + +import com.querydsl.core.JoinType; +import com.querydsl.core.dml.InsertClause; +import com.querydsl.core.support.QueryMixin; +import com.querydsl.core.types.EntityPath; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.SubQueryExpression; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.jpa.HQLTemplates; +import com.querydsl.jpa.JPAQueryMixin; +import com.querydsl.jpa.JPQLSerializer; +import com.querydsl.jpa.JPQLTemplates; + +/** + * UpdateClause implementation for Hibernate + * + * @author tiwe + * + */ +public class HibernateInsertClause implements + InsertClause<HibernateInsertClause> { + + private final QueryMixin<?> queryMixin = new JPAQueryMixin<Void>(); + + private final Map<Path<?>, Expression<?>> inserts = new LinkedHashMap<>(); + + private final List<Path<?>> columns = new ArrayList<Path<?>>(); + + private final List<Object> values = new ArrayList<Object>(); + + private SubQueryExpression<?> subQuery; + + private final SessionHolder session; + + private final JPQLTemplates templates; + + private final Map<Path<?>,LockMode> lockModes = new HashMap<Path<?>,LockMode>(); + + public HibernateInsertClause(Session session, EntityPath<?> entity) { + this(new DefaultSessionHolder(session), entity, HQLTemplates.DEFAULT); + } + + public HibernateInsertClause(StatelessSession session, EntityPath<?> entity) { + this(new StatelessSessionHolder(session), entity, HQLTemplates.DEFAULT); + } + + public HibernateInsertClause(Session session, EntityPath<?> entity, JPQLTemplates templates) { + this(new DefaultSessionHolder(session), entity, templates); + } + + public HibernateInsertClause(SessionHolder session, EntityPath<?> entity, + JPQLTemplates templates) { + this.session = session; + this.templates = templates; + queryMixin.addJoin(JoinType.DEFAULT, entity); + } + + @Override + public long execute() { + JPQLSerializer serializer = new JPQLSerializer(templates, null); + serializer.serializeForInsert(queryMixin.getMetadata(), inserts.isEmpty() ? columns : inserts.keySet(), values, subQuery, inserts); + + Query query = session.createQuery(serializer.toString()); + for (Map.Entry<Path<?>, LockMode> entry : lockModes.entrySet()) { + query.setLockMode(entry.getKey().toString(), entry.getValue()); + } + HibernateUtil.setConstants(query, serializer.getConstants(), queryMixin.getMetadata().getParams()); + return query.executeUpdate(); + } + + @Override + public HibernateInsertClause columns(Path<?>... columns) { + this.columns.addAll(Arrays.asList(columns)); + return this; + } + + @Override + public HibernateInsertClause select(SubQueryExpression<?> sq) { + subQuery = sq; + return this; + } + + /** + * Set the lock mode for the given path. + * @return the current object + */ + @SuppressWarnings("unchecked") + public HibernateInsertClause setLockMode(Path<?> path, LockMode lockMode) { + lockModes.put(path, lockMode); + return this; + } + + @Override + public String toString() { + JPQLSerializer serializer = new JPQLSerializer(templates, null); + serializer.serializeForInsert(queryMixin.getMetadata(), inserts.isEmpty() ? columns : inserts.keySet(), values, subQuery, inserts); + return serializer.toString(); + } + + @Override + public boolean isEmpty() { + return columns.isEmpty(); + } + + @Override + public <T> HibernateInsertClause set(Path<T> path, T value) { + if (value != null) { + inserts.put(path, Expressions.constant(value)); + } else { + setNull(path); + } + return this; + } + + @Override + public <T> HibernateInsertClause set(Path<T> path, Expression<? extends T> expression) { + if (expression != null) { + inserts.put(path, expression); + } else { + setNull(path); + } + return this; + } + + @Override + public <T> HibernateInsertClause setNull(Path<T> path) { + inserts.put(path, Expressions.nullExpression(path)); + return this; + } + + @Override + public HibernateInsertClause values(Object... v) { + this.values.addAll(Arrays.asList(v)); + return this; + } + + +} diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/hibernate/HibernateQuery.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/hibernate/HibernateQuery.java new file mode 100644 index 0000000000..02a36bd15a --- /dev/null +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/hibernate/HibernateQuery.java @@ -0,0 +1,126 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.hibernate; + +import org.hibernate.Session; +import org.hibernate.StatelessSession; + +import com.querydsl.core.DefaultQueryMetadata; +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.Tuple; +import com.querydsl.core.types.Expression; +import com.querydsl.jpa.HQLTemplates; +import com.querydsl.jpa.JPQLQuery; +import com.querydsl.jpa.JPQLTemplates; + +/** + * {@code HibernateQuery} is the default implementation of the JPQLQuery interface for Hibernate + * + * @param <T> result type + * + * @author tiwe + */ +public class HibernateQuery<T> extends AbstractHibernateQuery<T, HibernateQuery<T>> implements JPQLQuery<T> { + + /** + * Creates a detached query + * The query can be attached via the clone method + */ + public HibernateQuery() { + super(NoSessionHolder.DEFAULT, HQLTemplates.DEFAULT, new DefaultQueryMetadata()); + } + + /** + * Creates a new Session bound query + * + * @param session session + */ + public HibernateQuery(Session session) { + super(new DefaultSessionHolder(session), HQLTemplates.DEFAULT, new DefaultQueryMetadata()); + } + + /** + * Creates a new Session bound query + * + * @param session session + */ + public HibernateQuery(Session session, QueryMetadata metadata) { + super(new DefaultSessionHolder(session), HQLTemplates.DEFAULT, metadata); + } + + /** + * Creates a new Session bound query + * + * @param session session + * @param templates templates + */ + public HibernateQuery(Session session, JPQLTemplates templates) { + super(new DefaultSessionHolder(session), templates, new DefaultQueryMetadata()); + } + + /** + * Creates a new Stateless session bound query + * + * @param session session + */ + public HibernateQuery(StatelessSession session) { + super(new StatelessSessionHolder(session), HQLTemplates.DEFAULT, new DefaultQueryMetadata()); + } + + /** + * Creates a new Session bound query + * + * @param session session + * @param templates templates + */ + public HibernateQuery(SessionHolder session, JPQLTemplates templates) { + super(session, templates, new DefaultQueryMetadata()); + } + + /** + * Creates a new Session bound query + * + * @param session session + * @param templates templates + * @param metadata query metadata + */ + public HibernateQuery(SessionHolder session, JPQLTemplates templates, QueryMetadata metadata) { + super(session, templates, metadata); + } + + @Override + protected HibernateQuery<T> clone(SessionHolder sessionHolder) { + HibernateQuery<T> q = new HibernateQuery<T>(sessionHolder, + getTemplates(), getMetadata().clone()); + q.clone(this); + return q; + } + + @Override + public <U> HibernateQuery<U> select(Expression<U> expr) { + queryMixin.setProjection(expr); + @SuppressWarnings("unchecked") // This is the new type + HibernateQuery<U> newType = (HibernateQuery<U>) this; + return newType; + } + + @Override + public HibernateQuery<Tuple> select(Expression<?>... exprs) { + queryMixin.setProjection(exprs); + @SuppressWarnings("unchecked") // This is the new type + HibernateQuery<Tuple> newType = (HibernateQuery<Tuple>) this; + return newType; + } + +} diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/hibernate/HibernateQueryFactory.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/hibernate/HibernateQueryFactory.java new file mode 100644 index 0000000000..a16b49ff20 --- /dev/null +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/hibernate/HibernateQueryFactory.java @@ -0,0 +1,123 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.hibernate; + +import org.hibernate.Session; + +import com.querydsl.core.Tuple; +import com.querydsl.core.types.EntityPath; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.jpa.HQLTemplates; +import com.querydsl.jpa.JPQLQueryFactory; +import com.querydsl.jpa.JPQLTemplates; + +import java.util.function.Supplier; + +/** + * Factory class for query and DML clause creation + * + * @author tiwe + * + */ +public class HibernateQueryFactory implements JPQLQueryFactory { + + private final JPQLTemplates templates; + + private final Supplier<Session> session; + + public HibernateQueryFactory(Session session) { + this(HQLTemplates.DEFAULT, session); + } + + public HibernateQueryFactory(JPQLTemplates templates, final Session session) { + this.session = () -> session; + this.templates = templates; + } + + public HibernateQueryFactory(Supplier<Session> session) { + this(HQLTemplates.DEFAULT, session); + } + + public HibernateQueryFactory(JPQLTemplates templates, Supplier<Session> session) { + this.session = session; + this.templates = templates; + } + + @Override + public HibernateDeleteClause delete(EntityPath<?> path) { + return new HibernateDeleteClause(session.get(), path, templates); + } + + @Override + public <T> HibernateQuery<T> select(Expression<T> expr) { + return query().select(expr); + } + + @Override + public HibernateQuery<Tuple> select(Expression<?>... exprs) { + return query().select(exprs); + } + + @Override + public <T> HibernateQuery<T> selectDistinct(Expression<T> expr) { + return select(expr).distinct(); + } + + @Override + public HibernateQuery<Tuple> selectDistinct(Expression<?>... exprs) { + return select(exprs).distinct(); + } + + @Override + public HibernateQuery<Integer> selectOne() { + return select(Expressions.ONE); + } + + @Override + public HibernateQuery<Integer> selectZero() { + return select(Expressions.ZERO); + } + + @Override + public <T> HibernateQuery<T> selectFrom(EntityPath<T> from) { + return select(from).from(from); + } + + @Override + public HibernateQuery<?> from(EntityPath<?> from) { + return query().from(from); + } + + @Override + public HibernateQuery<?> from(EntityPath<?>... from) { + return query().from(from); + } + + @Override + public HibernateUpdateClause update(EntityPath<?> path) { + return new HibernateUpdateClause(session.get(), path, templates); + } + + @Override + public HibernateInsertClause insert(EntityPath<?> path) { + return new HibernateInsertClause(session.get(), path, templates); + } + + @Override + public HibernateQuery<?> query() { + return new HibernateQuery<Void>(session.get(), templates); + } + +} diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/hibernate/HibernateUpdateClause.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/hibernate/HibernateUpdateClause.java new file mode 100644 index 0000000000..5e8a951f39 --- /dev/null +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/hibernate/HibernateUpdateClause.java @@ -0,0 +1,160 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.hibernate; + +import com.querydsl.core.JoinType; +import com.querydsl.core.dml.UpdateClause; +import com.querydsl.core.support.QueryMixin; +import com.querydsl.core.types.EntityPath; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.Predicate; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.jpa.HQLTemplates; +import com.querydsl.jpa.JPAQueryMixin; +import com.querydsl.jpa.JPQLSerializer; +import com.querydsl.jpa.JPQLTemplates; +import org.hibernate.LockMode; +import org.hibernate.Session; +import org.hibernate.StatelessSession; +import org.hibernate.query.Query; + +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +/** + * UpdateClause implementation for Hibernate + * + * @author tiwe + * + */ +public class HibernateUpdateClause implements + UpdateClause<HibernateUpdateClause> { + + private final QueryMixin<?> queryMixin = new JPAQueryMixin<Void>(); + + private final Map<Path<?>, Expression<?>> updates = new LinkedHashMap<>(); + + private final SessionHolder session; + + private final JPQLTemplates templates; + + private final Map<Path<?>,LockMode> lockModes = new HashMap<Path<?>,LockMode>(); + + public HibernateUpdateClause(Session session, EntityPath<?> entity) { + this(new DefaultSessionHolder(session), entity, HQLTemplates.DEFAULT); + } + + public HibernateUpdateClause(StatelessSession session, EntityPath<?> entity) { + this(new StatelessSessionHolder(session), entity, HQLTemplates.DEFAULT); + } + + public HibernateUpdateClause(Session session, EntityPath<?> entity, JPQLTemplates templates) { + this(new DefaultSessionHolder(session), entity, templates); + } + + public HibernateUpdateClause(SessionHolder session, EntityPath<?> entity, + JPQLTemplates templates) { + this.session = session; + this.templates = templates; + queryMixin.addJoin(JoinType.DEFAULT, entity); + } + + @Override + public long execute() { + JPQLSerializer serializer = new JPQLSerializer(templates, null); + serializer.serializeForUpdate(queryMixin.getMetadata(), updates); + + Query query = session.createQuery(serializer.toString()); + for (Map.Entry<Path<?>, LockMode> entry : lockModes.entrySet()) { + query.setLockMode(entry.getKey().toString(), entry.getValue()); + } + HibernateUtil.setConstants(query, serializer.getConstants(), queryMixin.getMetadata().getParams()); + return query.executeUpdate(); + } + + @Override + public <T> HibernateUpdateClause set(Path<T> path, T value) { + if (value != null) { + updates.put(path, Expressions.constant(value)); + } else { + setNull(path); + } + return this; + } + + @Override + public <T> HibernateUpdateClause set(Path<T> path, Expression<? extends T> expression) { + if (expression != null) { + updates.put(path, expression); + } else { + setNull(path); + } + return this; + } + + @Override + public <T> HibernateUpdateClause setNull(Path<T> path) { + updates.put(path, Expressions.nullExpression(path)); + return this; + } + + @SuppressWarnings("unchecked") + @Override + public HibernateUpdateClause set(List<? extends Path<?>> paths, List<?> values) { + for (int i = 0; i < paths.size(); i++) { + if (values.get(i) != null) { + updates.put(paths.get(i), Expressions.constant(values.get(i))); + } else { + updates.put(paths.get(i), Expressions.nullExpression(paths.get(i))); + } + + } + return this; + } + + @Override + public HibernateUpdateClause where(Predicate... o) { + for (Predicate p : o) { + queryMixin.where(p); + } + return this; + } + + /** + * Set the lock mode for the given path. + * @return the current object + */ + @SuppressWarnings("unchecked") + public HibernateUpdateClause setLockMode(Path<?> path, LockMode lockMode) { + lockModes.put(path, lockMode); + return this; + } + + @Override + public String toString() { + JPQLSerializer serializer = new JPQLSerializer(templates, null); + serializer.serializeForUpdate(queryMixin.getMetadata(), updates); + return serializer.toString(); + } + + @Override + public boolean isEmpty() { + return updates.isEmpty(); + } + + +} diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/hibernate/HibernateUtil.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/hibernate/HibernateUtil.java new file mode 100644 index 0000000000..7a1adc4270 --- /dev/null +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/hibernate/HibernateUtil.java @@ -0,0 +1,98 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.hibernate; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.*; + +import org.hibernate.type.*; + +import com.querydsl.core.types.ParamExpression; +import com.querydsl.core.types.ParamNotSetException; +import com.querydsl.core.types.dsl.Param; + +/** + * {@code HibernateUtil} provides static utility methods for Hibernate + * + * @author tiwe + */ +public final class HibernateUtil { + + private static final Set<Class<?>> BUILT_IN = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(Boolean.class, Byte.class, + Character.class, Double.class, Float.class, Integer.class, Long.class, Short.class, + String.class, BigDecimal.class, byte[].class, Byte[].class, java.util.Date.class, + java.util.Calendar.class, java.sql.Date.class, java.sql.Time.class, java.sql.Timestamp.class, + java.util.Locale.class, java.util.TimeZone.class, java.util.Currency.class, Class.class, + java.io.Serializable.class, java.sql.Blob.class, java.sql.Clob.class))); + + private static final Map<Class<?>, Type> TYPES; + + static { + Map<Class<?>, Type> builder = new HashMap<>(); + builder.put(Byte.class, new ByteType()); + builder.put(Short.class, new ShortType()); + builder.put(Integer.class, new IntegerType()); + builder.put(Long.class, new LongType()); + builder.put(BigInteger.class, new BigIntegerType()); + builder.put(Double.class, new DoubleType()); + builder.put(Float.class, new FloatType()); + builder.put(BigDecimal.class, new BigDecimalType()); + builder.put(String.class, new StringType()); + builder.put(Character.class, new CharacterType()); + builder.put(Date.class, new DateType()); + builder.put(Boolean.class, new BooleanType()); + TYPES = Collections.unmodifiableMap(builder); + } + + private HibernateUtil() { + } + + public static void setConstants( + org.hibernate.query.Query<?> query, + List<Object> constants, + Map<ParamExpression<?>, Object> params + ) { + for (int i = 0; i < constants.size(); i++) { + Object val = constants.get(i); + + if (val instanceof Param) { + Param<?> param = (Param<?>) val; + val = params.get(val); + if (val == null) { + throw new ParamNotSetException(param); + } + } + + setValueWithNumberedLabel(query, i + 1, val); + } + } + + private static void setValueWithNumberedLabel(org.hibernate.query.Query<?> query, Integer key, Object val) { + if (val instanceof Collection<?>) { + query.setParameterList(key, (Collection<?>) val); + } else if (val instanceof Object[] && !BUILT_IN.contains(val.getClass())) { + query.setParameterList(key, (Object[]) val); + } else if (val instanceof Number && TYPES.containsKey(val.getClass())) { + query.setParameter(key, val, getType(val.getClass())); + } else { + query.setParameter(key, val); + } + } + + public static Type getType(Class<?> clazz) { + return TYPES.get(clazz); + } + +} diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/hibernate/NoSessionHolder.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/hibernate/NoSessionHolder.java new file mode 100644 index 0000000000..1ec65c735f --- /dev/null +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/hibernate/NoSessionHolder.java @@ -0,0 +1,41 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.hibernate; + +import org.hibernate.query.Query; +import org.hibernate.query.NativeQuery; + +/** + * {@code NoSessionHolder} is a session holder for detached {@link HibernateQuery} usage + * + * @author tiwe + * + */ +public final class NoSessionHolder implements SessionHolder { + + public static final SessionHolder DEFAULT = new NoSessionHolder(); + + private NoSessionHolder() { } + + @Override + public Query<?> createQuery(String queryString) { + throw new UnsupportedOperationException("No session in detached Query available"); + } + + @Override + public NativeQuery<?> createSQLQuery(String queryString) { + throw new UnsupportedOperationException("No session in detached Query available"); + } + +} diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/hibernate/SessionHolder.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/hibernate/SessionHolder.java new file mode 100644 index 0000000000..b15b52f088 --- /dev/null +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/hibernate/SessionHolder.java @@ -0,0 +1,43 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.hibernate; + +import org.hibernate.query.Query; +import org.hibernate.query.NativeQuery; + +/** + * Abstraction for different Hibernate Session signatures + * + * @author tiwe + * + */ +public interface SessionHolder { + + /** + * Create a JPQL query for the given query string + * + * @param queryString JPQL query string + * @return query + */ + Query<?> createQuery(String queryString); + + /** + * Create an SQL query for the given query string + * + * @param queryString JPQL query string + * @return query + */ + NativeQuery<?> createSQLQuery(String queryString); + +} diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/hibernate/StatelessSessionHolder.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/hibernate/StatelessSessionHolder.java new file mode 100644 index 0000000000..c42a43b4b6 --- /dev/null +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/hibernate/StatelessSessionHolder.java @@ -0,0 +1,44 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.hibernate; + +import org.hibernate.query.Query; +import org.hibernate.query.NativeQuery; +import org.hibernate.StatelessSession; + +/** + * SessionHolder implementation using StatelessSession + * + * @author tiwe + * + */ +public class StatelessSessionHolder implements SessionHolder { + + private final StatelessSession session; + + public StatelessSessionHolder(StatelessSession session) { + this.session = session; + } + + @Override + public Query<?> createQuery(String queryString) { + return session.createQuery(queryString); + } + + @Override + public NativeQuery<?> createSQLQuery(String queryString) { + return session.createSQLQuery(queryString); + } + +} diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/hibernate/package-info.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/hibernate/package-info.java new file mode 100644 index 0000000000..cb7c2b7846 --- /dev/null +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/hibernate/package-info.java @@ -0,0 +1,18 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ + +/** + * JPQL for Hibernate + */ +package com.querydsl.jpa.hibernate; diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/hibernate/sql/AbstractHibernateSQLQuery.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/hibernate/sql/AbstractHibernateSQLQuery.java new file mode 100644 index 0000000000..ccb1bca5e5 --- /dev/null +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/hibernate/sql/AbstractHibernateSQLQuery.java @@ -0,0 +1,311 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.hibernate.sql; + +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.stream.Stream; + +import org.jetbrains.annotations.Nullable; + +import org.hibernate.query.Query; +import org.hibernate.*; + +import com.mysema.commons.lang.CloseableIterator; +import com.querydsl.core.*; +import com.querydsl.core.NonUniqueResultException; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.FactoryExpression; +import com.querydsl.jpa.AbstractSQLQuery; +import com.querydsl.jpa.FactoryExpressionTransformer; +import com.querydsl.jpa.NativeSQLSerializer; +import com.querydsl.jpa.ScrollableResultsIterator; +import com.querydsl.jpa.hibernate.DefaultSessionHolder; +import com.querydsl.jpa.hibernate.HibernateUtil; +import com.querydsl.jpa.hibernate.SessionHolder; +import com.querydsl.jpa.hibernate.StatelessSessionHolder; +import com.querydsl.sql.Configuration; +import com.querydsl.sql.SQLSerializer; + +/** + * {@code AbstractHibernateSQLQuery} is the base class for Hibernate Native SQL queries + * + * @param <T> result type + * @param <Q> concrete subtype + * + * @author tiwe + */ +public abstract class AbstractHibernateSQLQuery<T, Q extends AbstractHibernateSQLQuery<T, Q>> extends AbstractSQLQuery<T, Q> { + + private static final Logger logger = Logger.getLogger(AbstractHibernateSQLQuery.class.getName()); + + protected Boolean cacheable, readOnly; + + protected String cacheRegion; + + protected int fetchSize = 0; + + private final SessionHolder session; + + protected int timeout = 0; + + public AbstractHibernateSQLQuery(Session session, Configuration conf) { + this(new DefaultSessionHolder(session), conf, new DefaultQueryMetadata()); + } + + public AbstractHibernateSQLQuery(StatelessSession session, Configuration conf) { + this(new StatelessSessionHolder(session), conf, new DefaultQueryMetadata()); + } + + public AbstractHibernateSQLQuery(SessionHolder session, Configuration conf, QueryMetadata metadata) { + super(metadata, conf); + this.session = session; + } + + public Query createQuery() { + return createQuery(false); + } + + private Query createQuery(boolean forCount) { + NativeSQLSerializer serializer = (NativeSQLSerializer) serialize(forCount); + String queryString = serializer.toString(); + logQuery(queryString); + org.hibernate.query.NativeQuery query = session.createSQLQuery(queryString); + // set constants + HibernateUtil.setConstants(query, serializer.getConstants(), queryMixin.getMetadata().getParams()); + + if (!forCount) { + Map<Expression<?>, List<String>> aliases = serializer.getAliases(); + Set<String> used = new HashSet<>(); + // set entity paths + Expression<?> projection = queryMixin.getMetadata().getProjection(); + if (projection instanceof FactoryExpression) { + for (Expression<?> expr : ((FactoryExpression<?>) projection).getArgs()) { + if (isEntityExpression(expr)) { + query.addEntity(extractEntityExpression(expr).toString(), expr.getType()); + } else if (aliases.containsKey(expr)) { + for (String scalar : aliases.get(expr)) { + if (!used.contains(scalar)) { + query.addScalar(scalar); + used.add(scalar); + break; + } + } + } + } + } else if (isEntityExpression(projection)) { + query.addEntity(extractEntityExpression(projection).toString(), projection.getType()); + } else if (aliases.containsKey(projection)) { + for (String scalar : aliases.get(projection)) { + if (!used.contains(scalar)) { + query.addScalar(scalar); + used.add(scalar); + break; + } + } + } + + // set result transformer, if projection is a FactoryExpression instance + if (projection instanceof FactoryExpression) { + query.setResultTransformer(new FactoryExpressionTransformer((FactoryExpression<?>) projection)); + } + } + + if (fetchSize > 0) { + query.setFetchSize(fetchSize); + } + if (timeout > 0) { + query.setTimeout(timeout); + } + if (cacheable != null) { + query.setCacheable(cacheable); + } + if (cacheRegion != null) { + query.setCacheRegion(cacheRegion); + } + if (readOnly != null) { + query.setReadOnly(readOnly); + } + return query; + } + + @Override + protected SQLSerializer createSerializer() { + return new NativeSQLSerializer(configuration, true); + } + + @SuppressWarnings("unchecked") + @Override + public List<T> fetch() { + try { + return createQuery().list(); + } finally { + reset(); + } + } + + @Override + public CloseableIterator<T> iterate() { + try { + Query query = createQuery(); + ScrollableResults results = query.scroll(ScrollMode.FORWARD_ONLY); + return new ScrollableResultsIterator<T>(results); + } finally { + reset(); + } + } + + @Override + public Stream<T> stream() { + try { + Query query = createQuery(); + return query.getResultStream(); + } finally { + reset(); + } + } + + @Override + public QueryResults<T> fetchResults() { + // TODO : handle entity projections as well + try { + Query query = createQuery(true); + long total = ((Number) query.uniqueResult()).longValue(); + if (total > 0) { + QueryModifiers modifiers = queryMixin.getMetadata().getModifiers(); + query = createQuery(false); + @SuppressWarnings("unchecked") + List<T> list = query.list(); + return new QueryResults<T>(list, modifiers, total); + } else { + return QueryResults.emptyResults(); + } + } finally { + reset(); + } + } + + protected void logQuery(String queryString) { + if (logger.isLoggable(Level.FINE)) { + String normalizedQuery = queryString.replace('\n', ' '); + logger.fine(normalizedQuery); + } + } + + protected void reset() { + } + + @SuppressWarnings("unchecked") + @Override + public T fetchOne() throws NonUniqueResultException { + try { + Query query = createQuery(); + return (T) uniqueResult(query); + } finally { + reset(); + } + } + + @Nullable + private Object uniqueResult(Query query) { + try { + return query.uniqueResult(); + } catch (org.hibernate.NonUniqueResultException e) { + throw new NonUniqueResultException(e); + } + } + + /** + * Enable caching of this query result set. + * @param cacheable Should the query results be cacheable? + */ + @SuppressWarnings("unchecked") + public Q setCacheable(boolean cacheable) { + this.cacheable = cacheable; + return (Q) this; + } + + /** + * Set the name of the cache region. + * @param cacheRegion the name of a query cache region, or {@code null} + * for the default query cache + */ + @SuppressWarnings("unchecked") + public Q setCacheRegion(String cacheRegion) { + this.cacheRegion = cacheRegion; + return (Q) this; + } + + /** + * Set a fetchJoin size for the underlying JDBC query. + * @param fetchSize the fetchJoin size + */ + @SuppressWarnings("unchecked") + public Q setFetchSize(int fetchSize) { + this.fetchSize = fetchSize; + return (Q) this; + } + + /** + * Entities retrieved by this query will be loaded in + * a read-only mode where Hibernate will never dirty-check + * them or make changes persistent. + * + */ + @SuppressWarnings("unchecked") + public Q setReadOnly(boolean readOnly) { + this.readOnly = readOnly; + return (Q) this; + } + + /** + * Set a timeout for the underlying JDBC query. + * @param timeout the timeout in seconds + */ + @SuppressWarnings("unchecked") + public Q setTimeout(int timeout) { + this.timeout = timeout; + return (Q) this; + } + + @Override + protected void clone(Q query) { + super.clone(query); + cacheable = query.cacheable; + cacheRegion = query.cacheRegion; + fetchSize = query.fetchSize; + readOnly = query.readOnly; + timeout = query.timeout; + } + + protected abstract Q clone(SessionHolder session); + + public Q clone(Session session) { + return this.clone(new DefaultSessionHolder(session)); + } + + public Q clone(StatelessSession statelessSession) { + return this.clone(new StatelessSessionHolder(statelessSession)); + } + + @Override + public Q clone() { + return this.clone(this.session); + } + +} diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/hibernate/sql/HibernateSQLQuery.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/hibernate/sql/HibernateSQLQuery.java new file mode 100644 index 0000000000..0e73aeb221 --- /dev/null +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/hibernate/sql/HibernateSQLQuery.java @@ -0,0 +1,84 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.hibernate.sql; + +import org.hibernate.Session; +import org.hibernate.StatelessSession; + +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.Tuple; +import com.querydsl.core.types.Expression; +import com.querydsl.jpa.hibernate.SessionHolder; +import com.querydsl.sql.Configuration; +import com.querydsl.sql.SQLTemplates; + +/** + * {@code HibernateSQLQuery} is an SQLQuery implementation that uses Hibernate's Native SQL functionality + * to execute queries + * + * @param <T> result type + * + * @author tiwe + * + */ +public class HibernateSQLQuery<T> extends AbstractHibernateSQLQuery<T, HibernateSQLQuery<T>> { + + public HibernateSQLQuery(Session session, SQLTemplates sqlTemplates) { + super(session, new Configuration(sqlTemplates)); + } + + public HibernateSQLQuery(Session session, Configuration conf) { + super(session, conf); + } + + public HibernateSQLQuery(StatelessSession session, SQLTemplates sqlTemplates) { + super(session, new Configuration(sqlTemplates)); + } + + public HibernateSQLQuery(StatelessSession session, Configuration conf) { + super(session, conf); + } + + public HibernateSQLQuery(SessionHolder session, SQLTemplates sqlTemplates, QueryMetadata metadata) { + super(session, new Configuration(sqlTemplates), metadata); + } + + public HibernateSQLQuery(SessionHolder session, Configuration conf, QueryMetadata metadata) { + super(session, conf, metadata); + } + + @Override + protected HibernateSQLQuery<T> clone(SessionHolder sessionHolder) { + HibernateSQLQuery<T> q = new HibernateSQLQuery<T>(sessionHolder, configuration, getMetadata().clone()); + q.clone(this); + return q; + } + + @Override + public <U> HibernateSQLQuery<U> select(Expression<U> expr) { + queryMixin.setProjection(expr); + @SuppressWarnings("unchecked") // This is the new type + HibernateSQLQuery<U> newType = (HibernateSQLQuery<U>) this; + return newType; + } + + @Override + public HibernateSQLQuery<Tuple> select(Expression<?>... exprs) { + queryMixin.setProjection(exprs); + @SuppressWarnings("unchecked") // This is the new type + HibernateSQLQuery<Tuple> newType = (HibernateSQLQuery<Tuple>) this; + return newType; + } + +} diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/hibernate/sql/package-info.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/hibernate/sql/package-info.java new file mode 100644 index 0000000000..5063dff5fe --- /dev/null +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/hibernate/sql/package-info.java @@ -0,0 +1,19 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ + +/** + * Native queries for Hibernate + */ +package com.querydsl.jpa.hibernate.sql; + diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/impl/AbstractJPAQuery.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/impl/AbstractJPAQuery.java new file mode 100644 index 0000000000..0305391fd8 --- /dev/null +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/impl/AbstractJPAQuery.java @@ -0,0 +1,395 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.impl; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.stream.Stream; + +import org.jetbrains.annotations.Nullable; +import javax.persistence.EntityManager; +import javax.persistence.FlushModeType; +import javax.persistence.LockModeType; +import javax.persistence.Query; + +import com.mysema.commons.lang.CloseableIterator; +import com.querydsl.core.*; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.FactoryExpression; +import com.querydsl.jpa.JPAQueryBase; +import com.querydsl.jpa.JPQLSerializer; +import com.querydsl.jpa.JPQLTemplates; +import com.querydsl.jpa.QueryHandler; + +/** + * Abstract base class for JPA API based implementations of the JPQLQuery interface + * + * @param <T> result type + * @param <Q> concrete subtype + * + * @author tiwe + */ +public abstract class AbstractJPAQuery<T, Q extends AbstractJPAQuery<T, Q>> extends JPAQueryBase<T, Q> { + + private static final Logger logger = Logger.getLogger(JPAQuery.class.getName()); + + protected final Map<String, Object> hints = new LinkedHashMap<>(); + + protected final EntityManager entityManager; + + protected final QueryHandler queryHandler; + + @Nullable + protected LockModeType lockMode; + + @Nullable + protected FlushModeType flushMode; + + @Nullable + protected FactoryExpression<?> projection; + + public AbstractJPAQuery(EntityManager em) { + this(em, JPAProvider.getTemplates(em), new DefaultQueryMetadata()); + } + + public AbstractJPAQuery(EntityManager em, JPQLTemplates templates, QueryMetadata metadata) { + super(metadata, templates); + this.queryHandler = templates.getQueryHandler(); + this.entityManager = em; + } + + /** + * {@inheritDoc} + * + * @deprecated {@code fetchCount} requires a count query to be computed. In {@code querydsl-sql}, this is done + * by wrapping the query in a subquery, like so: {@code SELECT COUNT(*) FROM (<original query>)}. Unfortunately, + * JPQL - the query language of JPA - does not allow queries to project from subqueries. As a result there isn't a + * universal way to express count queries in JPQL. Historically QueryDSL attempts at producing a modified query + * to compute the number of results instead. + * + * However, this approach only works for simple queries. Specifically + * queries with multiple group by clauses and queries with a having clause turn out to be problematic. This is because + * {@code COUNT(DISTINCT a, b, c)}, while valid SQL in most dialects, is not valid JPQL. Furthermore, a having + * clause may refer select elements or aggregate functions and therefore cannot be emulated by moving the predicate + * to the where clause instead. + * + * In order to support {@code fetchCount} for queries with multiple group by elements or a having clause, we + * generate the count in memory instead. This means that the method simply falls back to returning the size of + * {@link #fetch()}. For large result sets this may come at a severe performance penalty. + * + * For very specific domain models where {@link #fetchCount()} has to be used in conjunction with complex queries + * containing multiple group by elements and/or a having clause, we recommend using the + * <a href="https://persistence.blazebit.com/documentation/1.5/core/manual/en_US/index.html#querydsl-integration">Blaze-Persistence</a> + * integration for QueryDSL. Among other advanced query features, Blaze-Persistence makes it possible to select + * from subqueries in JPQL. As a result the {@code BlazeJPAQuery} provided with the integration, implements + * {@code fetchCount} properly and always executes a proper count query. + */ + @Override + @Deprecated + public long fetchCount() { + try { + if (getMetadata().getGroupBy().size() > 1 || getMetadata().getHaving() != null) { + logger.warning("Fetchable#fetchCount() was computed in memory! See the Javadoc for AbstractJPAQuery#fetchCount for more details."); + Query query = createQuery(null, false); + return query.getResultList().size(); + } + + Query query = createQuery(null, true); + return (Long) query.getSingleResult(); + } finally { + reset(); + } + } + + /** + * Expose the original JPA query for the given projection + * + * @return query + */ + public Query createQuery() { + return createQuery(getMetadata().getModifiers(), false); + } + + protected Query createQuery(@Nullable QueryModifiers modifiers, boolean forCount) { + JPQLSerializer serializer = serialize(forCount); + String queryString = serializer.toString(); + logQuery(queryString); + Query query = entityManager.createQuery(queryString); + JPAUtil.setConstants(query, serializer.getConstants(), getMetadata().getParams()); + if (modifiers != null && modifiers.isRestricting()) { + Integer limit = modifiers.getLimitAsInteger(); + Integer offset = modifiers.getOffsetAsInteger(); + if (limit != null) { + query.setMaxResults(limit); + } + if (offset != null) { + query.setFirstResult(offset); + } + } + if (lockMode != null) { + query.setLockMode(lockMode); + } + if (flushMode != null) { + query.setFlushMode(flushMode); + } + + for (Map.Entry<String, Object> entry : hints.entrySet()) { + query.setHint(entry.getKey(), entry.getValue()); + } + + // set transformer, if necessary and possible + Expression<?> projection = getMetadata().getProjection(); + this.projection = null; // necessary when query is reused + + if (!forCount && projection instanceof FactoryExpression) { + if (!queryHandler.transform(query, (FactoryExpression<?>) projection)) { + this.projection = (FactoryExpression) projection; + } + } + + return query; + } + + /** + * Transforms results using FactoryExpression if ResultTransformer can't be used + * + * @param query query + * @return results + */ + private List<?> getResultList(Query query) { + // TODO : use lazy fetch here? + if (projection != null) { + List<?> results = query.getResultList(); + List<Object> rv = new ArrayList<Object>(results.size()); + for (Object o : results) { + if (o != null) { + if (!o.getClass().isArray()) { + o = new Object[]{o}; + } + rv.add(projection.newInstance((Object[]) o)); + } else { + rv.add(projection.newInstance(new Object[] {null})); + } + } + return rv; + } else { + return query.getResultList(); + } + } + + /** + * Transforms results using FactoryExpression if ResultTransformer can't be used + * + * @param query query + * @return single result + */ + @Nullable + private Object getSingleResult(Query query) { + if (projection != null) { + Object result = query.getSingleResult(); + if (result != null) { + if (!result.getClass().isArray()) { + result = new Object[]{result}; + } + return projection.newInstance((Object[]) result); + } else { + return null; + } + } else { + return query.getSingleResult(); + } + } + + @Override + public CloseableIterator<T> iterate() { + try { + Query query = createQuery(); + return queryHandler.iterate(query, projection); + } finally { + reset(); + } + } + + @Override + public Stream<T> stream() { + try { + Query query = createQuery(); + return queryHandler.stream(query, projection); + } finally { + reset(); + } + } + + @Override + @SuppressWarnings("unchecked") + public List<T> fetch() { + try { + Query query = createQuery(); + return (List<T>) getResultList(query); + } finally { + reset(); + } + } + + /** + * {@inheritDoc} + * + * @deprecated {@code fetchResults} requires a count query to be computed. In {@code querydsl-sql}, this is done + * by wrapping the query in a subquery, like so: {@code SELECT COUNT(*) FROM (<original query>)}. Unfortunately, + * JPQL - the query language of JPA - does not allow queries to project from subqueries. As a result there isn't a + * universal way to express count queries in JPQL. Historically QueryDSL attempts at producing a modified query + * to compute the number of results instead. + * + * However, this approach only works for simple queries. Specifically + * queries with multiple group by clauses and queries with a having clause turn out to be problematic. This is because + * {@code COUNT(DISTINCT a, b, c)}, while valid SQL in most dialects, is not valid JPQL. Furthermore, a having + * clause may refer select elements or aggregate functions and therefore cannot be emulated by moving the predicate + * to the where clause instead. + * + * In order to support {@code fetchResults} for queries with multiple group by elements or a having clause, we + * generate the count in memory instead. This means that the method simply falls back to returning the size of + * {@link #fetch()}. For large result sets this may come at a severe performance penalty. + * + * For very specific domain models where {@link #fetchResults()} has to be used in conjunction with complex queries + * containing multiple group by elements and/or a having clause, we recommend using the + * <a href="https://persistence.blazebit.com/documentation/1.5/core/manual/en_US/index.html#querydsl-integration">Blaze-Persistence</a> + * integration for QueryDSL. Among other advanced query features, Blaze-Persistence makes it possible to select + * from subqueries in JPQL. As a result the {@code BlazeJPAQuery} provided with the integration, implements + * {@code fetchResults} properly and always executes a proper count query. + * + * Mind that for any scenario where the count is not strictly needed separately, we recommend to use {@link #fetch()} + * instead. + */ + @Override + @Deprecated + public QueryResults<T> fetchResults() { + try { + QueryModifiers modifiers = getMetadata().getModifiers(); + if (getMetadata().getGroupBy().size() > 1 || getMetadata().getHaving() != null) { + logger.warning("Fetchable#fetchResults() was computed in memory! See the Javadoc for AbstractJPAQuery#fetchResults for more details."); + Query query = createQuery(null, false); + @SuppressWarnings("unchecked") + List<T> resultList = query.getResultList(); + int offset = modifiers.getOffsetAsInteger() == null ? 0 : modifiers.getOffsetAsInteger(); + int limit = modifiers.getLimitAsInteger() == null ? resultList.size() : modifiers.getLimitAsInteger(); + return new QueryResults<T>(resultList.subList(offset, Math.min(resultList.size(), offset + limit)), modifiers, resultList.size()); + } + + Query countQuery = createQuery(null, true); + long total = (Long) countQuery.getSingleResult(); + if (total > 0) { + Query query = createQuery(modifiers, false); + @SuppressWarnings("unchecked") + List<T> list = (List<T>) getResultList(query); + return new QueryResults<T>(list, modifiers, total); + } else { + return QueryResults.emptyResults(); + } + } finally { + reset(); + } + + } + + protected void logQuery(String queryString) { + if (logger.isLoggable(Level.FINEST)) { + String normalizedQuery = queryString.replace('\n', ' '); + logger.finest(normalizedQuery); + } + } + + @Override + protected void reset() { + } + + @Nullable + @SuppressWarnings("unchecked") + @Override + public T fetchOne() throws NonUniqueResultException { + try { + Query query = createQuery(getMetadata().getModifiers(), false); + return (T) getSingleResult(query); + } catch (javax.persistence.NoResultException e) { + logger.log(Level.FINEST, e.getMessage(), e); + return null; + } catch (javax.persistence.NonUniqueResultException e) { + throw new NonUniqueResultException(e); + } finally { + reset(); + } + } + + @SuppressWarnings("unchecked") + public Q setLockMode(LockModeType lockMode) { + this.lockMode = lockMode; + return (Q) this; + } + + @SuppressWarnings("unchecked") + public Q setFlushMode(FlushModeType flushMode) { + this.flushMode = flushMode; + return (Q) this; + } + + @SuppressWarnings("unchecked") + public Q setHint(String name, Object value) { + hints.put(name, value); + return (Q) this; + } + + @Override + protected JPQLSerializer createSerializer() { + return new JPQLSerializer(getTemplates(), entityManager); + } + + protected void clone(Q query) { + projection = query.projection; + flushMode = query.flushMode; + hints.putAll(query.hints); + lockMode = query.lockMode; + } + + /** + * Clone the state of this query to a new instance with the given EntityManager + * + * @param entityManager entity manager + * @return cloned query + */ + public abstract Q clone(EntityManager entityManager); + + /** + * Clone the state of this query to a new instance with the given EntityManager + * and the specified templates + * + * @param entityManager entity manager + * @param templates templates + * @return cloned query + */ + public abstract Q clone(EntityManager entityManager, JPQLTemplates templates); + + /** + * Clone the state of this query to a new instance + * + * @return cloned query + */ + @Override + public Q clone() { + return clone(entityManager, getTemplates()); + } + +} diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/impl/JPADeleteClause.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/impl/JPADeleteClause.java new file mode 100644 index 0000000000..ad4de0af26 --- /dev/null +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/impl/JPADeleteClause.java @@ -0,0 +1,90 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.impl; + +import org.jetbrains.annotations.Nullable; +import javax.persistence.EntityManager; +import javax.persistence.LockModeType; +import javax.persistence.Query; + +import com.querydsl.core.JoinType; +import com.querydsl.core.dml.DeleteClause; +import com.querydsl.core.support.QueryMixin; +import com.querydsl.core.types.EntityPath; +import com.querydsl.core.types.Predicate; +import com.querydsl.jpa.JPAQueryMixin; +import com.querydsl.jpa.JPQLSerializer; +import com.querydsl.jpa.JPQLTemplates; + +/** + * DeleteClause implementation for JPA + * + * @author tiwe + * + */ +public class JPADeleteClause implements DeleteClause<JPADeleteClause> { + + private final QueryMixin<?> queryMixin = new JPAQueryMixin<Void>(); + + private final EntityManager entityManager; + + private final JPQLTemplates templates; + + @Nullable + private LockModeType lockMode; + + public JPADeleteClause(EntityManager em, EntityPath<?> entity) { + this(em, entity, JPAProvider.getTemplates(em)); + } + + public JPADeleteClause(EntityManager entityManager, EntityPath<?> entity, JPQLTemplates templates) { + this.entityManager = entityManager; + this.templates = templates; + queryMixin.addJoin(JoinType.DEFAULT, entity); + } + + @Override + public long execute() { + JPQLSerializer serializer = new JPQLSerializer(templates, entityManager); + serializer.serializeForDelete(queryMixin.getMetadata()); + + Query query = entityManager.createQuery(serializer.toString()); + if (lockMode != null) { + query.setLockMode(lockMode); + } + JPAUtil.setConstants(query, serializer.getConstants(), queryMixin.getMetadata().getParams()); + return query.executeUpdate(); + } + + @Override + public JPADeleteClause where(Predicate... o) { + for (Predicate p : o) { + queryMixin.where(p); + } + return this; + } + + public JPADeleteClause setLockMode(LockModeType lockMode) { + this.lockMode = lockMode; + return this; + } + + @Override + public String toString() { + JPQLSerializer serializer = new JPQLSerializer(templates, entityManager); + serializer.serializeForDelete(queryMixin.getMetadata()); + return serializer.toString(); + } + +} diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/impl/JPAInsertClause.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/impl/JPAInsertClause.java new file mode 100644 index 0000000000..2c5d6dc9a1 --- /dev/null +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/impl/JPAInsertClause.java @@ -0,0 +1,148 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.impl; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import org.jetbrains.annotations.Nullable; +import javax.persistence.EntityManager; +import javax.persistence.LockModeType; +import javax.persistence.Query; + +import com.querydsl.core.JoinType; +import com.querydsl.core.dml.InsertClause; +import com.querydsl.core.support.QueryMixin; +import com.querydsl.core.types.EntityPath; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.SubQueryExpression; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.jpa.JPAQueryMixin; +import com.querydsl.jpa.JPQLSerializer; +import com.querydsl.jpa.JPQLTemplates; + +/** + * UpdateClause implementation for JPA + * + * @author tiwe + * + */ +public class JPAInsertClause implements InsertClause<JPAInsertClause> { + + private final QueryMixin<?> queryMixin = new JPAQueryMixin<Void>(); + + private final Map<Path<?>, Expression<?>> inserts = new LinkedHashMap<>(); + + private final List<Path<?>> columns = new ArrayList<Path<?>>(); + + private final List<Object> values = new ArrayList<Object>(); + + private final EntityManager entityManager; + + private final JPQLTemplates templates; + + private SubQueryExpression<?> subQuery; + + @Nullable + private LockModeType lockMode; + + public JPAInsertClause(EntityManager em, EntityPath<?> entity) { + this(em, entity, JPAProvider.getTemplates(em)); + } + + public JPAInsertClause(EntityManager em, EntityPath<?> entity, JPQLTemplates templates) { + this.entityManager = em; + this.templates = templates; + queryMixin.addJoin(JoinType.DEFAULT, entity); + } + + @Override + public long execute() { + JPQLSerializer serializer = new JPQLSerializer(templates, entityManager); + serializer.serializeForInsert(queryMixin.getMetadata(), inserts.isEmpty() ? columns : inserts.keySet(), values, subQuery, inserts); + + Query query = entityManager.createQuery(serializer.toString()); + if (lockMode != null) { + query.setLockMode(lockMode); + } + JPAUtil.setConstants(query, serializer.getConstants(), queryMixin.getMetadata().getParams()); + return query.executeUpdate(); + } + + public JPAInsertClause setLockMode(LockModeType lockMode) { + this.lockMode = lockMode; + return this; + } + + @Override + public String toString() { + JPQLSerializer serializer = new JPQLSerializer(templates, entityManager); + serializer.serializeForInsert(queryMixin.getMetadata(), inserts.isEmpty() ? columns : inserts.keySet(), values, subQuery, inserts); + return serializer.toString(); + } + + @Override + public JPAInsertClause columns(Path<?>... columns) { + this.columns.addAll(Arrays.asList(columns)); + return this; + } + + @Override + public JPAInsertClause select(SubQueryExpression<?> sq) { + subQuery = sq; + return this; + } + + @Override + public JPAInsertClause values(Object... v) { + this.values.addAll(Arrays.asList(v)); + return this; + } + + @Override + public boolean isEmpty() { + return columns.isEmpty(); + } + + @Override + public <T> JPAInsertClause set(Path<T> path, T value) { + if (value != null) { + inserts.put(path, Expressions.constant(value)); + } else { + setNull(path); + } + return this; + } + + @Override + public <T> JPAInsertClause set(Path<T> path, Expression<? extends T> expression) { + if (expression != null) { + inserts.put(path, expression); + } else { + setNull(path); + } + return this; + } + + @Override + public <T> JPAInsertClause setNull(Path<T> path) { + inserts.put(path, Expressions.nullExpression(path)); + return this; + } + +} diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/impl/JPAProvider.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/impl/JPAProvider.java new file mode 100644 index 0000000000..522c6417d5 --- /dev/null +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/impl/JPAProvider.java @@ -0,0 +1,107 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.impl; + +import java.util.HashMap; +import java.util.Map; + +import javax.persistence.EntityManager; + +import com.querydsl.jpa.BatooTemplates; +import com.querydsl.jpa.DataNucleusTemplates; +import com.querydsl.jpa.EclipseLinkTemplates; +import com.querydsl.jpa.HQLTemplates; +import com.querydsl.jpa.Hibernate5Templates; +import com.querydsl.jpa.JPQLTemplates; +import com.querydsl.jpa.OpenJPATemplates; + +/** + * {@code JPAProvider} provides detection of the JPA provider based on the EntityManager instance + * + * @author tiwe + * + */ +public final class JPAProvider { + + private static final Map<Class<?>, JPQLTemplates> mappings = new HashMap<>(); + + private static final Map<String, JPQLTemplates> templatesByName = new HashMap<>(); + + private static void addMapping(String className, JPQLTemplates templates) { + try { + mappings.put(Class.forName(className), templates); + } catch (Exception e) { } + } + + static { + boolean hibernate5; + + try { + String version = Class.forName("org.hibernate.Session").getPackage().getImplementationVersion(); + String[] versionParts = version.split("\\."); + int major = Integer.parseInt(versionParts[0]); + hibernate5 = major >= 5; + } catch (Exception e) { + hibernate5 = true; + } + + JPQLTemplates hibernateTemplates = hibernate5 ? Hibernate5Templates.DEFAULT : HQLTemplates.DEFAULT; + + addMapping("org.batoo.jpa.core.impl.manager.EntityManagerImpl", BatooTemplates.DEFAULT); + addMapping("org.hibernate.Session", hibernateTemplates); + addMapping("org.hibernate.ejb.HibernateEntityManager", hibernateTemplates); + addMapping("org.hibernate.jpa.HibernateEntityManager", hibernateTemplates); + addMapping("org.eclipse.persistence.jpa.JpaEntityManager", EclipseLinkTemplates.DEFAULT); + addMapping("org.apache.openjpa.persistence.OpenJPAEntityManager", OpenJPATemplates.DEFAULT); + addMapping("org.datanucleus.jpa.EntityManagerImpl", DataNucleusTemplates.DEFAULT); + addMapping("org.datanucleus.ObjectManager", DataNucleusTemplates.DEFAULT); + addMapping("org.datanucleus.ObjectManagerImpl", DataNucleusTemplates.DEFAULT); + + templatesByName.put("batoo", BatooTemplates.DEFAULT); + templatesByName.put("eclipselink", EclipseLinkTemplates.DEFAULT); + templatesByName.put("hibernate4", HQLTemplates.DEFAULT); + templatesByName.put("hibernate", Hibernate5Templates.DEFAULT); + templatesByName.put("openjpa", OpenJPATemplates.DEFAULT); + templatesByName.put("datanucleus", DataNucleusTemplates.DEFAULT); + } + + public static JPQLTemplates getTemplates(EntityManager em) { + for (Map.Entry<Class<?>, JPQLTemplates> entry : mappings.entrySet()) { + Class<?> entityManagerClass = entry.getKey(); + try { + if (entityManagerClass.isInstance(em.unwrap(entityManagerClass))) { + return entry.getValue(); + } + } catch (Exception e) { // The PersistenceException is wrapped in an InvocationException for EclipseLink + // detect by delegate + if (entityManagerClass.isAssignableFrom(em.getDelegate().getClass())) { + return entry.getValue(); + } + } + } + // detect by properties + for (String key : em.getEntityManagerFactory().getProperties().keySet()) { + key = key.toLowerCase(); + for (Map.Entry<String, JPQLTemplates> entry : templatesByName.entrySet()) { + if (key.contains(entry.getKey())) { + return entry.getValue(); + } + } + } + return JPQLTemplates.DEFAULT; + } + + private JPAProvider() { } + +} diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/impl/JPAQuery.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/impl/JPAQuery.java new file mode 100644 index 0000000000..3dcc03e1e5 --- /dev/null +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/impl/JPAQuery.java @@ -0,0 +1,109 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.impl; + +import javax.persistence.EntityManager; + +import com.querydsl.core.DefaultQueryMetadata; +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.Tuple; +import com.querydsl.core.types.Expression; +import com.querydsl.jpa.JPQLQuery; +import com.querydsl.jpa.JPQLTemplates; + +/** + * {@code JPAQuery} is the default implementation of the {@link JPQLQuery} interface for JPA + * + * @param <T> result type + * + * @author tiwe + */ +public class JPAQuery<T> extends AbstractJPAQuery<T, JPAQuery<T>> { + + /** + * Creates a new detached query + * The query can be attached via the clone method + */ + public JPAQuery() { + super(null, JPQLTemplates.DEFAULT, new DefaultQueryMetadata()); + } + + /** + * Creates a new EntityManager bound query + * + * @param em entity manager + */ + public JPAQuery(EntityManager em) { + super(em, JPAProvider.getTemplates(em), new DefaultQueryMetadata()); + } + + /** + * Creates a new EntityManager bound query + * + * @param em entity manager + * @param metadata query metadata + */ + public JPAQuery(EntityManager em, QueryMetadata metadata) { + super(em, JPAProvider.getTemplates(em), metadata); + } + + /** + * Creates a new query + * + * @param em entity manager + * @param templates templates + */ + public JPAQuery(EntityManager em, JPQLTemplates templates) { + super(em, templates, new DefaultQueryMetadata()); + } + + /** + * Creates a new query + * + * @param em entity manager + * @param templates templates + * @param metadata query metadata + */ + public JPAQuery(EntityManager em, JPQLTemplates templates, QueryMetadata metadata) { + super(em, templates, metadata); + } + + @Override + public JPAQuery<T> clone(EntityManager entityManager, JPQLTemplates templates) { + JPAQuery<T> q = new JPAQuery<T>(entityManager, templates, getMetadata().clone()); + q.clone(this); + return q; + } + + @Override + public JPAQuery<T> clone(EntityManager entityManager) { + return clone(entityManager, JPAProvider.getTemplates(entityManager)); + } + + @Override + public <U> JPAQuery<U> select(Expression<U> expr) { + queryMixin.setProjection(expr); + @SuppressWarnings("unchecked") // This is the new type + JPAQuery<U> newType = (JPAQuery<U>) this; + return newType; + } + + @Override + public JPAQuery<Tuple> select(Expression<?>... exprs) { + queryMixin.setProjection(exprs); + @SuppressWarnings("unchecked") // This is the new type + JPAQuery<Tuple> newType = (JPAQuery<Tuple>) this; + return newType; + } +} diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/impl/JPAQueryFactory.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/impl/JPAQueryFactory.java new file mode 100644 index 0000000000..1919369c0e --- /dev/null +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/impl/JPAQueryFactory.java @@ -0,0 +1,142 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.impl; + +import org.jetbrains.annotations.Nullable; +import javax.persistence.EntityManager; + +import com.querydsl.core.Tuple; +import com.querydsl.core.types.EntityPath; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.jpa.JPQLQueryFactory; +import com.querydsl.jpa.JPQLTemplates; + +import java.util.function.Supplier; + +/** + * Factory class for query and DML clause creation + * + * @author tiwe + * + */ +public class JPAQueryFactory implements JPQLQueryFactory { + + @Nullable + private final JPQLTemplates templates; + + private final Supplier<EntityManager> entityManager; + + public JPAQueryFactory(final EntityManager entityManager) { + this.entityManager = () -> entityManager; + this.templates = null; + } + + public JPAQueryFactory(JPQLTemplates templates, final EntityManager entityManager) { + this.entityManager = () -> entityManager; + this.templates = templates; + } + + public JPAQueryFactory(Supplier<EntityManager> entityManager) { + this.entityManager = entityManager; + this.templates = null; + } + + public JPAQueryFactory(JPQLTemplates templates, Supplier<EntityManager> entityManager) { + this.entityManager = entityManager; + this.templates = templates; + } + + @Override + public JPADeleteClause delete(EntityPath<?> path) { + if (templates != null) { + return new JPADeleteClause(entityManager.get(), path, templates); + } else { + return new JPADeleteClause(entityManager.get(), path); + } + } + + @Override + public <T> JPAQuery<T> select(Expression<T> expr) { + return query().select(expr); + } + + @Override + public JPAQuery<Tuple> select(Expression<?>... exprs) { + return query().select(exprs); + } + + @Override + public <T> JPAQuery<T> selectDistinct(Expression<T> expr) { + return select(expr).distinct(); + } + + @Override + public JPAQuery<Tuple> selectDistinct(Expression<?>... exprs) { + return select(exprs).distinct(); + } + + @Override + public JPAQuery<Integer> selectOne() { + return select(Expressions.ONE); + } + + @Override + public JPAQuery<Integer> selectZero() { + return select(Expressions.ZERO); + } + + @Override + public <T> JPAQuery<T> selectFrom(EntityPath<T> from) { + return select(from).from(from); + } + + @Override + public JPAQuery<?> from(EntityPath<?> from) { + return query().from(from); + } + + @Override + public JPAQuery<?> from(EntityPath<?>... from) { + return query().from(from); + } + + @Override + public JPAUpdateClause update(EntityPath<?> path) { + if (templates != null) { + return new JPAUpdateClause(entityManager.get(), path, templates); + } else { + return new JPAUpdateClause(entityManager.get(), path); + } + } + + @Override + public JPAInsertClause insert(EntityPath<?> path) { + if (templates != null) { + return new JPAInsertClause(entityManager.get(), path, templates); + } else { + return new JPAInsertClause(entityManager.get(), path); + } + } + + @Override + public JPAQuery<?> query() { + if (templates != null) { + return new JPAQuery<Void>(entityManager.get(), templates); + } else { + return new JPAQuery<Void>(entityManager.get()); + } + } + +} diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/impl/JPAUpdateClause.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/impl/JPAUpdateClause.java new file mode 100644 index 0000000000..7e508867c4 --- /dev/null +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/impl/JPAUpdateClause.java @@ -0,0 +1,143 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.impl; + +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import org.jetbrains.annotations.Nullable; +import javax.persistence.EntityManager; +import javax.persistence.LockModeType; +import javax.persistence.Query; + +import com.querydsl.core.JoinType; +import com.querydsl.core.dml.UpdateClause; +import com.querydsl.core.support.QueryMixin; +import com.querydsl.core.types.EntityPath; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.Predicate; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.jpa.JPAQueryMixin; +import com.querydsl.jpa.JPQLSerializer; +import com.querydsl.jpa.JPQLTemplates; + +/** + * UpdateClause implementation for JPA + * + * @author tiwe + * + */ +public class JPAUpdateClause implements UpdateClause<JPAUpdateClause> { + + private final QueryMixin<?> queryMixin = new JPAQueryMixin<Void>(); + + private final Map<Path<?>, Expression<?>> updates = new LinkedHashMap<>(); + + private final EntityManager entityManager; + + private final JPQLTemplates templates; + + @Nullable + private LockModeType lockMode; + + public JPAUpdateClause(EntityManager em, EntityPath<?> entity) { + this(em, entity, JPAProvider.getTemplates(em)); + } + + public JPAUpdateClause(EntityManager em, EntityPath<?> entity, JPQLTemplates templates) { + this.entityManager = em; + this.templates = templates; + queryMixin.addJoin(JoinType.DEFAULT, entity); + } + + @Override + public long execute() { + JPQLSerializer serializer = new JPQLSerializer(templates, entityManager); + serializer.serializeForUpdate(queryMixin.getMetadata(), updates); + + Query query = entityManager.createQuery(serializer.toString()); + if (lockMode != null) { + query.setLockMode(lockMode); + } + JPAUtil.setConstants(query, serializer.getConstants(), queryMixin.getMetadata().getParams()); + return query.executeUpdate(); + } + + @Override + public <T> JPAUpdateClause set(Path<T> path, T value) { + if (value != null) { + updates.put(path, Expressions.constant(value)); + } else { + setNull(path); + } + return this; + } + + @Override + public <T> JPAUpdateClause set(Path<T> path, Expression<? extends T> expression) { + if (expression != null) { + updates.put(path, expression); + } else { + setNull(path); + } + return this; + } + + @Override + public <T> JPAUpdateClause setNull(Path<T> path) { + updates.put(path, Expressions.nullExpression(path)); + return this; + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Override + public JPAUpdateClause set(List<? extends Path<?>> paths, List<?> values) { + for (int i = 0; i < paths.size(); i++) { + if (values.get(i) != null) { + updates.put(paths.get(i), Expressions.constant(values.get(i))); + } else { + updates.put(paths.get(i), Expressions.nullExpression(paths.get(i))); + } + } + return this; + } + + @Override + public JPAUpdateClause where(Predicate... o) { + for (Predicate p : o) { + queryMixin.where(p); + } + return this; + } + + public JPAUpdateClause setLockMode(LockModeType lockMode) { + this.lockMode = lockMode; + return this; + } + + @Override + public String toString() { + JPQLSerializer serializer = new JPQLSerializer(templates, entityManager); + serializer.serializeForUpdate(queryMixin.getMetadata(), updates); + return serializer.toString(); + } + + @Override + public boolean isEmpty() { + return updates.isEmpty(); + } + +} diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/impl/JPAUtil.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/impl/JPAUtil.java new file mode 100644 index 0000000000..36b26c13f0 --- /dev/null +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/impl/JPAUtil.java @@ -0,0 +1,65 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.impl; + +import java.util.List; +import java.util.Map; + +import javax.persistence.Parameter; +import javax.persistence.Query; + +import com.querydsl.core.types.ParamExpression; +import com.querydsl.core.types.ParamNotSetException; +import com.querydsl.core.types.dsl.Param; +import com.querydsl.core.util.MathUtils; + +/** + * JPAUtil provides static utility methods for JPA + * + * @author tiwe + * + */ +public final class JPAUtil { + + private JPAUtil() { } + + public static void setConstants(Query query, List<Object> constants, Map<ParamExpression<?>, Object> params) { + boolean hasParameters = !query.getParameters().isEmpty(); + + for (int i = 0; i < constants.size(); i++) { + Object val = constants.get(i); + + if (val instanceof Param) { + Param<?> param = (Param<?>) val; + val = params.get(val); + if (val == null) { + throw new ParamNotSetException(param); + } + } + + if (hasParameters) { + Parameter parameter = query.getParameter(i + 1); + Class parameterType = parameter != null ? parameter.getParameterType() : null; + if (parameterType != null && !parameterType.isInstance(val)) { + if (val instanceof Number && Number.class.isAssignableFrom(parameterType)) { + val = MathUtils.cast((Number) val, parameterType); + } + } + } + + query.setParameter(i + 1, val); + } + } + +} diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/impl/package-info.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/impl/package-info.java new file mode 100644 index 0000000000..9cd84e949c --- /dev/null +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/impl/package-info.java @@ -0,0 +1,18 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ + +/** + * JPQL for JPA + */ +package com.querydsl.jpa.impl; diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/package-info.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/package-info.java new file mode 100644 index 0000000000..9cc94c55e8 --- /dev/null +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/package-info.java @@ -0,0 +1,18 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ + +/** + * JPA support + */ +package com.querydsl.jpa; diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/sql/AbstractJPASQLQuery.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/sql/AbstractJPASQLQuery.java new file mode 100644 index 0000000000..1431d54e72 --- /dev/null +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/sql/AbstractJPASQLQuery.java @@ -0,0 +1,348 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.sql; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.stream.Stream; + +import org.jetbrains.annotations.Nullable; +import javax.persistence.EntityManager; +import javax.persistence.FlushModeType; +import javax.persistence.LockModeType; +import javax.persistence.Query; + +import com.mysema.commons.lang.CloseableIterator; +import com.querydsl.core.*; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.FactoryExpression; +import com.querydsl.jpa.AbstractSQLQuery; +import com.querydsl.jpa.NativeSQLSerializer; +import com.querydsl.jpa.QueryHandler; +import com.querydsl.jpa.impl.JPAProvider; +import com.querydsl.jpa.impl.JPAUtil; +import com.querydsl.sql.Configuration; +import com.querydsl.sql.SQLSerializer; + +/** + * {@code AbstractJPASQLQuery} is the base class for JPA Native SQL queries + * + * @param <T> result type + * @param <Q> concrete subtype + * + * @author tiwe* + */ +public abstract class AbstractJPASQLQuery<T, Q extends AbstractJPASQLQuery<T, Q>> extends AbstractSQLQuery<T, Q> { + + private static final Logger logger = Logger.getLogger(AbstractJPASQLQuery.class.getName()); + + private final EntityManager entityManager; + + protected final Map<String, Object> hints = new LinkedHashMap<>(); + + protected final QueryHandler queryHandler; + + @Nullable + protected LockModeType lockMode; + + @Nullable + protected FlushModeType flushMode; + + @Nullable + + protected FactoryExpression<?> projection; + + public AbstractJPASQLQuery(EntityManager em, Configuration configuration) { + this(em, configuration, new DefaultQueryMetadata()); + } + + public AbstractJPASQLQuery(EntityManager em, Configuration configuration, QueryHandler queryHandler) { + this(em, configuration, queryHandler, new DefaultQueryMetadata()); + } + + public AbstractJPASQLQuery(EntityManager em, Configuration configuration, QueryMetadata metadata) { + this(em, configuration, JPAProvider.getTemplates(em).getQueryHandler(), metadata); + } + + public AbstractJPASQLQuery(EntityManager em, Configuration configuration, QueryHandler queryHandler, QueryMetadata metadata) { + super(metadata, configuration); + this.entityManager = em; + this.queryHandler = queryHandler; + } + + public Query createQuery() { + return createQuery(false); + } + + private Query createQuery(boolean forCount) { + NativeSQLSerializer serializer = (NativeSQLSerializer) serialize(forCount); + String queryString = serializer.toString(); + logQuery(queryString); + Expression<?> projection = queryMixin.getMetadata().getProjection(); + Query query; + + if (!FactoryExpression.class.isAssignableFrom(projection.getClass()) && isEntityExpression(projection)) { + if (queryHandler.createNativeQueryTyped()) { + query = entityManager.createNativeQuery(queryString, projection.getType()); + } else { + query = entityManager.createNativeQuery(queryString); + } + + } else { + query = entityManager.createNativeQuery(queryString); + } + if (!forCount) { + Map<Expression<?>, List<String>> aliases = serializer.getAliases(); + Set<String> used = new HashSet<>(); + if (projection instanceof FactoryExpression) { + for (Expression<?> expr : ((FactoryExpression<?>) projection).getArgs()) { + if (isEntityExpression(expr)) { + queryHandler.addEntity(query, extractEntityExpression(expr).toString(), expr.getType()); + } else if (aliases.containsKey(expr)) { + for (String scalar : aliases.get(expr)) { + if (!used.contains(scalar)) { + queryHandler.addScalar(query, scalar, expr.getType()); + used.add(scalar); + break; + } + + } + } + } + } else if (isEntityExpression(projection)) { + queryHandler.addEntity(query, extractEntityExpression(projection).toString(), projection.getType()); + } else if (aliases.containsKey(projection)) { + for (String scalar : aliases.get(projection)) { + if (!used.contains(scalar)) { + queryHandler.addScalar(query, scalar, projection.getType()); + used.add(scalar); + break; + } + } + } + } + + if (lockMode != null) { + query.setLockMode(lockMode); + } + if (flushMode != null) { + query.setFlushMode(flushMode); + } + + for (Map.Entry<String, Object> entry : hints.entrySet()) { + query.setHint(entry.getKey(), entry.getValue()); + } + + + // set constants + JPAUtil.setConstants(query, serializer.getConstants(), queryMixin.getMetadata().getParams()); + this.projection = null; // necessary when query is reused + + if (!forCount && projection instanceof FactoryExpression) { + if (!queryHandler.transform(query, (FactoryExpression<?>) projection)) { + this.projection = (FactoryExpression<?>) projection; + } + } + + return query; + } + + @Override + protected SQLSerializer createSerializer() { + return new NativeSQLSerializer(configuration, queryHandler.wrapEntityProjections()); + } + + /** + * Transforms results using FactoryExpression if ResultTransformer can't be used + * + * @param query query + * @return results + */ + private List<?> getResultList(Query query) { + // TODO : use lazy fetch here? + if (projection != null) { + List<?> results = query.getResultList(); + List<Object> rv = new ArrayList<Object>(results.size()); + for (Object o : results) { + if (o != null) { + Object[] arr; + if (!o.getClass().isArray()) { + arr = new Object[]{o}; + } else { + arr = (Object[]) o; + } + if (projection.getArgs().size() < arr.length) { + Object[] shortened = new Object[projection.getArgs().size()]; + System.arraycopy(arr, 0, shortened, 0, shortened.length); + arr = shortened; + } + rv.add(projection.newInstance(arr)); + } else { + rv.add(null); + } + } + return rv; + } else { + return query.getResultList(); + } + } + + /** + * Transforms results using FactoryExpression if ResultTransformer can't be used + * + * @param query query + * @return single result + */ + @Nullable + private Object getSingleResult(Query query) { + if (projection != null) { + Object result = query.getSingleResult(); + if (result != null) { + if (!result.getClass().isArray()) { + result = new Object[]{result}; + } + return projection.newInstance((Object[]) result); + } else { + return null; + } + } else { + return query.getSingleResult(); + } + } + + @SuppressWarnings("unchecked") + @Override + public List<T> fetch() { + try { + Query query = createQuery(); + return (List<T>) getResultList(query); + } finally { + reset(); + } + } + + @Override + public CloseableIterator<T> iterate() { + try { + Query query = createQuery(); + return queryHandler.iterate(query, null); + } finally { + reset(); + } + } + + @Override + @SuppressWarnings("unchecked") + public Stream<T> stream() { + try { + Query query = createQuery(); + return query.getResultStream(); + } finally { + reset(); + } + } + + @Override + public QueryResults<T> fetchResults() { + // TODO : handle entity projections as well + try { + Query countQuery = createQuery(true); + long total = ((Number) countQuery.getSingleResult()).longValue(); + if (total > 0) { + QueryModifiers modifiers = queryMixin.getMetadata().getModifiers(); + Query query = createQuery(false); + @SuppressWarnings("unchecked") + List<T> list = (List<T>) getResultList(query); + return new QueryResults<T>(list, modifiers, total); + } else { + return QueryResults.emptyResults(); + } + } finally { + reset(); + } + + } + + protected void logQuery(String queryString) { + if (logger.isLoggable(Level.FINE)) { + String normalizedQuery = queryString.replace('\n', ' '); + logger.fine(normalizedQuery); + } + } + + protected void reset() { + } + + @Override + @SuppressWarnings("unchecked") + public T fetchOne() throws NonUniqueResultException { + Query query = createQuery(); + return (T) uniqueResult(query); + } + + @Nullable + private Object uniqueResult(Query query) { + try { + return getSingleResult(query); + } catch (javax.persistence.NoResultException e) { + logger.log(Level.FINEST, e.getMessage(),e); + return null; + } catch (javax.persistence.NonUniqueResultException e) { + throw new NonUniqueResultException(e); + } finally { + reset(); + } + } + + @SuppressWarnings("unchecked") + public Q setLockMode(LockModeType lockMode) { + this.lockMode = lockMode; + return (Q) this; + } + + @SuppressWarnings("unchecked") + public Q setFlushMode(FlushModeType flushMode) { + this.flushMode = flushMode; + return (Q) this; + } + + @SuppressWarnings("unchecked") + public Q setHint(String name, Object value) { + hints.put(name, value); + return (Q) this; + } + + @Override + protected void clone(Q query) { + super.clone(query); + flushMode = query.flushMode; + hints.putAll(query.hints); + lockMode = query.lockMode; + projection = query.projection; + } + + public abstract Q clone(EntityManager entityManager); + + @Override + public Q clone() { + return this.clone(this.entityManager); + } + +} diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/sql/JPASQLQuery.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/sql/JPASQLQuery.java new file mode 100644 index 0000000000..a0aee81b3c --- /dev/null +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/sql/JPASQLQuery.java @@ -0,0 +1,83 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.sql; + +import javax.persistence.EntityManager; + +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.Tuple; +import com.querydsl.core.types.Expression; +import com.querydsl.jpa.QueryHandler; +import com.querydsl.sql.Configuration; +import com.querydsl.sql.SQLTemplates; + +/** + * {@code JPASQLQuery} is an SQLQuery implementation that uses JPA Native SQL functionality + * to execute queries + * + * @param <T> result type + * + * @author tiwe + * + */ +public class JPASQLQuery<T> extends AbstractJPASQLQuery<T, JPASQLQuery<T>> { + + public JPASQLQuery(EntityManager entityManager, SQLTemplates sqlTemplates) { + super(entityManager, new Configuration(sqlTemplates)); + } + + public JPASQLQuery(EntityManager entityManager, Configuration conf) { + super(entityManager, conf); + } + + public JPASQLQuery(EntityManager entityManager, Configuration conf, QueryHandler queryHandler) { + super(entityManager, conf, queryHandler); + } + + public JPASQLQuery(EntityManager entityManager, SQLTemplates sqlTemplates, QueryMetadata metadata) { + super(entityManager, new Configuration(sqlTemplates), metadata); + } + + public JPASQLQuery(EntityManager entityManager, Configuration conf, QueryMetadata metadata) { + super(entityManager, conf, metadata); + } + + public JPASQLQuery(EntityManager entityManager, Configuration conf, QueryHandler queryHandler, QueryMetadata metadata) { + super(entityManager, conf, queryHandler, metadata); + } + + @Override + public JPASQLQuery<T> clone(EntityManager entityManager) { + JPASQLQuery<T> q = new JPASQLQuery<T>(entityManager, configuration, queryHandler, getMetadata().clone()); + q.clone(this); + return q; + } + + @Override + public <U> JPASQLQuery<U> select(Expression<U> expr) { + queryMixin.setProjection(expr); + @SuppressWarnings("unchecked") // This is the new type + JPASQLQuery<U> newType = (JPASQLQuery<U>) this; + return newType; + } + + @Override + public JPASQLQuery<Tuple> select(Expression<?>... exprs) { + queryMixin.setProjection(exprs); + @SuppressWarnings("unchecked") // This is the new type + JPASQLQuery<Tuple> newType = (JPASQLQuery<Tuple>) this; + return newType; + } + +} diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/sql/package-info.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/sql/package-info.java new file mode 100644 index 0000000000..0240203041 --- /dev/null +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/sql/package-info.java @@ -0,0 +1,18 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ + +/** + * Native queries for JPA + */ +package com.querydsl.jpa.sql; diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/support/DialectSupport.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/support/DialectSupport.java new file mode 100644 index 0000000000..04e7676afe --- /dev/null +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/support/DialectSupport.java @@ -0,0 +1,69 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.support; + +import java.util.HashMap; +import java.util.Map; + +import org.hibernate.dialect.function.SQLFunction; +import org.hibernate.dialect.function.SQLFunctionTemplate; +import org.hibernate.type.Type; + +import com.querydsl.core.types.Operator; +import com.querydsl.core.types.Ops; +import com.querydsl.core.types.Template; +import com.querydsl.jpa.hibernate.HibernateUtil; +import com.querydsl.sql.SQLTemplates; + +final class DialectSupport { + + private DialectSupport() { } + + public static Map<String, SQLFunction> createFunctions(SQLTemplates templates) { + Map<String, SQLFunction> functions = new HashMap<>(); + functions.put("second", createFunction(templates, Ops.DateTimeOps.SECOND)); + functions.put("minute", createFunction(templates, Ops.DateTimeOps.MINUTE)); + functions.put("hour", createFunction(templates, Ops.DateTimeOps.HOUR)); + functions.put("day", createFunction(templates, Ops.DateTimeOps.DAY_OF_MONTH)); + functions.put("week", createFunction(templates, Ops.DateTimeOps.WEEK)); + functions.put("month", createFunction(templates, Ops.DateTimeOps.MONTH)); + functions.put("year", createFunction(templates, Ops.DateTimeOps.YEAR)); + return functions; + } + + public static SQLFunction createFunction(SQLTemplates templates, Operator operator) { + Template template = templates.getTemplate(operator); + Type type = HibernateUtil.getType(operator.getType()); + return new SQLFunctionTemplate(type, convert(template)); + } + + public static String convert(Template template) { + StringBuilder builder = new StringBuilder(); + for (Template.Element element : template.getElements()) { + if (element instanceof Template.AsString) { + builder.append("?").append(((Template.AsString) element).getIndex() + 1); + } else if (element instanceof Template.ByIndex) { + builder.append("?").append(((Template.ByIndex) element).getIndex() + 1); + } else if (element instanceof Template.Transformed) { + builder.append("?").append(((Template.Transformed) element).getIndex() + 1); + } else if (element instanceof Template.StaticText) { + builder.append(((Template.StaticText) element).getText()); + } else { + throw new IllegalStateException("Unsupported element " + element); + } + } + return builder.toString(); + } + +} diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/support/JPAPathBuilderValidator.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/support/JPAPathBuilderValidator.java new file mode 100644 index 0000000000..1f1c84301d --- /dev/null +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/support/JPAPathBuilderValidator.java @@ -0,0 +1,54 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.support; + +import javax.persistence.EntityManager; +import javax.persistence.metamodel.Attribute; +import javax.persistence.metamodel.ManagedType; +import javax.persistence.metamodel.Metamodel; +import javax.persistence.metamodel.PluralAttribute; + +import com.querydsl.core.types.dsl.PathBuilderValidator; +import com.querydsl.core.util.PrimitiveUtils; + +/** + * JPAPathBuilderValidator implements PathBuilderValidator using a JPA Metamodel instance + */ +public class JPAPathBuilderValidator implements PathBuilderValidator { + + private final Metamodel metamodel; + + public JPAPathBuilderValidator(EntityManager entityManager) { + this.metamodel = entityManager.getMetamodel(); + } + + public JPAPathBuilderValidator(Metamodel metamodel) { + this.metamodel = metamodel; + } + + @Override + public Class<?> validate(Class<?> parent, String property, Class<?> propertyType) { + try { + ManagedType managedType = metamodel.managedType(parent); + Attribute attribute = managedType.getAttribute(property); + if (attribute instanceof PluralAttribute) { + return ((PluralAttribute) attribute).getElementType().getJavaType(); + } else { + return PrimitiveUtils.wrap(attribute.getJavaType()); + } + } catch (IllegalArgumentException e) { + return null; + } + } +} diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/support/QDerbyDialect.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/support/QDerbyDialect.java new file mode 100644 index 0000000000..6593ae2df1 --- /dev/null +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/support/QDerbyDialect.java @@ -0,0 +1,51 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.support; + +import java.util.Arrays; +import java.util.List; + +import org.hibernate.dialect.DerbyDialect; +import org.hibernate.dialect.function.CastFunction; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.type.Type; + +import com.querydsl.core.types.Ops; +import com.querydsl.sql.DerbyTemplates; +import com.querydsl.sql.SQLTemplates; + +/** + * {@code QDerbyDialect} extends {@code DerbyDialect} with additional functions + */ +public class QDerbyDialect extends DerbyDialect { + + private static final CastFunction castFunction = new CastFunction() { + @Override + public String render(Type columnType, List args, SessionFactoryImplementor factory) { + if (args.get(1).equals("string")) { + return super.render(columnType, Arrays.asList("char(" + args.get(0) + ")", args.get(1)), factory); + } else { + return super.render(columnType, args, factory); + } + } + }; + + public QDerbyDialect() { + SQLTemplates templates = DerbyTemplates.DEFAULT; + getFunctions().putAll(DialectSupport.createFunctions(templates)); + registerFunction("concat", DialectSupport.createFunction(templates, Ops.CONCAT)); + registerFunction("cast", castFunction); + } + +} diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/support/QH2Dialect.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/support/QH2Dialect.java new file mode 100644 index 0000000000..69b2a188ae --- /dev/null +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/support/QH2Dialect.java @@ -0,0 +1,31 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.support; + +import org.hibernate.dialect.H2Dialect; + +import com.querydsl.sql.H2Templates; +import com.querydsl.sql.SQLTemplates; + +/** + * {@code QH2Dialect} extends {@code H2Dialect} with additional functions + */ +public class QH2Dialect extends H2Dialect { + + public QH2Dialect() { + SQLTemplates templates = H2Templates.DEFAULT; + getFunctions().putAll(DialectSupport.createFunctions(templates)); + } + +} diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/support/QHSQLDialect.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/support/QHSQLDialect.java new file mode 100644 index 0000000000..0602a6ff33 --- /dev/null +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/support/QHSQLDialect.java @@ -0,0 +1,32 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.support; + +import org.hibernate.dialect.HSQLDialect; + +import com.querydsl.core.types.Ops; +import com.querydsl.sql.HSQLDBTemplates; +import com.querydsl.sql.SQLTemplates; + +/** + * {@code QHSQLDialect} extends {@code HSQLDialect} with additional functions + */ +public class QHSQLDialect extends HSQLDialect { + + public QHSQLDialect() { + SQLTemplates templates = HSQLDBTemplates.DEFAULT; + getFunctions().putAll(DialectSupport.createFunctions(templates)); + registerFunction("trim", DialectSupport.createFunction(templates, Ops.TRIM)); + } +} diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/support/QMySQL57InnoDBDialect.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/support/QMySQL57InnoDBDialect.java new file mode 100644 index 0000000000..5ed6bdb55e --- /dev/null +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/support/QMySQL57InnoDBDialect.java @@ -0,0 +1,30 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.support; + +import org.hibernate.dialect.MySQL57InnoDBDialect; + +import com.querydsl.sql.MySQLTemplates; +import com.querydsl.sql.SQLTemplates; + +/** + * {@code QMySQL57InnoDBDialect} extends {@code MySQL57InnoDBDialect} with additional functions + */ +public class QMySQL57InnoDBDialect extends MySQL57InnoDBDialect { + + public QMySQL57InnoDBDialect() { + SQLTemplates templates = MySQLTemplates.DEFAULT; + getFunctions().putAll(DialectSupport.createFunctions(templates)); + } +} diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/support/QMySQL5Dialect.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/support/QMySQL5Dialect.java new file mode 100644 index 0000000000..e1a0b66a2b --- /dev/null +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/support/QMySQL5Dialect.java @@ -0,0 +1,30 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.support; + +import org.hibernate.dialect.MySQL5Dialect; + +import com.querydsl.sql.MySQLTemplates; +import com.querydsl.sql.SQLTemplates; + +/** + * {@code QMySQL5Dialect} extends {@code MySQL5Dialect} with additional functions + */ +public class QMySQL5Dialect extends MySQL5Dialect { + + public QMySQL5Dialect() { + SQLTemplates templates = MySQLTemplates.DEFAULT; + getFunctions().putAll(DialectSupport.createFunctions(templates)); + } +} diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/support/QMySQL5InnoDBDialect.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/support/QMySQL5InnoDBDialect.java new file mode 100644 index 0000000000..920228b21b --- /dev/null +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/support/QMySQL5InnoDBDialect.java @@ -0,0 +1,31 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.support; + +import org.hibernate.dialect.MySQL5InnoDBDialect; + +import com.querydsl.sql.MySQLTemplates; +import com.querydsl.sql.SQLTemplates; + +/** + * {@code QMySQL5InnoDBDialect} extends {@code MySQL5InnoDBDialect} with additional functions + */ +public class QMySQL5InnoDBDialect extends MySQL5InnoDBDialect { + + public QMySQL5InnoDBDialect() { + SQLTemplates templates = MySQLTemplates.DEFAULT; + getFunctions().putAll(DialectSupport.createFunctions(templates)); + } + +} diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/support/QOracle10gDialect.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/support/QOracle10gDialect.java new file mode 100644 index 0000000000..c6eb0793d2 --- /dev/null +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/support/QOracle10gDialect.java @@ -0,0 +1,30 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.support; + +import org.hibernate.dialect.Oracle10gDialect; + +import com.querydsl.sql.OracleTemplates; +import com.querydsl.sql.SQLTemplates; + +/** + * {@code QOracle10gDialect} extends {@code Oracle10gDialect} with additional functions + */ +public class QOracle10gDialect extends Oracle10gDialect { + + public QOracle10gDialect() { + SQLTemplates templates = OracleTemplates.DEFAULT; + getFunctions().putAll(DialectSupport.createFunctions(templates)); + } +} diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/support/QPostgreSQL9Dialect.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/support/QPostgreSQL9Dialect.java new file mode 100644 index 0000000000..dbe0075319 --- /dev/null +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/support/QPostgreSQL9Dialect.java @@ -0,0 +1,30 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.support; + +import org.hibernate.dialect.PostgreSQL9Dialect; + +import com.querydsl.sql.PostgreSQLTemplates; +import com.querydsl.sql.SQLTemplates; + +/** + * {@code QPostgreSQL9Dialect} extends {@code PostgreSQL9Dialect} with additional functions + */ +public class QPostgreSQL9Dialect extends PostgreSQL9Dialect { + + public QPostgreSQL9Dialect() { + SQLTemplates templates = PostgreSQLTemplates.DEFAULT; + getFunctions().putAll(DialectSupport.createFunctions(templates)); + } +} diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/support/QPostgreSQLDialect.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/support/QPostgreSQLDialect.java new file mode 100644 index 0000000000..1b5ffb8ba2 --- /dev/null +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/support/QPostgreSQLDialect.java @@ -0,0 +1,30 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.support; + +import org.hibernate.dialect.PostgreSQLDialect; + +import com.querydsl.sql.PostgreSQLTemplates; +import com.querydsl.sql.SQLTemplates; + +/** + * {@code QPostgreSQLDialect} extends {@code PostgreSQLDialect} with additional functions + */ +public class QPostgreSQLDialect extends PostgreSQLDialect { + + public QPostgreSQLDialect() { + SQLTemplates templates = PostgreSQLTemplates.DEFAULT; + getFunctions().putAll(DialectSupport.createFunctions(templates)); + } +} diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/support/QSQLServer2005Dialect.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/support/QSQLServer2005Dialect.java new file mode 100644 index 0000000000..54c90eae12 --- /dev/null +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/support/QSQLServer2005Dialect.java @@ -0,0 +1,33 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.support; + +import org.hibernate.dialect.SQLServer2005Dialect; + +import com.querydsl.core.types.Ops; +import com.querydsl.sql.SQLServer2005Templates; +import com.querydsl.sql.SQLTemplates; + +/** + * {@code QSQLServer2005Dialect} extends {@code SQLServer2005Dialect} with additional functions + */ +public class QSQLServer2005Dialect extends SQLServer2005Dialect { + + public QSQLServer2005Dialect() { + SQLTemplates templates = SQLServer2005Templates.DEFAULT; + getFunctions().putAll(DialectSupport.createFunctions(templates)); + registerFunction("current_date", + DialectSupport.createFunction(templates, Ops.DateTimeOps.CURRENT_DATE)); + } +} diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/support/QSQLServer2008Dialect.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/support/QSQLServer2008Dialect.java new file mode 100644 index 0000000000..a7f47cf9ee --- /dev/null +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/support/QSQLServer2008Dialect.java @@ -0,0 +1,33 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.support; + +import org.hibernate.dialect.SQLServer2008Dialect; + +import com.querydsl.core.types.Ops; +import com.querydsl.sql.SQLServer2008Templates; +import com.querydsl.sql.SQLTemplates; + +/** + * {@code QSQLServer2008Dialect} extends {@code SQLServer2008Dialect} with additional functions + */ +public class QSQLServer2008Dialect extends SQLServer2008Dialect { + + public QSQLServer2008Dialect() { + SQLTemplates templates = SQLServer2008Templates.DEFAULT; + getFunctions().putAll(DialectSupport.createFunctions(templates)); + registerFunction("current_date", + DialectSupport.createFunction(templates, Ops.DateTimeOps.CURRENT_DATE)); + } +} diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/support/QSQLServer2012Dialect.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/support/QSQLServer2012Dialect.java new file mode 100644 index 0000000000..94e8396b58 --- /dev/null +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/support/QSQLServer2012Dialect.java @@ -0,0 +1,33 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.support; + +import org.hibernate.dialect.SQLServer2012Dialect; + +import com.querydsl.core.types.Ops; +import com.querydsl.sql.SQLServer2012Templates; +import com.querydsl.sql.SQLTemplates; + +/** + * {@code QSQLServer2012Dialect} extends {@code SQLServer2012Dialect} with additional functions + */ +public class QSQLServer2012Dialect extends SQLServer2012Dialect { + + public QSQLServer2012Dialect() { + SQLTemplates templates = SQLServer2012Templates.DEFAULT; + getFunctions().putAll(DialectSupport.createFunctions(templates)); + registerFunction("current_date", + DialectSupport.createFunction(templates, Ops.DateTimeOps.CURRENT_DATE)); + } +} diff --git a/querydsl-jpa/src/main/java/com/querydsl/jpa/support/package-info.java b/querydsl-jpa/src/main/java/com/querydsl/jpa/support/package-info.java new file mode 100644 index 0000000000..c826785f90 --- /dev/null +++ b/querydsl-jpa/src/main/java/com/querydsl/jpa/support/package-info.java @@ -0,0 +1,18 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ + +/** + * Support classes + */ +package com.querydsl.jpa.support; diff --git a/querydsl-jpa/src/test/java/PackagelessEntityTest.java b/querydsl-jpa/src/test/java/PackagelessEntityTest.java index 2d35309bae..684db1f583 100644 --- a/querydsl-jpa/src/test/java/PackagelessEntityTest.java +++ b/querydsl-jpa/src/test/java/PackagelessEntityTest.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,22 +11,23 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + +import static com.querydsl.jpa.JPAExpressions.select; import static org.junit.Assert.assertEquals; import org.junit.Test; -import com.mysema.query.jpa.JPASubQuery; -import com.mysema.query.types.path.PathBuilder; +import com.querydsl.core.types.dsl.PathBuilder; +import com.querydsl.jpa.JPQLQuery; public class PackagelessEntityTest { - + @SuppressWarnings("unchecked") @Test - public void PackageLess_Path() { - JPASubQuery query = new JPASubQuery(); - PathBuilder builder = new PathBuilder(PackagelessEntityTest.class,"entity"); - query.from(builder); + public void packageLess_path() { + PathBuilder<PackagelessEntityTest> builder = new PathBuilder(PackagelessEntityTest.class,"entity"); + JPQLQuery<?> query = select(builder).from(builder); assertEquals("select entity\nfrom PackagelessEntityTest entity", query.toString()); } diff --git a/querydsl-jpa/src/test/java/com/mysema/query/AbstractJPATest.java b/querydsl-jpa/src/test/java/com/mysema/query/AbstractJPATest.java deleted file mode 100644 index 773c319048..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/AbstractJPATest.java +++ /dev/null @@ -1,1471 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query; - -import java.math.BigDecimal; -import java.math.BigInteger; -import java.util.*; -import java.util.Calendar; -import java.util.Map.Entry; - -import antlr.RecognitionException; -import antlr.TokenStreamException; -import com.google.common.collect.Lists; -import com.mysema.commons.lang.Pair; -import com.mysema.query.group.Group; -import com.mysema.query.group.GroupBy; -import com.mysema.query.group.QPair; -import com.mysema.query.jpa.JPAExpressions; -import com.mysema.query.jpa.JPASubQuery; -import com.mysema.query.jpa.JPQLQuery; -import com.mysema.query.jpa.domain.*; -import com.mysema.query.jpa.domain.Company.Rating; -import com.mysema.query.jpa.domain4.QBookMark; -import com.mysema.query.jpa.domain4.QBookVersion; -import com.mysema.query.jpa.hibernate.HibernateSubQuery; -import com.mysema.query.support.Expressions; -import com.mysema.query.types.*; -import com.mysema.query.types.expr.*; -import com.mysema.query.types.path.*; -import com.mysema.testutil.ExcludeIn; -import com.mysema.testutil.IncludeIn; -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; -import static com.mysema.query.Target.*; -import static org.junit.Assert.*; - -/** - * @author tiwe - * - */ -public abstract class AbstractJPATest { - - private static final Expression<?>[] NO_EXPRESSIONS = new Expression[0]; - - private static final QCompany company = QCompany.company; - - private static final QAnimal animal = QAnimal.animal; - - private static final QCat cat = QCat.cat; - - private static final QCat otherCat = new QCat("otherCat"); - - private static final BooleanExpression cond1 = cat.name.length().gt(0); - - private static final BooleanExpression cond2 = otherCat.name.length().gt(0); - - private static final Predicate condition = ExpressionUtils.and( - (Predicate)ExpressionUtils.extract(cond1), - (Predicate)ExpressionUtils.extract(cond2)); - - private static final Date birthDate; - - private static final java.sql.Date date; - - private static final java.sql.Time time; - - private final List<Cat> savedCats = new ArrayList<Cat>(); - - static { - Calendar cal = Calendar.getInstance(); - cal.set(2000, 1, 2, 3, 4); - cal.set(Calendar.MILLISECOND, 0); - birthDate = cal.getTime(); - date = new java.sql.Date(cal.getTimeInMillis()); - time = new java.sql.Time(cal.getTimeInMillis()); - } - - protected Target getTarget() { - return Mode.target.get(); - } - - protected abstract JPQLQuery query(); - - protected abstract JPQLQuery testQuery(); - - protected JPASubQuery subQuery() { - return new JPASubQuery(); - } - - protected abstract void save(Object entity); - - @Before - public void setUp() { - if (query().from(cat).exists()) { - savedCats.addAll(query().from(cat).orderBy(cat.id.asc()).list(cat)); - return; - } - - Cat prev = null; - for (Cat cat : Arrays.asList( - new Cat("Bob123", 1, 1.0), - new Cat("Ruth123", 2, 2.0), - new Cat("Felix123", 3, 3.0), - new Cat("Allen123", 4, 4.0), - new Cat("Mary_123", 5, 5.0))) { - if (prev != null) { - cat.addKitten(prev); - } - cat.setBirthdate(birthDate); - cat.setDateField(date); - cat.setTimeField(time); - cat.setColor(Color.BLACK); - save(cat); - savedCats.add(cat); - prev = cat; - } - - Animal animal = new Animal(10); - animal.setBodyWeight(10.5); - save(animal); - - Cat cat = new Cat("Some", 6, 6.0); - cat.setBirthdate(birthDate); - save(cat); - savedCats.add(cat); - - Show show = new Show(1); - show.acts = new HashMap<String,String>(); - show.acts.put("a","A"); - show.acts.put("b","B"); - save(show); - - Company company = new Company(); - company.name = "1234567890123456789012345678901234567890"; // 40 - company.id = 1; - company.ratingOrdinal = Company.Rating.A; - company.ratingString = Company.Rating.AA; - save(company); - - Employee employee = new Employee(); - employee.id = 1; - employee.lastName = "Smith"; - employee.jobFunctions.add(JobFunction.CODER); - save(employee); - - Employee employee2 = new Employee(); - employee2.id = 2; - employee2.lastName = "Doe"; - employee2.jobFunctions.add(JobFunction.CODER); - employee2.jobFunctions.add(JobFunction.CONSULTANT); - employee2.jobFunctions.add(JobFunction.CONTROLLER); - save(employee2); - - save(new Entity1(1)); - save(new Entity1(2)); - save(new Entity2(3)); - - Foo foo = new Foo(); - foo.id = 1; - foo.names = Arrays.asList("a","b"); - foo.bar = "München"; - save(foo); - - Numeric numeric = new Numeric(); - numeric.setValue(BigDecimal.valueOf(26.9)); - save(numeric); - } - - @Test - @ExcludeIn(ORACLE) - public void Add_BigDecimal() { - QSimpleTypes entity = new QSimpleTypes("entity1"); - QSimpleTypes entity2 = new QSimpleTypes("entity2"); - NumberPath<BigDecimal> bigd1 = entity.bigDecimal; - NumberPath<BigDecimal> bigd2 = entity2.bigDecimal; - - query().from(entity, entity2) - .where(bigd1.add(bigd2).loe(new BigDecimal("1.00"))) - .list(entity); - } - - @Test - public void Aggregates_List_Max() { - assertEquals(Integer.valueOf(6), query().from(cat).list(cat.id.max()).get(0)); - } - - @Test - public void Aggregates_List_Min() { - assertEquals(Integer.valueOf(1), query().from(cat).list(cat.id.min()).get(0)); - } - - @Test - public void Aggregates_UniqueResult_Max() { - assertEquals(Integer.valueOf(6), query().from(cat).uniqueResult(cat.id.max())); - } - - @Test - public void Aggregates_UniqueResult_Min() { - assertEquals(Integer.valueOf(1), query().from(cat).uniqueResult(cat.id.min())); - } - - @Test - public void Any_And_Gt() { - assertEquals(0, query().from(cat).where( - cat.kittens.any().name.eq("Ruth123"), - cat.kittens.any().bodyWeight.gt(10.0)).count()); - } - - @Test - public void Any_And_Lt() { - assertEquals(1, query().from(cat).where( - cat.kittens.any().name.eq("Ruth123"), - cat.kittens.any().bodyWeight.lt(10.0)).count()); - } - - @Test - public void Any_In_Order() { - assertFalse(query().from(cat).orderBy(cat.kittens.any().name.asc()).list(cat).isEmpty()); - } - - @Test - public void Any_In_Projection() { - assertFalse(query().from(cat).list(cat.kittens.any()).isEmpty()); - } - - @Test - public void Any_In_Projection2() { - assertFalse(query().from(cat).list(cat.kittens.any().name).isEmpty()); - } - - @Test - public void Any_In1() { - //select cat from Cat cat where exists ( - // select cat_kittens from Cat cat_kittens where cat_kittens member of cat.kittens and cat_kittens in ?1) - assertFalse(query().from(cat).where(cat.kittens.any().in(savedCats)).list(cat).isEmpty()); - } - - @Test - public void Any_In11() { - List<Integer> ids = Lists.newArrayList(); - for (Cat cat : savedCats) ids.add(cat.getId()); - assertFalse(query().from(cat).where(cat.kittens.any().id.in(ids)).list(cat).isEmpty()); - } - - @Test - public void Any_In2() { - assertFalse(query().from(cat).where( - cat.kittens.any().in(savedCats), - cat.kittens.any().in(savedCats.subList(0, 1)).not()) - .list(cat).isEmpty()); - } - - @Test - @NoBatooJPA - public void Any_In3() { - QEmployee employee = QEmployee.employee; - assertFalse(query().from(employee).where( - employee.jobFunctions.any().in(JobFunction.CODER, JobFunction.CONSULTANT)) - .list(employee).isEmpty()); - } - - @Test - public void Any_Simple() { - assertEquals(1, query().from(cat).where(cat.kittens.any().name.eq("Ruth123")).count()); - } - - @Test - public void Any_Usage() { - assertEquals(1, query().from(cat).where(cat.kittens.any().name.eq("Ruth123")).count()); - } - - @SuppressWarnings("unchecked") - @Test - public void ArrayProjection() { - List<String[]> results = query().from(cat) - .list(new ArrayConstructorExpression<String>(String[].class, cat.name)); - assertFalse(results.isEmpty()); - for (String[] result : results) { - assertNotNull(result[0]); - } - } - - @Test - public void As() { - assertTrue(query().from(QAnimal.animal.as(QCat.class)).count() > 0); - } - - @Test - @NoHibernate // https://hibernate.atlassian.net/browse/HHH-4700 - @NoBatooJPA - public void Case() { - query().from(cat).list(cat.name.when("Bob").then(1).otherwise(2)); - } - - @Test(expected=ClassCastException.class) - @NoEclipseLink - @NoBatooJPA - public void Case_Hibernate() { - query().from(cat).list(cat.name.when("Bob").then(1).otherwise(2)); - } - - @Test - public void Case2() { - query().from(cat) - .list(Expressions.cases().when(cat.toes.eq(2)).then(cat.id.multiply(2)) - .when(cat.toes.eq(3)).then(cat.id.multiply(3)) - .otherwise(4)); - } - - @Test - public void Cast() { - List<Cat> cats = query().from(cat).list(cat); - List<Integer> weights = query().from(cat).list(cat.bodyWeight.castToNum(Integer.class)); - for (int i = 0; i < cats.size(); i++) { - assertEquals(Integer.valueOf((int)(cats.get(i).getBodyWeight())), weights.get(i)); - } - } - - @Test - public void Collection_Predicates() { - ListPath<Cat, QCat> path = cat.kittens; - List<Predicate> predicates = Arrays.<Predicate>asList( -// path.eq(savedCats), -// path.in(savedCats), -// path.isNotNull(), -// path.isNull(), -// path.ne(savedCats), -// path.notIn(savedCats) -// path.when(other) - ); - for (Predicate pred : predicates) { - System.err.println(pred); - query().from(cat).where(pred).list(cat); - } - } - - @Test - public void Collection_Projections() { - ListPath<Cat, QCat> path = cat.kittens; - List<Expression<?>> projections = Arrays.<Expression<?>>asList( -// path.count(), -// path.countDistinct() - ); - for (Expression<?> proj : projections) { - System.err.println(proj); - query().from(cat).list(proj); - } - } - - @Test - @NoHibernate // https://github.com/mysema/querydsl/issues/290 - public void Constant() { - //select cat.id, ?1 as const from Cat cat - List<Cat> cats = query().from(cat).list(cat); - Path<String> path = new StringPath("const"); - List<Tuple> tuples = query().from(cat).list(new QTuple(cat.id, Expressions.constantAs("abc", path))); - for (int i = 0; i < cats.size(); i++) { - assertEquals(Integer.valueOf(cats.get(i).getId()), tuples.get(i).get(cat.id)); - assertEquals("abc", tuples.get(i).get(path)); - } - } - - @Test(expected=ClassCastException.class) - @NoEclipseLink - @NoBatooJPA - public void Constant_Hibernate() { - //select cat.id, ?1 as const from Cat cat - query().from(cat).list(new QTuple(cat.id, Expressions.constantAs("abc", new StringPath("const")))); - } - - @Test - @NoHibernate // https://github.com/mysema/querydsl/issues/290 - public void Constant2() { - assertFalse(query().from(cat).map(cat.id, Expressions.constant("name")).isEmpty()); - } - - @Test - public void ConstructorProjection() { - List<Projection> projections = query().from(cat) - .list(ConstructorExpression.create(Projection.class, cat.name, cat)); - assertFalse(projections.isEmpty()); - for (Projection projection : projections) { - assertNotNull(projection); - } - } - - @Test - public void ConstructorProjection2() { - List<Projection> projections = query().from(cat).list(new QProjection(cat.name, cat)); - assertFalse(projections.isEmpty()); - for (Projection projection : projections) { - assertNotNull(projection); - } - } - - @Test - public void Contains_Ic() { - QFoo foo = QFoo.foo; - assertEquals(1, query().from(foo).where(foo.bar.containsIgnoreCase("München")).count()); - } - - @Test - public void Contains1() { - assertEquals(1, query().from(cat).where(cat.name.contains("eli")).count()); - } - - @Test - public void Contains2() { - assertEquals(1l, query().from(cat).where(cat.kittens.contains(savedCats.get(0))).count()); - } - - @Test - public void Contains3() { - assertEquals(1l, query().from(cat).where(cat.name.contains("_")).count()); - } - - @Test - public void Contains4() { - QEmployee employee = QEmployee.employee; - query().from(employee) - .where( - employee.jobFunctions.contains(JobFunction.CODER), - employee.jobFunctions.contains(JobFunction.CONSULTANT), - employee.jobFunctions.size().eq(2)) - .list(employee); - } - - @Test - public void Count() { - QShow show = QShow.show; - assertTrue(query().from(show).count() > 0); - } - - @Test - public void Count_Distinct() { - QCat cat = QCat.cat; - query().from(cat) - .groupBy(cat.id) - .list(cat.id, cat.breed.countDistinct()); - } - - @Test - @NoBatooJPA - @NoHibernate - public void Count_Distinct2() { - QCat cat = QCat.cat; - query().from(cat) - .groupBy(cat.id) - .list(cat.id, cat.birthdate.dayOfMonth().countDistinct()); - } - - @Test - public void DistinctResults() { - System.out.println("-- list results"); - SearchResults<Date> res = query().from(cat).limit(2).listResults(cat.birthdate); - assertEquals(2, res.getResults().size()); - assertEquals(6l, res.getTotal()); - System.out.println(); - - System.out.println("-- list distinct results"); - res = query().from(cat).limit(2).distinct().listResults(cat.birthdate); - assertEquals(1, res.getResults().size()); - assertEquals(1l, res.getTotal()); - System.out.println(); - - System.out.println("-- list distinct"); - assertEquals(1, query().from(cat).distinct().list(cat.birthdate).size()); - } - - @Test - @ExcludeIn(ORACLE) - public void Divide() { - QSimpleTypes entity = new QSimpleTypes("entity1"); - QSimpleTypes entity2 = new QSimpleTypes("entity2"); - - query().from(entity, entity2) - .where(entity.ddouble.divide(entity2.ddouble).loe(2.0)) - .list(entity); - - query().from(entity, entity2) - .where(entity.ddouble.divide(entity2.iint).loe(2.0)) - .list(entity); - - query().from(entity, entity2) - .where(entity.iint.divide(entity2.ddouble).loe(2.0)) - .list(entity); - - query().from(entity, entity2) - .where(entity.iint.divide(entity2.iint).loe(2)) - .list(entity); - } - - @Test - @ExcludeIn(ORACLE) - public void Divide_BigDecimal() { - QSimpleTypes entity = new QSimpleTypes("entity1"); - QSimpleTypes entity2 = new QSimpleTypes("entity2"); - NumberPath<BigDecimal> bigd1 = entity.bigDecimal; - NumberPath<BigDecimal> bigd2 = entity2.bigDecimal; - - query().from(entity, entity2) - .where(bigd1.divide(bigd2).loe(new BigDecimal("1.00"))) - .list(entity); - - query().from(entity, entity2) - .where(entity.ddouble.divide(bigd2).loe(new BigDecimal("1.00"))) - .list(entity); - - query().from(entity, entity2) - .where(bigd1.divide(entity.ddouble).loe(new BigDecimal("1.00"))) - .list(entity); - } - - @Test - public void EndsWith() { - assertEquals(1, query().from(cat).where(cat.name.endsWith("h123")).count()); - } - - @Test - public void EndsWith_IgnoreCase() { - assertEquals(1, query().from(cat).where(cat.name.endsWithIgnoreCase("H123")).count()); - } - - @Test - public void EndsWith2() { - assertEquals(0, query().from(cat).where(cat.name.endsWith("X")).count()); - } - - @Test - public void EndsWith3() { - assertEquals(1, query().from(cat).where(cat.name.endsWith("_123")).count()); - } - - @Test - @NoBatooJPA - public void Enum_in() { - assertEquals(1, query().from(company).where(company.ratingOrdinal.in(Rating.A, Rating.AA)).count()); - assertEquals(1, query().from(company).where(company.ratingString.in(Rating.A, Rating.AA)).count()); - } - - @Test - @NoBatooJPA - public void Enum_In() { - QEmployee employee = QEmployee.employee; - - JPQLQuery query = query(); - query.from(employee).where(employee.lastName.eq("Smith"), employee.jobFunctions - .contains(JobFunction.CODER)); - assertEquals(1l, query.count()); - } - - @Test - public void Exists() { - assertTrue(query().from(cat).where(cat.kittens.any().name.eq("Ruth123")).exists()); - } - - @Test - @NoEclipseLink @NoOpenJPA @NoBatooJPA - public void Fetch() { - QMammal mammal = QMammal.mammal; - QHuman human = new QHuman("mammal"); - query().from(mammal) - .leftJoin(human.hairs).fetch() - .list(mammal); - } - - @Test - @NoEclipseLink @NoOpenJPA @NoBatooJPA - public void Fetch2() { - QWorld world = QWorld.world; - QMammal mammal = QMammal.mammal; - QHuman human = new QHuman("mammal"); - query().from(world) - .leftJoin(world.mammals, mammal).fetch() - .leftJoin(human.hairs).fetch() - .list(world); - } - - @Test - @ExcludeIn({MYSQL, DERBY}) - @NoBatooJPA - public void GroupBy() { - QAuthor author = QAuthor.author; - QBook book = QBook.book; - - for (int i = 0; i < 10; i++) { - Author a = new Author(); - a.setName(String.valueOf(i)); - save(a); - for (int j = 0; j < 2; j++) { - Book b = new Book(); - b.setTitle(String.valueOf(i)+" "+String.valueOf(j)); - b.setAuthor(a); - save(b); - } - } - - Map<Long, List<Pair<Long, String>>> map = query() - .from(author) - .join(author.books, book) - .transform(GroupBy - .groupBy(author.id) - .as(GroupBy.list(QPair.create(book.id, book.title)))); - - for (Entry<Long, List<Pair<Long, String>>> entry : map.entrySet()) { - System.out.println("author = " + entry.getKey()); - - for (Pair<Long,String> pair : entry.getValue()) { - System.out.println(" book = " + pair.getFirst() + "," + pair.getSecond()); - } - } - } - - @Test - public void GroupBy2() { -// select cat0_.name as col_0_0_, cat0_.breed as col_1_0_, sum(cat0_.bodyWeight) as col_2_0_ -// from animal_ cat0_ where cat0_.DTYPE in ('C', 'DC') and cat0_.bodyWeight>? -// group by cat0_.name , cat0_.breed - query().from(cat) - .where(cat.bodyWeight.gt(0)) - .groupBy(cat.name, cat.breed) - .list(cat.name, cat.breed, cat.bodyWeight.sum()); - } - - @Test - @NoEclipseLink - public void GroupBy_YearMonth() { - query().from(cat) - .groupBy(cat.birthdate.yearMonth()) - .orderBy(cat.birthdate.yearMonth().asc()) - .list(cat.id.count()); - } - - @Test - public void In() { - assertEquals(3l, query().from(cat).where(cat.name.in("Bob123", "Ruth123", "Felix123")).count()); - - query().from(cat).where(cat.id.in(Arrays.asList(1,2,3))).count(); - query().from(cat).where(cat.name.in(Arrays.asList("A","B","C"))).count(); - } - - @Test - public void In2() { - query().from(cat).where(cat.id.in(1,2,3)).count(); - query().from(cat).where(cat.name.in("A","B","C")).count(); - } - - @Test - public void In3() { - query().from(cat).where(cat.name.in("A,B,C".split(","))).count(); - } - - @Test - public void In4() { - //$.parameterRelease.id.eq(releaseId).and($.parameterGroups.any().id.in(filter.getGroups())); - query().from(cat).where(cat.id.eq(1), cat.kittens.any().id.in(1,2,3)).list(cat); - } - - @Test - public void In5() { - query().from(cat).where(cat.mate.in(savedCats)).count(); - } - - @Test - @Ignore - public void In6() { - //query().from(cat).where(cat.kittens.in(savedCats)).count(); - } - - @Test - public void In7() { - query().from(cat).where(cat.kittens.any().in(savedCats)).count(); - } - - @Test - @IncludeIn(Target.H2) - @NoBatooJPA - public void In_Empty() { - query().from(cat).where(cat.name.in(Collections.<String>emptyList())).count(); - } - - @Test - @NoOpenJPA - public void IndexOf() { - assertEquals(Integer.valueOf(0), query().from(cat).where(cat.name.eq("Bob123")) - .uniqueResult(cat.name.indexOf("B"))); - } - - @Test - @NoOpenJPA - public void IndexOf2() { - assertEquals(Integer.valueOf(1), query().from(cat).where(cat.name.eq("Bob123")) - .uniqueResult(cat.name.indexOf("o"))); - } - - @Test - public void InstanceOf_Cat() { - assertEquals(6l, query().from(cat).where(cat.instanceOf(Cat.class)).count()); - } - - @Test - public void InstanceOf_DomesticCat() { - assertEquals(0l, query().from(cat).where(cat.instanceOf(DomesticCat.class)).count()); - } - - @Test - public void InstanceOf_Entity1() { - QEntity1 entity1 = QEntity1.entity1; - assertEquals(2l, query().from(entity1).where(entity1.instanceOf(Entity1.class)).count()); - } - - @Test - public void InstanceOf_Entity2() { - QEntity1 entity1 = QEntity1.entity1; - assertEquals(1l, query().from(entity1).where(entity1.instanceOf(Entity2.class)).count()); - } - - @Test - @NoHibernate // https://hibernate.atlassian.net/browse/HHH-6686 - public void IsEmpty_ElementCollection() { - QEmployee employee = QEmployee.employee; - query().from(employee).where(employee.jobFunctions.isEmpty()).count(); - } - - @Test - public void IsEmpty_Relation() { - query().from(cat).where(cat.kittensSet.isEmpty()).count(); - } - - @Test - @NoEclipseLink - @ExcludeIn({ORACLE, TERADATA}) - public void JoinEmbeddable() { - QBookVersion bookVersion = QBookVersion.bookVersion; - QBookMark bookMark = QBookMark.bookMark; - - query().from(bookVersion) - .join(bookVersion.definition.bookMarks, bookMark) - .where( - bookVersion.definition.bookMarks.size().eq(1), - bookMark.page.eq(2357L).or(bookMark.page.eq(2356L))) - .list(bookVersion); - } - - @Test - public void Length() { - assertEquals(6, query().from(cat).where(cat.name.length().gt(0)).count()); - } - - @Test - public void Like() { - query().from(cat).where(cat.name.like("!")).count(); - query().from(cat).where(cat.name.like("\\")).count(); - } - - @Test - public void Limit() { - List<String> names1 = Arrays.asList("Allen123","Bob123"); - assertEquals(names1, query().from(cat).orderBy(cat.name.asc()).limit(2).list(cat.name)); - } - - @Test - public void Limit_and_offset() { - List<String> names3 = Arrays.asList("Felix123","Mary_123"); - assertEquals(names3, query().from(cat).orderBy(cat.name.asc()).limit(2).offset(2).list(cat.name)); - } - - @Test - public void Limit2() { - assertEquals(Collections.singletonList("Allen123"), - query().from(cat).orderBy(cat.name.asc()).limit(1).list(cat.name)); - } - - @Test - public void Limit3() { - assertEquals(6, query().from(cat).limit(Long.MAX_VALUE).list(cat).size()); - } - - @Test - public void List_ElementCollection_Of_Enum() { - QEmployee employee = QEmployee.employee; - //QJobFunction jobFunction = QJobFunction.jobFunction; - EnumPath<JobFunction> jobFunction = new EnumPath<JobFunction>(JobFunction.class, "jf"); - - List<JobFunction> jobFunctions = query().from(employee) - .innerJoin(employee.jobFunctions, jobFunction).list(jobFunction); - assertEquals(4, jobFunctions.size()); - } - - @Test - @NoBatooJPA - public void List_ElementCollection_Of_String() { - QFoo foo = QFoo.foo; - StringPath str = new StringPath("str"); - - List<String> strings = query().from(foo).innerJoin(foo.names, str).list(str); - assertEquals(2, strings.size()); - assertTrue(strings.contains("a")); - assertTrue(strings.contains("b")); - } - - @Test - @NoEclipseLink @NoOpenJPA @NoBatooJPA - public void Map_ContainsKey() { - QShow show = QShow.show; - assertEquals(1l, query().from(show).where(show.acts.containsKey("a")).count()); - } - - @Test - @NoEclipseLink @NoOpenJPA @NoBatooJPA - public void Map_ContainsKey2() { - QShow show = QShow.show; - assertEquals(1l, query().from(show).where(show.acts.containsKey("b")).count()); - } - - @Test - @NoEclipseLink @NoOpenJPA @NoBatooJPA - public void Map_ContainsKey3() { - QShow show = QShow.show; - assertEquals(0l, query().from(show).where(show.acts.containsKey("c")).count()); - } - - @Test - @NoEclipseLink @NoOpenJPA @NoBatooJPA - public void Map_ContainsValue() { - QShow show = QShow.show; - assertEquals(1l, query().from(show).where(show.acts.containsValue("A")).count()); - } - - @Test - @NoEclipseLink @NoOpenJPA @NoBatooJPA - public void Map_ContainsValue2() { - QShow show = QShow.show; - assertEquals(1l, query().from(show).where(show.acts.containsValue("B")).count()); - } - - @Test - @NoEclipseLink @NoOpenJPA @NoBatooJPA - public void Map_ContainsValue3() { - QShow show = QShow.show; - assertEquals(0l, query().from(show).where(show.acts.containsValue("C")).count()); - } - - @Test - @Ignore - public void Map_Join() { - //select m.text from Show s join s.acts a where key(a) = 'B' - QShow show = QShow.show; - StringPath act = new StringPath("act"); - query().from(show).join(show.acts, act); - } - - @Test - public void Max() { - query().from(cat).uniqueResult(cat.bodyWeight.max()); - } - - @Test - public void Min() { - query().from(cat).uniqueResult(cat.bodyWeight.min()); - } - - @Test - @ExcludeIn(ORACLE) - public void Multiply() { - QSimpleTypes entity = new QSimpleTypes("entity1"); - QSimpleTypes entity2 = new QSimpleTypes("entity2"); - query().from(entity, entity2) - .where(entity.ddouble.multiply(entity2.ddouble).loe(2.0)) - .list(entity); - } - - @Test - @ExcludeIn(ORACLE) - public void Multiply_BigDecimal() { - QSimpleTypes entity = new QSimpleTypes("entity1"); - QSimpleTypes entity2 = new QSimpleTypes("entity2"); - NumberPath<BigDecimal> bigd1 = entity.bigDecimal; - NumberPath<BigDecimal> bigd2 = entity2.bigDecimal; - - query().from(entity, entity2) - .where(bigd1.multiply(bigd2).loe(new BigDecimal("1.00"))) - .list(entity); - } - - @Test - public void NestedProjection() { - Concatenation concat = new Concatenation(cat.name, cat.name); - List<Tuple> tuples = query().from(cat).list(new QTuple(cat.name, concat)); - assertFalse(tuples.isEmpty()); - for (Tuple tuple : tuples) { - assertEquals( - tuple.get(concat), - tuple.get(cat.name)+tuple.get(cat.name)); - } - } - - @Test - public void Not_Exists() { - assertTrue(query().from(cat).where(cat.kittens.any().name.eq("XXX")).notExists()); - } - - @Test - public void Not_In() { - long all = query().from(cat).count(); - assertEquals(all - 3l, query().from(cat).where(cat.name.notIn("Bob123", "Ruth123", "Felix123")).count()); - - query().from(cat).where(cat.id.notIn(1,2,3)).count(); - query().from(cat).where(cat.name.notIn("A","B","C")).count(); - } - - @Test - @IncludeIn(Target.H2) - @NoBatooJPA - public void Not_In_Empty() { - query().from(cat).where(cat.name.notIn(Collections.<String>emptyList())).count(); - } - - @Test - public void Null_as_uniqueResult() { - assertNull(query().from(cat).where(cat.name.eq(UUID.randomUUID().toString())) - .uniqueResult(cat)); - } - - @Test - @NoEclipseLink - public void Numeric() { - QNumeric numeric = QNumeric.numeric; - BigDecimal singleResult = query().from(numeric).singleResult(numeric.value); - assertEquals(26.9, singleResult.doubleValue(), 0.001); - } - - @Test - @NoOpenJPA - @NoBatooJPA // FIXME - public void Offset1() { - List<String> names2 = Arrays.asList("Bob123", "Felix123", "Mary_123", "Ruth123", "Some"); - assertEquals(names2, query().from(cat).orderBy(cat.name.asc()).offset(1).list(cat.name)); - } - - @Test - @NoOpenJPA - @NoBatooJPA // FIXME - public void Offset2() { - List<String> names2 = Arrays.asList("Felix123", "Mary_123", "Ruth123", "Some"); - assertEquals(names2, query().from(cat).orderBy(cat.name.asc()).offset(2).list(cat.name)); - } - - @Test - public void One_To_One() { - QEmployee employee = QEmployee.employee; - QUser user = QUser.user; - - JPQLQuery query = query(); - query.from(employee); - query.innerJoin(employee.user, user); - query.list(employee); - } - - @Test - public void Order() { - NumberPath<Double> weight = new NumberPath<Double>(Double.class, "weight"); - query().from(cat).orderBy(weight.asc()).list(cat.bodyWeight.as(weight)); - } - - @Test - public void Order_By_Count() { - NumberPath<Long> count = Expressions.numberPath(Long.class, "c"); - query().from(cat) - .groupBy(cat.id) - .orderBy(count.asc()) - .list(cat.id, cat.id.count().as(count)); - } - - @Test - public void Order_StringValue() { - int count = (int)query().from(cat).count(); - assertEquals(count, query().from(cat).orderBy(cat.id.stringValue().asc()).list(cat).size()); - } - - @Test - @NoBatooJPA // can't be parsed - public void Order_StringValue_To_Integer() { - int count = (int)query().from(cat).count(); - assertEquals(count, query().from(cat).orderBy(cat.id.stringValue().castToNum(Integer.class).asc()).list(cat).size()); - } - - @Test - @NoBatooJPA // can't be parsed - public void Order_StringValue_ToLong() { - int count = (int)query().from(cat).count(); - assertEquals(count, query().from(cat).orderBy(cat.id.stringValue().castToNum(Long.class).asc()).list(cat).size()); - } - - @Test - @NoBatooJPA // can't be parsed - public void Order_StringValue_ToBigInteger() { - int count = (int)query().from(cat).count(); - assertEquals(count, query().from(cat).orderBy(cat.id.stringValue().castToNum(BigInteger.class).asc()).list(cat).size()); - } - - @Test - @NoBatooJPA - public void Order_NullsFirst() { - assertNull(query().from(cat) - .orderBy(cat.dateField.asc().nullsFirst()) - .singleResult(cat.dateField)); - } - - @Test - @NoBatooJPA - public void Order_NullsLast() { - assertNotNull(query().from(cat) - .orderBy(cat.dateField.asc().nullsLast()) - .singleResult(cat.dateField)); - } - - @Test - public void Params() { - Param<String> name = new Param<String>(String.class,"name"); - assertEquals("Bob123",query().from(cat).where(cat.name.eq(name)).set(name, "Bob123") - .uniqueResult(cat.name)); - } - - @Test - public void Params_anon() { - Param<String> name = new Param<String>(String.class); - assertEquals("Bob123",query().from(cat).where(cat.name.eq(name)).set(name, "Bob123") - .uniqueResult(cat.name)); - } - - @Test(expected=ParamNotSetException.class) - public void Params_not_set() { - Param<String> name = new Param<String>(String.class,"name"); - assertEquals("Bob123",query().from(cat).where(cat.name.eq(name)).uniqueResult(cat.name)); - } - - @Test - public void Precedence() { - StringPath str = cat.name; - Predicate where = str.like("Bob%").and(str.like("%ob123")) - .or(str.like("Ruth%").and(str.like("%uth123"))); - assertEquals(2l, query().from(cat).where(where).count()); - } - - @Test - public void Precedence2() { - StringPath str = cat.name; - Predicate where = str.like("Bob%").and(str.like("%ob123") - .or(str.like("Ruth%"))).and(str.like("%uth123")); - assertEquals(0l, query().from(cat).where(where).count()); - } - - @Test - public void Precedence3() { - Predicate where = cat.name.eq("Bob123").and(cat.id.eq(1)) - .or(cat.name.eq("Ruth123").and(cat.id.eq(2))); - assertEquals(2l, query().from(cat).where(where).count()); - } - - @Test - public void FactoryExpression_In_GroupBy() { - Expression<Cat> catBean = Projections.bean(Cat.class, cat.id, cat.name); - assertFalse(query().from(cat).groupBy(catBean).list(catBean).isEmpty()); - } - - @Test - @Ignore - public void Size() { - // NOT SUPPORTED - query().from(cat).list(cat, cat.kittens.size()); - } - - @Test - public void StartsWith() { - assertEquals(1, query().from(cat).where(cat.name.startsWith("R")).count()); - } - - @Test - public void StartsWith_IgnoreCase() { - assertEquals(1, query().from(cat).where(cat.name.startsWithIgnoreCase("r")).count()); - } - - @Test - public void StartsWith2() { - assertEquals(0, query().from(cat).where(cat.name.startsWith("X")).count()); - } - - @Test - public void StartsWith3() { - assertEquals(1, query().from(cat).where(cat.name.startsWith("Mary_")).count()); - } - - @Test - @ExcludeIn({MYSQL, TERADATA}) - @NoOpenJPA - public void StringOperations() { - // NOTE : locate in MYSQL is case-insensitive - assertEquals(0, query().from(cat).where(cat.name.startsWith("r")).count()); - assertEquals(0, query().from(cat).where(cat.name.endsWith("H123")).count()); - assertEquals(Integer.valueOf(2), query().from(cat).where(cat.name.eq("Bob123")) - .uniqueResult(cat.name.indexOf("b"))); - } - - @Test - public void SubQuery() { - QShow show = QShow.show; - QShow show2 = new QShow("show2"); - query().from(show).where(subQuery().from(show2) - .where(show2.id.ne(show.id)).count().gt(0)).count(); - } - - @Test - public void SubQuery2() { - QCat cat = QCat.cat; - QCat other = new QCat("other"); - List<Cat> cats = query().from(cat) - .where(cat.name.in(new HibernateSubQuery().from(other) - .groupBy(other.name).list(other.name))) - .list(cat); - assertNotNull(cats); - } - - @Test - public void SubQuery3() { - QCat cat = QCat.cat; - QCat other = new QCat("other"); - query().from(cat) - .where(cat.name.eq(new JPASubQuery().from(other) - .where(other.name.indexOf("B").eq(0)) - .unique(other.name))) - .list(cat); - } - - @Test - public void Substring() { - for (String str : query().from(cat).list(cat.name.substring(1,2))) { - assertEquals(1, str.length()); - } - } - - @Test - @NoBatooJPA - @ExcludeIn(ORACLE) - public void Substring2() { - QCompany company = QCompany.company; - StringExpression name = company.name; - Integer companyId = query().from(company).singleResult(company.id); - JPQLQuery query = query().from(company).where(company.id.eq(companyId)); - String str = query.singleResult(company.name); - - assertEquals(Integer.valueOf(29), - query.singleResult(name.length().subtract(11))); - - assertEquals(str.substring(0, 7), - query.singleResult(name.substring(0, 7))); - - assertEquals(str.substring(15), - query.singleResult(name.substring(15))); - - assertEquals(str.substring(str.length()), - query.singleResult(name.substring(name.length()))); - - assertEquals(str.substring(str.length() - 11), - query.singleResult(name.substring(name.length().subtract(11)))); - } - - @Test - @ExcludeIn(DERBY) - public void Substring_From_Right() { - query().from(cat) - .where(cat.name.substring(-1, 1).eq(cat.name.substring(-2, 1))) - .list(cat); - } - - @Test - @ExcludeIn({HSQLDB, DERBY}) - public void Substring_From_Right2() { - query().from(cat) - .where(cat.name.substring(cat.name.length().subtract(1), cat.name.length()) - .eq(cat.name.substring(cat.name.length().subtract(2), cat.name.length().subtract(1)))) - .list(cat); - } - - @Test - @ExcludeIn(ORACLE) - public void Subtract_BigDecimal() { - QSimpleTypes entity = new QSimpleTypes("entity1"); - QSimpleTypes entity2 = new QSimpleTypes("entity2"); - NumberPath<BigDecimal> bigd1 = entity.bigDecimal; - NumberPath<BigDecimal> bigd2 = entity2.bigDecimal; - - query().from(entity, entity2) - .where(bigd1.subtract(bigd2).loe(new BigDecimal("1.00"))) - .list(entity); - } - - @Test - @Ignore - public void Sum() throws RecognitionException, TokenStreamException { - // NOT SUPPORTED - query().from(cat).list(cat.kittens.size().sum()); - } - - @Test - @Ignore - public void Sum_2() throws RecognitionException, TokenStreamException { - // NOT SUPPORTED - query().from(cat).where(cat.kittens.size().sum().gt(0)).list(cat); - } - - @Test - public void Sum_3() { - query().from(cat).uniqueResult(cat.bodyWeight.sum()); - } - - @Test - public void Sum_3_Projected() { - double val = query().from(cat).uniqueResult(cat.bodyWeight.sum()); - DoubleProjection projection = query().from(cat) - .uniqueResult(new QDoubleProjection(cat.bodyWeight.sum())); - assertEquals(val, projection.val, 0.001); - } - - @Test - public void Sum_4() { - Double dbl = query().from(cat).uniqueResult(cat.bodyWeight.sum().negate()); - assertNotNull(dbl); - } - - @Test - public void Sum_5() { - QShow show = QShow.show; - Long lng = query().from(show).uniqueResult(show.id.sum()); - assertNotNull(lng); - } - - @Test - public void Sum_of_Integer() { - QCat cat2 = new QCat("cat2"); - query().from(cat) - .where(new JPASubQuery() - .from(cat2).where(cat2.eq(cat.mate)) - .unique(cat2.breed.sum()).gt(0)) - .list(cat); - } - - @Test - public void Sum_of_Float() { - QCat cat2 = new QCat("cat2"); - query().from(cat) - .where(new JPASubQuery() - .from(cat2).where(cat2.eq(cat.mate)) - .unique(cat2.floatProperty.sum()).gt(0.0)) - .list(cat); - } - - @Test - public void Sum_of_Double() { - QCat cat2 = new QCat("cat2"); - query().from(cat) - .where(new JPASubQuery() - .from(cat2).where(cat2.eq(cat.mate)) - .unique(cat2.bodyWeight.sum()).gt(0.0)) - .list(cat); - } - - @Test - public void Sum_as_Float() { - float val = query().from(cat).uniqueResult(cat.floatProperty.sum()); - assertTrue(val > 0); - } - - @Test - public void Sum_as_Float_Projected() { - float val = query().from(cat).uniqueResult(cat.floatProperty.sum()); - FloatProjection projection = query().from(cat) - .uniqueResult(new QFloatProjection(cat.floatProperty.sum())); - assertEquals(val, projection.val, 0.001); - } - - @Test - public void Sum_as_Float2() { - float val = query().from(cat).uniqueResult(cat.floatProperty.sum().negate()); - assertTrue(val < 0); - } - - @Test - public void Sum_Coalesce() { - int val = query().from(cat).uniqueResult(cat.weight.sum().coalesce(0)); - assertTrue(val == 0); - } - - @Test - public void Sum_NoRows_Double() { - query().from(cat) - .where(cat.name.eq(UUID.randomUUID().toString())) - .uniqueResult(cat.bodyWeight.sum()); - } - - @Test - public void Sum_NoRows_Float() { - query().from(cat) - .where(cat.name.eq(UUID.randomUUID().toString())) - .uniqueResult(cat.floatProperty.sum()); - } - - @Test - @NoEclipseLink @NoOpenJPA @NoBatooJPA - public void test() { - Cat kitten = savedCats.get(0); - Cat noKitten = savedCats.get(savedCats.size()-1); - - ProjectionsFactory projections = new ProjectionsFactory(Module.JPA, getTarget()) { - @Override - public <A,Q extends SimpleExpression<A>> Collection<Expression<?>> list(ListPath<A,Q> expr, - ListExpression<A,Q> other, A knownElement) { - // NOTE : expr.get(0) is only supported in the where clause - return Collections.<Expression<?>>singleton(expr.size()); - } - }; - - final EntityPath<?>[] sources = new EntityPath[]{cat, otherCat}; - final Predicate[] conditions = new Predicate[]{condition}; - final Expression<?>[] projection = new Expression[]{cat.name, otherCat.name}; - - QueryExecution standardTest = new QueryExecution( - projections, - new FilterFactory(projections, Module.JPA, getTarget()), - new MatchingFiltersFactory(Module.JPA, getTarget())) { - - @Override - protected Pair<Projectable, Expression<?>[]> createQuery() { - // NOTE : EclipseLink needs extra conditions cond1 and code2 - return Pair.of( - (Projectable)testQuery().from(sources).where(conditions), - NO_EXPRESSIONS); - } - - @Override - protected Pair<Projectable, Expression<?>[]> createQuery(Predicate filter) { - // NOTE : EclipseLink needs extra conditions cond1 and code2 - return Pair.of( - (Projectable)testQuery().from(sources).where(condition, filter), - projection); - } - }; - - // standardTest.runArrayTests(cat.kittensArray, otherCat.kittensArray, kitten, noKitten); - standardTest.runBooleanTests(cat.name.isNull(), otherCat.kittens.isEmpty()); - standardTest.runCollectionTests(cat.kittens, otherCat.kittens, kitten, noKitten); - standardTest.runDateTests(cat.dateField, otherCat.dateField, date); - standardTest.runDateTimeTests(cat.birthdate, otherCat.birthdate, birthDate); - standardTest.runListTests(cat.kittens, otherCat.kittens, kitten, noKitten); - // standardTest.mapTests(cat.kittensByName, otherCat.kittensByName, "Kitty", kitten); - - // int - standardTest.runNumericCasts(cat.id, otherCat.id, 1); - standardTest.runNumericTests(cat.id, otherCat.id, 1); - - // double - standardTest.runNumericCasts(cat.bodyWeight, otherCat.bodyWeight, 1.0); - standardTest.runNumericTests(cat.bodyWeight, otherCat.bodyWeight, 1.0); - - standardTest.runStringTests(cat.name, otherCat.name, kitten.getName()); - standardTest.runTimeTests(cat.timeField, otherCat.timeField, time); - - standardTest.report(); - } - - @Test - public void TupleProjection() { - List<Tuple> tuples = query().from(cat).list(new QTuple(cat.name, cat)); - assertFalse(tuples.isEmpty()); - for (Tuple tuple : tuples) { - assertNotNull(tuple.get(cat.name)); - assertNotNull(tuple.get(cat)); - } - } - - @Test - public void TupleProjection_As_SearchResults() { - SearchResults<Tuple> tuples = query().from(cat).limit(1) - .listResults(new QTuple(cat.name, cat)); - assertEquals(1, tuples.getResults().size()); - assertTrue(tuples.getTotal() > 0); - } - - @Test - @ExcludeIn(DERBY) - public void Transform_GroupBy() { - QCat kitten = new QCat("kitten"); - Map<Integer, Cat> result = query().from(cat).innerJoin(cat.kittens, kitten) - .transform(GroupBy.groupBy(cat.id) - .as(Projections.constructor(Cat.class, cat.name, cat.id, - GroupBy.list(Projections.constructor(Cat.class, kitten.name, kitten.id))))); - - for (Cat entry : result.values()) { - assertEquals(1, entry.getKittens().size()); - } - } - - @Test - @ExcludeIn(DERBY) - public void Transform_GroupBy2() { - QCat kitten = new QCat("kitten"); - Map<List<?>, Group> result = query().from(cat).innerJoin(cat.kittens, kitten) - .transform(GroupBy.groupBy(cat.id, kitten.id) - .as(cat, kitten)); - - assertFalse(result.isEmpty()); - for (Tuple row : query().from(cat).innerJoin(cat.kittens, kitten) - .list(cat, kitten)) { - assertNotNull(result.get(Arrays.asList(row.get(cat).getId(), row.get(kitten).getId()))); - } - } - - @Test - @ExcludeIn(DERBY) - public void Transform_GroupBy_Alias() { - QCat kitten = new QCat("kitten"); - SimplePath<Cat> k = new SimplePath<Cat>(Cat.class, "k"); - Map<Integer, Group> result = query().from(cat).innerJoin(cat.kittens, kitten) - .transform(GroupBy.groupBy(cat.id) - .as(cat.name, cat.id, - GroupBy.list(Projections.constructor(Cat.class, kitten.name, kitten.id).as(k)))); - - for (Group entry : result.values()) { - assertNotNull(entry.getOne(cat.id)); - assertNotNull(entry.getOne(cat.name)); - assertFalse(entry.getList(k).isEmpty()); - } - } - - @Test - @NoBatooJPA - public void Treat() { - QDomesticCat domesticCat = QDomesticCat.domesticCat; - query().from(cat) - .innerJoin(cat.mate, domesticCat._super) - .where(domesticCat.name.eq("Bobby")) - .count(); - } - - @Test - @Ignore - public void Type() { - assertEquals(Arrays.asList("C","C","C","C","C","C","A"), - query().from(animal).orderBy(animal.id.asc()).list(JPAExpressions.type(animal))); - } - - @Test - @NoOpenJPA - public void Type_Order() { - assertEquals(Arrays.asList(10,1,2,3,4,5,6), - query().from(animal).orderBy(JPAExpressions.type(animal).asc(), animal.id.asc()) - .list(animal.id)); - } -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/AbstractSQLTest.java b/querydsl-jpa/src/test/java/com/mysema/query/AbstractSQLTest.java deleted file mode 100644 index d10181690b..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/AbstractSQLTest.java +++ /dev/null @@ -1,359 +0,0 @@ -package com.mysema.query; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -import java.sql.SQLException; -import java.util.Arrays; -import java.util.List; -import java.util.UUID; - -import org.junit.Ignore; -import org.junit.Test; - -import com.mysema.query.jpa.AbstractSQLQuery; -import com.mysema.query.jpa.domain.Cat; -import com.mysema.query.jpa.domain.Color; -import com.mysema.query.jpa.domain.QCat; -import com.mysema.query.jpa.domain.sql.SAnimal; -import com.mysema.query.sql.SQLSubQuery; -import com.mysema.query.types.ConstructorExpression; -import com.mysema.query.types.Expression; -import com.mysema.query.types.Projections; -import com.mysema.query.types.SubQueryExpression; -import com.mysema.query.types.expr.DateExpression; -import com.mysema.query.types.expr.Wildcard; -import com.mysema.testutil.ExcludeIn; - -public abstract class AbstractSQLTest { - - protected static final SAnimal cat = new SAnimal("cat"); - - protected abstract AbstractSQLQuery<?> query(); - - public static class CatDTO { - - Cat cat; - - public CatDTO(Cat cat) { - this.cat = cat; - } - - } - - protected SQLSubQuery sq() { - return new SQLSubQuery(); - } - - @Test - public void Count() { - assertEquals(6l, query().from(cat).where(cat.dtype.eq("C")).count()); - } - - @Test - public void Count_Via_Unique() { - assertEquals(Long.valueOf(6), query().from(cat).where(cat.dtype.eq("C")) - .uniqueResult(cat.id.count())); - } - - @Test - public void CountDistinct() { - assertEquals(6l, query().from(cat).where(cat.dtype.eq("C")).distinct().count()); - } - - @Test - public void Enum_Binding() { - List<Cat> cats = query().from(cat) - .list(Projections.bean(Cat.class, QCat.cat.color)); - assertFalse(cats.isEmpty()); - - for (Cat cat : cats) { - assertEquals(Color.BLACK, cat.getColor()); - } - } - - @Test - @Ignore - public void EntityProjections() { - List<Cat> cats = query().from(cat).orderBy(cat.name.asc()) - .list(ConstructorExpression.create(Cat.class, cat.name, cat.id)); - assertEquals(6, cats.size()); - for (Cat c : cats) { - System.out.println(c.getName()); - } - } - - @Test - public void EntityQueries() { - QCat catEntity = QCat.cat; - - List<Cat> cats = query().from(cat).orderBy(cat.name.asc()).list(catEntity); - assertEquals(6, cats.size()); - for (Cat c : cats) { - System.out.println(c.getName()); - } - } - - @Test - public void EntityQueries2() { - SAnimal mate = new SAnimal("mate"); - QCat catEntity = QCat.cat; - - List<Cat> cats = query().from(cat) - .innerJoin(mate).on(cat.mateId.eq(mate.id)) - .where(cat.dtype.eq("C"), mate.dtype.eq("C")) - .list(catEntity); - assertTrue(cats.isEmpty()); - } - - @Test - public void EntityQueries3() { - QCat catEntity = new QCat("animal_"); - query().from(catEntity).list(catEntity.toes.max()); - } - - @Test - @NoBatooJPA - @NoEclipseLink - public void EntityQueries4() { - QCat catEntity = QCat.cat; - List<Tuple> cats = query().from(cat).list(catEntity, cat.name, cat.id); - assertEquals(6, cats.size()); - - for (Tuple tuple : cats) { - assertTrue(tuple.get(catEntity) instanceof Cat); - assertTrue(tuple.get(cat.name) instanceof String); - assertTrue(tuple.get(cat.id) instanceof Integer); - } - } - - @Test - @NoBatooJPA - @NoEclipseLink - public void EntityQueries5() { - QCat catEntity = QCat.cat; - SAnimal otherCat = new SAnimal("otherCat"); - QCat otherCatEntity = new QCat("otherCat"); - List<Tuple> cats = query().from(cat, otherCat).list(catEntity, otherCatEntity); - assertEquals(36, cats.size()); - - for (Tuple tuple : cats) { - assertTrue(tuple.get(catEntity) instanceof Cat); - assertTrue(tuple.get(otherCatEntity) instanceof Cat); - } - } - - @Test - @NoBatooJPA - @NoEclipseLink - public void EntityQueries6() { - QCat catEntity = QCat.cat; - List<CatDTO> results = query().from(cat).list(Projections.constructor(CatDTO.class, catEntity)); - assertEquals(6, results.size()); - - for (CatDTO cat : results) { - assertTrue(cat.cat instanceof Cat); - } - } - - @Test - public void In() { - assertEquals(6l, query().from(cat).where(cat.dtype.in("C", "CX")).count()); - } - - @Test - public void Limit_Offset() { - assertEquals(2, query().from(cat).limit(2).offset(2).list(cat.id, cat.name).size()); - } - - @Test - public void List() { - assertEquals(6, query().from(cat).where(cat.dtype.eq("C")).list(cat.id).size()); - } - - @Test - public void List_Limit_And_Offset() { - assertEquals(3, query().from(cat).offset(3).limit(3).list(cat.id).size()); - } - - @Test - public void List_Limit_And_Offset2() { - List<Tuple> tuples = query().from(cat).offset(3).limit(3).list(cat.id, cat.name); - assertEquals(3, tuples.size()); - assertEquals(2, tuples.get(0).size()); - } - - @Test - public void List_Multiple() { - print(query().from(cat).where(cat.dtype.eq("C")).list(cat.id, cat.name, cat.bodyWeight)); - } - - @Test - public void List_Non_Path() { - assertEquals(6, query().from(cat).where(cat.dtype.eq("C")).list( - cat.birthdate.year(), - cat.birthdate.month(), - cat.birthdate.dayOfMonth()).size()); - } - - @Test - public void List_Results() { - SearchResults<String> results = query().from(cat).limit(3).orderBy(cat.name.asc()) - .listResults(cat.name); - assertEquals(Arrays.asList("Beck","Bobby","Harold"), results.getResults()); - assertEquals(6l, results.getTotal()); - } - - @Test - @ExcludeIn(Target.H2) - public void List_Wildcard() { - assertEquals(6l, query().from(cat).where(cat.dtype.eq("C")).list(Wildcard.all).size()); - } - - @Test - public void List_With_Count() { - print(query().from(cat).where(cat.dtype.eq("C")).groupBy(cat.name) - .list(cat.name, cat.id.count())); - } - - @Test - public void List_With_Limit() { - assertEquals(3, query().from(cat).limit(3).list(cat.id).size()); - } - - @Test - @ExcludeIn({Target.H2, Target.MYSQL}) - public void List_With_Offset() { - assertEquals(3, query().from(cat).offset(3).list(cat.id).size()); - } - - @Test - @ExcludeIn(Target.HSQLDB) - public void No_From() { - assertNotNull(query().singleResult(DateExpression.currentDate())); - } - - @Test - public void Null_As_UniqueResult() { - assertNull(query().from(cat).where(cat.name.eq(UUID.randomUUID().toString())) - .uniqueResult(cat.name)); - } - - private void print(Iterable<Tuple> rows) { - for (Tuple row : rows) { - System.out.println(row); - } - } - - @Test - public void Single_Result() { - query().from(cat).singleResult(cat.id); - } - - @Test - public void Single_Result_Multiple() { - query().from(cat).singleResult(new Expression[]{cat.id}); - } - - @Test - @SuppressWarnings("unchecked") - public void Union() throws SQLException { - SubQueryExpression<Integer> sq1 = sq().from(cat).unique(cat.id.max()); - SubQueryExpression<Integer> sq2 = sq().from(cat).unique(cat.id.min()); - List<Integer> list = query().union(sq1, sq2).list(); - assertFalse(list.isEmpty()); - } - - @Test - @SuppressWarnings("unchecked") - public void Union_All() { - SubQueryExpression<Integer> sq1 = sq().from(cat).unique(cat.id.max()); - SubQueryExpression<Integer> sq2 = sq().from(cat).unique(cat.id.min()); - List<Integer> list = query().unionAll(sq1, sq2).list(); - assertFalse(list.isEmpty()); - } - - @Test - @ExcludeIn({Target.DERBY, Target.POSTGRES}) - public void Union2() { - List<Tuple> rows = query().union( - new SQLSubQuery().from(cat).where(cat.name.eq("Beck")).distinct().list(cat.name, cat.id), - new SQLSubQuery().from(cat).where(cat.name.eq("Kate")).distinct().list(cat.name, null)) - .list(); - - assertEquals(2, rows.size()); - for (Tuple row : rows) { - System.err.println(row); - } - } - - @Test - @ExcludeIn(Target.DERBY) - public void Union3() { - SAnimal cat2 = new SAnimal("cat2"); - List<Tuple> rows = query().union( - new SQLSubQuery().from(cat).innerJoin(cat2).on(cat2.id.eq(cat.id)).list(cat.id, cat2.id), - new SQLSubQuery().from(cat).list(cat.id, null)) - .list(); - - assertEquals(12, rows.size()); - int nulls = 0; - for (Tuple row : rows) { - System.err.println(Arrays.asList(row)); - if (row.get(1, Object.class) == null) nulls++; - } - assertEquals(6, nulls); - } - - @Test - @ExcludeIn({Target.DERBY, Target.POSTGRES}) - public void Union4() { - query().union(cat, - new SQLSubQuery().from(cat).where(cat.name.eq("Beck")).distinct().list(cat.name, cat.id), - new SQLSubQuery().from(cat).where(cat.name.eq("Kate")).distinct().list(cat.name, null)) - .list(cat.name, cat.id); - } - - @Test - @ExcludeIn({Target.DERBY, Target.ORACLE}) - public void Union5() { - SAnimal cat2 = new SAnimal("cat2"); - List<Tuple> rows = query().union( - new SQLSubQuery().from(cat).join(cat2).on(cat2.id.eq(cat.id.add(1))).list(cat.id, cat2.id), - new SQLSubQuery().from(cat).join(cat2).on(cat2.id.eq(cat.id.add(1))).list(cat.id, cat2.id)) - .list(); - - assertEquals(5, rows.size()); - for (Tuple row : rows) { - int first = row.get(cat.id).intValue(); - int second = row.get(cat2.id).intValue(); - assertEquals(first + 1, second); - } - } - - @Test - public void Unique_Result() { - query().from(cat).limit(1).uniqueResult(cat.id); - } - - @Test - public void Unique_Result_Multiple() { - query().from(cat).limit(1).uniqueResult(new Expression[]{cat.id}); - } - - @Test - @ExcludeIn(Target.H2) - public void Wildcard() { - List<Tuple> rows = query().from(cat).list(cat.all()); - assertEquals(6, rows.size()); - print(rows); - -// rows = query().from(cat).list(cat.id, cat.all()); -// assertEquals(6, rows.size()); -// print(rows); - } - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/CustomFinder.java b/querydsl-jpa/src/test/java/com/mysema/query/CustomFinder.java deleted file mode 100644 index 8a80bd7f0d..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/CustomFinder.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query; - -import java.util.List; -import java.util.Map; - -import javax.persistence.EntityManager; - -import com.mysema.query.jpa.impl.JPAQuery; -import com.mysema.query.types.EntityPath; -import com.mysema.query.types.path.ComparablePath; -import com.mysema.query.types.path.EntityPathBase; -import com.mysema.query.types.path.SimplePath; - -/** - * @author tiwe - * - */ -public class CustomFinder { - - public static <T> List<T> findCustom(EntityManager em, Class<T> entityClass,Map<String,?> filters, String sort) { - EntityPath<T> entityPath = new EntityPathBase<T>(entityClass, "entity"); - BooleanBuilder builder = new BooleanBuilder(); - for (Map.Entry<String, ?> entry : filters.entrySet()) { - SimplePath<Object> property = new SimplePath<Object>(entry.getValue().getClass(), entityPath, entry.getKey()); - builder.and(property.eq(entry.getValue())); - } - ComparablePath<?> sortProperty = new ComparablePath(Comparable.class, entityPath, sort); - return new JPAQuery(em).from(entityPath).where(builder.getValue()).orderBy(sortProperty.asc()).list(entityPath); - } - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/DependenciesTest.java b/querydsl-jpa/src/test/java/com/mysema/query/DependenciesTest.java deleted file mode 100644 index 6649fbaabc..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/DependenciesTest.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query; - -import static org.junit.Assert.assertFalse; - -import java.io.IOException; - -import jdepend.framework.JDepend; - -import org.junit.Test; - -public class DependenciesTest { - - @Test - public void test() throws IOException{ - JDepend jdepend = new JDepend(); - jdepend.addDirectory("target/classes/com/mysema/query/jpa"); - jdepend.addDirectory("target/classes/com/mysema/query/jpa/hibernate"); - jdepend.addDirectory("target/classes/com/mysema/query/jpa/hibernate/sql"); - jdepend.addDirectory("target/classes/com/mysema/query/jpa/impl"); - jdepend.addDirectory("target/classes/com/mysema/query/jpa/sql"); - - jdepend.analyze(); - assertFalse(jdepend.containsCycles()); - - } - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/HibernateBase.java b/querydsl-jpa/src/test/java/com/mysema/query/HibernateBase.java deleted file mode 100644 index 6ca8703d5f..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/HibernateBase.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -import java.io.IOException; -import java.util.List; - -import org.hibernate.LockMode; -import org.hibernate.Session; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.MethodRule; -import org.junit.runner.RunWith; - -import com.mysema.commons.lang.CloseableIterator; -import com.mysema.query.jpa.HQLTemplates; -import com.mysema.query.jpa.JPQLTemplates; -import com.mysema.query.jpa.ScrollableResultsIterator; -import com.mysema.query.jpa.domain.Cat; -import com.mysema.query.jpa.domain.QCat; -import com.mysema.query.jpa.hibernate.DefaultSessionHolder; -import com.mysema.query.jpa.hibernate.HibernateQuery; -import com.mysema.testutil.HibernateTestRunner; - -/** - * @author tiwe - * - */ -@RunWith(HibernateTestRunner.class) -public class HibernateBase extends AbstractJPATest { - - private static final QCat cat = QCat.cat; - - @Rule - public static MethodRule jpaProviderRule = new JPAProviderRule(); - - @Rule - public static MethodRule targetRule = new TargetRule(); - - private Session session; - - @Override - protected HibernateQuery query() { - return new HibernateQuery(session, getTemplates()); - } - - @Override - protected HibernateQuery testQuery() { - return new HibernateQuery(new DefaultSessionHolder(session), - getTemplates(), new DefaultQueryMetadata().noValidate()); - } - - protected JPQLTemplates getTemplates() { - return HQLTemplates.DEFAULT; - } - - public void setSession(Session session) { - this.session = session; - } - - @Override - protected void save(Object entity) { - session.save(entity); - } - - @Test - public void QueryExposure() { -// save(new Cat()); - List<Cat> results = query().from(cat).createQuery(cat).list(); - assertNotNull(results); - assertFalse(results.isEmpty()); - } - - @Test - public void WithComment() { - query().from(cat).setComment("my comment").list(cat); - } - - @Test - public void LockMode() { - query().from(cat).setLockMode(cat, LockMode.PESSIMISTIC_WRITE).list(cat); - } - - @Test - public void FlushMode() { - query().from(cat).setFlushMode(org.hibernate.FlushMode.AUTO).list(cat); - } - - @Test - public void Scroll() throws IOException{ - CloseableIterator<Cat> cats = new ScrollableResultsIterator<Cat>(query().from(cat) - .createQuery(cat).scroll()); - assertTrue(cats.hasNext()); - while (cats.hasNext()) { - assertNotNull(cats.next()); - } - cats.close(); - } - - @Test - public void ScrollArray() throws IOException{ - CloseableIterator<Object[]> rows = new ScrollableResultsIterator<Object[]>(query() - .from(cat) - .createQuery(cat.name, cat.birthdate).scroll(), true); - assertTrue(rows.hasNext()); - while (rows.hasNext()) { - Object[] row = rows.next(); - assertEquals(2, row.length); - assertNotNull(row[0]); - assertNotNull(row[1]); - } - rows.close(); - } - - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/HibernateQueryMutabilityTest.java b/querydsl-jpa/src/test/java/com/mysema/query/HibernateQueryMutabilityTest.java deleted file mode 100644 index 44a672802e..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/HibernateQueryMutabilityTest.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query; - -import static org.junit.Assert.assertEquals; - -import java.io.IOException; -import java.lang.reflect.InvocationTargetException; - -import org.hibernate.Session; -import org.junit.Ignore; -import org.junit.Test; -import org.junit.runner.RunWith; - -import com.mysema.query.jpa.domain.QCat; -import com.mysema.query.jpa.hibernate.HibernateQuery; -import com.mysema.testutil.HibernateTestRunner; - -@Ignore -@RunWith(HibernateTestRunner.class) -public class HibernateQueryMutabilityTest{ - - private Session session; - - protected HibernateQuery query() { - return new HibernateQuery(session); - } - - public void setSession(Session session) { - this.session = session; - } - - @Test - public void test() throws SecurityException, IllegalArgumentException, - NoSuchMethodException, IllegalAccessException, - InvocationTargetException, IOException { - QCat cat = QCat.cat; - HibernateQuery query = query().from(cat); - new QueryMutability(query).test(cat, cat.name); - } - - @Test - public void Clone() { - QCat cat = QCat.cat; - HibernateQuery query = query().from(cat).where(cat.name.isNotNull()); - HibernateQuery query2 = query.clone(session); - assertEquals(query.getMetadata().getJoins(), query2.getMetadata().getJoins()); - assertEquals(query.getMetadata().getWhere(), query2.getMetadata().getWhere()); - query2.list(cat); - } - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/HibernateSQLBase.java b/querydsl-jpa/src/test/java/com/mysema/query/HibernateSQLBase.java deleted file mode 100644 index f218c54ccf..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/HibernateSQLBase.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query; - -import static org.junit.Assert.assertEquals; - -import org.hibernate.Query; -import org.hibernate.Session; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.MethodRule; -import org.junit.runner.RunWith; - -import com.mysema.query.jpa.domain.Cat; -import com.mysema.query.jpa.domain.Color; -import com.mysema.query.jpa.domain.QCat; -import com.mysema.query.jpa.domain.sql.SAnimal; -import com.mysema.query.jpa.hibernate.sql.HibernateSQLQuery; -import com.mysema.query.sql.SQLTemplates; -import com.mysema.testutil.ExcludeIn; -import com.mysema.testutil.HibernateTestRunner; - -@RunWith(HibernateTestRunner.class) -public class HibernateSQLBase extends AbstractSQLTest { - - @Rule - public static MethodRule targetRule = new TargetRule(); - - private final SQLTemplates templates = Mode.getSQLTemplates(); - - private final SAnimal cat = new SAnimal("cat"); - - private Session session; - - @Override - protected HibernateSQLQuery query() { - return new HibernateSQLQuery(session, templates); - } - - public void setSession(Session session) { - this.session = session; - } - - @Before - public void setUp() { - if (query().from(cat).notExists()) { - session.save(new Cat("Beck", 1, Color.BLACK)); - session.save(new Cat("Kate", 2, Color.BLACK)); - session.save(new Cat("Kitty", 3, Color.BLACK)); - session.save(new Cat("Bobby", 4, Color.BLACK)); - session.save(new Cat("Harold", 5, Color.BLACK)); - session.save(new Cat("Tim", 6, Color.BLACK)); - session.flush(); - } - } - - @Test - public void EntityQueries_CreateQuery() { - SAnimal cat = new SAnimal("cat"); - QCat catEntity = QCat.cat; - - Query query = query().from(cat).createQuery(catEntity); - assertEquals(6, query.list().size()); - } - - @Test - @ExcludeIn(Target.MYSQL) - public void EntityQueries_CreateQuery2() { - SAnimal cat = new SAnimal("CAT"); - QCat catEntity = QCat.cat; - - Query query = query().from(cat).createQuery(catEntity); - assertEquals(6, query.list().size()); - } - - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/JPABase.java b/querydsl-jpa/src/test/java/com/mysema/query/JPABase.java deleted file mode 100644 index 84786d2e8f..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/JPABase.java +++ /dev/null @@ -1,228 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query; - -import com.mysema.commons.lang.CloseableIterator; -import com.mysema.query.jpa.JPASubQuery; -import com.mysema.query.jpa.domain.*; -import com.mysema.query.jpa.impl.JPADeleteClause; -import com.mysema.query.jpa.impl.JPAQuery; -import com.mysema.query.types.EntityPath; -import com.mysema.query.types.expr.BooleanExpression; -import com.mysema.testutil.ExcludeIn; -import com.mysema.testutil.JPATestRunner; -import org.junit.Ignore; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.MethodRule; -import org.junit.runner.RunWith; - -import javax.persistence.EntityManager; -import javax.persistence.FlushModeType; -import javax.persistence.LockModeType; -import java.sql.Connection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static org.junit.Assert.*; - -/** - * @author tiwe - * - */ -@RunWith(JPATestRunner.class) -public class JPABase extends AbstractJPATest { - - private static final QCat cat = QCat.cat; - - @Rule - public static MethodRule targetRule = new TargetRule(); - - @Rule - public static MethodRule jpaProviderRule = new JPAProviderRule(); - - private EntityManager entityManager; - - @Override - protected JPAQuery query() { - return new JPAQuery(entityManager); - } - - protected JPADeleteClause delete(EntityPath<?> path) { - return new JPADeleteClause(entityManager, path); - } - - @Override - protected JPAQuery testQuery() { - return new JPAQuery(entityManager, new DefaultQueryMetadata().noValidate()); - } - - public void setEntityManager(EntityManager entityManager) { - this.entityManager = entityManager; - } - - @Override - protected void save(Object entity) { - entityManager.persist(entity); - } - - @Test - @NoEclipseLink - @NoOpenJPA - @NoHibernate - public void Connection_Access() { - assertNotNull(query().from(cat).createQuery(cat).unwrap(Connection.class)); - } - - @Test - @Ignore - public void Delete() { - delete(cat).execute(); - } - - @Test - @NoBatooJPA - public void Delete_Where() { - delete(cat).where(cat.name.eq("XXX")).execute(); - } - - @Test - @NoBatooJPA - @ExcludeIn(Target.MYSQL) - public void Delete_Where_SubQuery_Exists() { - QCat parent = cat; - QCat child = new QCat("kitten"); - - delete(child) - .where(child.id.eq(-100), new JPASubQuery() - .from(parent) - .where(parent.id.eq(-200), - child.in(parent.kittens)).exists()) - .execute(); - } - - @Test - @NoBatooJPA - public void Delete_Where_SubQuery2() { - QChild child = QChild.child; - QParent parent = QParent.parent; - - JPASubQuery subQuery = new JPASubQuery() - .from(parent) - .where(parent.id.eq(2), - child.parent.eq(parent)); - //child.in(parent.children)); - - delete(child) - .where(child.id.eq(1), subQuery.exists()) - .execute(); - } - - @Test - public void Finder() { - Map<String,Object> conditions = new HashMap<String,Object>(); - conditions.put("name", "Bob123"); - - List<Cat> cats = CustomFinder.findCustom(entityManager, Cat.class, conditions, "name"); - assertEquals(1, cats.size()); - assertEquals("Bob123", cats.get(0).getName()); - } - - @Test - public void FlushMode() { - assertFalse(query().from(cat).setFlushMode(FlushModeType.AUTO).list(cat).isEmpty()); - } - - @Test - @NoEclipseLink @NoOpenJPA - public void Hint() { - javax.persistence.Query query = query().from(cat) - .setHint("org.hibernate.cacheable", true) - .createQuery(cat); - - assertNotNull(query); - assertTrue(query.getHints().containsKey("org.hibernate.cacheable")); - assertFalse(query.getResultList().isEmpty()); - } - - @Test - public void Hint2() { - assertFalse(query().from(cat).setHint("org.hibernate.cacheable", true) - .list(cat).isEmpty()); - } - - @Test @Ignore - @NoHibernate @NoOpenJPA @NoBatooJPA - public void Hint3() { - javax.persistence.Query query = query().from(cat) - .setHint("eclipselink.batch.type", "IN") - .setHint("eclipselink.batch", "person.workAddress") - .setHint("eclipselink.batch", "person.homeAddress") - .createQuery(cat); - - assertNotNull(query); - assertEquals("person.homeAddress", query.getHints().get("eclipselink.batch")); - } - - @Test - @ExcludeIn(Target.DERBY) - public void Iterate() { - CloseableIterator<Cat> cats = query().from(cat).iterate(cat); - while (cats.hasNext()) { - Cat cat = cats.next(); - assertNotNull(cat); - } - cats.close(); - } - - @Test - public void Limit1_UniqueResult() { - assertNotNull(query().from(cat).limit(1).uniqueResult(cat)); - } - - @Test - public void LockMode() { - javax.persistence.Query query = query().from(cat) - .setLockMode(LockModeType.PESSIMISTIC_READ).createQuery(cat); - assertTrue(query.getLockMode().equals(LockModeType.PESSIMISTIC_READ)); - assertFalse(query.getResultList().isEmpty()); - } - - @Test - public void LockMode2() { - assertFalse(query().from(cat).setLockMode(LockModeType.PESSIMISTIC_READ) - .list(cat).isEmpty()); - } - - @Test - public void QueryExposure() { - //save(new Cat(20)); - List<Cat> results = query().from(cat).createQuery(cat).getResultList(); - assertNotNull(results); - assertFalse(results.isEmpty()); - } - - @Test - @Ignore // isn't a valid JPQL query - public void Subquery_UniqueResult() { - QCat cat2 = new QCat("cat2"); - - BooleanExpression exists = new JPASubQuery().from(cat2).where(cat2.eyecolor.isNotNull()).exists(); - assertNotNull(query().from(cat) - .where(cat.breed.eq(0).not()) - .singleResult(new QCatSummary(cat.breed.count(), exists))); - } - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/JPAProviderRule.java b/querydsl-jpa/src/test/java/com/mysema/query/JPAProviderRule.java deleted file mode 100644 index f38737b2a8..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/JPAProviderRule.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.mysema.query; - -import java.lang.annotation.Annotation; - -import org.junit.rules.MethodRule; -import org.junit.runners.model.FrameworkMethod; -import org.junit.runners.model.Statement; - -import com.mysema.testutil.EmptyStatement; - -/** - * @author tiwe - * - */ -public class JPAProviderRule implements MethodRule { - - @Override - public Statement apply(Statement base, FrameworkMethod method, Object target) { - boolean noEclipseLink = hasAnnotation(method, NoEclipseLink.class); - boolean noOpenJPA = hasAnnotation(method, NoOpenJPA.class); - boolean noBatooJPA = hasAnnotation(method, NoBatooJPA.class); - boolean noHibernate = hasAnnotation(method, NoHibernate.class); - String mode = Mode.mode.get(); - if (mode == null) { - return base; - } else if (noEclipseLink && mode.contains("-eclipselink")) { - return EmptyStatement.DEFAULT; - } else if (noOpenJPA && mode.contains("-openjpa")) { - return EmptyStatement.DEFAULT; - } else if (noBatooJPA && mode.contains("-batoo")) { - return EmptyStatement.DEFAULT; - } else if (noHibernate && !mode.contains("-")) { - return EmptyStatement.DEFAULT; - } else { - return base; - } - } - - private <T extends Annotation> boolean hasAnnotation(FrameworkMethod method, Class<T> clazz) { - T rv = method.getMethod().getAnnotation(clazz); - if (rv == null) { - rv = method.getMethod().getDeclaringClass().getAnnotation(clazz); - } - return rv != null; - } - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/JPAQueryMutabilityTest.java b/querydsl-jpa/src/test/java/com/mysema/query/JPAQueryMutabilityTest.java deleted file mode 100644 index cb29ada3c2..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/JPAQueryMutabilityTest.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import javax.persistence.EntityManager; - -import org.junit.Ignore; -import org.junit.Test; -import org.junit.runner.RunWith; - -import com.mysema.query.jpa.domain.QCat; -import com.mysema.query.jpa.impl.JPAQuery; -import com.mysema.testutil.JPATestRunner; - -@Ignore -@RunWith(JPATestRunner.class) -public class JPAQueryMutabilityTest { - - private EntityManager entityManager; - - protected JPAQuery query() { - return new JPAQuery(entityManager); - } - - public void setEntityManager(EntityManager entityManager) { - this.entityManager = entityManager; - } - - @Test - public void test() { - QCat cat = QCat.cat; - JPAQuery query = query().from(cat); - - query.count(); - assertProjectionEmpty(query); - query.distinct().count(); - assertProjectionEmpty(query); - - query.iterate(cat); - assertProjectionEmpty(query); - query.iterate(cat,cat); - assertProjectionEmpty(query); - query.distinct().iterate(cat); - assertProjectionEmpty(query); - query.distinct().iterate(cat,cat); - assertProjectionEmpty(query); - - query.list(cat); - assertProjectionEmpty(query); - query.list(cat,cat); - assertProjectionEmpty(query); - query.distinct().list(cat); - assertProjectionEmpty(query); - query.distinct().list(cat,cat); - assertProjectionEmpty(query); - - query.listResults(cat); - assertProjectionEmpty(query); - query.distinct().listResults(cat); - assertProjectionEmpty(query); - - query.map(cat.name, cat); - assertProjectionEmpty(query); - } - - @Test - public void Clone() { - QCat cat = QCat.cat; - JPAQuery query = query().from(cat).where(cat.name.isNotNull()); - JPAQuery query2 = query.clone(entityManager); - assertEquals(query.getMetadata().getJoins(), query2.getMetadata().getJoins()); - assertEquals(query.getMetadata().getWhere(), query2.getMetadata().getWhere()); - query2.list(cat); - } - - private void assertProjectionEmpty(JPAQuery query) { - assertTrue(query.getMetadata().getProjection().isEmpty()); - } - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/JPASQLBase.java b/querydsl-jpa/src/test/java/com/mysema/query/JPASQLBase.java deleted file mode 100644 index 006a1f186b..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/JPASQLBase.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query; - -import static org.junit.Assert.assertEquals; - -import javax.persistence.EntityManager; -import javax.persistence.Query; - -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.MethodRule; -import org.junit.runner.RunWith; - -import com.mysema.query.jpa.domain.Cat; -import com.mysema.query.jpa.domain.Color; -import com.mysema.query.jpa.domain.QCat; -import com.mysema.query.jpa.domain.sql.SAnimal; -import com.mysema.query.jpa.sql.JPASQLQuery; -import com.mysema.query.sql.SQLTemplates; -import com.mysema.testutil.ExcludeIn; -import com.mysema.testutil.JPATestRunner; - -@RunWith(JPATestRunner.class) -public class JPASQLBase extends AbstractSQLTest { - - @Rule - public static MethodRule targetRule = new TargetRule(); - - @Rule - public static MethodRule hibernateOnly = new JPAProviderRule(); - - private final SQLTemplates templates = Mode.getSQLTemplates(); - - private EntityManager entityManager; - - @Override - protected JPASQLQuery query() { - return new JPASQLQuery(entityManager, templates); - } - - - public void setEntityManager(EntityManager entityManager) { - this.entityManager = entityManager; - } - - @Before - public void setUp() { - if (query().from(cat).notExists()) { - entityManager.persist(new Cat("Beck", 1, Color.BLACK)); - entityManager.persist(new Cat("Kate", 2, Color.BLACK)); - entityManager.persist(new Cat("Kitty", 3, Color.BLACK)); - entityManager.persist(new Cat("Bobby", 4, Color.BLACK)); - entityManager.persist(new Cat("Harold", 5, Color.BLACK)); - entityManager.persist(new Cat("Tim", 6, Color.BLACK)); - entityManager.flush(); - } - } - - @Test - public void EntityQueries_CreateQuery() { - SAnimal cat = new SAnimal("cat"); - QCat catEntity = QCat.cat; - - Query query = query().from(cat).createQuery(catEntity); - assertEquals(6, query.getResultList().size()); - } - - @Test - @ExcludeIn(Target.MYSQL) - public void EntityQueries_CreateQuery2() { - SAnimal cat = new SAnimal("CAT"); - QCat catEntity = QCat.cat; - - Query query = query().from(cat).createQuery(catEntity); - assertEquals(6, query.getResultList().size()); - } - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/Mode.java b/querydsl-jpa/src/test/java/com/mysema/query/Mode.java deleted file mode 100644 index c1d8ace308..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/Mode.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.mysema.query; - -import com.mysema.query.sql.CUBRIDTemplates; -import com.mysema.query.sql.DerbyTemplates; -import com.mysema.query.sql.H2Templates; -import com.mysema.query.sql.HSQLDBTemplates; -import com.mysema.query.sql.MySQLTemplates; -import com.mysema.query.sql.OracleTemplates; -import com.mysema.query.sql.PostgresTemplates; -import com.mysema.query.sql.SQLServerTemplates; -import com.mysema.query.sql.SQLTemplates; -import com.mysema.query.sql.SQLiteTemplates; -import com.mysema.query.sql.TeradataTemplates; - -/** - * @author tiwe - * - */ -public final class Mode { - - public static final ThreadLocal<String> mode = new ThreadLocal<String>(); - - public static final ThreadLocal<Target> target = new ThreadLocal<Target>(); - - public static SQLTemplates getSQLTemplates() { - switch (target.get()) { - case CUBRID:return new CUBRIDTemplates(); - case DERBY: return new DerbyTemplates(); - case H2: return new H2Templates(); - case HSQLDB:return new HSQLDBTemplates(); - case SQLSERVER: return new SQLServerTemplates(); - case MYSQL: return new MySQLTemplates(); - case ORACLE:return new OracleTemplates(); - case POSTGRES: return new PostgresTemplates(); - case SQLITE:return new SQLiteTemplates(); - case TERADATA: return new TeradataTemplates(); - } - throw new IllegalStateException("Unknown mode " + mode); - } - - private Mode() {} - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/NoBatooJPA.java b/querydsl-jpa/src/test/java/com/mysema/query/NoBatooJPA.java deleted file mode 100644 index f6644dcf97..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/NoBatooJPA.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.mysema.query; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Inherited; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Retention(RetentionPolicy.RUNTIME) -@Target({ElementType.METHOD, ElementType.TYPE}) -@Inherited -public @interface NoBatooJPA { - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/NoEclipseLink.java b/querydsl-jpa/src/test/java/com/mysema/query/NoEclipseLink.java deleted file mode 100644 index 6170d2f75d..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/NoEclipseLink.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.mysema.query; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Inherited; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Retention(RetentionPolicy.RUNTIME) -@Target({ElementType.METHOD, ElementType.TYPE}) -@Inherited -public @interface NoEclipseLink { - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/NoHibernate.java b/querydsl-jpa/src/test/java/com/mysema/query/NoHibernate.java deleted file mode 100644 index 065297157d..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/NoHibernate.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.mysema.query; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Inherited; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Retention(RetentionPolicy.RUNTIME) -@Target({ElementType.METHOD, ElementType.TYPE}) -@Inherited -public @interface NoHibernate { - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/NoOpenJPA.java b/querydsl-jpa/src/test/java/com/mysema/query/NoOpenJPA.java deleted file mode 100644 index 8909cc00ff..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/NoOpenJPA.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.mysema.query; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Inherited; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Retention(RetentionPolicy.RUNTIME) -@Target({ElementType.METHOD, ElementType.TYPE}) -@Inherited -public @interface NoOpenJPA { - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/PackageVerification.java b/querydsl-jpa/src/test/java/com/mysema/query/PackageVerification.java deleted file mode 100644 index 2f09259ca1..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/PackageVerification.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import java.io.File; -import java.net.URL; -import java.net.URLClassLoader; - -import javax.persistence.Entity; - -import org.junit.Test; - -import com.google.common.base.Charsets; -import com.google.common.io.Resources; -import com.mysema.codegen.CodeWriter; -import com.mysema.query.apt.hibernate.HibernateAnnotationProcessor; -import com.mysema.query.apt.jpa.JPAAnnotationProcessor; -import com.mysema.query.codegen.CodegenModule; -import com.mysema.query.types.Expression; - -public class PackageVerification { - - @Test - public void Verify_Package() throws Exception{ - String version = System.getProperty("version"); - verify(new File("target/querydsl-jpa-"+version+"-apt-hibernate-one-jar.jar"), true); - verify(new File("target/querydsl-jpa-"+version+"-apt-one-jar.jar"), false); - } - - private void verify(File oneJar, boolean hibernateDeps) throws Exception { - assertTrue(oneJar.getPath() + " doesn't exist", oneJar.exists()); - // verify classLoader - URLClassLoader oneJarClassLoader = new URLClassLoader(new URL[]{oneJar.toURI().toURL()}); - oneJarClassLoader.loadClass(Expression.class.getName()); // querydsl-core - oneJarClassLoader.loadClass(CodeWriter.class.getName()); // codegen - oneJarClassLoader.loadClass(CodegenModule.class.getName()).newInstance(); - oneJarClassLoader.loadClass(Entity.class.getName()); // jpa - Class<?> processor; - if (hibernateDeps) { - oneJarClassLoader.loadClass(org.hibernate.annotations.Type.class.getName()); // hibernate - processor = HibernateAnnotationProcessor.class; - } else { - processor = JPAAnnotationProcessor.class; - } - Class cl = oneJarClassLoader.loadClass(processor.getName()); // querydsl-apt - cl.newInstance(); - String resourceKey = "META-INF/services/javax.annotation.processing.Processor"; - assertEquals(processor.getName(), Resources.toString(oneJarClassLoader.findResource(resourceKey), Charsets.UTF_8)); - } - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/Projection.java b/querydsl-jpa/src/test/java/com/mysema/query/Projection.java deleted file mode 100644 index f0dc71c675..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/Projection.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.mysema.query; - -import com.mysema.query.jpa.domain.Cat; - -public class Projection { - - public Projection(String str, Cat cat) {} - -} \ No newline at end of file diff --git a/querydsl-jpa/src/test/java/com/mysema/query/QProjection.java b/querydsl-jpa/src/test/java/com/mysema/query/QProjection.java deleted file mode 100644 index 03e189628e..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/QProjection.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.mysema.query; - -import com.mysema.query.jpa.domain.Cat; -import com.mysema.query.jpa.domain.QCat; -import com.mysema.query.types.ConstructorExpression; -import com.mysema.query.types.Expression; -import com.mysema.query.types.expr.StringExpression; - -public class QProjection extends ConstructorExpression<Projection>{ - - private static final long serialVersionUID = -5866362075090550839L; - - public QProjection(StringExpression str, QCat cat) { - super(Projection.class, - new Class[]{String.class, Cat.class}, new Expression[]{str, cat}); - } - -} \ No newline at end of file diff --git a/querydsl-jpa/src/test/java/com/mysema/query/QueryPerformanceTest.java b/querydsl-jpa/src/test/java/com/mysema/query/QueryPerformanceTest.java deleted file mode 100644 index c0df3b55db..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/QueryPerformanceTest.java +++ /dev/null @@ -1,107 +0,0 @@ -package com.mysema.query; - -import static org.junit.Assert.assertNotNull; - -import javax.persistence.EntityManager; - -import org.junit.AfterClass; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Ignore; -import org.junit.Test; -import org.junit.experimental.categories.Category; -import org.junit.runner.RunWith; - -import com.mysema.query.jpa.domain.Cat; -import com.mysema.query.jpa.domain.QCat; -import com.mysema.query.jpa.impl.JPAQuery; -import com.mysema.testutil.JPATestRunner; -import com.mysema.testutil.Performance; - -@RunWith(JPATestRunner.class) -@Ignore -@Category(Performance.class) -public class QueryPerformanceTest { - - private static final int iterations = 1000; - - private EntityManager entityManager; - - @BeforeClass - public static void setUpClass() { - Mode.mode.set("h2perf"); - Mode.target.set(Target.H2); - } - - @AfterClass - public static void tearDownClass() { - Mode.mode.remove(); - Mode.target.remove(); - } - - private JPAQuery query() { - return new JPAQuery(entityManager); - } - - @Before - public void setUp() { - if (query().from(QCat.cat).notExists()) { - for (int i = 0; i < iterations; i++) { - entityManager.persist(new Cat(String.valueOf(i), i + 100)); - } - entityManager.flush(); - } - } - - @Test - public void ById_Raw() { - long start = System.currentTimeMillis(); - for (int i = 0; i < iterations; i++) { - Cat cat = (Cat)entityManager.createQuery("select cat from Cat cat where id = ?") - .setParameter(1, i + 100).getSingleResult(); - assertNotNull(cat); - } - System.err.println("by id - raw" + (System.currentTimeMillis() - start)); - } - - @Test - public void ById_Qdsl() { - long start = System.currentTimeMillis(); - for (int i = 0; i < iterations; i++) { - QCat cat = QCat.cat; - Cat c = query().from(cat).where(cat.id.eq(i+100)).uniqueResult(cat); - assertNotNull(c); - } - System.err.println("by id - dsl" + (System.currentTimeMillis() - start)); - } - - @Test - public void ById_TwoCols_Raw() { - long start = System.currentTimeMillis(); - for (int i = 0; i < iterations; i++) { - Object[] row = (Object[])entityManager.createQuery( - "select cat.id, cat.name from Cat cat where id = ?") - .setParameter(1, i + 100).getSingleResult(); - assertNotNull(row); - } - System.err.println("by id - 2 cols - raw" + (System.currentTimeMillis() - start)); - } - - @Test - public void ById_TwoCols_Qdsl() { - long start = System.currentTimeMillis(); - for (int i = 0; i < iterations; i++) { - QCat cat = QCat.cat; - Tuple row = query().from(cat).where(cat.id.eq(i+100)).uniqueResult(cat.id, cat.name); - assertNotNull(row); - } - System.err.println("by id - 2 cols - dsl" + (System.currentTimeMillis() - start)); - } - - - public void setEntityManager(EntityManager entityManager) { - this.entityManager = entityManager; - } - - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/SignatureTest.java b/querydsl-jpa/src/test/java/com/mysema/query/SignatureTest.java deleted file mode 100644 index 13f793cf88..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/SignatureTest.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query; - -import org.junit.Test; - -import com.mysema.query.jpa.JPQLQuery; -import com.mysema.query.jpa.hibernate.HibernateQuery; -import com.mysema.query.jpa.impl.JPAQuery; - -public class SignatureTest { - - @Test - public void test() { - meet((JPAQuery)null); - meet((HibernateQuery)null); - meet((JPQLQuery)null); - } - - public static <T extends FilteredClause<? super T>> T meet(T query) { - return null; - } - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/TargetRule.java b/querydsl-jpa/src/test/java/com/mysema/query/TargetRule.java deleted file mode 100644 index 04db406969..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/TargetRule.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.mysema.query; - -import java.lang.reflect.Method; -import java.util.Arrays; - -import org.junit.rules.MethodRule; -import org.junit.runners.model.FrameworkMethod; -import org.junit.runners.model.Statement; - -import com.mysema.testutil.EmptyStatement; -import com.mysema.testutil.ExcludeIn; -import com.mysema.testutil.IncludeIn; - -/** - * @author tiwe - * - */ -public class TargetRule implements MethodRule { - - @Override - public Statement apply(Statement base, FrameworkMethod method, Object obj) { - //Target target = Connections.getTarget(); - Target target = Mode.target.get(); - boolean run = target == null || isExecuted(method.getMethod(), target); - return run ? base : EmptyStatement.DEFAULT; - } - - private boolean isExecuted(Method method, Target target) { - ExcludeIn ex = method.getAnnotation(ExcludeIn.class); - if (ex == null) { - ex = method.getDeclaringClass().getAnnotation(ExcludeIn.class); - } - // excluded in given targets - if (ex != null && Arrays.asList(ex.value()).contains(target)) { - return false; - } - // included only in given targets - IncludeIn in = method.getAnnotation(IncludeIn.class); - if (in == null) { - in = method.getDeclaringClass().getAnnotation(IncludeIn.class); - } - if (in != null && !Arrays.asList(in.value()).contains(target)) { - return false; - } - return true; - } - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/AbstractQueryTest.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/AbstractQueryTest.java deleted file mode 100644 index e7d9a3bff5..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/AbstractQueryTest.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa; - -import static org.junit.Assert.assertEquals; - -import com.mysema.query.types.Expression; - -public abstract class AbstractQueryTest implements Constants { - - protected QueryHelper query() { - return new QueryHelper(HQLTemplates.DEFAULT); - } - - protected JPASubQuery sub() { - return new JPASubQuery(); - } - - protected static void assertToString(String expected, Expression<?> expr) { - JPQLSerializer serializer = new JPQLSerializer(HQLTemplates.DEFAULT, null); - assertEquals(expected, serializer.handle(expr).toString().replace("\n", " ")); - } - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/AggregationTest.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/AggregationTest.java deleted file mode 100644 index 8f4cf0d416..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/AggregationTest.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa; - -import org.junit.Test; - -public class AggregationTest extends AbstractQueryTest{ - - @Test - public void Max() { - assertToString("max(cat.bodyWeight)", cat.bodyWeight.max()); - } - - @Test - public void Min() { - assertToString("min(cat.bodyWeight)", cat.bodyWeight.min()); - } - - @Test - public void Avg() { - assertToString("avg(cat.bodyWeight)", cat.bodyWeight.avg()); - } - - @Test - public void Count() { - assertToString("count(cat)", cat.count()); - } - - @Test - public void CountDistinct() { - assertToString("count(distinct cat)", cat.countDistinct()); - } - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/Article.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/Article.java deleted file mode 100644 index a67db8b0fe..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/Article.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.mysema.query.jpa; - - -public class Article { - - String name; - - Content content; - - Person author; - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/BooleanOperationsTest.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/BooleanOperationsTest.java deleted file mode 100644 index 7ba5ca6272..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/BooleanOperationsTest.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa; - -import static org.junit.Assert.assertEquals; - -import org.junit.Test; - -import com.mysema.query.BooleanBuilder; - -public class BooleanOperationsTest extends AbstractQueryTest { - - @Test - public void BooleanOperations_Or() { - assertToString("cust is null or cat is null", cust.isNull().or(cat.isNull())); - } - - @Test - public void BooleanOperations_And() { - assertToString("cust is null and cat is null", cust.isNull().and(cat.isNull())); - } - - - @Test - public void BooleanOperations_Not() { - assertToString("not (cust is null)", cust.isNull().not()); - } - - - @Test - public void BooleanOperations2_And() { - cat.name.eq(cust.name.firstName).and(cat.bodyWeight.eq(kitten.bodyWeight)); - } - - @Test - public void BooleanOperations2_Or() { - cat.name.eq(cust.name.firstName).or(cat.bodyWeight.eq(kitten.bodyWeight)); - } - - @Test - public void LogicalOperations_Or() { - assertToString("cat = kitten or kitten = cat", cat.eq(kitten).or(kitten.eq(cat))); - } - - @Test - public void LogicalOperations_And() { - assertToString("cat = kitten and kitten = cat", cat.eq(kitten).and(kitten.eq(cat))); - } - - @Test - public void LogicalOperations_And2() { - assertToString("cat is null and (kitten is null or kitten.bodyWeight > ?1)", - cat.isNull().and(kitten.isNull().or(kitten.bodyWeight.gt(10)))); - } - - @Test - public void BooleanBuilder1() { - BooleanBuilder bb1 = new BooleanBuilder(); - bb1.and(cat.eq(cat)); - - BooleanBuilder bb2 = new BooleanBuilder(); - bb2.or(cat.eq(cat)); - bb2.or(cat.eq(cat)); - - assertToString("cat = cat and (cat = cat or cat = cat)", bb1.and(bb2)); - } - - @Test - public void BooleanBuilder2() { - BooleanBuilder bb1 = new BooleanBuilder(); - bb1.and(cat.eq(cat)); - - BooleanBuilder bb2 = new BooleanBuilder(); - bb2.or(cat.eq(cat)); - bb2.or(cat.eq(cat)); - - assertToString("cat = cat and (cat = cat or cat = cat)", bb1.and(bb2.getValue())); - } - - @Test - public void BooleanBuilder_With_Null_In_Where() { - assertEquals("select cat\nfrom Cat cat", sub().from(cat).where(new BooleanBuilder()).toString()); - } - - @Test - public void BooleanBuilder_With_Null_In_Having() { - assertEquals("select cat\nfrom Cat cat\ngroup by cat.name", - sub().from(cat).groupBy(cat.name).having(new BooleanBuilder()).toString()); - } - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/CastTest.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/CastTest.java deleted file mode 100644 index be5eaea864..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/CastTest.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa; - -import static org.junit.Assert.assertEquals; - -import org.junit.Test; - -import com.mysema.query.types.expr.NumberExpression; -import com.mysema.query.types.path.NumberPath; - -public class CastTest extends AbstractQueryTest { - - private static NumberExpression<Integer> expr = new NumberPath<Integer>(Integer.class,"int"); - - @Test - public void Byte() { - assertEquals(Byte.class, expr.byteValue().getType()); - } - - @Test - public void Double() { - assertEquals(Double.class, expr.doubleValue().getType()); - } - - @Test - public void Float() { - assertEquals(Float.class, expr.floatValue().getType()); - } - - @Test - public void Integer() { - assertEquals(Integer.class, expr.intValue().getType()); - } - - @Test - public void Long() { - assertEquals(Long.class, expr.longValue().getType()); - } - - @Test - public void Short() { - assertEquals(Short.class, expr.shortValue().getType()); - } - - @Test - public void StringCast() { - assertEquals(String.class, expr.stringValue().getType()); - } -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/CollectionTest.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/CollectionTest.java deleted file mode 100644 index 631cd4a20f..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/CollectionTest.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa; - -import org.junit.Test; - -import com.mysema.query.jpa.domain.Cat; - -public class CollectionTest extends AbstractQueryTest{ - - @Test - public void Constant_InElements_Set() { - assertToString("?1 in elements(cat.kittensSet)", cat.kittensSet.contains(new Cat())); - } - - @Test - public void Constant_InElements_List() { - assertToString("?1 in elements(cat.kittens)", cat.kittens.contains(new Cat())); - } - - @Test - public void Path_InElements_List() { - assertToString("cat in elements(cat1.kittens)", cat.in(cat1.kittens)); - } - - @Test - public void Path_InElements_Set() { - assertToString("cat in elements(cat1.kittensSet)", cat.in(cat1.kittensSet)); - } - - - @Test - public void CollectionOperations() { - // HQL functions that take collection-valued path expressions: size(), - // minelement(), maxelement(), minindex(), maxindex(), along with the - // special elements() and indices functions which may be quantified - // using some, all, exists, any, in. - cat.kittens.size(); -// minelement(cat.kittens); -// maxelement(cat.kittens); -// minindex(cat.kittens); -// maxindex(cat.kittens); - assertToString("cat.kittens[0]", cat.kittens(0)); - assertToString("cat.kittens[0]", cat.kittens.get(0)); - - // some, all, exists, any, in. - } -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/ComparableTest.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/ComparableTest.java deleted file mode 100644 index 6ab399d59b..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/ComparableTest.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa; - -import org.junit.Test; - -public class ComparableTest extends AbstractQueryTest{ - - @Test - public void Eq() { - assertToString("cat.bodyWeight = kitten.bodyWeight", cat.bodyWeight.eq(kitten.bodyWeight)); - } - - @Test - public void Goe() { - assertToString("cat.bodyWeight >= kitten.bodyWeight", cat.bodyWeight.goe(kitten.bodyWeight)); - } - - @Test - public void Gt() { - assertToString("cat.bodyWeight > kitten.bodyWeight", cat.bodyWeight.gt(kitten.bodyWeight)); - } - - @Test - public void Loe() { - assertToString("cat.bodyWeight <= kitten.bodyWeight", cat.bodyWeight.loe(kitten.bodyWeight)); - } - - @Test - public void Lt() { - assertToString("cat.bodyWeight < kitten.bodyWeight", cat.bodyWeight.lt(kitten.bodyWeight)); - } - - @Test - public void Ne() { - assertToString("cat.bodyWeight <> kitten.bodyWeight", cat.bodyWeight.ne(kitten.bodyWeight)); - } - - - - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/Constants.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/Constants.java deleted file mode 100644 index f4599a06df..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/Constants.java +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa; - -import com.mysema.query.jpa.domain.QAccount; -import com.mysema.query.jpa.domain.QAnimal; -import com.mysema.query.jpa.domain.QAuditLog; -import com.mysema.query.jpa.domain.QBar; -import com.mysema.query.jpa.domain.QCalendar; -import com.mysema.query.jpa.domain.QCat; -import com.mysema.query.jpa.domain.QCatalog; -import com.mysema.query.jpa.domain.QCompany; -import com.mysema.query.jpa.domain.QCustomer; -import com.mysema.query.jpa.domain.QDocument; -import com.mysema.query.jpa.domain.QDomesticCat; -import com.mysema.query.jpa.domain.QFoo; -import com.mysema.query.jpa.domain.QFormula; -import com.mysema.query.jpa.domain.QItem; -import com.mysema.query.jpa.domain.QName; -import com.mysema.query.jpa.domain.QNameList; -import com.mysema.query.jpa.domain.QNamed; -import com.mysema.query.jpa.domain.QOrder; -import com.mysema.query.jpa.domain.QParameter; -import com.mysema.query.jpa.domain.QPayment; -import com.mysema.query.jpa.domain.QPerson; -import com.mysema.query.jpa.domain.QPlayer; -import com.mysema.query.jpa.domain.QPrice; -import com.mysema.query.jpa.domain.QProduct; -import com.mysema.query.jpa.domain.QShow; -import com.mysema.query.jpa.domain.QStatus; -import com.mysema.query.jpa.domain.QStatusChange; -import com.mysema.query.jpa.domain.QStore; -import com.mysema.query.jpa.domain.QUser; - -public interface Constants { - - QAccount account = new QAccount("account"); - - QAnimal an = new QAnimal("an"); - - QBar bar = new QBar("bar"); - - QCalendar calendar = new QCalendar("calendar"); - - // QCat - QCat cat = new QCat("cat"); - - QCat cat1 = new QCat("cat1"); - - QCat cat2 = new QCat("cat2"); - - QCat cat3 = new QCat("cat3"); - - QCat cat4 = new QCat("cat4"); - - QCat cat5 = new QCat("cat5"); - - // QCatalog - QCatalog catalog = new QCatalog("catalog"); - - QCat child = new QCat("child"); - // QCompany - QCompany company = new QCompany("company"); - - QCompany company1 = new QCompany("company1"); - - QCompany company2 = new QCompany("company2"); - - QCompany company3 = new QCompany("company3"); - - QCompany company4 = new QCompany("company4"); - - QCompany company5 = new QCompany("company5"); - - // Customer - QCustomer cust = new QCustomer("cust"); - -// Qdoofus d = new Qdoofus("d"); - - // QDocument - QDocument doc = new QDocument("doc"); - - // DomesticQCat - QDomesticCat domesticCat = new QDomesticCat("domesticCat"); - - QCat fatcat = new QCat("fatcat"); - - QFoo foo = new QFoo("foo"); - - QFormula form = new QFormula("form"); - // QItem - QItem item = new QItem("item"); - - QCat kit = new QCat("kit"); - - QCat kitten = new QCat("kitten"); - - QCat kitten2 = new QCat("kitten2"); - - QCat kittens = new QCat("kittens"); - - QNameList list = new QNameList("list"); - - // AuditLog - QAuditLog log = new QAuditLog("log"); - - QNamed m = new QNamed("m"); - - QCat mate = new QCat("mate"); - - QCat mother = new QCat("mother"); - - QNamed n = new QNamed("n"); - - QName name = new QName("name"); - - QCat offspr = new QCat("offspr"); - - QOrder ord = new QOrder("ord"); - // Order - QOrder order = new QOrder("order"); - - QPerson p = new QPerson("p"); - - QParameter param = new QParameter("param"); - - // Payment - QPayment payment = new QPayment("payment"); - - QPerson person = new QPerson("person"); - - QPlayer player = new QPlayer("player"); - - // Price - QPrice price = new QPrice("price"); - - QProduct prod = new QProduct("prod"); - - // Product - QProduct product = new QProduct("product"); - - QCat qat = new QCat("qat"); - - QCat rival = new QCat("rival"); - - QShow show = new QShow("show"); - - QStatus status = new QStatus("status"); - - QStatusChange statusChange = new QStatusChange("statusChange"); - - QStore store = new QStore("store"); - - // User - QUser user = new QUser("user"); - - QUser user1 = new QUser("user1"); - - QUser user2 = new QUser("user2"); - - QUser user3 = new QUser("user3"); - - QUser user4 = new QUser("user4"); - - QUser user5 = new QUser("user5"); - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/ConstructorsTest.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/ConstructorsTest.java deleted file mode 100644 index 71f09c6268..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/ConstructorsTest.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa; - -import org.junit.Ignore; -import org.junit.Test; - -import com.mysema.query.types.ConstructorExpression; -import com.mysema.query.types.Expression; - -public class ConstructorsTest extends AbstractQueryTest{ - - public static final class BookmarkDTO { - - } - - public static final class _BookmarkDTO extends ConstructorExpression<BookmarkDTO> { - - private static final long serialVersionUID = 2664671413344744578L; - - public _BookmarkDTO(Expression<java.lang.String> address) { - super(BookmarkDTO.class, new Class[] { String.class }, address); - } - } - - @Test - @Ignore - public void Constructors() { - ConstructorExpression<com.mysema.query.jpa.domain.Cat> c = - new ConstructorExpression<com.mysema.query.jpa.domain.Cat>( - com.mysema.query.jpa.domain.Cat.class, - new Class[]{String.class}, - cat.name); - assertToString("new " + com.mysema.query.jpa.domain.Cat.class.getName()+ "(cat.name)", c); - assertToString("new " + getClass().getName() + "$BookmarkDTO(cat.name)",new _BookmarkDTO(cat.name)); - } - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/Content.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/Content.java deleted file mode 100644 index b1d7fb9af2..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/Content.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.mysema.query.jpa; - - -public class Content { - - Article article; - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/CustomExpressionsTest.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/CustomExpressionsTest.java deleted file mode 100644 index e8d05d2567..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/CustomExpressionsTest.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa; - -import org.junit.Test; - -import com.google.common.collect.ImmutableList; -import com.mysema.query.types.Expression; -import com.mysema.query.types.TemplateFactory; -import com.mysema.query.types.template.StringTemplate; - -public class CustomExpressionsTest extends AbstractQueryTest{ - - public static class MyCustomExpr extends StringTemplate { - - private static final long serialVersionUID = 1L; - - public MyCustomExpr(Expression<?>... args) { - super(TemplateFactory.DEFAULT.create("myCustom({0},{1})"), ImmutableList.copyOf(args)); - } - } - - @Test - public void CustomExpressions() { - assertToString("myCustom(cust,cat)", new MyCustomExpr(cust, cat)); - } - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/DateTimeTest.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/DateTimeTest.java deleted file mode 100644 index 0746605968..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/DateTimeTest.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa; - -import java.util.Date; - -import org.junit.Test; - -import com.mysema.query.types.expr.DateExpression; -import com.mysema.query.types.expr.DateTimeExpression; -import com.mysema.query.types.expr.TimeExpression; -import com.mysema.query.types.path.DatePath; -import com.mysema.query.types.path.DateTimePath; - -public class DateTimeTest extends AbstractQueryTest { - - @Test - public void CurrentDate() { - assertToString("current_date", DateExpression.currentDate()); - } - - @Test - public void CurrentDate2() { - assertToString("current_date", DateTimeExpression.currentDate()); - } - - @Test - public void CurrentTime() { - assertToString("current_time", TimeExpression.currentTime()); - } - - @Test - public void CurrentTimestamp() { - assertToString("current_timestamp", DateTimeExpression.currentTimestamp()); - } - - @Test - public void DayOfMonth() { - assertToString("day(date)", new DatePath<Date>(Date.class, "date").dayOfMonth()); - } - - @Test - public void DayOfMonth2() { - assertToString("day(date)", new DateTimePath<Date>(Date.class, "date").dayOfMonth()); - } - - @Test - public void DateOperations2() { -// catalog.effectiveDate.second(); -// catalog.effectiveDate.minute(); -// catalog.effectiveDate.hour(); - catalog.effectiveDate.dayOfMonth(); - catalog.effectiveDate.month(); - catalog.effectiveDate.year(); - } - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/DummySessionHolder.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/DummySessionHolder.java deleted file mode 100644 index e743a80edc..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/DummySessionHolder.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa; - -import org.hibernate.Query; -import org.hibernate.SQLQuery; - -import com.mysema.query.jpa.hibernate.SessionHolder; - -public class DummySessionHolder implements SessionHolder{ - - @Override - public Query createQuery(String queryString) { - throw new UnsupportedOperationException(); - } - - @Override - public SQLQuery createSQLQuery(String queryString) { - throw new UnsupportedOperationException(); - } - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/EJBQLTest.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/EJBQLTest.java deleted file mode 100644 index e51dd03980..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/EJBQLTest.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa; - -import org.junit.Test; - -public class EJBQLTest extends AbstractQueryTest{ - - // Any function or operator defined by EJB-QL 3.0: substring(), trim(), - // lower(), upper(), length(), locate(), abs(), sqrt(), bit_length(), - // mod() - // substring(), - // trim(), - // lower(), - // upper(), - // length(), - // locate(), - // abs(), - // sqrt(), - // bit_length(), - // mod() - - @Test - public void Trim() { - assertToString("trim(cat.name)", cat.name.trim()); - } - - @Test - public void Lower() { - assertToString("lower(cat.name)", cat.name.lower()); - } - - @Test - public void Upper() { - assertToString("upper(cat.name)", cat.name.upper()); - } - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/ExpressionSerializationTest.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/ExpressionSerializationTest.java deleted file mode 100644 index e0abe5364b..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/ExpressionSerializationTest.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.mysema.query.jpa; - -import static org.junit.Assert.assertEquals; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; - -import org.junit.Test; - -import com.mysema.query.jpa.domain.QCat; -import com.mysema.query.jpa.impl.JPAQuery; -import com.mysema.query.types.Expression; - -public class ExpressionSerializationTest { - - private <T> T serialize(T obj) throws ClassNotFoundException, IOException { - // serialize - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ObjectOutputStream out = new ObjectOutputStream(baos); - out.writeObject(obj); - out.close(); - - // deserialize - ByteArrayInputStream bain = new ByteArrayInputStream(baos.toByteArray()); - ObjectInputStream in = new ObjectInputStream(bain); - T obj2 = (T) in.readObject(); - in.close(); - return obj2; - } - - @Test - public void Serialize() throws Exception { - //QAdress.adress.name.eq("test" - Expression<?> expr = QCat.cat.name.eq("test"); - Expression<?> expr2 = serialize(expr); - - assertEquals(expr, expr2); - assertEquals(expr.hashCode(), expr2.hashCode()); - } - - @Test - public void Query() throws ClassNotFoundException, IOException { - JPAQuery query = new JPAQuery(); - query.from(QCat.cat); - query.where(serialize(QCat.cat.name.eq("test"))); - } - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/HibernateQueryFactoryTest.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/HibernateQueryFactoryTest.java deleted file mode 100644 index b1305459c5..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/HibernateQueryFactoryTest.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa; - -import static org.junit.Assert.assertNotNull; - -import javax.inject.Provider; - -import org.easymock.EasyMock; -import org.hibernate.Session; -import org.junit.Before; -import org.junit.Test; - -import com.mysema.query.jpa.domain.QAnimal; -import com.mysema.query.jpa.hibernate.HibernateQueryFactory; - -public class HibernateQueryFactoryTest { - - private HibernateQueryFactory queryFactory; - - @Before - public void setUp() { - Provider<Session> provider = new Provider<Session>() { - @Override - public Session get() { - return EasyMock.createNiceMock(Session.class); - } - }; - queryFactory = new HibernateQueryFactory(JPQLTemplates.DEFAULT, provider); - } - - @Test - public void Query() { - assertNotNull(queryFactory.query()); - } - - @Test - public void SubQuery() { - assertNotNull(queryFactory.subQuery()); - } - - @Test - public void From() { - assertNotNull(queryFactory.from(QAnimal.animal)); - } - - @Test - public void Delete() { - assertNotNull(queryFactory.delete(QAnimal.animal)); - } - - @Test - public void Update() { - assertNotNull(queryFactory.update(QAnimal.animal)); - } - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/HibernateQueryTest.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/HibernateQueryTest.java deleted file mode 100644 index 76fdbed5b5..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/HibernateQueryTest.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa; - -import com.mysema.query.BooleanBuilder; -import com.mysema.query.jpa.domain.QCat; -import com.mysema.query.jpa.domain.QEmployee; -import com.mysema.query.jpa.domain.QUser; -import com.mysema.query.jpa.hibernate.HibernateQuery; -import org.junit.Test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -public class HibernateQueryTest { - - @Test - public void Clone() { - QCat cat = QCat.cat; - BooleanBuilder emptyBooleanBuilder = new BooleanBuilder(); - HibernateQuery hq = new HibernateQuery().from(cat).where(cat.name.isNull().and(emptyBooleanBuilder)); - - HibernateQuery hq2 = hq.clone(); - assertNotNull(hq2); - } - - @Test - public void InnerJoin() { - HibernateQuery hqlQuery = new HibernateQuery(); - QEmployee employee = QEmployee.employee; - hqlQuery.from(employee); - hqlQuery.innerJoin(employee.user, QUser.user); - assertEquals("select employee\nfrom Employee employee\n inner join employee.user as user", hqlQuery.toString()); - } - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/IntegrationBase.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/IntegrationBase.java deleted file mode 100644 index 32f080fb2a..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/IntegrationBase.java +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa; - -import antlr.RecognitionException; -import antlr.TokenStreamException; -import com.mysema.query.jpa.domain.Cat; -import com.mysema.query.jpa.domain.QCat; -import com.mysema.query.jpa.hibernate.HibernateDeleteClause; -import com.mysema.query.jpa.hibernate.HibernateQuery; -import com.mysema.query.jpa.hibernate.HibernateUpdateClause; -import com.mysema.query.jpa.hibernate.HibernateUtil; -import com.mysema.query.types.EntityPath; -import com.mysema.testutil.HibernateTestRunner; -import org.hibernate.Query; -import org.hibernate.ScrollMode; -import org.hibernate.ScrollableResults; -import org.hibernate.Session; -import org.junit.Test; -import org.junit.runner.RunWith; - -import java.util.Arrays; -import java.util.List; - -import static org.junit.Assert.assertEquals; - -@RunWith(HibernateTestRunner.class) -public class IntegrationBase extends ParsingTest { - - private Session session; - - @Override - protected QueryHelper query() { - return new QueryHelper(HQLTemplates.DEFAULT) { - @Override - public void parse() throws RecognitionException, TokenStreamException { - try { - System.out.println("query : " + toString().replace('\n', ' ')); - JPQLSerializer serializer = new JPQLSerializer(HQLTemplates.DEFAULT); - serializer.serialize(getMetadata(), false, null); - Query query = session.createQuery(serializer.toString()); - HibernateUtil.setConstants(query, serializer.getConstantToLabel(), getMetadata().getParams()); - query.list(); - } catch (Exception e) { - e.printStackTrace(); - throw new RuntimeException(e); - } finally { - System.out.println(); - } - } - }; - } - - @Override - @Test - public void GroupBy() throws Exception { - // NOTE : commented out, because HQLSDB doesn't support these queries - } - - @Override - @Test - public void GroupBy_2() throws Exception { - // NOTE : commented out, because HQLSDB doesn't support these queries - } - - @Override - @Test - public void OrderBy() throws Exception { - // NOTE : commented out, because HQLSDB doesn't support these queries - } - - @Override - @Test - public void DocoExamples910() throws Exception { - // NOTE : commented out, because HQLSDB doesn't support these queries - } - - private HibernateDeleteClause delete(EntityPath<?> entity) { - return new HibernateDeleteClause(session, entity); - } - - private HibernateUpdateClause update(EntityPath<?> entity) { - return new HibernateUpdateClause(session, entity); - } - - @Test - public void Scroll() { - session.save(new Cat("Bob",10)); - session.save(new Cat("Steve",11)); - - QCat cat = QCat.cat; - HibernateQuery query = new HibernateQuery(session); - ScrollableResults results = query.from(cat).scroll(ScrollMode.SCROLL_INSENSITIVE, cat); - while (results.next()) { - System.out.println(results.get(0)); - } - results.close(); - } - - @Test - public void Update() { - session.save(new Cat("Bob",10)); - session.save(new Cat("Steve",11)); - - QCat cat = QCat.cat; - long amount = update(cat).where(cat.name.eq("Bob")) - .set(cat.name, "Bobby") - .set(cat.alive, false) - .execute(); - assertEquals(1, amount); - - assertEquals(0l, query().from(cat).where(cat.name.eq("Bob")).count()); - } - - @Test - public void Update_with_null() { - session.save(new Cat("Bob",10)); - session.save(new Cat("Steve",11)); - - QCat cat = QCat.cat; - long amount = update(cat).where(cat.name.eq("Bob")) - .set(cat.name, (String)null) - .set(cat.alive, false) - .execute(); - assertEquals(1, amount); - } - - @Test - public void Delete() { - session.save(new Cat("Bob",10)); - session.save(new Cat("Steve",11)); - - QCat cat = QCat.cat; - long amount = delete(cat).where(cat.name.eq("Bob")) - .execute(); - assertEquals(1, amount); - } - - @Test - public void Collection() throws Exception{ - List<Cat> cats = Arrays.asList(new Cat("Bob",10), new Cat("Steve",11)); - for (Cat cat : cats) { - session.save(cat); - } - - query().from(cat) - .innerJoin(cat.kittens, kitten) - .where(kitten.in(cats)) - .parse(); - - } - - public void setSession(Session session) { - this.session = session; - } - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/JPACollectionAnyVisitorTest.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/JPACollectionAnyVisitorTest.java deleted file mode 100644 index d2d149db37..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/JPACollectionAnyVisitorTest.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa; - -import static org.junit.Assert.assertTrue; - -import org.junit.Test; - -import com.mysema.query.jpa.domain.JobFunction; -import com.mysema.query.jpa.domain.QCat; -import com.mysema.query.jpa.domain.QDomesticCat; -import com.mysema.query.jpa.domain.QEmployee; -import com.mysema.query.support.Context; -import com.mysema.query.types.ConstantImpl; -import com.mysema.query.types.Expression; -import com.mysema.query.types.Predicate; -import com.mysema.query.types.TemplateExpressionImpl; - - -public class JPACollectionAnyVisitorTest { - - private QCat cat = QCat.cat; - - @Test - public void Path() { - assertMatches("cat_kittens.*", serialize(cat.kittens.any())); - } - - @Test - public void Longer_Path() { - assertMatches("cat_kittens.*\\.name", serialize(cat.kittens.any().name)); - } - - @Test - public void Simple_BooleanOperation() { - Predicate predicate = cat.kittens.any().name.eq("Ruth123"); - assertMatches("exists \\(select 1\n" + - "from Cat cat_kittens.*\n" + - "where cat_kittens.* in elements\\(cat\\.kittens\\) and cat_kittens.*\\.name = \\?1\\)", serialize(predicate)); - } - - @Test - public void Simple_BooleanOperation_ElementCollection() { - QEmployee employee = QEmployee.employee; - Predicate predicate = employee.jobFunctions.any().eq(JobFunction.CODER); - assertMatches("exists \\(select 1\n" + - "from Employee employee.*\n" + - " inner join employee.*.jobFunctions as employee_jobFunctions.*\n" + - "where employee.* = employee and employee_jobFunctions.* = \\?1\\)", serialize(predicate)); - } - - @Test - public void Simple_StringOperation() { - Predicate predicate = cat.kittens.any().name.substring(1).eq("uth123"); - assertMatches("exists \\(select 1\n"+ - "from Cat cat_kittens.*\n" + - "where cat_kittens.* in elements\\(cat.kittens\\) and substring\\(cat_kittens.*\\.name,2\\) = \\?1\\)", serialize(predicate)); - } - - @Test - public void And_Operation() { - Predicate predicate = cat.kittens.any().name.eq("Ruth123").and(cat.kittens.any().bodyWeight.gt(10.0)); - assertMatches("exists \\(select 1\n"+ - "from Cat cat_kittens.*\n" + - "where cat_kittens.* in elements\\(cat.kittens\\) and cat_kittens.*\\.name = \\?1\\) and exists \\(select 1\n" + - "from Cat cat_kittens.*\n" + - "where cat_kittens.* in elements\\(cat.kittens\\) and cat_kittens.*\\.bodyWeight > \\?2\\)", serialize(predicate)); - } - - @Test - public void Template() { - Expression<Boolean> templateExpr = TemplateExpressionImpl.create(Boolean.class, "{0} = {1}", - cat.kittens.any().name, ConstantImpl.create("Ruth123")); - assertMatches("exists \\(select 1\n" + - "from Cat cat_kittens.*\n" + - "where cat_kittens.* in elements\\(cat\\.kittens\\) and cat_kittens.*\\.name = \\?1\\)", serialize(templateExpr)); - } - - @Test - public void Cast() { -// JPAQuery query = new JPAQuery(em).from(QPerson.person); -// QDog anyDog = QPerson.person.animals.any().as(QDog.class); -// query.where(anyDog.gender.eq("M")); -// List<Person> foundOwners = query.list(QPerson.person); - - QDomesticCat anyCat = QCat.cat.kittens.any().as(QDomesticCat.class); - Predicate predicate = anyCat.name.eq("X"); - - assertMatches("exists \\(select 1\n" + - "from DomesticCat cat_kittens.*\n" + - "where cat_kittens.* in elements\\(cat.kittens\\) and cat_kittens.*\\.name = \\?1\\)", serialize(predicate)); - } - - private String serialize(Expression<?> expression) { - Expression<?> transformed = expression.accept(JPACollectionAnyVisitor.DEFAULT, new Context()); - JPQLSerializer serializer = new JPQLSerializer(HQLTemplates.DEFAULT, null); - serializer.handle(transformed); - return serializer.toString(); - } - - private static void assertMatches(String str1, String str2) { - assertTrue(str2, str2.matches(str1)); - } -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/JPAIntegrationBase.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/JPAIntegrationBase.java deleted file mode 100644 index be18c06d42..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/JPAIntegrationBase.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa; - -import javax.persistence.EntityManager; -import javax.persistence.Query; - -import antlr.RecognitionException; -import antlr.TokenStreamException; -import com.mysema.query.JPAProviderRule; -import com.mysema.query.TargetRule; -import com.mysema.query.jpa.impl.JPAProvider; -import com.mysema.query.jpa.impl.JPAUtil; -import com.mysema.testutil.JPATestRunner; -import org.junit.Rule; -import org.junit.rules.MethodRule; -import org.junit.runner.RunWith; - -@RunWith(JPATestRunner.class) -public class JPAIntegrationBase extends ParsingTest { - - @Rule - public static MethodRule targetRule = new TargetRule(); - - @Rule - public static MethodRule hibernateOnly = new JPAProviderRule(); - - private EntityManager em; - - private JPQLTemplates templates; - - @Override - protected QueryHelper query() { - return new QueryHelper(templates) { - @Override - public void parse() throws RecognitionException, TokenStreamException { - try { - //System.out.println("query : " + toString().replace('\n', ' ')); - - // create Query and execute it - JPQLSerializer serializer = new JPQLSerializer(templates); - serializer.serialize(getMetadata(), false, null); - Query query = em.createQuery(serializer.toString()); - JPAUtil.setConstants(query, serializer.getConstantToLabel(), getMetadata().getParams()); - try { - query.getResultList(); - } catch (Exception e) { - e.printStackTrace(); - throw new RuntimeException(e); - } - } finally { - //System.out.println(); - } - } - }; - } - - public void setEntityManager(EntityManager em) { - this.em = em; - this.templates = JPAProvider.getTemplates(em); - } - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/JPAQueryFactoryTest.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/JPAQueryFactoryTest.java deleted file mode 100644 index eb3d7c7dd0..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/JPAQueryFactoryTest.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa; - -import static org.junit.Assert.assertNotNull; - -import java.util.Date; -import java.util.Map; - -import javax.inject.Provider; -import javax.persistence.EntityManager; -import javax.persistence.EntityManagerFactory; - -import org.easymock.EasyMock; -import org.junit.Before; -import org.junit.Test; - -import com.google.common.collect.Maps; -import com.mysema.query.jpa.domain.QAnimal; -import com.mysema.query.jpa.impl.JPAQueryFactory; - -public class JPAQueryFactoryTest { - - private EntityManagerFactory factoryMock; - - private EntityManager mock; - - private JPAQueryFactory queryFactory; - - private JPQLQueryFactory queryFactory2; - - private JPAQueryFactory queryFactory3; - - private Map<String, Object> properties = Maps.newHashMap(); - - @Before - public void setUp() { - factoryMock = EasyMock.createMock(EntityManagerFactory.class); - mock = EasyMock.createMock(EntityManager.class); - Provider<EntityManager> provider = new Provider<EntityManager>() { - @Override - public EntityManager get() { - return mock; - } - }; - queryFactory = new JPAQueryFactory(JPQLTemplates.DEFAULT, provider); - queryFactory2 = queryFactory; - - queryFactory3 = new JPAQueryFactory(provider); - - } - - @Test - public void Query() { - assertNotNull(queryFactory.query()); - } - - @Test - public void Query2() { - queryFactory2.query().from(QAnimal.animal); - } - - @Test - public void Query3() { - EasyMock.expect(mock.getEntityManagerFactory()).andReturn(factoryMock); - EasyMock.expect(factoryMock.getProperties()).andReturn(properties); - EasyMock.expect(mock.getDelegate()).andReturn(mock).atLeastOnce(); - EasyMock.replay(mock, factoryMock); - - queryFactory3.query().from(QAnimal.animal); - - EasyMock.verify(mock, factoryMock); - } - - @Test - public void SubQuery() { - assertNotNull(queryFactory.subQuery()); - } - - @Test - public void SubQuery2() { - queryFactory2.subQuery().from(QAnimal.animal); - } - - @Test - public void SubQuery3() { - queryFactory3.subQuery().from(QAnimal.animal); - } - - @Test - public void From() { - assertNotNull(queryFactory.from(QAnimal.animal)); - } - - @Test - public void Delete() { - assertNotNull(queryFactory.delete(QAnimal.animal)); - } - - @Test - public void Delete2() { - queryFactory2.delete(QAnimal.animal) - .where(QAnimal.animal.bodyWeight.gt(0)); - } - - @Test - public void Delete3() { - EasyMock.expect(mock.getEntityManagerFactory()).andReturn(factoryMock); - EasyMock.expect(factoryMock.getProperties()).andReturn(properties); - EasyMock.expect(mock.getDelegate()).andReturn(mock).atLeastOnce(); - EasyMock.replay(mock, factoryMock); - - assertNotNull(queryFactory3.delete(QAnimal.animal)); - - EasyMock.verify(mock, factoryMock); - } - - @Test - public void Update() { - assertNotNull(queryFactory.update(QAnimal.animal)); - } - - @Test - public void Update2() { - queryFactory2.update(QAnimal.animal) - .set(QAnimal.animal.birthdate, new Date()) - .where(QAnimal.animal.birthdate.isNull()); - } - - @Test - public void Update3() { - EasyMock.expect(mock.getEntityManagerFactory()).andReturn(factoryMock); - EasyMock.expect(factoryMock.getProperties()).andReturn(properties); - EasyMock.expect(mock.getDelegate()).andReturn(mock).atLeastOnce(); - EasyMock.replay(mock, factoryMock); - - assertNotNull(queryFactory3.update(QAnimal.animal)); - - EasyMock.verify(mock, factoryMock); - } - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/JPAQueryMixinTest.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/JPAQueryMixinTest.java deleted file mode 100644 index 91684b9501..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/JPAQueryMixinTest.java +++ /dev/null @@ -1,196 +0,0 @@ -package com.mysema.query.jpa; - -import java.util.Arrays; - -import com.mysema.query.JoinExpression; -import com.mysema.query.JoinType; -import com.mysema.query.QueryMetadata; -import com.mysema.query.jpa.domain.QCat; -import com.mysema.query.jpa.domain4.QBookMark; -import com.mysema.query.jpa.domain4.QBookVersion; -import com.mysema.query.types.PathMetadataFactory; -import com.mysema.query.types.Predicate; -import com.mysema.query.types.path.StringPath; -import org.junit.Test; -import static org.junit.Assert.assertEquals; - -public class JPAQueryMixinTest { - - private JPAQueryMixin mixin = new JPAQueryMixin(); - - @Test - public void Where_Null() { - mixin.where((Predicate)null); - } - - @Test - public void OrderBy() { - QCat cat = QCat.cat; - QCat cat_mate = new QCat("cat_mate"); - mixin.from(cat); - mixin.orderBy(cat.mate.name.asc()); - - QueryMetadata md = mixin.getMetadata(); - assertEquals(Arrays.asList( - new JoinExpression(JoinType.DEFAULT, cat), - new JoinExpression(JoinType.LEFTJOIN, cat.mate.as(cat_mate))), - md.getJoins()); - assertEquals(Arrays.asList(cat_mate.name.asc()), - md.getOrderBy()); - } - - @Test - public void OrderBy_Where() { - QCat cat = QCat.cat; - mixin.from(cat); - mixin.where(cat.mate.name.isNotNull()); - mixin.orderBy(cat.mate.name.asc()); - - QueryMetadata md = mixin.getMetadata(); - assertEquals(Arrays.asList(new JoinExpression(JoinType.DEFAULT, cat)), md.getJoins()); - assertEquals(Arrays.asList(cat.mate.name.asc()), md.getOrderBy()); - } - - @Test - public void OrderBy_GroupBy() { - QCat cat = QCat.cat; - mixin.from(cat); - mixin.groupBy(cat.mate.name); - mixin.orderBy(cat.mate.name.asc()); - - QueryMetadata md = mixin.getMetadata(); - assertEquals(Arrays.asList(new JoinExpression(JoinType.DEFAULT, cat)), md.getJoins()); - assertEquals(Arrays.asList(cat.mate.name.asc()), md.getOrderBy()); - } - - @Test - public void OrderBy_Operation() { - QCat cat = QCat.cat; - QCat cat_mate = new QCat("cat_mate"); - mixin.from(cat); - mixin.orderBy(cat.mate.name.lower().asc()); - - QueryMetadata md = mixin.getMetadata(); - assertEquals(Arrays.asList( - new JoinExpression(JoinType.DEFAULT, cat), - new JoinExpression(JoinType.LEFTJOIN, cat.mate.as(cat_mate))), - md.getJoins()); - assertEquals(Arrays.asList(cat_mate.name.lower().asc()), - md.getOrderBy()); - } - - @Test - public void OrderBy_Long() { - QCat cat = QCat.cat; - QCat catMate = new QCat(PathMetadataFactory.forProperty(cat, "mate")); - QCat cat_mate = new QCat("cat_mate"); - QCat cat_mate_mate = new QCat("cat_mate_mate"); - mixin.from(cat); - mixin.orderBy(cat.mate.mate.name.asc()); - - QueryMetadata md = mixin.getMetadata(); - assertEquals(Arrays.asList( - new JoinExpression(JoinType.DEFAULT, cat), - new JoinExpression(JoinType.LEFTJOIN, cat.mate.as(cat_mate)), - new JoinExpression(JoinType.LEFTJOIN, cat_mate.mate.as(cat_mate_mate))), - md.getJoins()); - assertEquals(Arrays.asList(cat_mate_mate.name.asc()), - md.getOrderBy()); - } - - @Test - public void OrderBy_Reuse() { - QCat cat = QCat.cat; - QCat mate = new QCat("mate"); - mixin.from(cat); - mixin.leftJoin(cat.mate, mate); - mixin.orderBy(cat.mate.name.asc()); - - QueryMetadata md = mixin.getMetadata(); - assertEquals(Arrays.asList( - new JoinExpression(JoinType.DEFAULT, cat), - new JoinExpression(JoinType.LEFTJOIN, cat.mate.as(mate))), - md.getJoins()); - assertEquals(Arrays.asList(mate.name.asc()), - md.getOrderBy()); - } - - @Test - public void OrderBy_Long_Reuse() { - QCat cat = QCat.cat; - QCat mate = new QCat("mate"); - QCat mate_mate = new QCat("mate_mate"); - mixin.from(cat); - mixin.leftJoin(cat.mate, mate); - mixin.orderBy(cat.mate.mate.name.asc()); - - QueryMetadata md = mixin.getMetadata(); - assertEquals(Arrays.asList( - new JoinExpression(JoinType.DEFAULT, cat), - new JoinExpression(JoinType.LEFTJOIN, cat.mate.as(mate)), - new JoinExpression(JoinType.LEFTJOIN, mate.mate.as(mate_mate))), - md.getJoins()); - assertEquals(Arrays.asList(mate_mate.name.asc()), - md.getOrderBy()); - } - - @Test - public void OrderBy_Any() { - QCat cat = QCat.cat; - QCat cat_kittens = new QCat("cat_kittens"); - mixin.from(cat); - mixin.orderBy(cat.kittens.any().name.asc()); - - QueryMetadata md = mixin.getMetadata(); - assertEquals(Arrays.asList( - new JoinExpression(JoinType.DEFAULT, cat), - new JoinExpression(JoinType.LEFTJOIN, cat.kittens.as(cat_kittens))), - md.getJoins()); - assertEquals(Arrays.asList(cat_kittens.name.asc()), - md.getOrderBy()); - } - - @Test - public void OrderBy_Embeddable() { - QBookVersion bookVersion = QBookVersion.bookVersion; - mixin.from(bookVersion); - mixin.orderBy(bookVersion.definition.name.asc()); - - QueryMetadata md = mixin.getMetadata(); - assertEquals(Arrays.asList(new JoinExpression(JoinType.DEFAULT, bookVersion)), - md.getJoins()); - assertEquals(Arrays.asList(bookVersion.definition.name.asc()), - md.getOrderBy()); - } - - @Test - public void OrderBy_Embeddable2() { - QArticle article = QArticle.article; - QArticle article_content_article = new QArticle("article_content_article"); - mixin.from(article); - mixin.orderBy(article.content.article.name.asc()); - - QueryMetadata md = mixin.getMetadata(); - assertEquals(Arrays.asList( - new JoinExpression(JoinType.DEFAULT, article), - new JoinExpression(JoinType.LEFTJOIN, article.content.article.as(article_content_article))), - md.getJoins()); - assertEquals(Arrays.asList(article_content_article.name.asc()), - md.getOrderBy()); - } - - @Test - public void OrderBy_Embeddable_Colllection() { - QBookVersion bookVersion = QBookVersion.bookVersion; - QBookMark bookMark = new QBookMark("bookVersion_definition_bookMarks"); - mixin.from(bookVersion); - mixin.orderBy(bookVersion.definition.bookMarks.any().comment.asc()); - - QueryMetadata md = mixin.getMetadata(); - assertEquals(Arrays.asList(new JoinExpression(JoinType.DEFAULT, bookVersion)), - md.getJoins()); - assertEquals(Arrays.asList(new StringPath(bookVersion.definition.bookMarks, "comment").asc()), - md.getOrderBy()); - - } -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/JPAQueryMutabilityTest.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/JPAQueryMutabilityTest.java deleted file mode 100644 index 54bb4254c6..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/JPAQueryMutabilityTest.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa; - -import static org.junit.Assert.assertEquals; - -import java.io.IOException; -import java.lang.reflect.InvocationTargetException; - -import javax.persistence.EntityManager; - -import org.junit.Ignore; -import org.junit.Test; -import org.junit.runner.RunWith; - -import com.mysema.query.QueryMutability; -import com.mysema.query.jpa.domain.Cat; -import com.mysema.query.jpa.domain.sql.SAnimal; -import com.mysema.query.jpa.sql.JPASQLQuery; -import com.mysema.query.sql.DerbyTemplates; -import com.mysema.query.sql.SQLTemplates; -import com.mysema.testutil.JPATestRunner; - -@Ignore -@RunWith(JPATestRunner.class) -public class JPAQueryMutabilityTest{ - - private static final SQLTemplates derbyTemplates = new DerbyTemplates(); - - private EntityManager entityManager; - - protected JPASQLQuery query() { - return new JPASQLQuery(entityManager, derbyTemplates); - } - - public void setEntityManager(EntityManager entityManager) { - this.entityManager = entityManager; - } - - @Test - public void test() throws SecurityException, IllegalArgumentException, - NoSuchMethodException, IllegalAccessException, - InvocationTargetException, IOException { - entityManager.persist(new Cat("Beck", 1)); - entityManager.flush(); - - SAnimal cat = new SAnimal("cat"); - JPASQLQuery query = query().from(cat); - new QueryMutability(query).test(cat.id, cat.name); - } - - @Test - public void Clone() { - SAnimal cat = new SAnimal("cat"); - JPASQLQuery query = query().from(cat).where(cat.name.isNotNull()); - JPASQLQuery query2 = query.clone(entityManager); - assertEquals(query.getMetadata().getJoins(), query2.getMetadata().getJoins()); - assertEquals(query.getMetadata().getWhere(), query2.getMetadata().getWhere()); - query2.list(cat.id); - } - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/JPASubQueryTest.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/JPASubQueryTest.java deleted file mode 100644 index c14dc66bb1..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/JPASubQueryTest.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa; - -import static org.junit.Assert.assertEquals; - -import org.junit.Test; - -import com.mysema.query.jpa.domain.QCat; - -public class JPASubQueryTest { - - @Test - public void Multiple_Projections() { - QCat cat = QCat.cat; - JPASubQuery query = new JPASubQuery(); - query.from(cat); - assertEquals(1, query.list(cat).getMetadata().getProjection().size()); - assertEquals(1, query.list(cat).getMetadata().getProjection().size()); - } - - @Test - public void Via_Interface() { - QCat cat = QCat.cat; - JPQLSubQuery query = new JPASubQuery(); - query.from(cat); - assertEquals(1, query.list(cat).getMetadata().getProjection().size()); - assertEquals(1, query.list(cat).getMetadata().getProjection().size()); - } - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/JPQLQueryTest.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/JPQLQueryTest.java deleted file mode 100644 index fd54d3c5bc..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/JPQLQueryTest.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa; - -import org.junit.Before; -import org.junit.Test; - -import com.mysema.query.jpa.domain.QCat; -import com.mysema.query.jpa.hibernate.HibernateQuery; - -public class JPQLQueryTest { - - private QCat cat = QCat.cat; - - private HibernateQuery query = new HibernateQuery(); - - @Before - public void setUp() { - query.from(cat); - } - - @Test(expected=IllegalArgumentException.class) - public void InnerJoinPEntityOfPPEntityOfP() { - query.innerJoin(cat.mate, cat.mate); - } - - @Test(expected=IllegalArgumentException.class) - public void InnerJoinPathOfQextendsCollectionOfPPathOfP() { - query.innerJoin(cat.kittens, cat.mate); - } - - @Test(expected=IllegalArgumentException.class) - public void JoinPEntityOfPPEntityOfP() { - query.join(cat.mate, cat.mate); - } - - @Test(expected=IllegalArgumentException.class) - public void JoinPathOfQextendsCollectionOfPPathOfP() { - query.join(cat.kittens, cat.mate); - } - - @Test(expected=IllegalArgumentException.class) - public void LeftJoinPEntityOfPPEntityOfP() { - query.leftJoin(cat.mate, cat.mate); - } - - @Test(expected=IllegalArgumentException.class) - public void LeftJoinPathOfQextendsCollectionOfPPathOfP() { - query.leftJoin(cat.kittens, cat.mate); - } - - @Test(expected=IllegalArgumentException.class) - public void FullJoinPEntityOfPPEntityOfP() { - query.fullJoin(cat.mate, cat.mate); - } - - @Test(expected=IllegalArgumentException.class) - public void FullJoinPathOfQextendsCollectionOfPPathOfP() { - query.fullJoin(cat.kittens, cat.mate); - } - - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/JPQLSerializerTest.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/JPQLSerializerTest.java deleted file mode 100644 index b2068f9d11..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/JPQLSerializerTest.java +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa; - -import java.util.Arrays; - -import com.mysema.query.DefaultQueryMetadata; -import com.mysema.query.JoinType; -import com.mysema.query.QueryMetadata; -import com.mysema.query.domain.QCat; -import com.mysema.query.jpa.domain.Location; -import com.mysema.query.jpa.domain.QDomesticCat; -import com.mysema.query.jpa.domain.QEmployee; -import com.mysema.query.support.Expressions; -import com.mysema.query.types.EntityPath; -import com.mysema.query.types.Expression; -import com.mysema.query.types.Path; -import com.mysema.query.types.Predicate; -import com.mysema.query.types.path.EntityPathBase; -import com.mysema.query.types.path.NumberPath; -import com.mysema.query.types.path.StringPath; -import org.junit.Test; -import static org.junit.Assert.assertEquals; - -public class JPQLSerializerTest { - - @Test - public void And_Or() { - //A.a.id.eq(theId).and(B.b.on.eq(false).or(B.b.id.eq(otherId))); - QCat cat = QCat.cat; - Predicate pred = cat.id.eq(1).and(cat.name.eq("Kitty").or(cat.name.eq("Boris"))); - JPQLSerializer serializer = new JPQLSerializer(HQLTemplates.DEFAULT); - serializer.handle(pred); - assertEquals("cat.id = ?1 and (cat.name = ?2 or cat.name = ?3)", serializer.toString()); - assertEquals("cat.id = 1 && (cat.name = Kitty || cat.name = Boris)", pred.toString()); - } - - @Test - public void Case() { - QCat cat = QCat.cat; - JPQLSerializer serializer = new JPQLSerializer(HQLTemplates.DEFAULT); - Expression<?> expr = Expressions.cases().when(cat.toes.eq(2)).then(2) - .when(cat.toes.eq(3)).then(3) - .otherwise(4); - serializer.handle(expr); - assertEquals("case when (cat.toes = ?1) then ?1 when (cat.toes = ?2) then ?2 else ?3 end", serializer.toString()); - } - - - @Test - public void Case2() { - QCat cat = QCat.cat; - JPQLSerializer serializer = new JPQLSerializer(HQLTemplates.DEFAULT); - Expression<?> expr = Expressions.cases().when(cat.toes.eq(2)).then(cat.id.multiply(2)) - .when(cat.toes.eq(3)).then(cat.id.multiply(3)) - .otherwise(4); - serializer.handle(expr); - assertEquals("case when (cat.toes = ?1) then (cat.id * ?1) when (cat.toes = ?2) then (cat.id * ?2) else ?3 end", serializer.toString()); - } - - @Test - public void FromWithCustomEntityName() { - JPQLSerializer serializer = new JPQLSerializer(HQLTemplates.DEFAULT); - EntityPath<Location> entityPath = new EntityPathBase<Location>(Location.class, "entity"); - QueryMetadata md = new DefaultQueryMetadata(); - md.addJoin(JoinType.DEFAULT, entityPath); - serializer.serialize(md, false, null); - assertEquals("select entity\nfrom Location2 entity", serializer.toString()); - } - - @Test - public void Join_With() { - QCat cat = QCat.cat; - JPQLSerializer serializer = new JPQLSerializer(HQLTemplates.DEFAULT); - QueryMetadata md = new DefaultQueryMetadata(); - md.addJoin(JoinType.DEFAULT, cat); - md.addJoin(JoinType.INNERJOIN, cat.mate); - md.addJoinCondition(cat.mate.alive); - serializer.serialize(md, false, null); - assertEquals("select cat\nfrom Cat cat\n inner join cat.mate with cat.mate.alive", serializer.toString()); - } - - @Test - public void NormalizeNumericArgs() { - JPQLSerializer serializer = new JPQLSerializer(HQLTemplates.DEFAULT); - NumberPath<Double> doublePath = new NumberPath<Double>(Double.class, "doublePath"); - serializer.handle(doublePath.add(1)); - serializer.handle(doublePath.between((float)1.0, 1l)); - serializer.handle(doublePath.lt((byte)1)); - for (Object constant : serializer.getConstantToLabel().keySet()) { - assertEquals(Double.class, constant.getClass()); - } - } - - @Test - public void Delete_Clause_Uses_DELETE_FROM() { - QEmployee employee = QEmployee.employee; - JPQLSerializer serializer = new JPQLSerializer(HQLTemplates.DEFAULT); - QueryMetadata md = new DefaultQueryMetadata(); - md.addJoin(JoinType.DEFAULT, employee); - md.addWhere(employee.lastName.isNull()); - serializer.serializeForDelete(md); - assertEquals("delete from Employee employee\nwhere employee.lastName is null", serializer.toString()); - } - - @Test - public void Delete_With_SubQuery() { - QCat parent = QCat.cat; - QCat child = new QCat("kitten"); - - JPQLSerializer serializer = new JPQLSerializer(HQLTemplates.DEFAULT); - QueryMetadata md = new DefaultQueryMetadata(); - md.addJoin(JoinType.DEFAULT, child); - md.addWhere( - child.id.eq(1) - .and(new JPASubQuery() - .from(parent) - .where(parent.id.eq(2), child.in(parent.kittens)).exists())); - serializer.serializeForDelete(md); - assertEquals("delete from Cat kitten\n" + - "where kitten.id = ?1 and exists (select 1\n" + - "from Cat cat\nwhere cat.id = ?2 and kitten in elements(cat.kittens))", serializer.toString()); - } - - @Test - public void In() { - JPQLSerializer serializer = new JPQLSerializer(HQLTemplates.DEFAULT); - serializer.handle(new NumberPath<Integer>(Integer.class, "id").in(Arrays.asList(1, 2))); - assertEquals("id in (?1)", serializer.toString()); - } - - @Test - public void Not_In() { - JPQLSerializer serializer = new JPQLSerializer(HQLTemplates.DEFAULT); - serializer.handle(new NumberPath<Integer>(Integer.class, "id").notIn(Arrays.asList(1, 2))); - assertEquals("id not in (?1)", serializer.toString()); - } - - @Test - public void Like() { - JPQLSerializer serializer = new JPQLSerializer(HQLTemplates.DEFAULT); - serializer.handle(new StringPath("str").contains("abc!")); - assertEquals("str like ?1 escape '!'", serializer.toString()); - assertEquals("%abc!!%", serializer.getConstantToLabel().keySet().iterator().next().toString()); - } - - @Test - public void StringContainsIc() { - JPQLSerializer serializer = new JPQLSerializer(HQLTemplates.DEFAULT); - serializer.handle(new StringPath("str").containsIgnoreCase("ABc!")); - assertEquals("lower(str) like ?1 escape '!'", serializer.toString()); - assertEquals("%abc!!%", serializer.getConstantToLabel().keySet().iterator().next().toString()); - } - - @Test - public void Substring() { - JPQLSerializer serializer = new JPQLSerializer(HQLTemplates.DEFAULT); - QCat cat = QCat.cat; - serializer.handle(cat.name.substring(cat.name.length().subtract(1), 1)); - assertEquals("substring(cat.name,(length(cat.name) - ?1)+1,1-(length(cat.name) - ?1))", serializer.toString()); - } - - @Test - public void NullsFirst() { - QCat cat = QCat.cat; - JPQLSerializer serializer = new JPQLSerializer(HQLTemplates.DEFAULT); - QueryMetadata md = new DefaultQueryMetadata(); - md.addJoin(JoinType.DEFAULT, cat); - md.addOrderBy(cat.name.asc().nullsFirst()); - serializer.serialize(md, false, null); - assertEquals("select cat\n" + - "from Cat cat\n" + - "order by cat.name asc nulls first", serializer.toString()); - } - - @Test - public void NullsLast() { - QCat cat = QCat.cat; - JPQLSerializer serializer = new JPQLSerializer(HQLTemplates.DEFAULT); - QueryMetadata md = new DefaultQueryMetadata(); - md.addJoin(JoinType.DEFAULT, cat); - md.addOrderBy(cat.name.asc().nullsLast()); - serializer.serialize(md, false, null); - assertEquals("select cat\n" + - "from Cat cat\n" + - "order by cat.name asc nulls last", serializer.toString()); - } - - @Test - public void Treat() { - QCat cat = QCat.cat; - JPQLSerializer serializer = new JPQLSerializer(HQLTemplates.DEFAULT); - QueryMetadata md = new DefaultQueryMetadata(); - md.addJoin(JoinType.DEFAULT, cat); - md.addJoin(JoinType.JOIN, cat.mate.as((Path) QDomesticCat.domesticCat)); - md.addProjection(QDomesticCat.domesticCat); - serializer.serialize(md, false, null); - assertEquals("select domesticCat\n" + - "from Cat cat\n" + - " inner join treat(cat.mate as DomesticCat) as domesticCat", serializer.toString()); - } - - @Test - public void OpenJPA_Variables() { - QCat cat = QCat.cat; - JPQLSerializer serializer = new JPQLSerializer(OpenJPATemplates.DEFAULT); - QueryMetadata md = new DefaultQueryMetadata(); - md.addJoin(JoinType.DEFAULT, cat); - md.addJoin(JoinType.INNERJOIN, cat.mate); - md.addJoinCondition(cat.mate.alive); - serializer.serialize(md, false, null); - assertEquals("select cat_\nfrom Cat cat_\n inner join cat_.mate on cat_.mate.alive", - serializer.toString()); - } -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/JPQLTemplatesTest.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/JPQLTemplatesTest.java deleted file mode 100644 index c0cfb041a1..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/JPQLTemplatesTest.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.mysema.query.jpa; - -import static org.junit.Assert.assertEquals; - -import java.util.Arrays; -import java.util.List; - -import org.junit.Test; - -import com.mysema.query.types.Ops; -import com.mysema.query.types.Templates; - -public class JPQLTemplatesTest { - - @Test - public void Escape() { - List<Templates> templates = Arrays.<Templates>asList( - new JPQLTemplates(), new HQLTemplates(), - new EclipseLinkTemplates(), new OpenJPATemplates() - ); - - for (Templates t : templates) { - assertEquals("{0} like {1} escape '!'", t.getTemplate(Ops.LIKE).toString()); - } - } - - - @Test - public void Custom_Escape() { - List<Templates> templates = Arrays.<Templates>asList( - new JPQLTemplates('X'), new HQLTemplates('X'), - new EclipseLinkTemplates('X'), new OpenJPATemplates('X') - ); - - for (Templates t : templates) { - assertEquals("{0} like {1} escape 'X'", t.getTemplate(Ops.LIKE).toString()); - } - } - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/JoinFlagsTest.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/JoinFlagsTest.java deleted file mode 100644 index f76ddcffe8..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/JoinFlagsTest.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa; - -import static org.junit.Assert.assertEquals; - -import org.junit.Test; - - -public class JoinFlagsTest extends AbstractQueryTest{ - - @Test - public void FetchAll() { - QueryHelper query1 = query().from(cat).fetchAll().where(cat.name.isNotNull()); - assertEquals("select cat\nfrom Cat cat fetch all properties\nwhere cat.name is not null", query1.toString()); - } - - @Test - public void FetchAll2() { - QueryHelper query2 = query().from(cat).fetchAll().from(cat1).fetchAll(); - assertEquals("select cat\nfrom Cat cat fetch all properties, Cat cat1 fetch all properties", query2.toString()); - } - - @Test - public void Fetch() { - QueryHelper query = query().from(cat).innerJoin(cat.mate, cat1).fetch(); - assertEquals("select cat\nfrom Cat cat\n inner join fetch cat.mate as cat1", query.toString()); - } - - @Test - public void RightJoin() { - QueryHelper query = query().from(cat).rightJoin(cat.mate, cat1); - assertEquals("select cat\nfrom Cat cat\n right join cat.mate as cat1", query.toString()); - } -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/JoinTest.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/JoinTest.java deleted file mode 100644 index 481edad017..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/JoinTest.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa; - -import static com.mysema.query.alias.Alias.$; - -import java.util.List; - -import org.junit.Test; - -import com.mysema.query.alias.Alias; -import com.mysema.query.jpa.hibernate.HibernateQuery; -import com.mysema.query.types.path.StringPath; - -public class JoinTest { - - public interface Entity{ - - List<String> getNames(); - } - - private final Entity alias = Alias.alias(Entity.class); - - private final StringPath path = new StringPath("path"); - private final JPASubQuery subQuery = new JPASubQuery(); - private final HibernateQuery query = new HibernateQuery(new DummySessionHolder(), HQLTemplates.DEFAULT); - - - @Test - public void SubQuery_FullJoin() { - subQuery.from($(alias)); - subQuery.fullJoin($(alias.getNames()), path); - // TODO : assertions - } - - @Test - public void SubQuery_InnerJoin() { - subQuery.from($(alias)); - subQuery.innerJoin($(alias.getNames()), path); - // TODO : assertions - } - - @Test - public void SubQuery_Join() { - subQuery.from($(alias)); - subQuery.join($(alias.getNames()), path); - // TODO : assertions - } - - @Test - public void SubQuery_LeftJoin() { - subQuery.from($(alias)); - subQuery.leftJoin($(alias.getNames()), path); - // TODO : assertions - } - - @Test - public void Query_FullJoin() { - query.from($(alias)); - query.fullJoin($(alias.getNames()), path); - // TODO : assertions - } - - @Test - public void Query_InnerJoin() { - query.from($(alias)); - query.innerJoin($(alias.getNames()), path); - // TODO : assertions - } - - @Test - public void Query_Join() { - query.from($(alias)); - query.join($(alias.getNames()), path); - // TODO : assertions - } - - @Test - public void Query_LeftJoin() { - query.from($(alias)); - query.leftJoin($(alias.getNames()), path); - // TODO : assertions - } - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/MapTest.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/MapTest.java deleted file mode 100644 index 7259f5818b..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/MapTest.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa; - -import org.junit.Test; - -import com.mysema.query.jpa.domain.QShow; - -public class MapTest extends AbstractQueryTest { - - private QShow show = QShow.show; - - @Test - public void Contains() { - assertToString("show.acts[?1] = ?2", show.acts.contains("x", "y")); - } - - @Test - public void Contains_Key() { - assertToString("?1 in indices(show.acts)", show.acts.containsKey("x")); - } - - @Test - public void Contains_Value() { - assertToString("?1 in elements(show.acts)", show.acts.containsValue("y")); - } -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/MathTest.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/MathTest.java deleted file mode 100644 index 55665d1664..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/MathTest.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa; - -import org.junit.Test; - -import com.mysema.query.jpa.domain.QCat; -import com.mysema.query.types.path.NumberPath; - -public class MathTest extends AbstractQueryTest{ - - @Test - public void test() { - NumberPath<Double> path = QCat.cat.bodyWeight; - assertToString("(cat.bodyWeight - sum(cat.bodyWeight)) * cat.bodyWeight", path.subtract(path.sum()).multiply(path)); - } - - @Test - public void Add() { - assertToString("cat.bodyWeight + ?1", cat.bodyWeight.add(10)); - } - - @Test - public void Subtract() { - assertToString("cat.bodyWeight - ?1", cat.bodyWeight.subtract(10)); - } - - @Test - public void Multiply() { - assertToString("cat.bodyWeight * ?1", cat.bodyWeight.multiply(10)); - } - - @Test - public void Divide() { - assertToString("cat.bodyWeight / ?1", cat.bodyWeight.divide(10)); - } - - @Test - public void Add_And_Compare() { - assertToString("cat.bodyWeight + ?1 < ?1", cat.bodyWeight.add(10.0).lt(10.0)); - } - - @Test - public void Subtract_And_Compare() { - assertToString("cat.bodyWeight - ?1 < ?1", cat.bodyWeight.subtract(10.0).lt(10.0)); - } - - @Test - public void Multiply_And_Compare() { - assertToString("cat.bodyWeight * ?1 < ?1", cat.bodyWeight.multiply(10.0).lt(10.0)); - } - - @Test - public void Divide_And_Compare() { - assertToString("cat.bodyWeight / ?1 < ?2", cat.bodyWeight.divide(10.0).lt(20.0)); - } - - @Test - public void Add_And_Multiply() { - assertToString("(cat.bodyWeight + ?1) * ?2", cat.bodyWeight.add(10).multiply(20)); - } - - @Test - public void Subtract_And_Multiply() { - assertToString("(cat.bodyWeight - ?1) * ?2", cat.bodyWeight.subtract(10).multiply(20)); - } - - - @Test - public void Multiply_And_Add() { - assertToString("cat.bodyWeight * ?1 + ?2", cat.bodyWeight.multiply(10).add(20)); - } - - - @Test - public void Multiply_And_Subtract() { - assertToString("cat.bodyWeight * ?1 - ?2", cat.bodyWeight.multiply(10).subtract(20)); - } - - - @Test - public void Arithmetic_And_Arithmetic2() { - QCat c1 = new QCat("c1"); - QCat c2 = new QCat("c2"); - QCat c3 = new QCat("c3"); - assertToString("c1.id + c2.id * c3.id", c1.id.add(c2.id.multiply(c3.id))); - assertToString("c1.id * (c2.id + c3.id)", c1.id.multiply(c2.id.add(c3.id))); - assertToString("(c1.id + c2.id) * c3.id", c1.id.add(c2.id).multiply(c3.id)); - } - - @Test - public void MathematicalOperations() { - // mathematical operators +, -, *, / - cat.bodyWeight.add(kitten.bodyWeight); - cat.bodyWeight.subtract(kitten.bodyWeight); - cat.bodyWeight.multiply(kitten.bodyWeight); - cat.bodyWeight.divide(kitten.bodyWeight); - } - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/NativeSQLSerializerTest.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/NativeSQLSerializerTest.java deleted file mode 100644 index 6978045932..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/NativeSQLSerializerTest.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa; - -import com.mysema.query.DefaultQueryMetadata; -import com.mysema.query.JoinType; -import com.mysema.query.jpa.domain.sql.SAnimal; -import com.mysema.query.sql.Configuration; -import com.mysema.query.sql.MySQLTemplates; -import org.junit.Test; - -import static org.junit.Assert.assertEquals; - - -public class NativeSQLSerializerTest { - - @Test - public void In() { - Configuration conf = new Configuration(new MySQLTemplates()); - NativeSQLSerializer serializer = new NativeSQLSerializer(conf, true); - DefaultQueryMetadata md = new DefaultQueryMetadata(); - SAnimal cat = SAnimal.animal_; - md.addJoin(JoinType.DEFAULT, cat); - md.addWhere(cat.name.in("X", "Y")); - md.addProjection(cat.id); - serializer.serialize(md, false); - assertEquals("select animal_.id\n" + - "from animal_ animal_\n" + - "where animal_.name in (?1, ?2)", serializer.toString()); - } - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/OrderHelper.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/OrderHelper.java deleted file mode 100644 index 22fef2eabf..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/OrderHelper.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.mysema.query.jpa; - -import java.util.List; -import java.util.Map; -import java.util.regex.Pattern; - -import org.apache.commons.lang.StringUtils; - -import com.google.common.collect.Maps; -import com.mysema.query.types.EntityPath; -import com.mysema.query.types.path.PathBuilder; - -public class OrderHelper { - - private static final Pattern DOT = Pattern.compile("\\."); - - public static PathBuilder<?> join(JPACommonQuery<?> query, PathBuilder<?> builder, Map<String, PathBuilder<?>> joins, String path) { - PathBuilder<?> rv = joins.get(path); - if (rv == null) { - if (path.contains(".")) { - String[] tokens = DOT.split(path); - String[] parent = new String[tokens.length - 1]; - System.arraycopy(tokens, 0, parent, 0, tokens.length - 1); - String parentKey = StringUtils.join(parent, "."); - builder = join(query, builder, joins, parentKey); - rv = new PathBuilder(Object.class, StringUtils.join(tokens, "_")); - query.leftJoin((EntityPath)builder.get(tokens[tokens.length - 1]), rv); - } else { - rv = new PathBuilder(Object.class, path); - query.leftJoin((EntityPath)builder.get(path), rv); - } - joins.put(path, rv); - } - return rv; - } - - public static void orderBy(JPACommonQuery<?> query, EntityPath<?> entity, List<String> order) { - PathBuilder<?> builder = new PathBuilder(entity.getType(), entity.getMetadata()); - Map<String, PathBuilder<?>> joins = Maps.newHashMap(); - - for (String entry : order) { - String[] tokens = DOT.split(entry); - if (tokens.length > 1) { - String[] parent = new String[tokens.length - 1]; - System.arraycopy(tokens, 0, parent, 0, tokens.length - 1); - PathBuilder<?> parentAlias = join(query, builder, joins, StringUtils.join(parent, ".")); - query.orderBy(parentAlias.getString(tokens[tokens.length - 1]).asc()); - } else { - query.orderBy(builder.getString(tokens[0]).asc()); - } - } - } - -} - - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/OrderHelperTest.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/OrderHelperTest.java deleted file mode 100644 index 543a73648d..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/OrderHelperTest.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.mysema.query.jpa; - -import static org.junit.Assert.assertEquals; - -import java.util.List; - -import org.junit.Test; - -import com.google.common.collect.Lists; -import com.mysema.query.types.path.PathBuilder; - -public class OrderHelperTest { - - @Test - public void Order() { - PathBuilder<Object> entity = new PathBuilder<Object>(Object.class, "project"); - List<String> order = Lists.newArrayList(); - order.add("customer.name"); - order.add("department.superior.name"); - order.add("customer.company.name"); - order.add("previousProject.customer.company.name"); - order.add("department.name"); - - JPASubQuery query = new JPASubQuery(); - query.from(entity); - OrderHelper.orderBy(query, entity, order); - assertEquals("select project\n" + - "from Object project\n" + - " left join project.customer as customer\n" + - " left join project.department as department\n" + - " left join department.superior as department_superior\n" + - " left join customer.company as customer_company\n" + - " left join project.previousProject as previousProject\n" + - " left join previousProject.customer as previousProject_customer\n" + - " left join previousProject_customer.company as previousProject_customer_company\n" + - "order by customer.name asc, department_superior.name asc, customer_company.name asc," + - " previousProject_customer_company.name asc, department.name asc", - query.toString()); - } - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/ParsingTest.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/ParsingTest.java deleted file mode 100644 index b473741f68..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/ParsingTest.java +++ /dev/null @@ -1,735 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa; - -import static com.mysema.query.Target.DERBY; -import static com.mysema.query.Target.H2; -import static com.mysema.query.Target.HSQLDB; -import static com.mysema.query.Target.MYSQL; -import static com.mysema.query.Target.ORACLE; -import static com.mysema.query.Target.POSTGRES; -import static com.mysema.query.alias.Alias.$; -import static com.mysema.query.alias.Alias.alias; -import static org.junit.Assert.assertEquals; - -import org.junit.Ignore; -import org.junit.Test; - -import antlr.RecognitionException; -import antlr.TokenStreamException; - -import com.mysema.query.NoBatooJPA; -import com.mysema.query.NoEclipseLink; -import com.mysema.query.NoOpenJPA; -import com.mysema.query.jpa.domain.Cat; -import com.mysema.query.jpa.domain.Catalog; -import com.mysema.query.jpa.domain.Color; -import com.mysema.query.jpa.domain.Customer; -import com.mysema.query.jpa.domain.DomesticCat; -import com.mysema.query.jpa.domain.Payment; -import com.mysema.query.jpa.domain.Product; -import com.mysema.query.jpa.domain.QFamily; -import com.mysema.query.jpa.domain.QFooDTO; -import com.mysema.query.jpa.domain.QItem; -import com.mysema.query.jpa.domain.QProduct; -import com.mysema.query.types.expr.ComparableExpression; -import com.mysema.query.types.expr.DateExpression; -import com.mysema.query.types.expr.NumberExpression; -import com.mysema.testutil.ExcludeIn; - -public class ParsingTest extends AbstractQueryTest { - - @Test - @Ignore - public void ArrayExpr() throws Exception { - query().from(ord).where(ord.items(0).id.eq(1234l)).parse(); - } - - @Test - public void Basic() throws RecognitionException, TokenStreamException{ - query().from(cat, fatcat).select(cat.name, fatcat.name).parse(); - } - - @Test - public void BeforeAndAfter() throws RecognitionException, TokenStreamException { - ComparableExpression<java.util.Date> ed = catalog.effectiveDate; - query() - .from(catalog) - .where( - ed.gt(DateExpression.currentDate()), - ed.goe(DateExpression.currentDate()), - ed.lt(DateExpression.currentDate()), - ed.loe(DateExpression.currentDate())) - .select(catalog).parse(); - } - - @Test - @ExcludeIn(ORACLE) - public void ComplexConstructor() throws Exception { - query().from(bar).select(new QFooDTO(bar.count())).parse(); - } - - @Test - public void DocoExamples910() throws Exception { - query().from(cat) - .groupBy(cat.color) - .select(cat.color, cat.weight.sum(), cat.count()).parse(); - } - - @Test - public void DocoExamples910_2() throws Exception { - query().from(cat) - .groupBy(cat.color) - .having(cat.color.in(Color.TABBY, Color.BLACK)) - .select(cat.color, cat.weight.sum(), cat.count()).parse(); - } - - @Test - @Ignore - public void DocoExamples910_3() throws Exception { - query().from(cat).join(cat.kittens, kitten) - .groupBy(cat) - .having(kitten.weight.avg().gt(100.0)) - .orderBy(kitten.count().asc(), kitten.weight.sum().desc()) - .select(cat) - .parse(); - } - - @Test - public void DocoExamples911() throws Exception { - query().from(fatcat).where( - fatcat.weight.gt(sub().from(cat).unique(cat.weight.avg()))) - .parse(); - } - - @Test - public void DocoExamples911_2() throws Exception { - query().from(cat).where( - cat.name.eqAny(sub().from(name).list(name.nickName))) - .parse(); - } - - @Test - public void DocoExamples911_3() throws Exception { - query().from(cat).where( - sub().from(mate).where(mate.mate.eq(cat)).list(mate).notExists()) - .parse(); - } - - @Test - public void DocoExamples911_4() throws Exception { - query().from(cat).where( - sub().from(mate).where(mate.mate.eq(cat)).exists()) - .parse(); - } - - @Test - public void DocoExamples911_5() throws Exception { - query().from(cat).where( - cat.name.notIn(sub().from(name).list(name.nickName))) - .parse(); - } - - @Test - public void DocoExamples912() throws Exception { - query().from(ord, cust) - .join(ord.lineItems, item).join(item.product, product) - .from(catalog).join(catalog.prices, price).where( - ord.paid.not().and(ord.customer.eq(cust)).and( - price.product.eq(product)).and( - catalog.effectiveDate.gt(DateExpression.currentDate())).and( - catalog.effectiveDate.gtAny( - sub().from(catalog).where( - catalog.effectiveDate.lt(DateExpression.currentDate())) - .list(catalog.effectiveDate)))) - .groupBy(ord).having(price.amount.sum().gt(0l)) - .orderBy(price.amount.sum().desc()) - .select(ord.id, price.amount.sum(), item.count()); - - Customer c1 = new Customer(); - Catalog c2 = new Catalog(); - - query().from(ord) - .join(ord.lineItems, item).join(item.product, product) - .from(catalog).join(catalog.prices, price).where( - ord.paid.not().and(ord.customer.eq(c1)).and( - price.product.eq(product)).and(catalog.eq(c2))) - .groupBy(ord).having(price.amount.sum().gt(0l)) - .orderBy(price.amount.sum().desc()) - .select(ord.id, price.amount.sum(), item.count()); - - } - - @Test - public void DocoExamples92() throws Exception { - query().from(cat).parse(); - } - - @Test - public void DocoExamples92_2() throws Exception { - query().from(cat).parse(); - } - - @Test - public void DocoExamples92_3() throws Exception { - query().from(form, param).parse(); - } - - @Test - public void DocoExamples93() throws Exception { - query().from(cat).innerJoin(cat.mate, mate).leftJoin(cat.kittens, kitten).parse(); - } - - @Test - public void DocoExamples93_2() throws Exception { - query().from(cat).leftJoin(cat.mate.kittens, kitten).parse(); - } - - @Test - public void DocoExamples93_3() throws Exception { - query().from(cat).join(cat.mate, mate).leftJoin(cat.kittens, kitten).parse(); - } - - @Test - public void DocoExamples93_4() throws Exception { - query().from(cat).innerJoin(cat.mate, mate).leftJoin(cat.kittens, kitten).parse(); - } - - @Test - public void DocoExamples93_viaAlias() throws Exception { - Cat c = alias(Cat.class, "cat"); - Cat k = alias(Cat.class, "kittens"); - Cat m = alias(Cat.class, "mate"); - - query().from($(c)).innerJoin($(c.getMate()),$(m)).leftJoin($(c.getKittens()),$(k)).parse(); - } - - @Test - public void DocoExamples93_viaAlias2() throws Exception { - Cat c = alias(Cat.class, "cat"); - Cat k = alias(Cat.class, "kittens"); - - query().from($(c)).leftJoin($(c.getMate().getKittens()),$(k)).parse(); - } - - @Test - public void DocoExamples93_viaAlias3() throws Exception { - Cat c = alias(Cat.class, "cat"); - Cat k = alias(Cat.class, "kittens"); - Cat m = alias(Cat.class, "mate"); - - query().from($(c)).innerJoin($(c.getMate()),$(m)).leftJoin($(c.getKittens()),$(k)).parse(); - } - - @Test - public void DocoExamples93_viaAlias4() throws Exception { - Cat c = alias(Cat.class, "cat"); - Cat k = alias(Cat.class, "kittens"); - Cat m = alias(Cat.class, "mate"); - - query().from($(c)).innerJoin($(c.getMate()),$(m)).leftJoin($(c.getKittens()),$(k)).parse(); - } - - @Test - public void DocoExamples94() throws Exception { - query().from(cat).innerJoin(cat.mate, mate).select(cat.mate).parse(); - } - - @Test - public void DocoExamples94_2() throws Exception { - query().from(cat).select(cat.mate).parse(); - } - - @Test - @NoOpenJPA @NoBatooJPA - public void DocoExamples94_3() throws Exception { - query().from(cat).select(cat.kittens).parse(); - } - - @Test - public void DocoExamples94_4() throws Exception { - query().from(cust).select(cust.name.firstName).parse(); - } - - @Test - public void DocoExamples94_5() throws Exception { - query().from(mother) - .innerJoin(mother.mate, mate) - .leftJoin(mother.kittens, offspr) - .select(mother, offspr, mate).parse(); - } - - @Test - public void DocoExamples94_6() throws Exception { - query().from(mother) - .innerJoin(mother.mate, mate) - .leftJoin(mother.kittens, kitten) - .select(new QFamily(mother, mate, kitten)).parse(); - } - - @Test - public void DocoExamples95() throws Exception { - query().from(cat) - .select(cat.weight.avg(), cat.weight.sum(), cat.weight.max(), cat.count()) - .parse(); - } - - @Test - public void DocoExamples96() throws Exception { - query().from(cat).parse(); - } - - @Test - public void DocoExamples96_2() throws Exception { - query().from(m, n).where(n.name.eq(m.name)).parse(); - } - - @Test - @ExcludeIn(ORACLE) - public void DocoExamples97() throws Exception { - query().from(foo, bar).where(foo.startDate.eq(bar.date)).select(foo).parse(); - } - - @Test - public void DocoExamples97_2() throws Exception { - query().from(cat).where(cat.mate.name.isNotNull()).parse(); - } - - @Test - public void DocoExamples97_3() throws Exception { - query().from(cat, rival).where(cat.mate.eq(rival.mate)).parse(); - } - - @Test - public void DocoExamples97_4() throws Exception { - query().from(cat, mate).where(cat.mate.eq(mate)).select(cat, mate).parse(); - } - - @Test - public void DocoExamples97_5() throws Exception { - query().from(cat).where(cat.id.eq(123)).parse(); - } - - @Test - public void DocoExamples97_6() throws Exception { - query().from(cat).where(cat.mate.id.eq(69)).parse(); - } - - @Test - public void DocoExamples97_7() throws Exception { - query().from(person).where( - person.pid.country.eq("AU"), - person.pid.medicareNumber.eq(123456)).parse(); - } - - @Test - public void DocoExamples97_8() throws Exception { - query().from(account).where(account.owner.pid.medicareNumber.eq(123456)).parse(); - } - - @Test - public void DocoExamples97_9() throws Exception { - query().from(cat).where(cat.instanceOf(DomesticCat.class)).parse(); - } - - @Test - @Ignore - //@NoEclipseLink - public void DocoExamples97_10() throws Exception { - query().from(log, payment).where( - log.item.instanceOf(Payment.class), - log.item.id.eq(payment.id)).parse(); - } - - @Test - public void DocoExamples97_10_2() throws Exception { - query().from(log, payment).innerJoin(log.item, item).where( - item.instanceOf(Payment.class), - item.id.eq(payment.id)).parse(); - } - - @Test - public void DocoExamples98_1() throws Exception { - query().from(cat).where(cat.name.between("A", "B")).parse(); - } - - @Test - public void DocoExamples98_2() throws Exception { - query().from(cat).where(cat.name.in("Foo", "Bar", "Baz")).parse(); - } - - @Test - public void DocoExamples98_3() throws Exception { - query().from(cat).where(cat.name.notBetween("A", "B")).parse(); - } - - @Test - public void DocoExamples98_4() throws Exception { - query().from(cat).where(cat.name.notIn("Foo", "Bar", "Baz")).parse(); - } - - @Test - public void DocoExamples98_5() throws Exception { - query().from(cat).where(cat.kittens.size().gt(0)).parse(); - } - - @Test - public void DocoExamples98_6() throws Exception { - query().from(mother, kit).select(mother).where(kit.in(mother.kittens)).parse(); - } - - @Test - @NoEclipseLink - public void DocoExamples98_7() throws Exception { - query().from(list, p).select(p).where(p.name.eqAny(list.names)).parse(); - } - - @Test - public void DocoExamples98_8() throws Exception { - query().from(cat).where(cat.kittens.isNotEmpty()).parse(); - } - - @Test - @NoEclipseLink @NoOpenJPA @NoBatooJPA - public void DocoExamples98_9() throws Exception { - query().from(person, calendar).select(person).where( - calendar.holidays("national holiday").eq(person.birthDay), - person.nationality.calendar.eq(calendar)).parse(); - } - - @Test - @NoEclipseLink @NoOpenJPA @NoBatooJPA - @ExcludeIn({DERBY, HSQLDB, ORACLE}) - public void DocoExamples98_10() throws Exception { - query().from(item, ord).select(item).where( - ord.items(ord.deliveredItemIndices(0)).eq(item), - ord.id.eq(1l)).parse(); - } - - @Test - @NoEclipseLink - @ExcludeIn({DERBY, HSQLDB, H2, MYSQL, ORACLE, POSTGRES}) - @Ignore - public void DocoExamples98_11() throws Exception { - query().from(item, ord).select(item).where( - ord.items(ord.items.size().subtract(1)).eq(item)) - .parse(); - } - - @Test - @NoEclipseLink @NoOpenJPA @NoBatooJPA - @ExcludeIn({DERBY, HSQLDB, ORACLE}) - public void DocoExamples98_12() throws Exception { - query() - .from(prod, store) - .innerJoin(store.customers, cust) - .select(cust) - .where( - prod.name.eq("widget"), - store.location.name.in("Melbourne", "Sydney"), - prod.eqAll(cust.currentOrder.lineItems)) - .parse(); - - } - - @Test - public void DocoExamples98() throws Exception { - prod.eq(new Product()); - prod.eq(new QProduct("p")); - prod.eq(new QItem("p")); - - } - - @Test - public void DocoExamples99() throws Exception { - query().from(cat).orderBy(cat.name.asc(), cat.weight.desc(), - cat.birthdate.asc()).parse(); - } - - @Test - public void DoubleLiteral() throws Exception { - query().from(cat).where(cat.weight.lt((int) 3.1415)).parse(); - } - - @Test - public void DoubleLiteral2() throws Exception { - query().from(cat).where(cat.weight.gt((int) 3.1415e3)).parse(); - } - - @Test - @NoOpenJPA - public void Fetch() throws RecognitionException, TokenStreamException{ - query().from(cat).innerJoin(cat.mate, mate).fetch().parse(); - } - - @Test - @NoOpenJPA - public void Fetch2() throws RecognitionException, TokenStreamException{ - query().from(cat).innerJoin(cat.mate, mate).fetch().fetch().parse(); - } - - @Test - public void In() throws Exception { - query().from(foo).where(foo.bar.in("a", "b", "c")).parse(); - } - - @Test - public void NotIn() throws Exception { - query().from(foo).where(foo.bar.notIn("a", "b", "c")).parse(); - } - - @Test - @NoEclipseLink @NoOpenJPA - public void JoinFlags1() throws RecognitionException, TokenStreamException{ - query().from(cat).fetchAll().parse(); - } - - @Test - @NoEclipseLink @NoOpenJPA @NoBatooJPA - public void JoinFlags2() throws RecognitionException, TokenStreamException{ - query().from(cat).fetchAll().from(cat1).fetchAll().parse(); - } - - @Test - @NoEclipseLink @NoOpenJPA @NoBatooJPA - public void JoinFlags3() throws RecognitionException, TokenStreamException{ - query().from(cat).fetchAll().from(cat1).fetchAll().parse(); - } - - @Test - public void Joins() throws RecognitionException, TokenStreamException{ - query().from(cat).join(cat.mate, mate).select(cat).parse(); - } - - @Test - public void InnerJoin() throws RecognitionException, TokenStreamException{ - query().from(cat).innerJoin(cat.mate, mate).select(cat).parse(); - } - - @Test - public void LeftJoin() throws RecognitionException, TokenStreamException{ - query().from(cat).leftJoin(cat.mate, mate).select(cat).parse(); - } - - @Test - @NoOpenJPA @NoBatooJPA - public void Joins2() throws RecognitionException, TokenStreamException{ - query().from(cat).join(cat.mate, mate).on(mate.name.eq("Bob")).parse(); - } - - @Test - public void MultipleFromClasses() throws Exception { - query().from(qat, foo).parse(); - } - - @Test - public void Serialization() { - QueryHelper query = query(); - - query.from(cat); - assertEquals("select cat\nfrom Cat cat", query.toString()); - - query.from(fatcat); - assertEquals("select cat\nfrom Cat cat, Cat fatcat", query.toString()); - } - - @Test - @NoEclipseLink @NoOpenJPA - @ExcludeIn(MYSQL) - public void Casts_Byte() throws Exception { - NumberExpression<Double> bw = cat.bodyWeight; - query().from(cat).select(bw.byteValue()).parse(); - } - - @Test - @NoOpenJPA - public void Casts_Double() throws Exception { - NumberExpression<Double> bw = cat.bodyWeight; - query().from(cat).select(bw.doubleValue()).parse(); - } - - @Test - @NoOpenJPA - @ExcludeIn(MYSQL) - public void Casts_Float() throws Exception { - NumberExpression<Double> bw = cat.bodyWeight; - query().from(cat).select(bw.floatValue()).parse(); - } - - @Test - @NoOpenJPA - @ExcludeIn(MYSQL) - public void Casts_Int() throws Exception { - NumberExpression<Double> bw = cat.bodyWeight; - query().from(cat).select(bw.intValue()).parse(); - } - - @Test - @NoOpenJPA - @ExcludeIn({DERBY, HSQLDB, MYSQL}) - public void Casts_Long() throws Exception { - NumberExpression<Double> bw = cat.bodyWeight; - query().from(cat).select(bw.longValue()).parse(); - } - - @Test - @NoEclipseLink @NoOpenJPA - @ExcludeIn(MYSQL) - public void Casts_Short() throws Exception { - NumberExpression<Double> bw = cat.bodyWeight; - query().from(cat).select(bw.shortValue()).parse(); - } - - @Test - @NoOpenJPA - @ExcludeIn({DERBY, HSQLDB, MYSQL}) - public void Casts_String() throws Exception { - NumberExpression<Double> bw = cat.bodyWeight; - query().from(cat).select(bw.stringValue()).parse(); - } - - @Test - @NoEclipseLink @NoOpenJPA - @ExcludeIn(MYSQL) - public void Casts_2() throws Exception { - NumberExpression<Double> bw = cat.bodyWeight; - query().from(cat).select(bw.castToNum(Byte.class)).parse(); - } - - @Test - @Ignore - public void GroupBy() throws Exception { - query().from(qat).groupBy(qat.breed).parse(); - } - - @Test - @Ignore - public void GroupBy_2() throws Exception { - query().from(qat).groupBy(qat.breed, qat.eyecolor).parse(); - } - - @Test - public void Not() throws Exception { - query().from(cat).where(cat.kittens.size().lt(1).not()).parse(); - } - - @Test - public void Not_2() throws Exception { - query().from(cat).where(cat.kittens.size().gt(1).not()).parse(); - } - - @Test - public void Not_3() throws Exception { - query().from(cat).where(cat.kittens.size().goe(1).not()).parse(); - } - - @Test - public void Not_4() throws Exception { - query().from(cat).where(cat.kittens.size().loe(1).not()).parse(); - } - - @Test - public void Not_5() throws Exception { - query().from(cat).where(cat.name.between("A", "B").not()).parse(); - } - - @Test - public void Not_6() throws Exception { - query().from(cat).where(cat.name.notBetween("A", "B").not()).parse(); - } - - @Test - public void Not_7() throws Exception { - query().from(cat).where(cat.kittens.size().loe(1).not().not()).parse(); - } - - @Test - public void Not_8() throws Exception { - query().from(cat).where(cat.kittens.size().loe(1).not().not().not()).parse(); - } - - - @Test - @Ignore - public void OrderBy() throws Exception { - // NOT SUPPORTED - query().from(qat).orderBy(qat.toes.avg().asc()).parse(); - } - - @Test - @NoOpenJPA - public void OrderBy_2() throws Exception { - query().from(an).orderBy(an.bodyWeight.sqrt().divide(2.0).asc()).parse(); - } - - @Test - public void Select() throws Exception { -// query().select(Ops.AggOps.COUNT_ALL_AGG_EXPR).from(qat).parse(); - - query().from(qat).select(qat.weight.avg()).parse(); - } - - @Test - @Ignore - public void Sum() throws RecognitionException, TokenStreamException { - // NOT SUPPORTED - query().from(cat).select(cat.kittens.size().sum()).parse(); - } - - @Test - @Ignore - public void Sum_2() throws RecognitionException, TokenStreamException { - // NOT SUPPORTED - query().from(cat).where(cat.kittens.size().sum().gt(0)).select(cat).parse(); - } - - @Test - public void Sum_3() throws RecognitionException, TokenStreamException { - query().from(cat).where(cat.kittens.isEmpty()).select(cat).parse(); - } - - @Test - public void Sum_4() throws RecognitionException, TokenStreamException { - query().from(cat).where(cat.kittens.isNotEmpty()).select(cat).parse(); - } - - @Test - public void Where() throws Exception { - query().from(qat).where(qat.name.in("crater", "bean", "fluffy")).parse(); - } - - @Test - public void Where_2() throws Exception { - query().from(qat).where(qat.name.notIn("crater", "bean", "fluffy")).parse(); - } - - @Test - public void Where_3() throws Exception { - query().from(an).where(an.bodyWeight.sqrt().gt(10.0)).parse(); - } - - @Test - public void Where_4() throws Exception { - query().from(an).where(an.bodyWeight.sqrt().divide(2d).gt(10.0)).parse(); - } - - @Test - public void Where_5() throws Exception { - query().from(an).where( - an.bodyWeight.gt(10), - an.bodyWeight.lt(100).or(an.bodyWeight.isNull())) - .parse(); - } - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/Person.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/Person.java deleted file mode 100644 index 3b42637fa7..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/Person.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.mysema.query.jpa; - - -public class Person { - - String firstName, lastName; -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/QArticle.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/QArticle.java deleted file mode 100644 index 67a05b63fd..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/QArticle.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.mysema.query.jpa; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; -import com.mysema.query.types.path.PathInits; - - -/** - * QArticle is a Querydsl query type for Article - */ -@Generated("com.mysema.query.codegen.EntitySerializer") -public class QArticle extends EntityPathBase<Article> { - - private static final long serialVersionUID = 1732636838L; - - private static final PathInits INITS = PathInits.DIRECT2; - - public static final QArticle article = new QArticle("article"); - - public final QPerson author; - - public final QContent content; - - public final StringPath name = createString("name"); - - public QArticle(String variable) { - this(Article.class, forVariable(variable), INITS); - } - - public QArticle(Path<? extends Article> path) { - this(path.getType(), path.getMetadata(), path.getMetadata().isRoot() ? INITS : PathInits.DEFAULT); - } - - public QArticle(PathMetadata<?> metadata) { - this(metadata, metadata.isRoot() ? INITS : PathInits.DEFAULT); - } - - public QArticle(PathMetadata<?> metadata, PathInits inits) { - this(Article.class, metadata, inits); - } - - public QArticle(Class<? extends Article> type, PathMetadata<?> metadata, PathInits inits) { - super(type, metadata, inits); - this.author = inits.isInitialized("author") ? new QPerson(forProperty("author")) : null; - this.content = inits.isInitialized("content") ? new QContent(forProperty("content"), inits.get("content")) : null; - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/QContent.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/QContent.java deleted file mode 100644 index 3ecf0a9f69..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/QContent.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.mysema.query.jpa; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; -import com.mysema.query.types.path.PathInits; - - -/** - * QContent is a Querydsl query type for Content - */ -@Generated("com.mysema.query.codegen.EmbeddableSerializer") -public class QContent extends BeanPath<Content> { - - private static final long serialVersionUID = -878421975L; - - private static final PathInits INITS = PathInits.DIRECT2; - - public static final QContent content = new QContent("content"); - - public final QArticle article; - - public QContent(String variable) { - this(Content.class, forVariable(variable), INITS); - } - - public QContent(Path<? extends Content> path) { - this(path.getType(), path.getMetadata(), path.getMetadata().isRoot() ? INITS : PathInits.DEFAULT); - } - - public QContent(PathMetadata<?> metadata) { - this(metadata, metadata.isRoot() ? INITS : PathInits.DEFAULT); - } - - public QContent(PathMetadata<?> metadata, PathInits inits) { - this(Content.class, metadata, inits); - } - - public QContent(Class<? extends Content> type, PathMetadata<?> metadata, PathInits inits) { - super(type, metadata, inits); - this.article = inits.isInitialized("article") ? new QArticle(forProperty("article"), inits.get("article")) : null; - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/QPerson.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/QPerson.java deleted file mode 100644 index 5352d3ebec..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/QPerson.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.mysema.query.jpa; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - - -/** - * QPerson is a Querydsl query type for Person - */ -@Generated("com.mysema.query.codegen.EntitySerializer") -public class QPerson extends EntityPathBase<Person> { - - private static final long serialVersionUID = -219463259L; - - public static final QPerson person = new QPerson("person"); - - public final StringPath firstName = createString("firstName"); - - public final StringPath lastName = createString("lastName"); - - public QPerson(String variable) { - super(Person.class, forVariable(variable)); - } - - public QPerson(Path<? extends Person> path) { - super(path.getType(), path.getMetadata()); - } - - public QPerson(PathMetadata<?> metadata) { - super(Person.class, metadata); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/QueryHelper.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/QueryHelper.java deleted file mode 100644 index 2957dd0ab8..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/QueryHelper.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa; - -import javax.annotation.Nullable; -import java.io.ByteArrayOutputStream; -import java.io.PrintStream; - -import antlr.RecognitionException; -import antlr.TokenStreamException; -import antlr.collections.AST; -import com.mysema.commons.lang.CloseableIterator; -import com.mysema.query.DefaultQueryMetadata; -import com.mysema.query.QueryMetadata; -import com.mysema.query.SearchResults; -import com.mysema.query.Tuple; -import com.mysema.query.types.Expression; -import org.hibernate.hql.internal.ast.HqlParser; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import static org.junit.Assert.assertEquals; - -class QueryHelper extends JPAQueryBase<QueryHelper> { - - private static final Logger logger = LoggerFactory.getLogger(QueryHelper.class); - - public QueryHelper(JPQLTemplates templates) { - this(new DefaultQueryMetadata(), templates); - } - - public QueryHelper(QueryMetadata metadata, JPQLTemplates templates) { - super(metadata, templates); - } - - @Override - protected JPQLSerializer createSerializer() { - return new JPQLSerializer(getTemplates()); - } - - public long count() { - return 0; - } - - @Override - public CloseableIterator<Tuple> iterate(Expression<?>... args) { - throw new UnsupportedOperationException(); - } - - @Nullable - public <RT> CloseableIterator<RT> iterate(Expression<RT> projection) { - throw new UnsupportedOperationException(); - } - - @Nullable - public SearchResults<Tuple> listResults(Expression<?>... args) { - throw new UnsupportedOperationException(); - } - - @Nullable - public <RT> SearchResults<RT> listResults(Expression<RT> expr) { - throw new UnsupportedOperationException(); - } - - public void parse() throws RecognitionException, TokenStreamException { - try { - String input = toString(); - logger.debug("input: " + input.replace('\n', ' ')); - HqlParser parser = HqlParser.getInstance(input); - parser.setFilter(false); - parser.statement(); - AST ast = parser.getAST(); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - parser.showAst(ast, new PrintStream(baos)); - assertEquals("At least one error occurred during parsing " + input, - 0, parser.getParseErrorHandler().getErrorCount()); - } finally { - // clear(); - } - } - - public QueryHelper select(Expression<?>... exprs) { - queryMixin.addProjection(exprs); - return this; - } - - @Override - public <RT> RT uniqueResult(Expression<RT> projection) { - throw new UnsupportedOperationException(); - } - - @Override - public QueryHelper clone() { - return new QueryHelper(getMetadata().clone(), getTemplates()); - } - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/QueryMutabilityTest.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/QueryMutabilityTest.java deleted file mode 100644 index 2f20b2e0ae..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/QueryMutabilityTest.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa; - -import static org.junit.Assert.assertEquals; - -import java.io.IOException; -import java.lang.reflect.InvocationTargetException; - -import org.hibernate.Session; -import org.junit.Ignore; -import org.junit.Test; - -import com.mysema.query.QueryMutability; -import com.mysema.query.jpa.domain.sql.SAnimal; -import com.mysema.query.jpa.hibernate.sql.HibernateSQLQuery; -import com.mysema.query.sql.DerbyTemplates; -import com.mysema.query.sql.SQLTemplates; - -public class QueryMutabilityTest{ - - private static final SQLTemplates derbyTemplates = new DerbyTemplates(); - - private Session session; - - protected HibernateSQLQuery query() { - return new HibernateSQLQuery(session, derbyTemplates); - } - - public void setSession(Session session) { - this.session = session; - } - - @Test - @Ignore - public void QueryMutability() throws SecurityException, IllegalArgumentException, - NoSuchMethodException, IllegalAccessException, - InvocationTargetException, IOException { - SAnimal cat = new SAnimal("cat"); - HibernateSQLQuery query = query().from(cat); - new QueryMutability(query).test(cat.id, cat.name); - } - - @Test - public void Clone() { - SAnimal cat = new SAnimal("cat"); - HibernateSQLQuery query = query().from(cat).where(cat.name.isNotNull()); - HibernateSQLQuery query2 = query.clone(session); - assertEquals(query.getMetadata().getJoins(), query2.getMetadata().getJoins()); - assertEquals(query.getMetadata().getWhere(), query2.getMetadata().getWhere()); - //query2.list(cat.id); - } - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/RelationalFunctionCallTest.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/RelationalFunctionCallTest.java deleted file mode 100644 index bfb46d0845..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/RelationalFunctionCallTest.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa; - -import static org.junit.Assert.assertEquals; - -import org.junit.Test; - -import com.mysema.query.sql.Configuration; -import com.mysema.query.sql.RelationalFunctionCall; -import com.mysema.query.sql.RelationalPathBase; -import com.mysema.query.sql.SQLSerializer; -import com.mysema.query.sql.SQLServerTemplates; -import com.mysema.query.sql.SQLSubQuery; -import com.mysema.query.types.PathMetadataFactory; -import com.mysema.query.types.SubQueryExpression; -import com.mysema.query.types.path.PathBuilder; -import com.mysema.query.types.path.StringPath; - -public class RelationalFunctionCallTest { - -// @Schema("PUBLIC") -// @Table("SURVEY") - public class QSurvey extends RelationalPathBase<QSurvey>{ - - private static final long serialVersionUID = -7427577079709192842L; - - public final StringPath name = createString("NAME"); - - public QSurvey(String path) { - super(QSurvey.class, PathMetadataFactory.forVariable(path), "PUBLIC", "SURVEY"); - } - - } - - @Test - public void FunctionCall() { - //select tab.col from Table tab join TableValuedFunction('parameter') func on tab.col not like func.col - - QSurvey table = new QSurvey("SURVEY"); - RelationalFunctionCall<String> func = RelationalFunctionCall.create(String.class, "TableValuedFunction", "parameter"); - PathBuilder<String> funcAlias = new PathBuilder<String>(String.class, "tokFunc"); - SQLSubQuery sq = new SQLSubQuery(); - SubQueryExpression<?> expr = sq.from(table) - .join(func, funcAlias).on(table.name.like(funcAlias.getString("prop")).not()).list(table.name); - - Configuration conf = new Configuration(new SQLServerTemplates()); - SQLSerializer serializer = new NativeSQLSerializer(conf, true); - serializer.serialize(expr.getMetadata(), false); - assertEquals("select SURVEY.NAME\n" + - "from SURVEY SURVEY\n" + - "join TableValuedFunction(?1) as tokFunc\n" + - "on not SURVEY.NAME like tokFunc.prop escape '\\'", serializer.toString()); - - } - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/SerializationBase.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/SerializationBase.java deleted file mode 100644 index e1e9576063..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/SerializationBase.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; - -import javax.persistence.EntityManager; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import com.mysema.query.QueryMetadata; -import com.mysema.query.jpa.domain.QCat; -import com.mysema.query.jpa.impl.JPAQuery; -import com.mysema.testutil.JPATestRunner; - -@RunWith(JPATestRunner.class) -public class SerializationBase { - - private QCat cat = QCat.cat; - - private EntityManager entityManager; - - @Test - public void test() throws IOException, ClassNotFoundException{ - // create query - JPAQuery query = new JPAQuery(entityManager); - query.from(cat).where(cat.name.eq("Kate")).list(cat); - - // get metadata - QueryMetadata metadata = query.getMetadata(); - assertFalse(metadata.getJoins().isEmpty()); - assertTrue(metadata.getWhere() != null); - assertTrue(metadata.getProjection().isEmpty()); - - // serialize metadata - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ObjectOutputStream out = new ObjectOutputStream(baos); - out.writeObject(metadata); - out.close(); - - // deserialize metadata - ByteArrayInputStream bain = new ByteArrayInputStream(baos.toByteArray()); - ObjectInputStream in = new ObjectInputStream(bain); - QueryMetadata metadata2 = (QueryMetadata) in.readObject(); - in.close(); - - // validate it - assertEquals(metadata.getJoins(), metadata2.getJoins()); - assertEquals(metadata.getWhere(), metadata2.getWhere()); - assertEquals(metadata.getProjection(), metadata2.getProjection()); - - // create new query - JPAQuery query2 = new JPAQuery(entityManager, metadata2); - assertEquals("select cat\nfrom Cat cat\nwhere cat.name = ?1", query2.toString()); - query2.list(cat); - } - - public void setEntityManager(EntityManager entityManager) { - this.entityManager = entityManager; - } -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/StringOperationsTest.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/StringOperationsTest.java deleted file mode 100644 index d7d48c0ed8..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/StringOperationsTest.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa; - -import org.junit.Test; - -import com.mysema.query.domain.QCat; -import com.mysema.query.support.Expressions; -import com.mysema.query.types.Expression; -import com.mysema.query.types.Ops; -import com.mysema.query.types.Path; -import com.mysema.query.types.expr.NumberOperation; -import com.mysema.query.types.expr.StringOperation; -import com.mysema.query.types.path.StringPath; - -public class StringOperationsTest extends AbstractQueryTest{ - - @Test - public void StringConcatenations() { - assertToString("concat(cat.name,kitten.name)", cat.name.concat(kitten.name)); - } - - @Test - public void StringConversionOperations() { - assertToString("str(cat.bodyWeight)", cat.bodyWeight.stringValue()); - } - - @Test - public void StringOperationsInFunctionalWay() { - assertToString("concat(cat.name,cust.name.firstName)", cat.name.concat(cust.name.firstName)); - assertToString("lower(cat.name)", cat.name.lower()); - } - - @Test - @SuppressWarnings("rawtypes") - public void IndexOf() { - Path path = QCat.cat.name; - Expression startIndex = Expressions.constant(0); - Expression endIndex = NumberOperation.create(Integer.class, Ops.INDEX_OF, path, Expressions.constant("x")); - Expression substr = StringOperation.create(Ops.SUBSTR_2ARGS, path, startIndex, endIndex); - assertToString("substring(cat.name,1,locate(?1,cat.name)-1)", substr); - } - - @Test - public void IndexOf2() { - StringPath str = QCat.cat.name; - assertToString("substring(cat.name,1,locate(?1,cat.name)-1)", str.substring(0, str.indexOf("x"))); - } - - @Test - public void IndexOf3() { - assertToString("substring(cat.name,2,1)", QCat.cat.name.substring(1,2)); - } -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/SubQueryTest.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/SubQueryTest.java deleted file mode 100644 index 964b888841..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/SubQueryTest.java +++ /dev/null @@ -1,194 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa; - -import static org.junit.Assert.assertEquals; - -import org.junit.Test; - -import com.mysema.query.domain.QCat; -import com.mysema.query.jpa.domain.QEmployee; -import com.mysema.query.jpa.domain.QUser; - -public class SubQueryTest extends AbstractQueryTest{ - - @Test(expected=IllegalArgumentException.class) - public void WrongUsage() { - sub().exists(); - } - - @Test - public void Single_Source() { - JPASubQuery query = sub(); - query.from(cat); - assertEquals("select cat\nfrom Cat cat", query.toString()); - } - - @Test - public void Multiple_Sources() { - JPASubQuery query = sub(); - query.from(cat); - query.from(fatcat); - assertEquals("select cat\nfrom Cat cat, Cat fatcat", - query.toString()); - } - - @Test - public void In() { - cat.in(sub().from(cat).list(cat)); - } - - @Test - public void InnerJoin() { - assertEquals("select cat\nfrom Cat cat\n inner join cat.mate", - sub().from(cat).innerJoin(cat.mate).toString()); - } - - @Test - public void InnerJoin2() { - QEmployee employee = QEmployee.employee; - QUser user = QUser.user; - assertEquals("select employee\nfrom Employee employee\n inner join employee.user as user", - sub().from(employee).innerJoin(employee.user, user).toString()); - } - - @Test - public void LeftJoin() { - assertEquals("select cat\nfrom Cat cat\n left join cat.mate", - sub().from(cat).leftJoin(cat.mate).toString()); - } - - @Test - public void FullJoin() { - assertEquals("select cat\nfrom Cat cat\n full join cat.mate", - sub().from(cat).fullJoin(cat.mate).toString()); - } - - @Test - public void Join() { - assertEquals("select cat\nfrom Cat cat\n inner join cat.mate", - sub().from(cat).join(cat.mate).toString()); - } - - @Test - public void UniqueProjection() { - assertToString("(select cat from Cat cat)", - sub().from(cat).unique(cat)); - } - - @Test - public void ListProjection() { - assertToString("(select cat from Cat cat)", - sub().from(cat).list(cat)); - } - - @Test - public void ListContains() { - assertToString("cat1 in (select cat from Cat cat)", - sub().from(cat).list(cat).contains(cat1)); - } - - @Test - public void Exists() { - assertToString("exists (select 1 from Cat cat)", - sub().from(cat).exists()); - } - - @Test - public void Exists_Where() { - assertToString("exists (select 1 from Cat cat where cat.weight < ?1)", - sub().from(cat).where(cat.weight.lt(1)).exists()); - } - - @Test - public void Exists_Via_Unique() { - assertToString("exists (select 1 from Cat cat where cat.weight < ?1)", - sub().from(cat).where(cat.weight.lt(1)).unique(cat).exists()); - } - - @Test - public void NotExists() { - assertToString("not exists (select 1 from Cat cat)", - sub().from(cat).notExists()); - } - - @Test - public void NotExists_Where() { - assertToString("not exists (select 1 from Cat cat where cat.weight < ?1)", - sub().from(cat).where(cat.weight.lt(1)).notExists()); - } - - @Test - public void NotExists_Via_Unique() { - assertToString("not exists (select 1 from Cat cat where cat.weight < ?1)", - sub().from(cat).where(cat.weight.lt(1)).unique(cat).notExists()); - } - - @Test - public void Count() { - assertToString("(select count(cat) from Cat cat)", - sub().from(cat).count()); - } - - @Test - public void Count_Via_List() { - assertToString("(select count(cat) from Cat cat)", - sub().from(cat).list(cat).count()); - } - - @Test - public void Count_Name() { - assertToString("(select count(cat.name) from Cat cat)", - sub().from(cat).list(cat.name).count()); - } - - @Test - public void Count_Multiple_Sources() { - QCat other = new QCat("other"); - assertToString("(select count(cat, other) from Cat cat, Cat other)", - sub().from(cat, other).count()); - } - - @Test - public void Count_Multiple_Sources_Via_List() { - QCat other = new QCat("other"); - assertToString("(select count(cat, other) from Cat cat, Cat other)", - sub().from(cat, other).list(cat, other).count()); - } - - @Test - public void Indexed_Access() { - assertToString("(select count(cat) from Cat cat " + - "left join cat.kittens as cat_kittens_0 " + - "where index(cat_kittens_0) = ?1 and cat_kittens_0.name = ?2)", - - sub().from(cat).where(cat.kittens.get(0).name.eq("Kate")).count()); - } - - @Test - public void Indexed_Access_Without_Constant() { - assertToString("(select count(cat) from Cat cat " + - "left join cat.kittens as cat_kittens_cat_id " + - "where index(cat_kittens_cat_id) = cat.id and cat_kittens_cat_id.name = ?1)", - - sub().from(cat).where(cat.kittens.get(cat.id).name.eq("Kate")).count()); - } - - @Test - public void IndexOf() { - assertToString("(select count(cat) from Cat cat where locate(?1,cat.name)-1 = ?2)", - sub().from(cat).where(cat.name.indexOf("a").eq(1)).count()); - } - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/TupleTest.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/TupleTest.java deleted file mode 100644 index 1db3dc74f7..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/TupleTest.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa; - -import com.mysema.query.jpa.domain.QCat; -import com.mysema.query.jpa.hibernate.HibernateSubQuery; -import com.mysema.query.types.QTuple; -import com.mysema.query.types.SubQueryExpression; -import org.junit.Ignore; -import org.junit.Test; - -public class TupleTest extends AbstractQueryTest { - - @Test - @Ignore // FIXME - public void test() { - QCat cat = QCat.cat; - - SubQueryExpression<?> subQuery = subQuery().from(cat) - .where(subQuery() - .from(cat) - .groupBy(cat.mate) - .list(new QTuple(cat.mate, cat.birthdate.max())) - .contains(new QTuple(cat.mate, cat.birthdate))) - .list(new QTuple(cat.birthdate, cat.name, cat.mate)); - - assertToString( - "(select cat.birthdate, cat.name, cat.mate from Cat cat " + - "where (cat.mate, cat.birthdate) in " + - "(select cat.mate, max(cat.birthdate) from Cat cat group by cat.mate))", subQuery); - } - - private HibernateSubQuery subQuery() { - return new HibernateSubQuery(); - } - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/TypeCastTest.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/TypeCastTest.java deleted file mode 100644 index c40a07db84..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/TypeCastTest.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa; - -import static org.junit.Assert.assertEquals; - -import org.junit.Test; - -import com.mysema.query.jpa.domain.Animal; -import com.mysema.query.jpa.domain.Cat; -import com.mysema.query.jpa.domain.InheritedProperties; -import com.mysema.query.jpa.domain.QAnimal; -import com.mysema.query.jpa.domain.QCat; -import com.mysema.query.jpa.domain.QInheritedProperties; -import com.mysema.query.jpa.domain.QSuperclass; - -public class TypeCastTest { - - @Test - public void MappedSuperclass() { - QInheritedProperties subClass = QInheritedProperties.inheritedProperties; - QSuperclass superClass = subClass._super; - - assertEquals(InheritedProperties.class, superClass.getType()); -// assertEquals(InheritedProperties.class.getSimpleName(), superClass.getEntityName()); - assertEquals("inheritedProperties", superClass.toString()); - } - -// @Test -// public void mappedSuperclass2() { -// QInheritedProperties subClass = QInheritedProperties.inheritedProperties; -// QSuperclass superClass = new QSuperclass(subClass.getMetadata()); -// -// assertEquals(Superclass.class, superClass.getType()); -// assertEquals(Superclass.class.getSimpleName(), superClass.getEntityName()); -// assertEquals("inheritedProperties", superClass.toString()); -// } - - @Test - public void SubClassToSuper() { - QCat cat = QCat.cat; - QAnimal animal = new QAnimal(cat); - - assertEquals(Cat.class, animal.getType()); -// assertEquals(Cat.class.getSimpleName(), animal.getEntityName()); - assertEquals("cat", animal.toString()); - } - - @Test - public void SubClassToSuper2() { - QCat cat = QCat.cat; - QAnimal animal = new QAnimal(cat.getMetadata()); - - assertEquals(Animal.class, animal.getType()); -// assertEquals(Animal.class.getSimpleName(), animal.getEntityName()); - assertEquals("cat", animal.toString()); - } - - @Test - public void SuperClassToSub() { - QAnimal animal = QAnimal.animal; - QCat cat = new QCat(animal.getMetadata()); - - assertEquals(Cat.class, cat.getType()); -// assertEquals(Cat.class.getSimpleName(), cat.getEntityName()); - assertEquals("animal", cat.toString()); - } - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/UniqueResultsTest.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/UniqueResultsTest.java deleted file mode 100644 index d8fc8bb97f..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/UniqueResultsTest.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa; - -import static com.mysema.query.jpa.domain.QCat.cat; -import static org.junit.Assert.assertEquals; - -import org.hibernate.Session; -import org.junit.Ignore; -import org.junit.Test; -import org.junit.runner.RunWith; - -import com.mysema.query.jpa.domain.Cat; -import com.mysema.query.jpa.hibernate.HibernateQuery; -import com.mysema.testutil.HibernateTestRunner; - -@Ignore -@RunWith(HibernateTestRunner.class) -public class UniqueResultsTest { - - private Session session; - - @Test - public void test() { - session.save(new Cat("Bob1", 1)); - session.save(new Cat("Bob2", 2)); - session.save(new Cat("Bob3", 3)); - - assertEquals(Integer.valueOf(1), query().from(cat).orderBy(cat.name.asc()).offset(0).limit(1).uniqueResult(cat.id)); - assertEquals(Integer.valueOf(2), query().from(cat).orderBy(cat.name.asc()).offset(1).limit(1).uniqueResult(cat.id)); - assertEquals(Integer.valueOf(3), query().from(cat).orderBy(cat.name.asc()).offset(2).limit(1).uniqueResult(cat.id)); - - assertEquals(Long.valueOf(3), query().from(cat).uniqueResult(cat.count())); - } - - private HibernateQuery query() { - return new HibernateQuery(session); - } - - public void setSession(Session session) { - this.session = session; - } - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Account.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Account.java deleted file mode 100644 index 3132fd0c5b..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Account.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa.domain; - -import static org.junit.Assert.fail; - -import java.io.Serializable; - -import javax.persistence.Embedded; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.ManyToOne; -import javax.persistence.Table; -import javax.persistence.Transient; - -import org.junit.Test; - -import com.mysema.query.annotations.QueryInit; - -/** - * The Class Account. - */ -@SuppressWarnings("serial") -@Entity -@Table(name="account_") -public class Account implements Serializable{ - - @Transient - public int transientField; - - @Id - long id; - - @ManyToOne - @QueryInit("pid") - Person owner; - - @Embedded - EmbeddedType embeddedData; - - @Test - public void test() { - try { - QAccount.class.getField("serialVersionUID"); - fail("Got serialVersionUID"); - } catch (Exception e) { - // expected - } - try { - QAccount.class.getField("transientField"); - fail("Got transientField"); - } catch (Exception e) { - // expected - } - } -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Animal.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Animal.java deleted file mode 100644 index cd079ec290..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Animal.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa.domain; - -import java.util.Date; - -import javax.persistence.DiscriminatorValue; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.Table; -import javax.persistence.Temporal; -import javax.persistence.TemporalType; - -import org.hibernate.annotations.Type; - -/** - * The Class Animal. - */ -@Entity -@Table(name="animal_") -@DiscriminatorValue("A") -public class Animal { - private boolean alive; - - @Temporal(TemporalType.TIMESTAMP) - private java.util.Date birthdate; - - private int weight, toes; - - // needed for JPA tests - @Type(type="com.mysema.query.ExtDoubleType") - private double bodyWeight; - - private float floatProperty; - - private Color color; - -// @Temporal(TemporalType.DATE) - private java.sql.Date dateField; - - @Id - private int id; - - private String name; - - private java.sql.Time timeField; - - public Animal() {} - - public Animal(int id) { - setId(id); - } - - public java.util.Date getBirthdate() { - return new Date(birthdate.getTime()); - } - - public double getBodyWeight() { - return bodyWeight; - } - - public Color getColor() { - return color; - } - - public java.sql.Date getDateField() { - return new java.sql.Date(dateField.getTime()); - } - - public int getId() { - return id; - } - - public String getName() { - return name; - } - - public java.sql.Time getTimeField() { - return timeField; - } - - public int getToes() { - return toes; - } - - public int getWeight() { - return weight; - } - - public boolean isAlive() { - return alive; - } - - public void setAlive(boolean alive) { - this.alive = alive; - } - - public void setBirthdate(java.util.Date birthdate) { - this.birthdate = new java.util.Date(birthdate.getTime()); - } - - public void setBodyWeight(double bodyWeight) { - this.bodyWeight = bodyWeight; - } - - public void setColor(Color color) { - this.color = color; - } - - public void setDateField(java.sql.Date dateField) { - this.dateField = new java.sql.Date(dateField.getTime()); - } - - public void setId(int id) { - this.id = id; - } - - public void setName(String name) { - this.name = name; - } - - public void setTimeField(java.sql.Time timeField) { - this.timeField = timeField; - } - - public void setToes(int toes) { - this.toes = toes; - } - - public void setWeight(int weight) { - this.weight = weight; - } - - public float getFloatProperty() { - return floatProperty; - } - - public void setFloatProperty(float floatProperty) { - this.floatProperty = floatProperty; - } - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Author.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Author.java deleted file mode 100644 index 54a081cb3f..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Author.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.mysema.query.jpa.domain; - -import java.io.Serializable; -import java.util.Set; - -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import javax.persistence.OneToMany; -import javax.persistence.OrderBy; -import javax.persistence.Table; - -@Entity -@Table(name="author_") -public class Author implements Serializable { - - private static final long serialVersionUID = -1893968697250846661L; - - @Id - @GeneratedValue - private Long id; - - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - private String name; - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - @OneToMany(mappedBy = "author") - @OrderBy("title") - private Set<Book> books; - - public Set<Book> getBooks() { - return books; - } - - public void setBooks(Set<Book> books) { - this.books = books; - } -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Bar.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Bar.java deleted file mode 100644 index a6769c3a9b..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Bar.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa.domain; - -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.Table; -import javax.persistence.Temporal; -import javax.persistence.TemporalType; - -/** - * The Class Bar. - */ -@Entity -@Table(name="bar_") -public class Bar { - @Temporal(TemporalType.DATE) - java.util.Date date; - - @Id - int id; -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Book.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Book.java deleted file mode 100644 index b390e3b337..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Book.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.mysema.query.jpa.domain; - -import java.io.Serializable; - -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.Table; - -@Entity -@Table(name="book_") -public class Book implements Serializable { - - private static final long serialVersionUID = -9029792723035681319L; - - @Id - @GeneratedValue - private Long id; - - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - private String title; - - public String getTitle() { - return title; - } - - public void setTitle(String title) { - this.title = title; - } - - @ManyToOne - @JoinColumn(name = "AUTHOR_ID") - private Author author; - - public Author getAuthor() { - return author; - } - - public void setAuthor(Author author) { - this.author = author; - } -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Calendar.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Calendar.java deleted file mode 100644 index cb88c8701b..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Calendar.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa.domain; - -import java.io.Serializable; -import java.util.Map; - -import javax.persistence.ElementCollection; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.MapKeyColumn; -import javax.persistence.Table; -import javax.persistence.Temporal; -import javax.persistence.TemporalType; - - - -/** - * The Class Calendar. - */ -@SuppressWarnings("serial") -@Entity -@Table(name="calendar_") -public class Calendar implements Serializable{ - @ElementCollection - @Temporal(TemporalType.DATE) - @MapKeyColumn(name="holidays_key") - Map<String, java.util.Date> holidays; - - @Id - int id; -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Cat.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Cat.java deleted file mode 100644 index 0006125652..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Cat.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa.domain; - -import java.util.ArrayList; -import java.util.List; -import java.util.Set; - -import javax.persistence.DiscriminatorValue; -import javax.persistence.Entity; -import javax.persistence.JoinColumn; -import javax.persistence.JoinTable; -import javax.persistence.ManyToOne; -import javax.persistence.OneToMany; - -import org.hibernate.annotations.IndexColumn; - -/** - * The Class Cat. - */ -@Entity -@DiscriminatorValue("C") -public class Cat extends Animal { - - private int breed; - - private Color eyecolor; - - @OneToMany - @JoinTable(name = "kittens", joinColumns = @JoinColumn(name = "cat_id"), inverseJoinColumns = @JoinColumn(name = "kitten_id")) - @IndexColumn(name = "ind") - private List<Cat> kittens = new ArrayList<Cat>(); - - @OneToMany - @JoinTable(name = "kittens_set", joinColumns = @JoinColumn(name = "cat_id"), inverseJoinColumns = @JoinColumn(name = "kitten_id")) - private Set<Cat> kittensSet; - -// @OneToMany -// @JoinTable(name="kittens_array") -// @IndexColumn(name = "arrayIndex") -// private Cat[] kittensArray = new Cat[0]; - - @ManyToOne - private Cat mate; - - public Cat() {} - - public Cat(int id) { - setId(id); - } - - public Cat(String name, int id) { - setId(id); - setName( name); - } - - public Cat(String name, int id, Color color) { - setId(id); - setName( name); - setColor(color); - } - - public Cat(String name, int id, List<Cat> k) { - setId(id); - setName( name); - kittens.addAll(k); - } - - public Cat(String name, int id, double bodyWeight) { - this(name, id); - setBodyWeight(bodyWeight); - setFloatProperty((float)bodyWeight); - } - - public int getBreed() { - return breed; - } - - public Color getEyecolor() { - return eyecolor; - } - - public List<Cat> getKittens() { - return kittens; - } - - public Cat getMate() { - return mate; - } - -// public Cat[] getKittensArray() { -// return kittensArray; -// } - - public void addKitten(Cat kitten) { - kittens.add(kitten); -// kittensArray = new Cat[]{kitten}; - } - - public Set<Cat> getKittensSet() { - return kittensSet; - } - - public void setKittensSet(Set<Cat> kittensSet) { - this.kittensSet = kittensSet; - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Catalog.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Catalog.java deleted file mode 100644 index f563f87a0a..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Catalog.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa.domain; - -import java.util.Date; -import java.util.Set; - -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.OneToMany; -import javax.persistence.Table; -import javax.persistence.Temporal; -import javax.persistence.TemporalType; - -/** - * The Class Catalog. - */ -@Entity -@Table(name="catalog_") -public class Catalog { - @Temporal(TemporalType.DATE) - Date effectiveDate; - - @Id - int id; - - @OneToMany - Set<Price> prices; -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Child.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Child.java deleted file mode 100644 index e60d1c64fa..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Child.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.mysema.query.jpa.domain; - -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.ManyToOne; - -@Entity(name="Child2") -public class Child { - - @Id - int id; - - @ManyToOne - Parent parent; - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Color.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Color.java deleted file mode 100644 index 49431dd917..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Color.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa.domain; - -/** - * The Enum Color. - */ -public enum Color { - BLACK, TABBY -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Company.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Company.java deleted file mode 100644 index 1a510d3795..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Company.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa.domain; - -import java.util.List; - -import javax.persistence.Entity; -import javax.persistence.EnumType; -import javax.persistence.Enumerated; -import javax.persistence.Id; -import javax.persistence.ManyToOne; -import javax.persistence.OneToMany; -import javax.persistence.Table; - -import org.batoo.jpa.annotations.Index; - -/** - * The Class Company. - */ -@Entity -@Table(name="company_") -public class Company { - - public enum Rating { A, AA, AAA } - - @Enumerated - public Rating ratingOrdinal; - - @Enumerated(EnumType.STRING) - public Rating ratingString; - - @ManyToOne - public Employee ceo; - - @OneToMany - @Index(name = "_index") - public List<Department> departments; - - @Id - public int id; - - public String name; -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Customer.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Customer.java deleted file mode 100644 index 01e03f7161..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Customer.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa.domain; - -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.ManyToOne; -import javax.persistence.Table; - -/** - * The Class Customer. - */ -@Entity -@Table(name="customer_") -public class Customer { - @ManyToOne - Order currentOrder; - - @Id - int id; - - @ManyToOne - Name name; -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Department.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Department.java deleted file mode 100644 index d7c8c8b8d6..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Department.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa.domain; - -import java.util.List; - -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.ManyToOne; -import javax.persistence.OneToMany; -import javax.persistence.Table; - -import org.batoo.jpa.annotations.Index; - -/** - * The Class Department. - */ -@Entity -@Table(name="department_") -public class Department { - @ManyToOne - Company company; - - @OneToMany - @Index(name = "_index") - List<Employee> employees; - - @Id - int id; - - String name; -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Document.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Document.java deleted file mode 100644 index 488c4d6f4c..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Document.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa.domain; - -import java.util.Date; - -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.Table; -import javax.persistence.Temporal; -import javax.persistence.TemporalType; - -/** - * The Class Document. - */ -@Entity -@Table(name="document_") -public class Document { - @Id - int id; - - String name; - - @Temporal(TemporalType.DATE) - Date validTo; -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Dolphin.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Dolphin.java deleted file mode 100644 index 78f84a6c37..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Dolphin.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.mysema.query.jpa.domain; - -import javax.persistence.Entity; - -@Entity -public class Dolphin extends Mammal { - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/DoubleProjection.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/DoubleProjection.java deleted file mode 100644 index d7db43b1eb..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/DoubleProjection.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.mysema.query.jpa.domain; - -import com.mysema.query.annotations.QueryProjection; - -public class DoubleProjection { - - public double val; - - @QueryProjection - public DoubleProjection(double val) { - this.val = val; - } - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/EmbeddedType.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/EmbeddedType.java deleted file mode 100644 index 5fdb7cdd30..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/EmbeddedType.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa.domain; - -import java.io.Serializable; - -import javax.persistence.Embeddable; - -@SuppressWarnings("serial") -@Embeddable -public class EmbeddedType implements Serializable{ - - String someData; - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Employee.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Employee.java deleted file mode 100644 index 2db1928408..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Employee.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa.domain; - -import java.util.Collection; -import java.util.HashSet; - -import javax.persistence.Column; -import javax.persistence.ElementCollection; -import javax.persistence.Entity; -import javax.persistence.EnumType; -import javax.persistence.Enumerated; -import javax.persistence.FetchType; -import javax.persistence.Id; -import javax.persistence.ManyToOne; -import javax.persistence.OneToOne; -import javax.persistence.Table; - -/** - * The Class Employee. - */ -@Entity -@Table(name="employee_") -public class Employee { - @ManyToOne - public Company company; - - @OneToOne - public User user; - - public String firstName, lastName; - - @Id - public int id; - - @Enumerated(EnumType.STRING) - @Column(name = "jobfunction") - @ElementCollection (fetch = FetchType.EAGER) - public Collection<JobFunction> jobFunctions = new HashSet<JobFunction>(); - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Entity1.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Entity1.java deleted file mode 100644 index 662bc44c0b..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Entity1.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.mysema.query.jpa.domain; - -import javax.persistence.Entity; -import javax.persistence.Id; - -@Entity -public class Entity1 { - - public Entity1() {} - - public Entity1(int id) { - this.id = id; - } - - @Id - public int id; - - public String property; -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Entity2.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Entity2.java deleted file mode 100644 index 94a6ffb8be..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Entity2.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.mysema.query.jpa.domain; - -import javax.persistence.Entity; - -@Entity -public class Entity2 extends Entity1 { - - public Entity2() {} - - public Entity2(int id) { - this.id = id; - } - - public String property2; -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/FloatProjection.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/FloatProjection.java deleted file mode 100644 index 049df79d2c..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/FloatProjection.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.mysema.query.jpa.domain; - -import com.mysema.query.annotations.QueryProjection; - -public class FloatProjection { - - public float val; - - @QueryProjection - public FloatProjection(float val) { - this.val = val; - } - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Foo.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Foo.java deleted file mode 100644 index 57a204b422..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Foo.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa.domain; - -import java.util.List; - -import javax.persistence.CollectionTable; -import javax.persistence.ElementCollection; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.Table; -import javax.persistence.Temporal; -import javax.persistence.TemporalType; - -/** - * The Class Foo. - */ -@Entity -@Table(name="foo_") -public class Foo { - public String bar; - - @Id - //@GeneratedValue(strategy=GenerationType.AUTO) - public int id; - - @ElementCollection - @CollectionTable(name = "foo_names", joinColumns = {@JoinColumn(name="foo_id")}) - public List<String> names; - - @Temporal(TemporalType.DATE) - public java.util.Date startDate; -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Item.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Item.java deleted file mode 100644 index c37b059cdd..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Item.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa.domain; - -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.ManyToOne; -import javax.persistence.Table; - -/** - * The Class Item. - */ -@Entity -@Table(name="item_") -public class Item { - @Id - long id; - - @ManyToOne - Product product; -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Location.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Location.java deleted file mode 100644 index af4ddfa735..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Location.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa.domain; - -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.Table; - -/** - * The Class Location. - */ -@Entity(name="Location2") -@Table(name="location_") -public class Location { - @Id - long id; - - String name; -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Mammal.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Mammal.java deleted file mode 100644 index b3f9dd04c4..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Mammal.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.mysema.query.jpa.domain; - -import javax.persistence.Entity; -import javax.persistence.Id; - -@Entity -public class Mammal { - - @Id - Long id; - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Order.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Order.java deleted file mode 100644 index 881ab9bb4d..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Order.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa.domain; - -import java.util.List; - -import javax.persistence.ElementCollection; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.JoinTable; -import javax.persistence.ManyToOne; -import javax.persistence.OneToMany; -import javax.persistence.Table; - -import org.hibernate.annotations.IndexColumn; - -/** - * The Class Order. - */ -@Entity -@Table(name="order_") -public class Order { - @ManyToOne - Customer customer; - - @ElementCollection - @IndexColumn(name = "_index") - List<Integer> deliveredItemIndices; - - @Id - long id; - - @OneToMany - @IndexColumn(name = "_index") - List<Item> items; - - @OneToMany - @JoinTable(name = "LineItems") - @IndexColumn(name = "_index") - List<Item> lineItems; - - boolean paid; -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Parameter.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Parameter.java deleted file mode 100644 index 62ced9a8ed..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Parameter.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa.domain; - -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.Table; - -/** - * The Class Parameter. - */ -@Entity -@Table(name="parameter_") -public class Parameter { - @Id - long id; -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Parent.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Parent.java deleted file mode 100644 index e72db69244..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Parent.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.mysema.query.jpa.domain; - -import java.util.Set; - -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.OneToMany; - -@Entity(name="Parent2") -public class Parent { - - @Id - int id; - - @OneToMany(mappedBy = "parent") - Set<Child> children; - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Person.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Person.java deleted file mode 100644 index 43b5505a9c..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Person.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa.domain; - -import java.io.Serializable; - -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.ManyToOne; -import javax.persistence.Table; -import javax.persistence.Temporal; -import javax.persistence.TemporalType; - -import com.mysema.query.annotations.QueryInit; - -/** - * The Class Person. - */ -@SuppressWarnings("serial") -@Entity -@Table(name="person_") -public class Person implements Serializable{ - @Temporal(TemporalType.DATE) - java.util.Date birthDay; - - @Id - long i; - - @ManyToOne - PersonId pid; - - String name; - - @ManyToOne - @QueryInit("calendar") - Nationality nationality; -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Product.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Product.java deleted file mode 100644 index e74f463283..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Product.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa.domain; - -import javax.persistence.Entity; - -/** - * The Class Product. - */ -@Entity -public class Product extends Item { - // @Id long id; - String name; -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Show.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Show.java deleted file mode 100644 index 35368de2dc..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Show.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa.domain; - -import java.util.Map; - -import javax.persistence.ElementCollection; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.MapKeyColumn; -import javax.persistence.Table; - -/** - * The Class Show. - */ -@Entity -@Table(name="show_") -public class Show { - - @Id - long id; - - @ElementCollection - @MapKeyColumn(name="acts_key") - public Map<String, String> acts; - - public Show() {} - - public Show(int id) { - this.id = id; - } - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Status.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Status.java deleted file mode 100644 index ac2f31176e..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Status.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa.domain; - -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.Table; - -/** - * The Class Status. - */ -@Entity -@Table(name="status_") -public class Status { - @Id - long id; - - String name; -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/StatusChange.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/StatusChange.java deleted file mode 100644 index 4316f81db1..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/StatusChange.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa.domain; - -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.Table; -import javax.persistence.Temporal; -import javax.persistence.TemporalType; - -/** - * The Class StatusChange. - */ -@Entity -@Table(name="statuschange_") -public class StatusChange { - @Id - long id; - - @Temporal(TemporalType.TIMESTAMP) - java.util.Date timeStamp; -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Store.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Store.java deleted file mode 100644 index 9ae589ef3e..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Store.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa.domain; - -import java.util.List; - -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.ManyToOne; -import javax.persistence.OneToMany; -import javax.persistence.Table; - -/** - * The Class Store. - */ -@Entity -@Table(name="store_") -public class Store { - @OneToMany - List<Customer> customers; - - @Id - long id; - - @ManyToOne - Location location; -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Superclass.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Superclass.java deleted file mode 100644 index 92f9cd995d..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Superclass.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa.domain; - -import javax.persistence.MappedSuperclass; - -import com.mysema.query.annotations.PropertyType; -import com.mysema.query.annotations.QueryType; - -@MappedSuperclass -public class Superclass { - String superclassProperty; - - @QueryType(PropertyType.SIMPLE) - private String stringAsSimple; - - public String getStringAsSimple() { - return stringAsSimple; - } - - public void setStringAsSimple(String stringAsSimple) { - this.stringAsSimple = stringAsSimple; - } - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/User.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/User.java deleted file mode 100644 index 5d01d05a4f..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/User.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa.domain; - -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.ManyToOne; -import javax.persistence.Table; - -/** - * The Class User. - */ -@Entity -@Table(name="user_") -public class User { - @ManyToOne - Company company; - - @Id - long id; - - String userName, firstName, lastName; -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/package-info.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/package-info.java deleted file mode 100644 index 5da2082310..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/package-info.java +++ /dev/null @@ -1,9 +0,0 @@ -/* - * Copyright (c) 2009 Mysema Ltd. - * All rights reserved. - * - */ -@Config(listAccessors=true, mapAccessors=true) -package com.mysema.query.jpa.domain; -import com.mysema.query.annotations.Config; - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SAccount.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SAccount.java deleted file mode 100644 index 7814707998..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SAccount.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - - -/** - * SAccount is a Querydsl query type for SAccount - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SAccount extends com.mysema.query.sql.RelationalPathBase<SAccount> { - - private static final long serialVersionUID = -1514613821; - - public static final SAccount account_ = new SAccount("account_"); - - public final NumberPath<Long> id = createNumber("id", Long.class); - - public final NumberPath<Long> ownerI = createNumber("ownerI", Long.class); - - public final StringPath someData = createString("someData"); - - public final com.mysema.query.sql.PrimaryKey<SAccount> primary = createPrimaryKey(id); - - public final com.mysema.query.sql.ForeignKey<SPerson> fk809dbbd28cfac74 = createForeignKey(ownerI, "i"); - - public SAccount(String variable) { - super(SAccount.class, forVariable(variable), "null", "account_"); - addMetadata(); - } - - public SAccount(String variable, String schema, String table) { - super(SAccount.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SAccount(Path<? extends SAccount> path) { - super(path.getType(), path.getMetadata(), "null", "account_"); - addMetadata(); - } - - public SAccount(PathMetadata<?> metadata) { - super(SAccount.class, metadata, "null", "account_"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(-5).withSize(19).notNull()); - addMetadata(ownerI, ColumnMetadata.named("owner_i").withIndex(3).ofType(-5).withSize(19)); - addMetadata(someData, ColumnMetadata.named("someData").withIndex(2).ofType(12).withSize(255)); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SAnimal.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SAnimal.java deleted file mode 100644 index ce9844546e..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SAnimal.java +++ /dev/null @@ -1,107 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - - -/** - * SAnimal is a Querydsl query type for SAnimal - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SAnimal extends com.mysema.query.sql.RelationalPathBase<SAnimal> { - - private static final long serialVersionUID = 1795545042; - - public static final SAnimal animal_ = new SAnimal("animal_"); - - public final BooleanPath alive = createBoolean("alive"); - - public final DateTimePath<java.sql.Timestamp> birthdate = createDateTime("birthdate", java.sql.Timestamp.class); - - public final NumberPath<Double> bodyWeight = createNumber("bodyWeight", Double.class); - - public final NumberPath<Integer> breed = createNumber("breed", Integer.class); - - public final NumberPath<Integer> color = createNumber("color", Integer.class); - - public final DatePath<java.sql.Date> dateField = createDate("dateField", java.sql.Date.class); - - public final StringPath dtype = createString("dtype"); - - public final NumberPath<Integer> eyecolor = createNumber("eyecolor", Integer.class); - - public final NumberPath<Float> floatProperty = createNumber("floatProperty", Float.class); - - public final NumberPath<Integer> id = createNumber("id", Integer.class); - - public final NumberPath<Integer> mateId = createNumber("mateId", Integer.class); - - public final StringPath name = createString("name"); - - public final TimePath<java.sql.Time> timeField = createTime("timeField", java.sql.Time.class); - - public final NumberPath<Integer> toes = createNumber("toes", Integer.class); - - public final NumberPath<Integer> weight = createNumber("weight", Integer.class); - - public final com.mysema.query.sql.PrimaryKey<SAnimal> primary = createPrimaryKey(id); - - public final com.mysema.query.sql.ForeignKey<SAnimal> fkccec31e312a37469 = createForeignKey(mateId, "id"); - - public final com.mysema.query.sql.ForeignKey<SKittens> _fkd60087cc3881aaa7 = createInvForeignKey(id, "kitten_id"); - - public final com.mysema.query.sql.ForeignKey<SAnimal> _fkccec31e312a37469 = createInvForeignKey(id, "mate_id"); - - public final com.mysema.query.sql.ForeignKey<SKittensSet> _fk4fccad6f8f00fdf8 = createInvForeignKey(id, "cat_id"); - - public final com.mysema.query.sql.ForeignKey<SKittens> _fkd60087cc8f00fdf8 = createInvForeignKey(id, "cat_id"); - - public final com.mysema.query.sql.ForeignKey<SKittensSet> _fk4fccad6f3881aaa7 = createInvForeignKey(id, "kitten_id"); - - public SAnimal(String variable) { - super(SAnimal.class, forVariable(variable), "null", "animal_"); - addMetadata(); - } - - public SAnimal(String variable, String schema, String table) { - super(SAnimal.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SAnimal(Path<? extends SAnimal> path) { - super(path.getType(), path.getMetadata(), "null", "animal_"); - addMetadata(); - } - - public SAnimal(PathMetadata<?> metadata) { - super(SAnimal.class, metadata, "null", "animal_"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(alive, ColumnMetadata.named("alive").withIndex(3).ofType(-7).notNull()); - addMetadata(birthdate, ColumnMetadata.named("birthdate").withIndex(4).ofType(93).withSize(19)); - addMetadata(bodyWeight, ColumnMetadata.named("bodyWeight").withIndex(5).ofType(8).withSize(22).notNull()); - addMetadata(breed, ColumnMetadata.named("breed").withIndex(13).ofType(4).withSize(10)); - addMetadata(color, ColumnMetadata.named("color").withIndex(6).ofType(4).withSize(10)); - addMetadata(dateField, ColumnMetadata.named("dateField").withIndex(7).ofType(91).withSize(10)); - addMetadata(dtype, ColumnMetadata.named("DTYPE").withIndex(1).ofType(12).withSize(31).notNull()); - addMetadata(eyecolor, ColumnMetadata.named("eyecolor").withIndex(14).ofType(4).withSize(10)); - addMetadata(floatProperty, ColumnMetadata.named("floatProperty").withIndex(8).ofType(7).withSize(12).notNull()); - addMetadata(id, ColumnMetadata.named("id").withIndex(2).ofType(4).withSize(10).notNull()); - addMetadata(mateId, ColumnMetadata.named("mate_id").withIndex(15).ofType(4).withSize(10)); - addMetadata(name, ColumnMetadata.named("name").withIndex(9).ofType(12).withSize(255)); - addMetadata(timeField, ColumnMetadata.named("timeField").withIndex(10).ofType(92).withSize(8)); - addMetadata(toes, ColumnMetadata.named("toes").withIndex(11).ofType(4).withSize(10).notNull()); - addMetadata(weight, ColumnMetadata.named("weight").withIndex(12).ofType(4).withSize(10).notNull()); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SAuditlog.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SAuditlog.java deleted file mode 100644 index 7aeec671d6..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SAuditlog.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - - -/** - * SAuditlog is a Querydsl query type for SAuditlog - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SAuditlog extends com.mysema.query.sql.RelationalPathBase<SAuditlog> { - - private static final long serialVersionUID = -1982799323; - - public static final SAuditlog auditlog_ = new SAuditlog("auditlog_"); - - public final NumberPath<Integer> id = createNumber("id", Integer.class); - - public final NumberPath<Long> itemId = createNumber("itemId", Long.class); - - public final com.mysema.query.sql.PrimaryKey<SAuditlog> primary = createPrimaryKey(id); - - public final com.mysema.query.sql.ForeignKey<SItem> fkb88fbf6ae26109c = createForeignKey(itemId, "id"); - - public SAuditlog(String variable) { - super(SAuditlog.class, forVariable(variable), "null", "auditlog_"); - addMetadata(); - } - - public SAuditlog(String variable, String schema, String table) { - super(SAuditlog.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SAuditlog(Path<? extends SAuditlog> path) { - super(path.getType(), path.getMetadata(), "null", "auditlog_"); - addMetadata(); - } - - public SAuditlog(PathMetadata<?> metadata) { - super(SAuditlog.class, metadata, "null", "auditlog_"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(4).withSize(10).notNull()); - addMetadata(itemId, ColumnMetadata.named("item_id").withIndex(2).ofType(-5).withSize(19)); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SAuthor.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SAuthor.java deleted file mode 100644 index 4e10f626bd..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SAuthor.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - - -/** - * SAuthor is a Querydsl query type for SAuthor - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SAuthor extends com.mysema.query.sql.RelationalPathBase<SAuthor> { - - private static final long serialVersionUID = 2005972515; - - public static final SAuthor author_ = new SAuthor("author_"); - - public final NumberPath<Long> id = createNumber("id", Long.class); - - public final StringPath name = createString("name"); - - public final com.mysema.query.sql.PrimaryKey<SAuthor> primary = createPrimaryKey(id); - - public final com.mysema.query.sql.ForeignKey<SBook> _fk599229686eaf51c = createInvForeignKey(id, "AUTHOR_ID"); - - public SAuthor(String variable) { - super(SAuthor.class, forVariable(variable), "null", "author_"); - addMetadata(); - } - - public SAuthor(String variable, String schema, String table) { - super(SAuthor.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SAuthor(Path<? extends SAuthor> path) { - super(path.getType(), path.getMetadata(), "null", "author_"); - addMetadata(); - } - - public SAuthor(PathMetadata<?> metadata) { - super(SAuthor.class, metadata, "null", "author_"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(-5).withSize(19).notNull()); - addMetadata(name, ColumnMetadata.named("name").withIndex(2).ofType(12).withSize(255)); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SBar.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SBar.java deleted file mode 100644 index ae2c5e253a..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SBar.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - - -/** - * SBar is a Querydsl query type for SBar - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SBar extends com.mysema.query.sql.RelationalPathBase<SBar> { - - private static final long serialVersionUID = -1389576419; - - public static final SBar bar_ = new SBar("bar_"); - - public final DatePath<java.sql.Date> date = createDate("date", java.sql.Date.class); - - public final NumberPath<Integer> id = createNumber("id", Integer.class); - - public final com.mysema.query.sql.PrimaryKey<SBar> primary = createPrimaryKey(id); - - public SBar(String variable) { - super(SBar.class, forVariable(variable), "null", "bar_"); - addMetadata(); - } - - public SBar(String variable, String schema, String table) { - super(SBar.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SBar(Path<? extends SBar> path) { - super(path.getType(), path.getMetadata(), "null", "bar_"); - addMetadata(); - } - - public SBar(PathMetadata<?> metadata) { - super(SBar.class, metadata, "null", "bar_"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(date, ColumnMetadata.named("date").withIndex(2).ofType(91).withSize(10)); - addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(4).withSize(10).notNull()); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SBook.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SBook.java deleted file mode 100644 index 574121e5f9..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SBook.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - - -/** - * SBook is a Querydsl query type for SBook - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SBook extends com.mysema.query.sql.RelationalPathBase<SBook> { - - private static final long serialVersionUID = -126781371; - - public static final SBook book_ = new SBook("book_"); - - public final NumberPath<Long> authorId = createNumber("authorId", Long.class); - - public final StringPath dtype = createString("dtype"); - - public final NumberPath<Long> id = createNumber("id", Long.class); - - public final StringPath title = createString("title"); - - public final com.mysema.query.sql.PrimaryKey<SBook> primary = createPrimaryKey(id); - - public final com.mysema.query.sql.ForeignKey<SAuthor> fk599229686eaf51c = createForeignKey(authorId, "id"); - - public SBook(String variable) { - super(SBook.class, forVariable(variable), "null", "book_"); - addMetadata(); - } - - public SBook(String variable, String schema, String table) { - super(SBook.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SBook(Path<? extends SBook> path) { - super(path.getType(), path.getMetadata(), "null", "book_"); - addMetadata(); - } - - public SBook(PathMetadata<?> metadata) { - super(SBook.class, metadata, "null", "book_"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(authorId, ColumnMetadata.named("AUTHOR_ID").withIndex(4).ofType(-5).withSize(19)); - addMetadata(dtype, ColumnMetadata.named("DTYPE").withIndex(1).ofType(12).withSize(31).notNull()); - addMetadata(id, ColumnMetadata.named("id").withIndex(2).ofType(-5).withSize(19).notNull()); - addMetadata(title, ColumnMetadata.named("title").withIndex(3).ofType(12).withSize(255)); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SBookBookmarks.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SBookBookmarks.java deleted file mode 100644 index 030623dd86..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SBookBookmarks.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import java.util.*; - -import com.mysema.query.sql.ColumnMetadata; - - -/** - * SBookBookmarks is a Querydsl query type for SBookBookmarks - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SBookBookmarks extends com.mysema.query.sql.RelationalPathBase<SBookBookmarks> { - - private static final long serialVersionUID = -312126525; - - public static final SBookBookmarks bookBookmarks = new SBookBookmarks("book_bookmarks"); - - public final NumberPath<Integer> bookMarksORDER = createNumber("bookMarksORDER", Integer.class); - - public final NumberPath<Long> bookVersionBookIDIdentity = createNumber("bookVersionBookIDIdentity", Long.class); - - public final NumberPath<Long> bookVersionLibraryIdentity = createNumber("bookVersionLibraryIdentity", Long.class); - - public final StringPath comment = createString("comment"); - - public final NumberPath<Long> page = createNumber("page", Long.class); - - public final com.mysema.query.sql.PrimaryKey<SBookBookmarks> primary = createPrimaryKey(bookVersionBookIDIdentity, bookVersionLibraryIdentity, bookMarksORDER); - - public final com.mysema.query.sql.ForeignKey<SBookversion> fk94026827e33d3be4 = createForeignKey(Arrays.asList(bookVersionBookIDIdentity, bookVersionLibraryIdentity), Arrays.asList("bookID_identity", "library_identity")); - - public SBookBookmarks(String variable) { - super(SBookBookmarks.class, forVariable(variable), "null", "book_bookmarks"); - addMetadata(); - } - - public SBookBookmarks(String variable, String schema, String table) { - super(SBookBookmarks.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SBookBookmarks(Path<? extends SBookBookmarks> path) { - super(path.getType(), path.getMetadata(), "null", "book_bookmarks"); - addMetadata(); - } - - public SBookBookmarks(PathMetadata<?> metadata) { - super(SBookBookmarks.class, metadata, "null", "book_bookmarks"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(bookMarksORDER, ColumnMetadata.named("bookMarks_ORDER").withIndex(5).ofType(4).withSize(10).notNull()); - addMetadata(bookVersionBookIDIdentity, ColumnMetadata.named("BookVersion_bookID_identity").withIndex(1).ofType(-5).withSize(19).notNull()); - addMetadata(bookVersionLibraryIdentity, ColumnMetadata.named("BookVersion_library_identity").withIndex(2).ofType(-5).withSize(19).notNull()); - addMetadata(comment, ColumnMetadata.named("comment").withIndex(3).ofType(12).withSize(255)); - addMetadata(page, ColumnMetadata.named("page").withIndex(4).ofType(-5).withSize(19)); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SBookid.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SBookid.java deleted file mode 100644 index 13bc351255..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SBookid.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - - -/** - * SBookid is a Querydsl query type for SBookid - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SBookid extends com.mysema.query.sql.RelationalPathBase<SBookid> { - - private static final long serialVersionUID = -1577800438; - - public static final SBookid bookid_ = new SBookid("bookid_"); - - public final NumberPath<Long> identity = createNumber("identity", Long.class); - - public final com.mysema.query.sql.PrimaryKey<SBookid> primary = createPrimaryKey(identity); - - public final com.mysema.query.sql.ForeignKey<SBookversion> _fkef4bc0704dd5d6c3 = createInvForeignKey(identity, "bookID_identity"); - - public SBookid(String variable) { - super(SBookid.class, forVariable(variable), "null", "bookid_"); - addMetadata(); - } - - public SBookid(String variable, String schema, String table) { - super(SBookid.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SBookid(Path<? extends SBookid> path) { - super(path.getType(), path.getMetadata(), "null", "bookid_"); - addMetadata(); - } - - public SBookid(PathMetadata<?> metadata) { - super(SBookid.class, metadata, "null", "bookid_"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(identity, ColumnMetadata.named("identity").withIndex(1).ofType(-5).withSize(19).notNull()); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SBookversion.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SBookversion.java deleted file mode 100644 index 202f89af5c..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SBookversion.java +++ /dev/null @@ -1,70 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import java.util.*; - -import com.mysema.query.sql.ColumnMetadata; - - -/** - * SBookversion is a Querydsl query type for SBookversion - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SBookversion extends com.mysema.query.sql.RelationalPathBase<SBookversion> { - - private static final long serialVersionUID = 1615296481; - - public static final SBookversion bookversion_ = new SBookversion("bookversion_"); - - public final NumberPath<Long> bookIDIdentity = createNumber("bookIDIdentity", Long.class); - - public final StringPath description = createString("description"); - - public final NumberPath<Long> libraryIdentity = createNumber("libraryIdentity", Long.class); - - public final StringPath name = createString("name"); - - public final com.mysema.query.sql.PrimaryKey<SBookversion> primary = createPrimaryKey(bookIDIdentity, libraryIdentity); - - public final com.mysema.query.sql.ForeignKey<SBookid> fkef4bc0704dd5d6c3 = createForeignKey(bookIDIdentity, "identity"); - - public final com.mysema.query.sql.ForeignKey<SLibrary> fkef4bc070e364cd17 = createForeignKey(libraryIdentity, "identity"); - - public final com.mysema.query.sql.ForeignKey<SBookBookmarks> _fk94026827e33d3be4 = createInvForeignKey(Arrays.asList(bookIDIdentity, libraryIdentity), Arrays.asList("BookVersion_bookID_identity", "BookVersion_library_identity")); - - public SBookversion(String variable) { - super(SBookversion.class, forVariable(variable), "null", "bookversion_"); - addMetadata(); - } - - public SBookversion(String variable, String schema, String table) { - super(SBookversion.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SBookversion(Path<? extends SBookversion> path) { - super(path.getType(), path.getMetadata(), "null", "bookversion_"); - addMetadata(); - } - - public SBookversion(PathMetadata<?> metadata) { - super(SBookversion.class, metadata, "null", "bookversion_"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(bookIDIdentity, ColumnMetadata.named("bookID_identity").withIndex(3).ofType(-5).withSize(19).notNull()); - addMetadata(description, ColumnMetadata.named("description").withIndex(1).ofType(12).withSize(255)); - addMetadata(libraryIdentity, ColumnMetadata.named("library_identity").withIndex(4).ofType(-5).withSize(19).notNull()); - addMetadata(name, ColumnMetadata.named("name").withIndex(2).ofType(12).withSize(255)); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SCalendar.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SCalendar.java deleted file mode 100644 index fa8e2fe665..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SCalendar.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import com.mysema.query.sql.ColumnMetadata; -import com.mysema.query.types.Path; -import com.mysema.query.types.PathMetadata; -import com.mysema.query.types.path.NumberPath; - -import javax.annotation.Generated; - -import static com.mysema.query.types.PathMetadataFactory.forVariable; - - -/** - * SCalendar is a Querydsl query type for SCalendar - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SCalendar extends com.mysema.query.sql.RelationalPathBase<SCalendar> { - - private static final long serialVersionUID = 885543696; - - public static final SCalendar calendar_ = new SCalendar("calendar_"); - - public final NumberPath<Integer> id = createNumber("id", Integer.class); - - public final com.mysema.query.sql.PrimaryKey<SCalendar> primary = createPrimaryKey(id); - - public final com.mysema.query.sql.ForeignKey<SCalendarHolidays> _fk31ce1edc591ebbc = createInvForeignKey(id, "Calendar_id"); - - public final com.mysema.query.sql.ForeignKey<SNationality> _fkab8efa23591ebbc = createInvForeignKey(id, "calendar_id"); - - public SCalendar(String variable) { - super(SCalendar.class, forVariable(variable), "null", "calendar_"); - addMetadata(); - } - - public SCalendar(String variable, String schema, String table) { - super(SCalendar.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SCalendar(Path<? extends SCalendar> path) { - super(path.getType(), path.getMetadata(), "null", "calendar_"); - addMetadata(); - } - - public SCalendar(PathMetadata<?> metadata) { - super(SCalendar.class, metadata, "null", "calendar_"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(4).withSize(10).notNull()); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SCalendarHolidays.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SCalendarHolidays.java deleted file mode 100644 index 3b9fe385f6..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SCalendarHolidays.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - - -/** - * SCalendarHolidays is a Querydsl query type for SCalendarHolidays - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SCalendarHolidays extends com.mysema.query.sql.RelationalPathBase<SCalendarHolidays> { - - private static final long serialVersionUID = 850508650; - - public static final SCalendarHolidays CalendarHolidays = new SCalendarHolidays("Calendar_holidays"); - - public final NumberPath<Integer> calendarId = createNumber("calendarId", Integer.class); - - public final DatePath<java.sql.Date> holidays = createDate("holidays", java.sql.Date.class); - - public final StringPath holidaysKEY = createString("holidaysKEY"); - - public final com.mysema.query.sql.PrimaryKey<SCalendarHolidays> primary = createPrimaryKey(calendarId, holidaysKEY); - - public final com.mysema.query.sql.ForeignKey<SCalendar> fk31ce1edc591ebbc = createForeignKey(calendarId, "id"); - - public SCalendarHolidays(String variable) { - super(SCalendarHolidays.class, forVariable(variable), "null", "Calendar_holidays"); - addMetadata(); - } - - public SCalendarHolidays(String variable, String schema, String table) { - super(SCalendarHolidays.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SCalendarHolidays(Path<? extends SCalendarHolidays> path) { - super(path.getType(), path.getMetadata(), "null", "Calendar_holidays"); - addMetadata(); - } - - public SCalendarHolidays(PathMetadata<?> metadata) { - super(SCalendarHolidays.class, metadata, "null", "Calendar_holidays"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(calendarId, ColumnMetadata.named("Calendar_id").withIndex(1).ofType(4).withSize(10).notNull()); - addMetadata(holidays, ColumnMetadata.named("holidays").withIndex(2).ofType(91).withSize(10)); - addMetadata(holidaysKEY, ColumnMetadata.named("holidays_KEY").withIndex(3).ofType(12).withSize(255).notNull()); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SCatalog.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SCatalog.java deleted file mode 100644 index df33c7c8a7..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SCatalog.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - - -/** - * SCatalog is a Querydsl query type for SCatalog - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SCatalog extends com.mysema.query.sql.RelationalPathBase<SCatalog> { - - private static final long serialVersionUID = 669498199; - - public static final SCatalog catalog_ = new SCatalog("catalog_"); - - public final DatePath<java.sql.Date> effectiveDate = createDate("effectiveDate", java.sql.Date.class); - - public final NumberPath<Integer> id = createNumber("id", Integer.class); - - public final com.mysema.query.sql.PrimaryKey<SCatalog> primary = createPrimaryKey(id); - - public final com.mysema.query.sql.ForeignKey<SCatalog_price> _fkaa04532fbb9021ab = createInvForeignKey(id, "catalog__id"); - - public SCatalog(String variable) { - super(SCatalog.class, forVariable(variable), "null", "catalog_"); - addMetadata(); - } - - public SCatalog(String variable, String schema, String table) { - super(SCatalog.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SCatalog(Path<? extends SCatalog> path) { - super(path.getType(), path.getMetadata(), "null", "catalog_"); - addMetadata(); - } - - public SCatalog(PathMetadata<?> metadata) { - super(SCatalog.class, metadata, "null", "catalog_"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(effectiveDate, ColumnMetadata.named("effectiveDate").withIndex(2).ofType(91).withSize(10)); - addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(4).withSize(10).notNull()); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SCatalog_price.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SCatalog_price.java deleted file mode 100644 index 09eab12675..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SCatalog_price.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - - -/** - * SCatalog_price is a Querydsl query type for SCatalog_price - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SCatalog_price extends com.mysema.query.sql.RelationalPathBase<SCatalog_price> { - - private static final long serialVersionUID = 1271141965; - - public static final SCatalog_price catalog_price_ = new SCatalog_price("catalog__price_"); - - public final NumberPath<Integer> catalog_id = createNumber("catalog_id", Integer.class); - - public final NumberPath<Long> pricesId = createNumber("pricesId", Long.class); - - public final com.mysema.query.sql.PrimaryKey<SCatalog_price> primary = createPrimaryKey(catalog_id, pricesId); - - public final com.mysema.query.sql.ForeignKey<SCatalog> fkaa04532fbb9021ab = createForeignKey(catalog_id, "id"); - - public final com.mysema.query.sql.ForeignKey<SPrice> fkaa04532f5222eaf7 = createForeignKey(pricesId, "id"); - - public SCatalog_price(String variable) { - super(SCatalog_price.class, forVariable(variable), "null", "catalog__price_"); - addMetadata(); - } - - public SCatalog_price(String variable, String schema, String table) { - super(SCatalog_price.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SCatalog_price(Path<? extends SCatalog_price> path) { - super(path.getType(), path.getMetadata(), "null", "catalog__price_"); - addMetadata(); - } - - public SCatalog_price(PathMetadata<?> metadata) { - super(SCatalog_price.class, metadata, "null", "catalog__price_"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(catalog_id, ColumnMetadata.named("catalog__id").withIndex(1).ofType(4).withSize(10).notNull()); - addMetadata(pricesId, ColumnMetadata.named("prices_id").withIndex(2).ofType(-5).withSize(19).notNull()); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SCategory.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SCategory.java deleted file mode 100644 index 773a0704f8..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SCategory.java +++ /dev/null @@ -1,86 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import com.mysema.query.sql.ColumnMetadata; -import com.mysema.query.types.Path; -import com.mysema.query.types.PathMetadata; -import com.mysema.query.types.path.DateTimePath; -import com.mysema.query.types.path.NumberPath; -import com.mysema.query.types.path.StringPath; - -import javax.annotation.Generated; - -import static com.mysema.query.types.PathMetadataFactory.forVariable; - - -/** - * SCategory is a Querydsl query type for SCategory - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SCategory extends com.mysema.query.sql.RelationalPathBase<SCategory> { - - private static final long serialVersionUID = -610481840; - - public static final SCategory category_ = new SCategory("category_"); - - public final StringPath categoryDescription = createString("categoryDescription"); - - public final StringPath categoryName = createString("categoryName"); - - public final NumberPath<Double> createdBy = createNumber("createdBy", Double.class); - - public final DateTimePath<java.sql.Timestamp> creationDate = createDateTime("creationDate", java.sql.Timestamp.class); - - public final DateTimePath<java.sql.Timestamp> deleteDate = createDateTime("deleteDate", java.sql.Timestamp.class); - - public final NumberPath<Double> deletedBy = createNumber("deletedBy", Double.class); - - public final NumberPath<Long> id = createNumber("id", Long.class); - - public final DateTimePath<java.sql.Timestamp> modificationDate = createDateTime("modificationDate", java.sql.Timestamp.class); - - public final NumberPath<Double> modifiedBy = createNumber("modifiedBy", Double.class); - - public final com.mysema.query.sql.PrimaryKey<SCategory> primary = createPrimaryKey(id); - - public final com.mysema.query.sql.ForeignKey<SCategory_category> _fkc4e60b83561378ab = createInvForeignKey(id, "parentId"); - - public final com.mysema.query.sql.ForeignKey<SUserprop_category> _fk851f48d37ab543e8 = createInvForeignKey(id, "childCategories_id"); - - public final com.mysema.query.sql.ForeignKey<SCategory_categoryprop> _fk8543a2802974945f = createInvForeignKey(id, "category__id"); - - public final com.mysema.query.sql.ForeignKey<SCategory_category> _fkc4e60b833c83109d = createInvForeignKey(id, "childId"); - - public SCategory(String variable) { - super(SCategory.class, forVariable(variable), "null", "category_"); - addMetadata(); - } - - public SCategory(String variable, String schema, String table) { - super(SCategory.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SCategory(Path<? extends SCategory> path) { - super(path.getType(), path.getMetadata(), "null", "category_"); - addMetadata(); - } - - public SCategory(PathMetadata<?> metadata) { - super(SCategory.class, metadata, "null", "category_"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(categoryDescription, ColumnMetadata.named("categoryDescription").withIndex(2).ofType(12).withSize(255)); - addMetadata(categoryName, ColumnMetadata.named("categoryName").withIndex(3).ofType(12).withSize(255)); - addMetadata(createdBy, ColumnMetadata.named("createdBy").withIndex(4).ofType(8).withSize(22).notNull()); - addMetadata(creationDate, ColumnMetadata.named("creationDate").withIndex(5).ofType(93).withSize(19)); - addMetadata(deleteDate, ColumnMetadata.named("deleteDate").withIndex(6).ofType(93).withSize(19)); - addMetadata(deletedBy, ColumnMetadata.named("deletedBy").withIndex(7).ofType(8).withSize(22).notNull()); - addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(-5).withSize(19).notNull()); - addMetadata(modificationDate, ColumnMetadata.named("modificationDate").withIndex(8).ofType(93).withSize(19)); - addMetadata(modifiedBy, ColumnMetadata.named("modifiedBy").withIndex(9).ofType(8).withSize(22).notNull()); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SCategory_category.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SCategory_category.java deleted file mode 100644 index 411225ed64..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SCategory_category.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import com.mysema.query.sql.ColumnMetadata; -import com.mysema.query.types.Path; -import com.mysema.query.types.PathMetadata; -import com.mysema.query.types.path.NumberPath; - -import javax.annotation.Generated; - -import static com.mysema.query.types.PathMetadataFactory.forVariable; - - -/** - * SCategory_category_ is a Querydsl query type for SCategory_category_ - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SCategory_category extends com.mysema.query.sql.RelationalPathBase<SCategory_category> { - - private static final long serialVersionUID = -771910703; - - public static final SCategory_category category_category_ = new SCategory_category("category__category_"); - - public final NumberPath<Long> childId = createNumber("childId", Long.class); - - public final NumberPath<Long> parentId = createNumber("parentId", Long.class); - - public final com.mysema.query.sql.PrimaryKey<SCategory_category> primary = createPrimaryKey(childId, parentId); - - public final com.mysema.query.sql.ForeignKey<SCategory> fkc4e60b83561378ab = createForeignKey(parentId, "id"); - - public final com.mysema.query.sql.ForeignKey<SCategory> fkc4e60b833c83109d = createForeignKey(childId, "id"); - - public SCategory_category(String variable) { - super(SCategory_category.class, forVariable(variable), "null", "category__category_"); - addMetadata(); - } - - public SCategory_category(String variable, String schema, String table) { - super(SCategory_category.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SCategory_category(Path<? extends SCategory_category> path) { - super(path.getType(), path.getMetadata(), "null", "category__category_"); - addMetadata(); - } - - public SCategory_category(PathMetadata<?> metadata) { - super(SCategory_category.class, metadata, "null", "category__category_"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(childId, ColumnMetadata.named("childId").withIndex(2).ofType(-5).withSize(19).notNull()); - addMetadata(parentId, ColumnMetadata.named("parentId").withIndex(1).ofType(-5).withSize(19).notNull()); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SCategory_categoryprop.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SCategory_categoryprop.java deleted file mode 100644 index 1a2b29bd2c..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SCategory_categoryprop.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - - -/** - * SCategory_categoryprop is a Querydsl query type for SCategory_categoryprop - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SCategory_categoryprop extends com.mysema.query.sql.RelationalPathBase<SCategory_categoryprop> { - - private static final long serialVersionUID = -1348316210; - - public static final SCategory_categoryprop category_categoryprop_ = new SCategory_categoryprop("category__categoryprop_"); - - public final NumberPath<Long> category_id = createNumber("category_id", Long.class); - - public final NumberPath<Long> propertiesId = createNumber("propertiesId", Long.class); - - public final com.mysema.query.sql.PrimaryKey<SCategory_categoryprop> primary = createPrimaryKey(category_id, propertiesId); - - public final com.mysema.query.sql.ForeignKey<SCategoryprop> fk8543a280fd94cd90 = createForeignKey(propertiesId, "id"); - - public final com.mysema.query.sql.ForeignKey<SCategory> fk8543a2802974945f = createForeignKey(category_id, "id"); - - public SCategory_categoryprop(String variable) { - super(SCategory_categoryprop.class, forVariable(variable), "null", "category__categoryprop_"); - addMetadata(); - } - - public SCategory_categoryprop(String variable, String schema, String table) { - super(SCategory_categoryprop.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SCategory_categoryprop(Path<? extends SCategory_categoryprop> path) { - super(path.getType(), path.getMetadata(), "null", "category__categoryprop_"); - addMetadata(); - } - - public SCategory_categoryprop(PathMetadata<?> metadata) { - super(SCategory_categoryprop.class, metadata, "null", "category__categoryprop_"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(category_id, ColumnMetadata.named("category__id").withIndex(1).ofType(-5).withSize(19).notNull()); - addMetadata(propertiesId, ColumnMetadata.named("properties_id").withIndex(2).ofType(-5).withSize(19).notNull()); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SCategoryprop.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SCategoryprop.java deleted file mode 100644 index cf0b1cbed8..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SCategoryprop.java +++ /dev/null @@ -1,66 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - - -/** - * SCategoryprop is a Querydsl query type for SCategoryprop - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SCategoryprop extends com.mysema.query.sql.RelationalPathBase<SCategoryprop> { - - private static final long serialVersionUID = -1013141043; - - public static final SCategoryprop categoryprop_ = new SCategoryprop("categoryprop_"); - - public final NumberPath<Long> categoryId = createNumber("categoryId", Long.class); - - public final NumberPath<Long> id = createNumber("id", Long.class); - - public final StringPath propName = createString("propName"); - - public final StringPath propValue = createString("propValue"); - - public final com.mysema.query.sql.PrimaryKey<SCategoryprop> primary = createPrimaryKey(id); - - public final com.mysema.query.sql.ForeignKey<SUserprop_categoryprop> _fke0fdb7d0fd94cd90 = createInvForeignKey(id, "properties_id"); - - public final com.mysema.query.sql.ForeignKey<SCategory_categoryprop> _fk8543a280fd94cd90 = createInvForeignKey(id, "properties_id"); - - public SCategoryprop(String variable) { - super(SCategoryprop.class, forVariable(variable), "null", "categoryprop_"); - addMetadata(); - } - - public SCategoryprop(String variable, String schema, String table) { - super(SCategoryprop.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SCategoryprop(Path<? extends SCategoryprop> path) { - super(path.getType(), path.getMetadata(), "null", "categoryprop_"); - addMetadata(); - } - - public SCategoryprop(PathMetadata<?> metadata) { - super(SCategoryprop.class, metadata, "null", "categoryprop_"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(categoryId, ColumnMetadata.named("categoryId").withIndex(2).ofType(-5).withSize(19).notNull()); - addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(-5).withSize(19).notNull()); - addMetadata(propName, ColumnMetadata.named("propName").withIndex(3).ofType(12).withSize(255)); - addMetadata(propValue, ColumnMetadata.named("propValue").withIndex(4).ofType(12).withSize(255)); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SChild2.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SChild2.java deleted file mode 100644 index 837a877c5d..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SChild2.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - -import java.io.*; - -import java.io.File; - - -/** - * SChild2 is a Querydsl query type for SChild2 - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SChild2 extends com.mysema.query.sql.RelationalPathBase<SChild2> { - - private static final long serialVersionUID = 386731719; - - public static final SChild2 Child2 = new SChild2("Child2"); - - public final NumberPath<Integer> id = createNumber("id", Integer.class); - - public final NumberPath<Integer> parentId = createNumber("parentId", Integer.class); - - public final com.mysema.query.sql.PrimaryKey<SChild2> primary = createPrimaryKey(id); - - public final com.mysema.query.sql.ForeignKey<SParent2> fk783f9ab6c2dbacbc = createForeignKey(parentId, "id"); - - public SChild2(String variable) { - super(SChild2.class, forVariable(variable), "null", "Child2"); - addMetadata(); - } - - public SChild2(String variable, String schema, String table) { - super(SChild2.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SChild2(Path<? extends SChild2> path) { - super(path.getType(), path.getMetadata(), "null", "Child2"); - addMetadata(); - } - - public SChild2(PathMetadata<?> metadata) { - super(SChild2.class, metadata, "null", "Child2"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(4).withSize(10).notNull()); - addMetadata(parentId, ColumnMetadata.named("parent_id").withIndex(2).ofType(4).withSize(10)); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SCompany.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SCompany.java deleted file mode 100644 index 29c5c04e73..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SCompany.java +++ /dev/null @@ -1,75 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - - -/** - * SCompany is a Querydsl query type for SCompany - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SCompany extends com.mysema.query.sql.RelationalPathBase<SCompany> { - - private static final long serialVersionUID = 22768499; - - public static final SCompany company_ = new SCompany("company_"); - - public final NumberPath<Integer> ceoId = createNumber("ceoId", Integer.class); - - public final NumberPath<Integer> id = createNumber("id", Integer.class); - - public final StringPath name = createString("name"); - - public final NumberPath<Integer> ratingOrdinal = createNumber("ratingOrdinal", Integer.class); - - public final StringPath ratingString = createString("ratingString"); - - public final com.mysema.query.sql.PrimaryKey<SCompany> primary = createPrimaryKey(id); - - public final com.mysema.query.sql.ForeignKey<SEmployee> fkdc405382edf003bd = createForeignKey(ceoId, "id"); - - public final com.mysema.query.sql.ForeignKey<SEmployee> _fk9d39ef71dc953998 = createInvForeignKey(id, "company_id"); - - public final com.mysema.query.sql.ForeignKey<SUser> _fk6a68df4dc953998 = createInvForeignKey(id, "company_id"); - - public final com.mysema.query.sql.ForeignKey<SCompany_department> _fk100ba610f0d30873 = createInvForeignKey(id, "company__id"); - - public final com.mysema.query.sql.ForeignKey<SDepartment> _fk1f3a274ddc953998 = createInvForeignKey(id, "company_id"); - - public SCompany(String variable) { - super(SCompany.class, forVariable(variable), "null", "company_"); - addMetadata(); - } - - public SCompany(String variable, String schema, String table) { - super(SCompany.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SCompany(Path<? extends SCompany> path) { - super(path.getType(), path.getMetadata(), "null", "company_"); - addMetadata(); - } - - public SCompany(PathMetadata<?> metadata) { - super(SCompany.class, metadata, "null", "company_"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(ceoId, ColumnMetadata.named("ceo_id").withIndex(5).ofType(4).withSize(10)); - addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(4).withSize(10).notNull()); - addMetadata(name, ColumnMetadata.named("name").withIndex(2).ofType(12).withSize(255)); - addMetadata(ratingOrdinal, ColumnMetadata.named("ratingOrdinal").withIndex(3).ofType(4).withSize(10)); - addMetadata(ratingString, ColumnMetadata.named("ratingString").withIndex(4).ofType(12).withSize(255)); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SCompany_department.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SCompany_department.java deleted file mode 100644 index d01d8d66ef..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SCompany_department.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - - -/** - * SCompany_department is a Querydsl query type for SCompany_department - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SCompany_department extends com.mysema.query.sql.RelationalPathBase<SCompany_department> { - - private static final long serialVersionUID = -68475398; - - public static final SCompany_department company_department_ = new SCompany_department("company__department_"); - - public final NumberPath<Integer> company_id = createNumber("company_id", Integer.class); - - public final NumberPath<Integer> departmentsId = createNumber("departmentsId", Integer.class); - - public final com.mysema.query.sql.ForeignKey<SDepartment> fk100ba6107d36c84d = createForeignKey(departmentsId, "id"); - - public final com.mysema.query.sql.ForeignKey<SCompany> fk100ba610f0d30873 = createForeignKey(company_id, "id"); - - public SCompany_department(String variable) { - super(SCompany_department.class, forVariable(variable), "null", "company__department_"); - addMetadata(); - } - - public SCompany_department(String variable, String schema, String table) { - super(SCompany_department.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SCompany_department(Path<? extends SCompany_department> path) { - super(path.getType(), path.getMetadata(), "null", "company__department_"); - addMetadata(); - } - - public SCompany_department(PathMetadata<?> metadata) { - super(SCompany_department.class, metadata, "null", "company__department_"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(company_id, ColumnMetadata.named("company__id").withIndex(1).ofType(4).withSize(10).notNull()); - addMetadata(departmentsId, ColumnMetadata.named("departments_id").withIndex(2).ofType(4).withSize(10).notNull()); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SCustomer.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SCustomer.java deleted file mode 100644 index c4d8e51d26..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SCustomer.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - - -/** - * SCustomer is a Querydsl query type for SCustomer - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SCustomer extends com.mysema.query.sql.RelationalPathBase<SCustomer> { - - private static final long serialVersionUID = -564764048; - - public static final SCustomer customer_ = new SCustomer("customer_"); - - public final NumberPath<Long> currentOrderId = createNumber("currentOrderId", Long.class); - - public final NumberPath<Integer> id = createNumber("id", Integer.class); - - public final NumberPath<Long> nameId = createNumber("nameId", Long.class); - - public final com.mysema.query.sql.PrimaryKey<SCustomer> primary = createPrimaryKey(id); - - public final com.mysema.query.sql.ForeignKey<SName> fk600e7c4196a83d9c = createForeignKey(nameId, "id"); - - public final com.mysema.query.sql.ForeignKey<SOrder> fk600e7c419cc457f1 = createForeignKey(currentOrderId, "id"); - - public final com.mysema.query.sql.ForeignKey<SStore_customer> _fk82ba2ce051f3c3e5 = createInvForeignKey(id, "customers_id"); - - public final com.mysema.query.sql.ForeignKey<SOrder> _fkc3df62d1b29c27bc = createInvForeignKey(id, "customer_id"); - - public SCustomer(String variable) { - super(SCustomer.class, forVariable(variable), "null", "customer_"); - addMetadata(); - } - - public SCustomer(String variable, String schema, String table) { - super(SCustomer.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SCustomer(Path<? extends SCustomer> path) { - super(path.getType(), path.getMetadata(), "null", "customer_"); - addMetadata(); - } - - public SCustomer(PathMetadata<?> metadata) { - super(SCustomer.class, metadata, "null", "customer_"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(currentOrderId, ColumnMetadata.named("currentOrder_id").withIndex(2).ofType(-5).withSize(19)); - addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(4).withSize(10).notNull()); - addMetadata(nameId, ColumnMetadata.named("name_id").withIndex(3).ofType(-5).withSize(19)); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SDateTest.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SDateTest.java deleted file mode 100644 index fa6cfcab3e..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SDateTest.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - -import java.io.*; - -import java.io.File; - - -/** - * SDateTest is a Querydsl query type for SDateTest - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SDateTest extends com.mysema.query.sql.RelationalPathBase<SDateTest> { - - private static final long serialVersionUID = -1879688879; - - public static final SDateTest dateTest1 = new SDateTest("DATE_TEST"); - - public final DatePath<java.sql.Date> dateTest = createDate("dateTest", java.sql.Date.class); - - public SDateTest(String variable) { - super(SDateTest.class, forVariable(variable), "null", "DATE_TEST"); - addMetadata(); - } - - public SDateTest(String variable, String schema, String table) { - super(SDateTest.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SDateTest(Path<? extends SDateTest> path) { - super(path.getType(), path.getMetadata(), "null", "DATE_TEST"); - addMetadata(); - } - - public SDateTest(PathMetadata<?> metadata) { - super(SDateTest.class, metadata, "null", "DATE_TEST"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(dateTest, ColumnMetadata.named("DATE_TEST").withIndex(1).ofType(91).withSize(10)); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SDepartment.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SDepartment.java deleted file mode 100644 index 8d169e30c2..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SDepartment.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - - -/** - * SDepartment is a Querydsl query type for SDepartment - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SDepartment extends com.mysema.query.sql.RelationalPathBase<SDepartment> { - - private static final long serialVersionUID = 723598780; - - public static final SDepartment department_ = new SDepartment("department_"); - - public final NumberPath<Integer> companyId = createNumber("companyId", Integer.class); - - public final NumberPath<Integer> id = createNumber("id", Integer.class); - - public final StringPath name = createString("name"); - - public final com.mysema.query.sql.PrimaryKey<SDepartment> primary = createPrimaryKey(id); - - public final com.mysema.query.sql.ForeignKey<SCompany> fk1f3a274ddc953998 = createForeignKey(companyId, "id"); - - public final com.mysema.query.sql.ForeignKey<SCompany_department> _fk100ba6107d36c84d = createInvForeignKey(id, "departments_id"); - - public final com.mysema.query.sql.ForeignKey<SDepartment_employee> _fkc33a14ff7d2db0e1 = createInvForeignKey(id, "department__id"); - - public SDepartment(String variable) { - super(SDepartment.class, forVariable(variable), "null", "department_"); - addMetadata(); - } - - public SDepartment(String variable, String schema, String table) { - super(SDepartment.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SDepartment(Path<? extends SDepartment> path) { - super(path.getType(), path.getMetadata(), "null", "department_"); - addMetadata(); - } - - public SDepartment(PathMetadata<?> metadata) { - super(SDepartment.class, metadata, "null", "department_"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(companyId, ColumnMetadata.named("company_id").withIndex(3).ofType(4).withSize(10)); - addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(4).withSize(10).notNull()); - addMetadata(name, ColumnMetadata.named("name").withIndex(2).ofType(12).withSize(255)); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SDepartment_employee.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SDepartment_employee.java deleted file mode 100644 index 48b4d88c3f..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SDepartment_employee.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - - -/** - * SDepartment_employee is a Querydsl query type for SDepartment_employee - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SDepartment_employee extends com.mysema.query.sql.RelationalPathBase<SDepartment_employee> { - - private static final long serialVersionUID = 1293706549; - - public static final SDepartment_employee department_employee_ = new SDepartment_employee("department__employee_"); - - public final NumberPath<Integer> department_id = createNumber("department_id", Integer.class); - - public final NumberPath<Integer> employeesId = createNumber("employeesId", Integer.class); - - public final com.mysema.query.sql.ForeignKey<SEmployee> fkc33a14ffd846a985 = createForeignKey(employeesId, "id"); - - public final com.mysema.query.sql.ForeignKey<SDepartment> fkc33a14ff7d2db0e1 = createForeignKey(department_id, "id"); - - public SDepartment_employee(String variable) { - super(SDepartment_employee.class, forVariable(variable), "null", "department__employee_"); - addMetadata(); - } - - public SDepartment_employee(String variable, String schema, String table) { - super(SDepartment_employee.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SDepartment_employee(Path<? extends SDepartment_employee> path) { - super(path.getType(), path.getMetadata(), "null", "department__employee_"); - addMetadata(); - } - - public SDepartment_employee(PathMetadata<?> metadata) { - super(SDepartment_employee.class, metadata, "null", "department__employee_"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(department_id, ColumnMetadata.named("department__id").withIndex(1).ofType(4).withSize(10).notNull()); - addMetadata(employeesId, ColumnMetadata.named("employees_id").withIndex(2).ofType(4).withSize(10).notNull()); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SDocument.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SDocument.java deleted file mode 100644 index 5e5de2f5bc..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SDocument.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - - -/** - * SDocument is a Querydsl query type for SDocument - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SDocument extends com.mysema.query.sql.RelationalPathBase<SDocument> { - - private static final long serialVersionUID = -1232783149; - - public static final SDocument document_ = new SDocument("document_"); - - public final NumberPath<Integer> id = createNumber("id", Integer.class); - - public final StringPath name = createString("name"); - - public final DatePath<java.sql.Date> validTo = createDate("validTo", java.sql.Date.class); - - public final com.mysema.query.sql.PrimaryKey<SDocument> primary = createPrimaryKey(id); - - public SDocument(String variable) { - super(SDocument.class, forVariable(variable), "null", "document_"); - addMetadata(); - } - - public SDocument(String variable, String schema, String table) { - super(SDocument.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SDocument(Path<? extends SDocument> path) { - super(path.getType(), path.getMetadata(), "null", "document_"); - addMetadata(); - } - - public SDocument(PathMetadata<?> metadata) { - super(SDocument.class, metadata, "null", "document_"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(4).withSize(10).notNull()); - addMetadata(name, ColumnMetadata.named("name").withIndex(2).ofType(12).withSize(255)); - addMetadata(validTo, ColumnMetadata.named("validTo").withIndex(3).ofType(91).withSize(10)); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SDocumentprop.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SDocumentprop.java deleted file mode 100644 index 4aedd46a03..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SDocumentprop.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - - -/** - * SDocumentprop is a Querydsl query type for SDocumentprop - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SDocumentprop extends com.mysema.query.sql.RelationalPathBase<SDocumentprop> { - - private static final long serialVersionUID = 233547728; - - public static final SDocumentprop documentprop_ = new SDocumentprop("documentprop_"); - - public final NumberPath<Double> documentId = createNumber("documentId", Double.class); - - public final NumberPath<Long> id = createNumber("id", Long.class); - - public final StringPath propName = createString("propName"); - - public final StringPath propValue = createString("propValue"); - - public final StringPath propValueDetails = createString("propValueDetails"); - - public final com.mysema.query.sql.PrimaryKey<SDocumentprop> primary = createPrimaryKey(id); - - public SDocumentprop(String variable) { - super(SDocumentprop.class, forVariable(variable), "null", "documentprop_"); - addMetadata(); - } - - public SDocumentprop(String variable, String schema, String table) { - super(SDocumentprop.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SDocumentprop(Path<? extends SDocumentprop> path) { - super(path.getType(), path.getMetadata(), "null", "documentprop_"); - addMetadata(); - } - - public SDocumentprop(PathMetadata<?> metadata) { - super(SDocumentprop.class, metadata, "null", "documentprop_"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(documentId, ColumnMetadata.named("documentId").withIndex(2).ofType(8).withSize(22).notNull()); - addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(-5).withSize(19).notNull()); - addMetadata(propName, ColumnMetadata.named("propName").withIndex(3).ofType(12).withSize(255)); - addMetadata(propValue, ColumnMetadata.named("propValue").withIndex(4).ofType(12).withSize(255)); - addMetadata(propValueDetails, ColumnMetadata.named("propValueDetails").withIndex(5).ofType(12).withSize(255)); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SEmployee.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SEmployee.java deleted file mode 100644 index 3487e44af6..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SEmployee.java +++ /dev/null @@ -1,75 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import com.mysema.query.sql.ColumnMetadata; -import com.mysema.query.types.Path; -import com.mysema.query.types.PathMetadata; -import com.mysema.query.types.path.NumberPath; -import com.mysema.query.types.path.StringPath; - -import javax.annotation.Generated; - -import static com.mysema.query.types.PathMetadataFactory.forVariable; - - -/** - * SEmployee is a Querydsl query type for SEmployee - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SEmployee extends com.mysema.query.sql.RelationalPathBase<SEmployee> { - - private static final long serialVersionUID = 461493664; - - public static final SEmployee employee_ = new SEmployee("employee_"); - - public final NumberPath<Integer> companyId = createNumber("companyId", Integer.class); - - public final StringPath firstName = createString("firstName"); - - public final NumberPath<Integer> id = createNumber("id", Integer.class); - - public final StringPath lastName = createString("lastName"); - - public final NumberPath<Long> userId = createNumber("userId", Long.class); - - public final com.mysema.query.sql.PrimaryKey<SEmployee> primary = createPrimaryKey(id); - - public final com.mysema.query.sql.ForeignKey<SCompany> fk9d39ef71dc953998 = createForeignKey(companyId, "id"); - - public final com.mysema.query.sql.ForeignKey<SUser> fk9d39ef712743b59c = createForeignKey(userId, "id"); - - public final com.mysema.query.sql.ForeignKey<SCompany> _fkdc405382edf003bd = createInvForeignKey(id, "ceo_id"); - - public final com.mysema.query.sql.ForeignKey<SEmployeeJobFunctions> _fk49690e2f75b8f5bc = createInvForeignKey(id, "Employee_id"); - - public final com.mysema.query.sql.ForeignKey<SDepartment_employee> _fkc33a14ffd846a985 = createInvForeignKey(id, "employees_id"); - - public SEmployee(String variable) { - super(SEmployee.class, forVariable(variable), "null", "employee_"); - addMetadata(); - } - - public SEmployee(String variable, String schema, String table) { - super(SEmployee.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SEmployee(Path<? extends SEmployee> path) { - super(path.getType(), path.getMetadata(), "null", "employee_"); - addMetadata(); - } - - public SEmployee(PathMetadata<?> metadata) { - super(SEmployee.class, metadata, "null", "employee_"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(companyId, ColumnMetadata.named("company_id").withIndex(4).ofType(4).withSize(10)); - addMetadata(firstName, ColumnMetadata.named("firstName").withIndex(2).ofType(12).withSize(255)); - addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(4).withSize(10).notNull()); - addMetadata(lastName, ColumnMetadata.named("lastName").withIndex(3).ofType(12).withSize(255)); - addMetadata(userId, ColumnMetadata.named("user_id").withIndex(5).ofType(-5).withSize(19)); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SEmployeeJobFunctions.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SEmployeeJobFunctions.java deleted file mode 100644 index 4eb302c428..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SEmployeeJobFunctions.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - - -/** - * SEmployeeJobFunctions is a Querydsl query type for SEmployeeJobFunctions - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SEmployeeJobFunctions extends com.mysema.query.sql.RelationalPathBase<SEmployeeJobFunctions> { - - private static final long serialVersionUID = -666645347; - - public static final SEmployeeJobFunctions EmployeeJobFunctions = new SEmployeeJobFunctions("Employee_jobFunctions"); - - public final NumberPath<Integer> employeeId = createNumber("employeeId", Integer.class); - - public final StringPath jobfunction = createString("jobfunction"); - - public final com.mysema.query.sql.ForeignKey<SEmployee> fk49690e2f75b8f5bc = createForeignKey(employeeId, "id"); - - public SEmployeeJobFunctions(String variable) { - super(SEmployeeJobFunctions.class, forVariable(variable), "null", "Employee_jobFunctions"); - addMetadata(); - } - - public SEmployeeJobFunctions(String variable, String schema, String table) { - super(SEmployeeJobFunctions.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SEmployeeJobFunctions(Path<? extends SEmployeeJobFunctions> path) { - super(path.getType(), path.getMetadata(), "null", "Employee_jobFunctions"); - addMetadata(); - } - - public SEmployeeJobFunctions(PathMetadata<?> metadata) { - super(SEmployeeJobFunctions.class, metadata, "null", "Employee_jobFunctions"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(employeeId, ColumnMetadata.named("Employee_id").withIndex(1).ofType(4).withSize(10).notNull()); - addMetadata(jobfunction, ColumnMetadata.named("jobfunction").withIndex(2).ofType(12).withSize(255)); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SEntity1.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SEntity1.java deleted file mode 100644 index 88a757847c..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SEntity1.java +++ /dev/null @@ -1,66 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - -import java.io.*; - -import java.io.File; - - -/** - * SEntity1 is a Querydsl query type for SEntity1 - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SEntity1 extends com.mysema.query.sql.RelationalPathBase<SEntity1> { - - private static final long serialVersionUID = 1060650653; - - public static final SEntity1 Entity1 = new SEntity1("Entity1"); - - public final StringPath dtype = createString("dtype"); - - public final NumberPath<Integer> id = createNumber("id", Integer.class); - - public final StringPath property = createString("property"); - - public final StringPath property2 = createString("property2"); - - public final com.mysema.query.sql.PrimaryKey<SEntity1> primary = createPrimaryKey(id); - - public SEntity1(String variable) { - super(SEntity1.class, forVariable(variable), "null", "Entity1"); - addMetadata(); - } - - public SEntity1(String variable, String schema, String table) { - super(SEntity1.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SEntity1(Path<? extends SEntity1> path) { - super(path.getType(), path.getMetadata(), "null", "Entity1"); - addMetadata(); - } - - public SEntity1(PathMetadata<?> metadata) { - super(SEntity1.class, metadata, "null", "Entity1"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(dtype, ColumnMetadata.named("DTYPE").withIndex(1).ofType(12).withSize(31).notNull()); - addMetadata(id, ColumnMetadata.named("id").withIndex(2).ofType(4).withSize(10).notNull()); - addMetadata(property, ColumnMetadata.named("property").withIndex(3).ofType(12).withSize(255)); - addMetadata(property2, ColumnMetadata.named("property2").withIndex(4).ofType(12).withSize(255)); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SEviltype.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SEviltype.java deleted file mode 100644 index af2302f344..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SEviltype.java +++ /dev/null @@ -1,144 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - - -/** - * SEviltype is a Querydsl query type for SEviltype - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SEviltype extends com.mysema.query.sql.RelationalPathBase<SEviltype> { - - private static final long serialVersionUID = 1348954496; - - public static final SEviltype eviltype_ = new SEviltype("eviltype_"); - - public final NumberPath<Integer> _asc = createNumber("_asc", Integer.class); - - public final NumberPath<Integer> _desc = createNumber("_desc", Integer.class); - - public final NumberPath<Integer> getClassId = createNumber("getClassId", Integer.class); - - public final NumberPath<Integer> getId = createNumber("getId", Integer.class); - - public final NumberPath<Integer> getMetadataId = createNumber("getMetadataId", Integer.class); - - public final NumberPath<Integer> getTypeId = createNumber("getTypeId", Integer.class); - - public final NumberPath<Integer> hashCodeId = createNumber("hashCodeId", Integer.class); - - public final NumberPath<Integer> id = createNumber("id", Integer.class); - - public final NumberPath<Integer> isnotnullId = createNumber("isnotnullId", Integer.class); - - public final NumberPath<Integer> isnullId = createNumber("isnullId", Integer.class); - - public final NumberPath<Integer> notifyAllId = createNumber("notifyAllId", Integer.class); - - public final NumberPath<Integer> notifyId = createNumber("notifyId", Integer.class); - - public final NumberPath<Integer> toStringId = createNumber("toStringId", Integer.class); - - public final NumberPath<Integer> waitId = createNumber("waitId", Integer.class); - - public final com.mysema.query.sql.PrimaryKey<SEviltype> primary = createPrimaryKey(id); - - public final com.mysema.query.sql.ForeignKey<SEviltype> fkd21f83516787cd9e = createForeignKey(toStringId, "id"); - - public final com.mysema.query.sql.ForeignKey<SEviltype> fkd21f835114c0ad20 = createForeignKey(_desc, "id"); - - public final com.mysema.query.sql.ForeignKey<SEviltype> fkd21f835151e065d5 = createForeignKey(waitId, "id"); - - public final com.mysema.query.sql.ForeignKey<SEviltype> fkd21f83517e62bab2 = createForeignKey(notifyAllId, "id"); - - public final com.mysema.query.sql.ForeignKey<SEviltype> fkd21f8351c4df9054 = createForeignKey(getId, "id"); - - public final com.mysema.query.sql.ForeignKey<SEviltype> fkd21f835112489019 = createForeignKey(isnullId, "id"); - - public final com.mysema.query.sql.ForeignKey<SEviltype> fkd21f8351b09c8448 = createForeignKey(getClassId, "id"); - - public final com.mysema.query.sql.ForeignKey<SEviltype> fkd21f835180b69f81 = createForeignKey(notifyId, "id"); - - public final com.mysema.query.sql.ForeignKey<SEviltype> fkd21f8351b71279da = createForeignKey(getTypeId, "id"); - - public final com.mysema.query.sql.ForeignKey<SEviltype> fkd21f8351226ee98f = createForeignKey(hashCodeId, "id"); - - public final com.mysema.query.sql.ForeignKey<SEviltype> fkd21f8351f5ec12fa = createForeignKey(isnotnullId, "id"); - - public final com.mysema.query.sql.ForeignKey<SEviltype> fkd21f8351f839f62 = createForeignKey(_asc, "id"); - - public final com.mysema.query.sql.ForeignKey<SEviltype> fkd21f83512d7708c5 = createForeignKey(getMetadataId, "id"); - - public final com.mysema.query.sql.ForeignKey<SEviltype> _fkd21f83516787cd9e = createInvForeignKey(id, "toString_id"); - - public final com.mysema.query.sql.ForeignKey<SEviltype> _fkd21f835114c0ad20 = createInvForeignKey(id, "_desc"); - - public final com.mysema.query.sql.ForeignKey<SEviltype> _fkd21f835151e065d5 = createInvForeignKey(id, "wait_id"); - - public final com.mysema.query.sql.ForeignKey<SEviltype> _fkd21f83517e62bab2 = createInvForeignKey(id, "notifyAll_id"); - - public final com.mysema.query.sql.ForeignKey<SEviltype> _fkd21f8351c4df9054 = createInvForeignKey(id, "get_id"); - - public final com.mysema.query.sql.ForeignKey<SEviltype> _fkd21f835112489019 = createInvForeignKey(id, "isnull_id"); - - public final com.mysema.query.sql.ForeignKey<SEviltype> _fkd21f8351b09c8448 = createInvForeignKey(id, "getClass_id"); - - public final com.mysema.query.sql.ForeignKey<SEviltype> _fkd21f835180b69f81 = createInvForeignKey(id, "notify_id"); - - public final com.mysema.query.sql.ForeignKey<SEviltype> _fkd21f8351b71279da = createInvForeignKey(id, "getType_id"); - - public final com.mysema.query.sql.ForeignKey<SEviltype> _fkd21f8351226ee98f = createInvForeignKey(id, "hashCode_id"); - - public final com.mysema.query.sql.ForeignKey<SEviltype> _fkd21f8351f5ec12fa = createInvForeignKey(id, "isnotnull_id"); - - public final com.mysema.query.sql.ForeignKey<SEviltype> _fkd21f8351f839f62 = createInvForeignKey(id, "_asc"); - - public final com.mysema.query.sql.ForeignKey<SEviltype> _fkd21f83512d7708c5 = createInvForeignKey(id, "getMetadata_id"); - - public SEviltype(String variable) { - super(SEviltype.class, forVariable(variable), "null", "eviltype_"); - addMetadata(); - } - - public SEviltype(String variable, String schema, String table) { - super(SEviltype.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SEviltype(Path<? extends SEviltype> path) { - super(path.getType(), path.getMetadata(), "null", "eviltype_"); - addMetadata(); - } - - public SEviltype(PathMetadata<?> metadata) { - super(SEviltype.class, metadata, "null", "eviltype_"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(_asc, ColumnMetadata.named("_asc").withIndex(2).ofType(4).withSize(10)); - addMetadata(_desc, ColumnMetadata.named("_desc").withIndex(3).ofType(4).withSize(10)); - addMetadata(getClassId, ColumnMetadata.named("getClass_id").withIndex(5).ofType(4).withSize(10)); - addMetadata(getId, ColumnMetadata.named("get_id").withIndex(4).ofType(4).withSize(10)); - addMetadata(getMetadataId, ColumnMetadata.named("getMetadata_id").withIndex(6).ofType(4).withSize(10)); - addMetadata(getTypeId, ColumnMetadata.named("getType_id").withIndex(7).ofType(4).withSize(10)); - addMetadata(hashCodeId, ColumnMetadata.named("hashCode_id").withIndex(8).ofType(4).withSize(10)); - addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(4).withSize(10).notNull()); - addMetadata(isnotnullId, ColumnMetadata.named("isnotnull_id").withIndex(9).ofType(4).withSize(10)); - addMetadata(isnullId, ColumnMetadata.named("isnull_id").withIndex(10).ofType(4).withSize(10)); - addMetadata(notifyAllId, ColumnMetadata.named("notifyAll_id").withIndex(12).ofType(4).withSize(10)); - addMetadata(notifyId, ColumnMetadata.named("notify_id").withIndex(11).ofType(4).withSize(10)); - addMetadata(toStringId, ColumnMetadata.named("toString_id").withIndex(13).ofType(4).withSize(10)); - addMetadata(waitId, ColumnMetadata.named("wait_id").withIndex(14).ofType(4).withSize(10)); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SFoo.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SFoo.java deleted file mode 100644 index ec8c739361..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SFoo.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - - -/** - * SFoo is a Querydsl query type for SFoo - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SFoo extends com.mysema.query.sql.RelationalPathBase<SFoo> { - - private static final long serialVersionUID = -1389443894; - - public static final SFoo foo_ = new SFoo("foo_"); - - public final StringPath bar = createString("bar"); - - public final NumberPath<Integer> id = createNumber("id", Integer.class); - - public final DatePath<java.sql.Date> startDate = createDate("startDate", java.sql.Date.class); - - public final com.mysema.query.sql.PrimaryKey<SFoo> primary = createPrimaryKey(id); - - public final com.mysema.query.sql.ForeignKey<SFooNames> _fkb6129a8f94e297f8 = createInvForeignKey(id, "foo_id"); - - public SFoo(String variable) { - super(SFoo.class, forVariable(variable), "null", "foo_"); - addMetadata(); - } - - public SFoo(String variable, String schema, String table) { - super(SFoo.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SFoo(Path<? extends SFoo> path) { - super(path.getType(), path.getMetadata(), "null", "foo_"); - addMetadata(); - } - - public SFoo(PathMetadata<?> metadata) { - super(SFoo.class, metadata, "null", "foo_"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(bar, ColumnMetadata.named("bar").withIndex(2).ofType(12).withSize(255)); - addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(4).withSize(10).notNull()); - addMetadata(startDate, ColumnMetadata.named("startDate").withIndex(3).ofType(91).withSize(10)); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SFooNames.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SFooNames.java deleted file mode 100644 index 4a3b5f1486..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SFooNames.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - - -/** - * SFooNames is a Querydsl query type for SFooNames - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SFooNames extends com.mysema.query.sql.RelationalPathBase<SFooNames> { - - private static final long serialVersionUID = 982089235; - - public static final SFooNames fooNames = new SFooNames("foo_names"); - - public final NumberPath<Integer> fooId = createNumber("fooId", Integer.class); - - public final StringPath names = createString("names"); - - public final com.mysema.query.sql.ForeignKey<SFoo> fkb6129a8f94e297f8 = createForeignKey(fooId, "id"); - - public SFooNames(String variable) { - super(SFooNames.class, forVariable(variable), "null", "foo_names"); - addMetadata(); - } - - public SFooNames(String variable, String schema, String table) { - super(SFooNames.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SFooNames(Path<? extends SFooNames> path) { - super(path.getType(), path.getMetadata(), "null", "foo_names"); - addMetadata(); - } - - public SFooNames(PathMetadata<?> metadata) { - super(SFooNames.class, metadata, "null", "foo_names"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(fooId, ColumnMetadata.named("foo_id").withIndex(1).ofType(4).withSize(10).notNull()); - addMetadata(names, ColumnMetadata.named("names").withIndex(2).ofType(12).withSize(255)); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SFormula.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SFormula.java deleted file mode 100644 index 439559f290..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SFormula.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - - -/** - * SFormula is a Querydsl query type for SFormula - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SFormula extends com.mysema.query.sql.RelationalPathBase<SFormula> { - - private static final long serialVersionUID = 1097200554; - - public static final SFormula formula_ = new SFormula("formula_"); - - public final NumberPath<Integer> id = createNumber("id", Integer.class); - - public final NumberPath<Long> parameterId = createNumber("parameterId", Long.class); - - public final com.mysema.query.sql.PrimaryKey<SFormula> primary = createPrimaryKey(id); - - public final com.mysema.query.sql.ForeignKey<SParameter> fk1c4adbb924189298 = createForeignKey(parameterId, "id"); - - public SFormula(String variable) { - super(SFormula.class, forVariable(variable), "null", "formula_"); - addMetadata(); - } - - public SFormula(String variable, String schema, String table) { - super(SFormula.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SFormula(Path<? extends SFormula> path) { - super(path.getType(), path.getMetadata(), "null", "formula_"); - addMetadata(); - } - - public SFormula(PathMetadata<?> metadata) { - super(SFormula.class, metadata, "null", "formula_"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(4).withSize(10).notNull()); - addMetadata(parameterId, ColumnMetadata.named("parameter_id").withIndex(2).ofType(-5).withSize(19)); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SGeneratedKeys.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SGeneratedKeys.java deleted file mode 100644 index 3c98229115..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SGeneratedKeys.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - -import java.io.*; - -import java.io.File; - - -/** - * SGeneratedKeys is a Querydsl query type for SGeneratedKeys - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SGeneratedKeys extends com.mysema.query.sql.RelationalPathBase<SGeneratedKeys> { - - private static final long serialVersionUID = 379851474; - - public static final SGeneratedKeys generatedKeys = new SGeneratedKeys("GENERATED_KEYS"); - - public final NumberPath<Integer> id = createNumber("id", Integer.class); - - public final StringPath name = createString("name"); - - public final com.mysema.query.sql.PrimaryKey<SGeneratedKeys> primary = createPrimaryKey(id); - - public SGeneratedKeys(String variable) { - super(SGeneratedKeys.class, forVariable(variable), "null", "GENERATED_KEYS"); - addMetadata(); - } - - public SGeneratedKeys(String variable, String schema, String table) { - super(SGeneratedKeys.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SGeneratedKeys(Path<? extends SGeneratedKeys> path) { - super(path.getType(), path.getMetadata(), "null", "GENERATED_KEYS"); - addMetadata(); - } - - public SGeneratedKeys(PathMetadata<?> metadata) { - super(SGeneratedKeys.class, metadata, "null", "GENERATED_KEYS"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(id, ColumnMetadata.named("ID").withIndex(1).ofType(4).withSize(10).notNull()); - addMetadata(name, ColumnMetadata.named("NAME").withIndex(2).ofType(12).withSize(30)); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SHumanHairs.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SHumanHairs.java deleted file mode 100644 index f72df061a1..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SHumanHairs.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - -import java.io.*; - -import java.io.File; - - -/** - * SHumanHairs is a Querydsl query type for SHumanHairs - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SHumanHairs extends com.mysema.query.sql.RelationalPathBase<SHumanHairs> { - - private static final long serialVersionUID = 1372028757; - - public static final SHumanHairs HumanHairs = new SHumanHairs("Human_hairs"); - - public final NumberPath<Integer> hairs = createNumber("hairs", Integer.class); - - public final NumberPath<Long> humanId = createNumber("humanId", Long.class); - - public final com.mysema.query.sql.ForeignKey<SMammal> fk6649531ff097e318 = createForeignKey(humanId, "id"); - - public SHumanHairs(String variable) { - super(SHumanHairs.class, forVariable(variable), "null", "Human_hairs"); - addMetadata(); - } - - public SHumanHairs(String variable, String schema, String table) { - super(SHumanHairs.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SHumanHairs(Path<? extends SHumanHairs> path) { - super(path.getType(), path.getMetadata(), "null", "Human_hairs"); - addMetadata(); - } - - public SHumanHairs(PathMetadata<?> metadata) { - super(SHumanHairs.class, metadata, "null", "Human_hairs"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(hairs, ColumnMetadata.named("hairs").withIndex(2).ofType(4).withSize(10)); - addMetadata(humanId, ColumnMetadata.named("Human_id").withIndex(1).ofType(-5).withSize(19).notNull()); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SInheritedproperties.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SInheritedproperties.java deleted file mode 100644 index 6254246453..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SInheritedproperties.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - - -/** - * SInheritedproperties is a Querydsl query type for SInheritedproperties - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SInheritedproperties extends com.mysema.query.sql.RelationalPathBase<SInheritedproperties> { - - private static final long serialVersionUID = -992601885; - - public static final SInheritedproperties inheritedproperties_ = new SInheritedproperties("inheritedproperties_"); - - public final StringPath classProperty = createString("classProperty"); - - public final NumberPath<Long> id = createNumber("id", Long.class); - - public final StringPath stringAsSimple = createString("stringAsSimple"); - - public final StringPath superclassProperty = createString("superclassProperty"); - - public final com.mysema.query.sql.PrimaryKey<SInheritedproperties> primary = createPrimaryKey(id); - - public SInheritedproperties(String variable) { - super(SInheritedproperties.class, forVariable(variable), "null", "inheritedproperties_"); - addMetadata(); - } - - public SInheritedproperties(String variable, String schema, String table) { - super(SInheritedproperties.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SInheritedproperties(Path<? extends SInheritedproperties> path) { - super(path.getType(), path.getMetadata(), "null", "inheritedproperties_"); - addMetadata(); - } - - public SInheritedproperties(PathMetadata<?> metadata) { - super(SInheritedproperties.class, metadata, "null", "inheritedproperties_"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(classProperty, ColumnMetadata.named("classProperty").withIndex(4).ofType(12).withSize(255)); - addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(-5).withSize(19).notNull()); - addMetadata(stringAsSimple, ColumnMetadata.named("stringAsSimple").withIndex(2).ofType(12).withSize(255)); - addMetadata(superclassProperty, ColumnMetadata.named("superclassProperty").withIndex(3).ofType(12).withSize(255)); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SItem.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SItem.java deleted file mode 100644 index 539a95e40a..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SItem.java +++ /dev/null @@ -1,89 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - - -/** - * SItem is a Querydsl query type for SItem - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SItem extends com.mysema.query.sql.RelationalPathBase<SItem> { - - private static final long serialVersionUID = -120177317; - - public static final SItem item_ = new SItem("item_"); - - public final NumberPath<Long> currentStatusId = createNumber("currentStatusId", Long.class); - - public final StringPath dtype = createString("dtype"); - - public final NumberPath<Long> id = createNumber("id", Long.class); - - public final StringPath name = createString("name"); - - public final NumberPath<Integer> paymentStatus = createNumber("paymentStatus", Integer.class); - - public final NumberPath<Long> productId = createNumber("productId", Long.class); - - public final NumberPath<Long> statusId = createNumber("statusId", Long.class); - - public final com.mysema.query.sql.PrimaryKey<SItem> primary = createPrimaryKey(id); - - public final com.mysema.query.sql.ForeignKey<SStatus> fk5fde7acd23307bc = createForeignKey(statusId, "id"); - - public final com.mysema.query.sql.ForeignKey<SStatus> fk5fde7ac9ea26263 = createForeignKey(currentStatusId, "id"); - - public final com.mysema.query.sql.ForeignKey<SItem> fk5fde7ac2c7f0c58 = createForeignKey(productId, "id"); - - public final com.mysema.query.sql.ForeignKey<SAuditlog> _fkb88fbf6ae26109c = createInvForeignKey(id, "item_id"); - - public final com.mysema.query.sql.ForeignKey<SItem> _fk5fde7ac2c7f0c58 = createInvForeignKey(id, "product_id"); - - public final com.mysema.query.sql.ForeignKey<SOrder_item> _fk1b5e8cbe7640c8cf = createInvForeignKey(id, "items_id"); - - public final com.mysema.query.sql.ForeignKey<SPrice> _fkc59678362c7f0c58 = createInvForeignKey(id, "product_id"); - - public final com.mysema.query.sql.ForeignKey<SItem_statuschange> _fkcb99fb2aedc50192 = createInvForeignKey(id, "item__id"); - - public final com.mysema.query.sql.ForeignKey<SLineItems> _fkb2e400c3d8e44c3 = createInvForeignKey(id, "lineItems_id"); - - public SItem(String variable) { - super(SItem.class, forVariable(variable), "null", "item_"); - addMetadata(); - } - - public SItem(String variable, String schema, String table) { - super(SItem.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SItem(Path<? extends SItem> path) { - super(path.getType(), path.getMetadata(), "null", "item_"); - addMetadata(); - } - - public SItem(PathMetadata<?> metadata) { - super(SItem.class, metadata, "null", "item_"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(currentStatusId, ColumnMetadata.named("currentStatus_id").withIndex(6).ofType(-5).withSize(19)); - addMetadata(dtype, ColumnMetadata.named("DTYPE").withIndex(1).ofType(12).withSize(31).notNull()); - addMetadata(id, ColumnMetadata.named("id").withIndex(2).ofType(-5).withSize(19).notNull()); - addMetadata(name, ColumnMetadata.named("name").withIndex(4).ofType(12).withSize(255)); - addMetadata(paymentStatus, ColumnMetadata.named("paymentStatus").withIndex(3).ofType(4).withSize(10)); - addMetadata(productId, ColumnMetadata.named("product_id").withIndex(5).ofType(-5).withSize(19)); - addMetadata(statusId, ColumnMetadata.named("status_id").withIndex(7).ofType(-5).withSize(19)); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SItem_statuschange.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SItem_statuschange.java deleted file mode 100644 index 8fc74603cc..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SItem_statuschange.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - - -/** - * SItem_statuschange is a Querydsl query type for SItem_statuschange - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SItem_statuschange extends com.mysema.query.sql.RelationalPathBase<SItem_statuschange> { - - private static final long serialVersionUID = 210676994; - - public static final SItem_statuschange item_statuschange_ = new SItem_statuschange("item__statuschange_"); - - public final NumberPath<Long> item_id = createNumber("item_id", Long.class); - - public final NumberPath<Long> statusChangesId = createNumber("statusChangesId", Long.class); - - public final com.mysema.query.sql.ForeignKey<SStatuschange> fkcb99fb2ab2bd098d = createForeignKey(statusChangesId, "id"); - - public final com.mysema.query.sql.ForeignKey<SItem> fkcb99fb2aedc50192 = createForeignKey(item_id, "id"); - - public SItem_statuschange(String variable) { - super(SItem_statuschange.class, forVariable(variable), "null", "item__statuschange_"); - addMetadata(); - } - - public SItem_statuschange(String variable, String schema, String table) { - super(SItem_statuschange.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SItem_statuschange(Path<? extends SItem_statuschange> path) { - super(path.getType(), path.getMetadata(), "null", "item__statuschange_"); - addMetadata(); - } - - public SItem_statuschange(PathMetadata<?> metadata) { - super(SItem_statuschange.class, metadata, "null", "item__statuschange_"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(item_id, ColumnMetadata.named("item__id").withIndex(1).ofType(-5).withSize(19).notNull()); - addMetadata(statusChangesId, ColumnMetadata.named("statusChanges_id").withIndex(2).ofType(-5).withSize(19).notNull()); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SKittens.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SKittens.java deleted file mode 100644 index 8451c3be5e..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SKittens.java +++ /dev/null @@ -1,63 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - - -/** - * SKittens is a Querydsl query type for SKittens - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SKittens extends com.mysema.query.sql.RelationalPathBase<SKittens> { - - private static final long serialVersionUID = 1947872699; - - public static final SKittens kittens = new SKittens("kittens"); - - public final NumberPath<Integer> catId = createNumber("catId", Integer.class); - - public final NumberPath<Integer> ind = createNumber("ind", Integer.class); - - public final NumberPath<Integer> kittenId = createNumber("kittenId", Integer.class); - - public final com.mysema.query.sql.PrimaryKey<SKittens> primary = createPrimaryKey(catId, ind); - - public final com.mysema.query.sql.ForeignKey<SAnimal> fkd60087cc3881aaa7 = createForeignKey(kittenId, "id"); - - public final com.mysema.query.sql.ForeignKey<SAnimal> fkd60087cc8f00fdf8 = createForeignKey(catId, "id"); - - public SKittens(String variable) { - super(SKittens.class, forVariable(variable), "null", "kittens"); - addMetadata(); - } - - public SKittens(String variable, String schema, String table) { - super(SKittens.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SKittens(Path<? extends SKittens> path) { - super(path.getType(), path.getMetadata(), "null", "kittens"); - addMetadata(); - } - - public SKittens(PathMetadata<?> metadata) { - super(SKittens.class, metadata, "null", "kittens"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(catId, ColumnMetadata.named("cat_id").withIndex(1).ofType(4).withSize(10).notNull()); - addMetadata(ind, ColumnMetadata.named("ind").withIndex(3).ofType(4).withSize(10).notNull()); - addMetadata(kittenId, ColumnMetadata.named("kitten_id").withIndex(2).ofType(4).withSize(10).notNull()); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SKittensSet.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SKittensSet.java deleted file mode 100644 index a10b9fc028..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SKittensSet.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - - -/** - * SKittensSet is a Querydsl query type for SKittensSet - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SKittensSet extends com.mysema.query.sql.RelationalPathBase<SKittensSet> { - - private static final long serialVersionUID = -227477337; - - public static final SKittensSet kittensSet = new SKittensSet("kittens_set"); - - public final NumberPath<Integer> catId = createNumber("catId", Integer.class); - - public final NumberPath<Integer> kittenId = createNumber("kittenId", Integer.class); - - public final com.mysema.query.sql.PrimaryKey<SKittensSet> primary = createPrimaryKey(catId, kittenId); - - public final com.mysema.query.sql.ForeignKey<SAnimal> fk4fccad6f8f00fdf8 = createForeignKey(catId, "id"); - - public final com.mysema.query.sql.ForeignKey<SAnimal> fk4fccad6f3881aaa7 = createForeignKey(kittenId, "id"); - - public SKittensSet(String variable) { - super(SKittensSet.class, forVariable(variable), "null", "kittens_set"); - addMetadata(); - } - - public SKittensSet(String variable, String schema, String table) { - super(SKittensSet.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SKittensSet(Path<? extends SKittensSet> path) { - super(path.getType(), path.getMetadata(), "null", "kittens_set"); - addMetadata(); - } - - public SKittensSet(PathMetadata<?> metadata) { - super(SKittensSet.class, metadata, "null", "kittens_set"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(catId, ColumnMetadata.named("cat_id").withIndex(1).ofType(4).withSize(10).notNull()); - addMetadata(kittenId, ColumnMetadata.named("kitten_id").withIndex(2).ofType(4).withSize(10).notNull()); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SLibrary.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SLibrary.java deleted file mode 100644 index 1240ca9963..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SLibrary.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - - -/** - * SLibrary is a Querydsl query type for SLibrary - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SLibrary extends com.mysema.query.sql.RelationalPathBase<SLibrary> { - - private static final long serialVersionUID = 1480035061; - - public static final SLibrary library_ = new SLibrary("library_"); - - public final NumberPath<Long> identity = createNumber("identity", Long.class); - - public final com.mysema.query.sql.PrimaryKey<SLibrary> primary = createPrimaryKey(identity); - - public final com.mysema.query.sql.ForeignKey<SBookversion> _fkef4bc070e364cd17 = createInvForeignKey(identity, "library_identity"); - - public SLibrary(String variable) { - super(SLibrary.class, forVariable(variable), "null", "library_"); - addMetadata(); - } - - public SLibrary(String variable, String schema, String table) { - super(SLibrary.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SLibrary(Path<? extends SLibrary> path) { - super(path.getType(), path.getMetadata(), "null", "library_"); - addMetadata(); - } - - public SLibrary(PathMetadata<?> metadata) { - super(SLibrary.class, metadata, "null", "library_"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(identity, ColumnMetadata.named("identity").withIndex(1).ofType(-5).withSize(19).notNull()); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SLineItems.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SLineItems.java deleted file mode 100644 index 9d5ec7f4de..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SLineItems.java +++ /dev/null @@ -1,63 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - - -/** - * SLineItems is a Querydsl query type for SLineItems - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SLineItems extends com.mysema.query.sql.RelationalPathBase<SLineItems> { - - private static final long serialVersionUID = 302253659; - - public static final SLineItems LineItems = new SLineItems("LineItems"); - - public final NumberPath<Integer> _index = createNumber("_index", Integer.class); - - public final NumberPath<Long> lineItemsId = createNumber("lineItemsId", Long.class); - - public final NumberPath<Long> order_id = createNumber("order_id", Long.class); - - public final com.mysema.query.sql.PrimaryKey<SLineItems> primary = createPrimaryKey(_index, order_id); - - public final com.mysema.query.sql.ForeignKey<SOrder> fkb2e400cb968f515 = createForeignKey(order_id, "id"); - - public final com.mysema.query.sql.ForeignKey<SItem> fkb2e400c3d8e44c3 = createForeignKey(lineItemsId, "id"); - - public SLineItems(String variable) { - super(SLineItems.class, forVariable(variable), "null", "LineItems"); - addMetadata(); - } - - public SLineItems(String variable, String schema, String table) { - super(SLineItems.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SLineItems(Path<? extends SLineItems> path) { - super(path.getType(), path.getMetadata(), "null", "LineItems"); - addMetadata(); - } - - public SLineItems(PathMetadata<?> metadata) { - super(SLineItems.class, metadata, "null", "LineItems"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(_index, ColumnMetadata.named("_index").withIndex(3).ofType(4).withSize(10).notNull()); - addMetadata(lineItemsId, ColumnMetadata.named("lineItems_id").withIndex(2).ofType(-5).withSize(19).notNull()); - addMetadata(order_id, ColumnMetadata.named("order__id").withIndex(1).ofType(-5).withSize(19).notNull()); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SLocation.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SLocation.java deleted file mode 100644 index c1db61cc0f..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SLocation.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - - -/** - * SLocation is a Querydsl query type for SLocation - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SLocation extends com.mysema.query.sql.RelationalPathBase<SLocation> { - - private static final long serialVersionUID = 921451897; - - public static final SLocation location_ = new SLocation("location_"); - - public final NumberPath<Long> id = createNumber("id", Long.class); - - public final StringPath name = createString("name"); - - public final com.mysema.query.sql.PrimaryKey<SLocation> primary = createPrimaryKey(id); - - public final com.mysema.query.sql.ForeignKey<SStore> _fkcad4239e8a55845c = createInvForeignKey(id, "location_id"); - - public SLocation(String variable) { - super(SLocation.class, forVariable(variable), "null", "location_"); - addMetadata(); - } - - public SLocation(String variable, String schema, String table) { - super(SLocation.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SLocation(Path<? extends SLocation> path) { - super(path.getType(), path.getMetadata(), "null", "location_"); - addMetadata(); - } - - public SLocation(PathMetadata<?> metadata) { - super(SLocation.class, metadata, "null", "location_"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(-5).withSize(19).notNull()); - addMetadata(name, ColumnMetadata.named("name").withIndex(2).ofType(12).withSize(255)); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SMammal.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SMammal.java deleted file mode 100644 index b544c220aa..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SMammal.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - -import java.io.*; - -import java.io.File; - - -/** - * SMammal is a Querydsl query type for SMammal - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SMammal extends com.mysema.query.sql.RelationalPathBase<SMammal> { - - private static final long serialVersionUID = 666678672; - - public static final SMammal Mammal = new SMammal("Mammal"); - - public final StringPath dtype = createString("dtype"); - - public final NumberPath<Long> id = createNumber("id", Long.class); - - public final com.mysema.query.sql.PrimaryKey<SMammal> primary = createPrimaryKey(id); - - public final com.mysema.query.sql.ForeignKey<SHumanHairs> _fk6649531ff097e318 = createInvForeignKey(id, "Human_id"); - - public final com.mysema.query.sql.ForeignKey<SWorldMammal> _fk4070aeece01c8ee7 = createInvForeignKey(id, "mammals_id"); - - public SMammal(String variable) { - super(SMammal.class, forVariable(variable), "null", "Mammal"); - addMetadata(); - } - - public SMammal(String variable, String schema, String table) { - super(SMammal.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SMammal(Path<? extends SMammal> path) { - super(path.getType(), path.getMetadata(), "null", "Mammal"); - addMetadata(); - } - - public SMammal(PathMetadata<?> metadata) { - super(SMammal.class, metadata, "null", "Mammal"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(dtype, ColumnMetadata.named("DTYPE").withIndex(1).ofType(12).withSize(31).notNull()); - addMetadata(id, ColumnMetadata.named("id").withIndex(2).ofType(-5).withSize(19).notNull()); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SName.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SName.java deleted file mode 100644 index a89072cb9a..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SName.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - - -/** - * SName is a Querydsl query type for SName - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SName extends com.mysema.query.sql.RelationalPathBase<SName> { - - private static final long serialVersionUID = -116118301; - - public static final SName name_ = new SName("name_"); - - public final StringPath firstName = createString("firstName"); - - public final NumberPath<Long> id = createNumber("id", Long.class); - - public final StringPath lastName = createString("lastName"); - - public final StringPath nickName = createString("nickName"); - - public final com.mysema.query.sql.PrimaryKey<SName> primary = createPrimaryKey(id); - - public final com.mysema.query.sql.ForeignKey<SCustomer> _fk600e7c4196a83d9c = createInvForeignKey(id, "name_id"); - - public SName(String variable) { - super(SName.class, forVariable(variable), "null", "name_"); - addMetadata(); - } - - public SName(String variable, String schema, String table) { - super(SName.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SName(Path<? extends SName> path) { - super(path.getType(), path.getMetadata(), "null", "name_"); - addMetadata(); - } - - public SName(PathMetadata<?> metadata) { - super(SName.class, metadata, "null", "name_"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(firstName, ColumnMetadata.named("firstName").withIndex(2).ofType(12).withSize(255)); - addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(-5).withSize(19).notNull()); - addMetadata(lastName, ColumnMetadata.named("lastName").withIndex(3).ofType(12).withSize(255)); - addMetadata(nickName, ColumnMetadata.named("nickName").withIndex(4).ofType(12).withSize(255)); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SNameListNames.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SNameListNames.java deleted file mode 100644 index 790cf767fa..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SNameListNames.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - - -/** - * SNameListNames is a Querydsl query type for SNameListNames - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SNameListNames extends com.mysema.query.sql.RelationalPathBase<SNameListNames> { - - private static final long serialVersionUID = 150303150; - - public static final SNameListNames NameListNames = new SNameListNames("NameList_names"); - - public final NumberPath<Long> nameListId = createNumber("nameListId", Long.class); - - public final StringPath names = createString("names"); - - public final com.mysema.query.sql.ForeignKey<SNamelist> fkd6c82d7217b6c3fc = createForeignKey(nameListId, "id"); - - public SNameListNames(String variable) { - super(SNameListNames.class, forVariable(variable), "null", "NameList_names"); - addMetadata(); - } - - public SNameListNames(String variable, String schema, String table) { - super(SNameListNames.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SNameListNames(Path<? extends SNameListNames> path) { - super(path.getType(), path.getMetadata(), "null", "NameList_names"); - addMetadata(); - } - - public SNameListNames(PathMetadata<?> metadata) { - super(SNameListNames.class, metadata, "null", "NameList_names"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(nameListId, ColumnMetadata.named("NameList_id").withIndex(1).ofType(-5).withSize(19).notNull()); - addMetadata(names, ColumnMetadata.named("names").withIndex(2).ofType(12).withSize(255)); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SNamed.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SNamed.java deleted file mode 100644 index cb51ed2087..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SNamed.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - - -/** - * SNamed is a Querydsl query type for SNamed - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SNamed extends com.mysema.query.sql.RelationalPathBase<SNamed> { - - private static final long serialVersionUID = 695300215; - - public static final SNamed named_ = new SNamed("named_"); - - public final NumberPath<Long> id = createNumber("id", Long.class); - - public final StringPath name = createString("name"); - - public final com.mysema.query.sql.PrimaryKey<SNamed> primary = createPrimaryKey(id); - - public SNamed(String variable) { - super(SNamed.class, forVariable(variable), "null", "named_"); - addMetadata(); - } - - public SNamed(String variable, String schema, String table) { - super(SNamed.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SNamed(Path<? extends SNamed> path) { - super(path.getType(), path.getMetadata(), "null", "named_"); - addMetadata(); - } - - public SNamed(PathMetadata<?> metadata) { - super(SNamed.class, metadata, "null", "named_"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(-5).withSize(19).notNull()); - addMetadata(name, ColumnMetadata.named("name").withIndex(2).ofType(12).withSize(255)); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SNamelist.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SNamelist.java deleted file mode 100644 index c8dccc82b7..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SNamelist.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - - -/** - * SNamelist is a Querydsl query type for SNamelist - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SNamelist extends com.mysema.query.sql.RelationalPathBase<SNamelist> { - - private static final long serialVersionUID = -930763259; - - public static final SNamelist namelist_ = new SNamelist("namelist_"); - - public final NumberPath<Long> id = createNumber("id", Long.class); - - public final com.mysema.query.sql.PrimaryKey<SNamelist> primary = createPrimaryKey(id); - - public final com.mysema.query.sql.ForeignKey<SNameListNames> _fkd6c82d7217b6c3fc = createInvForeignKey(id, "NameList_id"); - - public SNamelist(String variable) { - super(SNamelist.class, forVariable(variable), "null", "namelist_"); - addMetadata(); - } - - public SNamelist(String variable, String schema, String table) { - super(SNamelist.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SNamelist(Path<? extends SNamelist> path) { - super(path.getType(), path.getMetadata(), "null", "namelist_"); - addMetadata(); - } - - public SNamelist(PathMetadata<?> metadata) { - super(SNamelist.class, metadata, "null", "namelist_"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(-5).withSize(19).notNull()); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SNationality.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SNationality.java deleted file mode 100644 index 13dee5532b..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SNationality.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - - -/** - * SNationality is a Querydsl query type for SNationality - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SNationality extends com.mysema.query.sql.RelationalPathBase<SNationality> { - - private static final long serialVersionUID = 478851476; - - public static final SNationality nationality_ = new SNationality("nationality_"); - - public final NumberPath<Integer> calendarId = createNumber("calendarId", Integer.class); - - public final NumberPath<Long> id = createNumber("id", Long.class); - - public final com.mysema.query.sql.PrimaryKey<SNationality> primary = createPrimaryKey(id); - - public final com.mysema.query.sql.ForeignKey<SCalendar> fkab8efa23591ebbc = createForeignKey(calendarId, "id"); - - public final com.mysema.query.sql.ForeignKey<SPerson> _fkd78fcfaaf6578e38 = createInvForeignKey(id, "nationality_id"); - - public SNationality(String variable) { - super(SNationality.class, forVariable(variable), "null", "nationality_"); - addMetadata(); - } - - public SNationality(String variable, String schema, String table) { - super(SNationality.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SNationality(Path<? extends SNationality> path) { - super(path.getType(), path.getMetadata(), "null", "nationality_"); - addMetadata(); - } - - public SNationality(PathMetadata<?> metadata) { - super(SNationality.class, metadata, "null", "nationality_"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(calendarId, ColumnMetadata.named("calendar_id").withIndex(2).ofType(4).withSize(10)); - addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(-5).withSize(19).notNull()); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SNumeric.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SNumeric.java deleted file mode 100644 index 0ec9525598..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SNumeric.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - - -/** - * SNumeric is a Querydsl query type for SNumeric - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SNumeric extends com.mysema.query.sql.RelationalPathBase<SNumeric> { - - private static final long serialVersionUID = -1260757277; - - public static final SNumeric numeric_ = new SNumeric("numeric_"); - - public final NumberPath<Long> id = createNumber("id", Long.class); - - public final NumberPath<java.math.BigDecimal> value = createNumber("value", java.math.BigDecimal.class); - - public final NumberPath<java.math.BigDecimal> value_ = createNumber("value_", java.math.BigDecimal.class); - - public final com.mysema.query.sql.PrimaryKey<SNumeric> primary = createPrimaryKey(id); - - public SNumeric(String variable) { - super(SNumeric.class, forVariable(variable), "null", "numeric_"); - addMetadata(); - } - - public SNumeric(String variable, String schema, String table) { - super(SNumeric.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SNumeric(Path<? extends SNumeric> path) { - super(path.getType(), path.getMetadata(), "null", "numeric_"); - addMetadata(); - } - - public SNumeric(PathMetadata<?> metadata) { - super(SNumeric.class, metadata, "null", "numeric_"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(-5).withSize(19).notNull()); - addMetadata(value, ColumnMetadata.named("value").withIndex(2).ofType(3).withSize(19).withDigits(2)); - addMetadata(value_, ColumnMetadata.named("value_").withIndex(3).ofType(3).withSize(19).withDigits(2)); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SOrder.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SOrder.java deleted file mode 100644 index 2833fa7952..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SOrder.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - - -/** - * SOrder is a Querydsl query type for SOrder - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SOrder extends com.mysema.query.sql.RelationalPathBase<SOrder> { - - private static final long serialVersionUID = 739361538; - - public static final SOrder order_ = new SOrder("order_"); - - public final NumberPath<Integer> customerId = createNumber("customerId", Integer.class); - - public final NumberPath<Long> id = createNumber("id", Long.class); - - public final BooleanPath paid = createBoolean("paid"); - - public final com.mysema.query.sql.PrimaryKey<SOrder> primary = createPrimaryKey(id); - - public final com.mysema.query.sql.ForeignKey<SCustomer> fkc3df62d1b29c27bc = createForeignKey(customerId, "id"); - - public final com.mysema.query.sql.ForeignKey<SOrder_item> _fk1b5e8cbeb968f515 = createInvForeignKey(id, "order__id"); - - public final com.mysema.query.sql.ForeignKey<SCustomer> _fk600e7c419cc457f1 = createInvForeignKey(id, "currentOrder_id"); - - public final com.mysema.query.sql.ForeignKey<SOrderDeliveredItemIndices> _fk30cbd6611a4d2378 = createInvForeignKey(id, "Order_id"); - - public final com.mysema.query.sql.ForeignKey<SLineItems> _fkb2e400cb968f515 = createInvForeignKey(id, "order__id"); - - public SOrder(String variable) { - super(SOrder.class, forVariable(variable), "null", "order_"); - addMetadata(); - } - - public SOrder(String variable, String schema, String table) { - super(SOrder.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SOrder(Path<? extends SOrder> path) { - super(path.getType(), path.getMetadata(), "null", "order_"); - addMetadata(); - } - - public SOrder(PathMetadata<?> metadata) { - super(SOrder.class, metadata, "null", "order_"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(customerId, ColumnMetadata.named("customer_id").withIndex(3).ofType(4).withSize(10)); - addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(-5).withSize(19).notNull()); - addMetadata(paid, ColumnMetadata.named("paid").withIndex(2).ofType(-7).notNull()); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SOrderDeliveredItemIndices.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SOrderDeliveredItemIndices.java deleted file mode 100644 index 0ec3dcc8b6..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SOrderDeliveredItemIndices.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - - -/** - * SOrderDeliveredItemIndices is a Querydsl query type for SOrderDeliveredItemIndices - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SOrderDeliveredItemIndices extends com.mysema.query.sql.RelationalPathBase<SOrderDeliveredItemIndices> { - - private static final long serialVersionUID = 860822157; - - public static final SOrderDeliveredItemIndices OrderDeliveredItemIndices = new SOrderDeliveredItemIndices("Order_deliveredItemIndices"); - - public final NumberPath<Integer> _index = createNumber("_index", Integer.class); - - public final NumberPath<Integer> deliveredItemIndices = createNumber("deliveredItemIndices", Integer.class); - - public final NumberPath<Long> orderId = createNumber("orderId", Long.class); - - public final com.mysema.query.sql.PrimaryKey<SOrderDeliveredItemIndices> primary = createPrimaryKey(orderId, _index); - - public final com.mysema.query.sql.ForeignKey<SOrder> fk30cbd6611a4d2378 = createForeignKey(orderId, "id"); - - public SOrderDeliveredItemIndices(String variable) { - super(SOrderDeliveredItemIndices.class, forVariable(variable), "null", "Order_deliveredItemIndices"); - addMetadata(); - } - - public SOrderDeliveredItemIndices(String variable, String schema, String table) { - super(SOrderDeliveredItemIndices.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SOrderDeliveredItemIndices(Path<? extends SOrderDeliveredItemIndices> path) { - super(path.getType(), path.getMetadata(), "null", "Order_deliveredItemIndices"); - addMetadata(); - } - - public SOrderDeliveredItemIndices(PathMetadata<?> metadata) { - super(SOrderDeliveredItemIndices.class, metadata, "null", "Order_deliveredItemIndices"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(_index, ColumnMetadata.named("_index").withIndex(3).ofType(4).withSize(10).notNull()); - addMetadata(deliveredItemIndices, ColumnMetadata.named("deliveredItemIndices").withIndex(2).ofType(4).withSize(10)); - addMetadata(orderId, ColumnMetadata.named("Order_id").withIndex(1).ofType(-5).withSize(19).notNull()); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SOrder_item.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SOrder_item.java deleted file mode 100644 index d8f7206f1b..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SOrder_item.java +++ /dev/null @@ -1,63 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - - -/** - * SOrder_item is a Querydsl query type for SOrder_item - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SOrder_item extends com.mysema.query.sql.RelationalPathBase<SOrder_item> { - - private static final long serialVersionUID = -2131249686; - - public static final SOrder_item order_item_ = new SOrder_item("order__item_"); - - public final NumberPath<Integer> _index = createNumber("_index", Integer.class); - - public final NumberPath<Long> itemsId = createNumber("itemsId", Long.class); - - public final NumberPath<Long> order_id = createNumber("order_id", Long.class); - - public final com.mysema.query.sql.PrimaryKey<SOrder_item> primary = createPrimaryKey(_index, order_id); - - public final com.mysema.query.sql.ForeignKey<SItem> fk1b5e8cbe7640c8cf = createForeignKey(itemsId, "id"); - - public final com.mysema.query.sql.ForeignKey<SOrder> fk1b5e8cbeb968f515 = createForeignKey(order_id, "id"); - - public SOrder_item(String variable) { - super(SOrder_item.class, forVariable(variable), "null", "order__item_"); - addMetadata(); - } - - public SOrder_item(String variable, String schema, String table) { - super(SOrder_item.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SOrder_item(Path<? extends SOrder_item> path) { - super(path.getType(), path.getMetadata(), "null", "order__item_"); - addMetadata(); - } - - public SOrder_item(PathMetadata<?> metadata) { - super(SOrder_item.class, metadata, "null", "order__item_"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(_index, ColumnMetadata.named("_index").withIndex(3).ofType(4).withSize(10).notNull()); - addMetadata(itemsId, ColumnMetadata.named("items_id").withIndex(2).ofType(-5).withSize(19).notNull()); - addMetadata(order_id, ColumnMetadata.named("order__id").withIndex(1).ofType(-5).withSize(19).notNull()); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SParameter.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SParameter.java deleted file mode 100644 index 368bc77790..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SParameter.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - - -/** - * SParameter is a Querydsl query type for SParameter - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SParameter extends com.mysema.query.sql.RelationalPathBase<SParameter> { - - private static final long serialVersionUID = 1712103815; - - public static final SParameter parameter_ = new SParameter("parameter_"); - - public final NumberPath<Long> id = createNumber("id", Long.class); - - public final com.mysema.query.sql.PrimaryKey<SParameter> primary = createPrimaryKey(id); - - public final com.mysema.query.sql.ForeignKey<SFormula> _fk1c4adbb924189298 = createInvForeignKey(id, "parameter_id"); - - public SParameter(String variable) { - super(SParameter.class, forVariable(variable), "null", "parameter_"); - addMetadata(); - } - - public SParameter(String variable, String schema, String table) { - super(SParameter.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SParameter(Path<? extends SParameter> path) { - super(path.getType(), path.getMetadata(), "null", "parameter_"); - addMetadata(); - } - - public SParameter(PathMetadata<?> metadata) { - super(SParameter.class, metadata, "null", "parameter_"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(-5).withSize(19).notNull()); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SParent.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SParent.java deleted file mode 100644 index e2149f173d..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SParent.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - - -/** - * SParent is a Querydsl query type for SParent - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SParent extends com.mysema.query.sql.RelationalPathBase<SParent> { - - private static final long serialVersionUID = 1859105508; - - public static final SParent parent_ = new SParent("parent_"); - - public final StringPath childName = createString("childName"); - - public final NumberPath<Long> id = createNumber("id", Long.class); - - public final StringPath name = createString("name"); - - public final com.mysema.query.sql.PrimaryKey<SParent> primary = createPrimaryKey(id); - - public SParent(String variable) { - super(SParent.class, forVariable(variable), "null", "parent_"); - addMetadata(); - } - - public SParent(String variable, String schema, String table) { - super(SParent.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SParent(Path<? extends SParent> path) { - super(path.getType(), path.getMetadata(), "null", "parent_"); - addMetadata(); - } - - public SParent(PathMetadata<?> metadata) { - super(SParent.class, metadata, "null", "parent_"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(childName, ColumnMetadata.named("childName").withIndex(2).ofType(12).withSize(255)); - addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(-5).withSize(19).notNull()); - addMetadata(name, ColumnMetadata.named("name").withIndex(3).ofType(12).withSize(255)); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SParent2.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SParent2.java deleted file mode 100644 index cfb7077e39..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SParent2.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - -import java.io.*; - -import java.io.File; - - -/** - * SParent2 is a Querydsl query type for SParent2 - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SParent2 extends com.mysema.query.sql.RelationalPathBase<SParent2> { - - private static final long serialVersionUID = 1859105463; - - public static final SParent2 Parent2 = new SParent2("Parent2"); - - public final NumberPath<Integer> id = createNumber("id", Integer.class); - - public final com.mysema.query.sql.PrimaryKey<SParent2> primary = createPrimaryKey(id); - - public final com.mysema.query.sql.ForeignKey<SChild2> _fk783f9ab6c2dbacbc = createInvForeignKey(id, "parent_id"); - - public SParent2(String variable) { - super(SParent2.class, forVariable(variable), "null", "Parent2"); - addMetadata(); - } - - public SParent2(String variable, String schema, String table) { - super(SParent2.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SParent2(Path<? extends SParent2> path) { - super(path.getType(), path.getMetadata(), "null", "Parent2"); - addMetadata(); - } - - public SParent2(PathMetadata<?> metadata) { - super(SParent2.class, metadata, "null", "Parent2"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(4).withSize(10).notNull()); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SPerson.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SPerson.java deleted file mode 100644 index bfb5404954..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SPerson.java +++ /dev/null @@ -1,71 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - - -/** - * SPerson is a Querydsl query type for SPerson - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SPerson extends com.mysema.query.sql.RelationalPathBase<SPerson> { - - private static final long serialVersionUID = 1974039961; - - public static final SPerson person_ = new SPerson("person_"); - - public final DatePath<java.sql.Date> birthDay = createDate("birthDay", java.sql.Date.class); - - public final NumberPath<Long> i = createNumber("i", Long.class); - - public final StringPath name = createString("name"); - - public final NumberPath<Long> nationalityId = createNumber("nationalityId", Long.class); - - public final NumberPath<Long> pidId = createNumber("pidId", Long.class); - - public final com.mysema.query.sql.PrimaryKey<SPerson> primary = createPrimaryKey(i); - - public final com.mysema.query.sql.ForeignKey<SPersonid> fkd78fcfaad7999e61 = createForeignKey(pidId, "id"); - - public final com.mysema.query.sql.ForeignKey<SNationality> fkd78fcfaaf6578e38 = createForeignKey(nationalityId, "id"); - - public final com.mysema.query.sql.ForeignKey<SAccount> _fk809dbbd28cfac74 = createInvForeignKey(i, "owner_i"); - - public SPerson(String variable) { - super(SPerson.class, forVariable(variable), "null", "person_"); - addMetadata(); - } - - public SPerson(String variable, String schema, String table) { - super(SPerson.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SPerson(Path<? extends SPerson> path) { - super(path.getType(), path.getMetadata(), "null", "person_"); - addMetadata(); - } - - public SPerson(PathMetadata<?> metadata) { - super(SPerson.class, metadata, "null", "person_"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(birthDay, ColumnMetadata.named("birthDay").withIndex(2).ofType(91).withSize(10)); - addMetadata(i, ColumnMetadata.named("i").withIndex(1).ofType(-5).withSize(19).notNull()); - addMetadata(name, ColumnMetadata.named("name").withIndex(3).ofType(12).withSize(255)); - addMetadata(nationalityId, ColumnMetadata.named("nationality_id").withIndex(4).ofType(-5).withSize(19)); - addMetadata(pidId, ColumnMetadata.named("pid_id").withIndex(5).ofType(-5).withSize(19)); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SPersonid.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SPersonid.java deleted file mode 100644 index 196a295547..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SPersonid.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - - -/** - * SPersonid is a Querydsl query type for SPersonid - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SPersonid extends com.mysema.query.sql.RelationalPathBase<SPersonid> { - - private static final long serialVersionUID = -1323129506; - - public static final SPersonid personid_ = new SPersonid("personid_"); - - public final StringPath country = createString("country"); - - public final NumberPath<Long> id = createNumber("id", Long.class); - - public final NumberPath<Integer> medicareNumber = createNumber("medicareNumber", Integer.class); - - public final com.mysema.query.sql.PrimaryKey<SPersonid> primary = createPrimaryKey(id); - - public final com.mysema.query.sql.ForeignKey<SPerson> _fkd78fcfaad7999e61 = createInvForeignKey(id, "pid_id"); - - public SPersonid(String variable) { - super(SPersonid.class, forVariable(variable), "null", "personid_"); - addMetadata(); - } - - public SPersonid(String variable, String schema, String table) { - super(SPersonid.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SPersonid(Path<? extends SPersonid> path) { - super(path.getType(), path.getMetadata(), "null", "personid_"); - addMetadata(); - } - - public SPersonid(PathMetadata<?> metadata) { - super(SPersonid.class, metadata, "null", "personid_"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(country, ColumnMetadata.named("country").withIndex(2).ofType(12).withSize(255)); - addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(-5).withSize(19).notNull()); - addMetadata(medicareNumber, ColumnMetadata.named("medicareNumber").withIndex(3).ofType(4).withSize(10).notNull()); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SPlayer.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SPlayer.java deleted file mode 100644 index 986aecdaea..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SPlayer.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - - -/** - * SPlayer is a Querydsl query type for SPlayer - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SPlayer extends com.mysema.query.sql.RelationalPathBase<SPlayer> { - - private static final long serialVersionUID = -2136053875; - - public static final SPlayer player_ = new SPlayer("player_"); - - public final NumberPath<Long> id = createNumber("id", Long.class); - - public final com.mysema.query.sql.PrimaryKey<SPlayer> primary = createPrimaryKey(id); - - public final com.mysema.query.sql.ForeignKey<SPlayerScores> _fkd5dc571fd8736d5c = createInvForeignKey(id, "Player_id"); - - public SPlayer(String variable) { - super(SPlayer.class, forVariable(variable), "null", "player_"); - addMetadata(); - } - - public SPlayer(String variable, String schema, String table) { - super(SPlayer.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SPlayer(Path<? extends SPlayer> path) { - super(path.getType(), path.getMetadata(), "null", "player_"); - addMetadata(); - } - - public SPlayer(PathMetadata<?> metadata) { - super(SPlayer.class, metadata, "null", "player_"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(-5).withSize(19).notNull()); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SPlayerScores.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SPlayerScores.java deleted file mode 100644 index 984b36a1e0..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SPlayerScores.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - - -/** - * SPlayerScores is a Querydsl query type for SPlayerScores - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SPlayerScores extends com.mysema.query.sql.RelationalPathBase<SPlayerScores> { - - private static final long serialVersionUID = 1627547091; - - public static final SPlayerScores PlayerScores = new SPlayerScores("Player_scores"); - - public final NumberPath<Long> playerId = createNumber("playerId", Long.class); - - public final NumberPath<Integer> scores = createNumber("scores", Integer.class); - - public final com.mysema.query.sql.ForeignKey<SPlayer> fkd5dc571fd8736d5c = createForeignKey(playerId, "id"); - - public SPlayerScores(String variable) { - super(SPlayerScores.class, forVariable(variable), "null", "Player_scores"); - addMetadata(); - } - - public SPlayerScores(String variable, String schema, String table) { - super(SPlayerScores.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SPlayerScores(Path<? extends SPlayerScores> path) { - super(path.getType(), path.getMetadata(), "null", "Player_scores"); - addMetadata(); - } - - public SPlayerScores(PathMetadata<?> metadata) { - super(SPlayerScores.class, metadata, "null", "Player_scores"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(playerId, ColumnMetadata.named("Player_id").withIndex(1).ofType(-5).withSize(19).notNull()); - addMetadata(scores, ColumnMetadata.named("scores").withIndex(2).ofType(4).withSize(10)); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SPrice.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SPrice.java deleted file mode 100644 index de1fdb5a81..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SPrice.java +++ /dev/null @@ -1,63 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - - -/** - * SPrice is a Querydsl query type for SPrice - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SPrice extends com.mysema.query.sql.RelationalPathBase<SPrice> { - - private static final long serialVersionUID = 768137319; - - public static final SPrice price_ = new SPrice("price_"); - - public final NumberPath<Long> amount = createNumber("amount", Long.class); - - public final NumberPath<Long> id = createNumber("id", Long.class); - - public final NumberPath<Long> productId = createNumber("productId", Long.class); - - public final com.mysema.query.sql.PrimaryKey<SPrice> primary = createPrimaryKey(id); - - public final com.mysema.query.sql.ForeignKey<SItem> fkc59678362c7f0c58 = createForeignKey(productId, "id"); - - public final com.mysema.query.sql.ForeignKey<SCatalog_price> _fkaa04532f5222eaf7 = createInvForeignKey(id, "prices_id"); - - public SPrice(String variable) { - super(SPrice.class, forVariable(variable), "null", "price_"); - addMetadata(); - } - - public SPrice(String variable, String schema, String table) { - super(SPrice.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SPrice(Path<? extends SPrice> path) { - super(path.getType(), path.getMetadata(), "null", "price_"); - addMetadata(); - } - - public SPrice(PathMetadata<?> metadata) { - super(SPrice.class, metadata, "null", "price_"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(amount, ColumnMetadata.named("amount").withIndex(2).ofType(-5).withSize(19).notNull()); - addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(-5).withSize(19).notNull()); - addMetadata(productId, ColumnMetadata.named("product_id").withIndex(3).ofType(-5).withSize(19)); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SShapes.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SShapes.java deleted file mode 100644 index 39553e0fe1..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SShapes.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - -import java.io.*; - -import java.io.File; - - -/** - * SShapes is a Querydsl query type for SShapes - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SShapes extends com.mysema.query.sql.RelationalPathBase<SShapes> { - - private static final long serialVersionUID = 844563747; - - public static final SShapes shapes = new SShapes("SHAPES"); - - public final SimplePath<byte[]> geometry = createSimple("geometry", byte[].class); - - public final NumberPath<Integer> id = createNumber("id", Integer.class); - - public final com.mysema.query.sql.PrimaryKey<SShapes> primary = createPrimaryKey(id); - - public SShapes(String variable) { - super(SShapes.class, forVariable(variable), "null", "SHAPES"); - addMetadata(); - } - - public SShapes(String variable, String schema, String table) { - super(SShapes.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SShapes(Path<? extends SShapes> path) { - super(path.getType(), path.getMetadata(), "null", "SHAPES"); - addMetadata(); - } - - public SShapes(PathMetadata<?> metadata) { - super(SShapes.class, metadata, "null", "SHAPES"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(geometry, ColumnMetadata.named("GEOMETRY").withIndex(2).ofType(-2)); - addMetadata(id, ColumnMetadata.named("ID").withIndex(1).ofType(4).withSize(10).notNull()); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SShow.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SShow.java deleted file mode 100644 index 746bed1393..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SShow.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - - -/** - * SShow is a Querydsl query type for SShow - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SShow extends com.mysema.query.sql.RelationalPathBase<SShow> { - - private static final long serialVersionUID = -111289679; - - public static final SShow show_ = new SShow("show_"); - - public final NumberPath<Long> id = createNumber("id", Long.class); - - public final com.mysema.query.sql.PrimaryKey<SShow> primary = createPrimaryKey(id); - - public final com.mysema.query.sql.ForeignKey<SShowActs> _fk5f6ee03ab40105c = createInvForeignKey(id, "Show_id"); - - public SShow(String variable) { - super(SShow.class, forVariable(variable), "null", "show_"); - addMetadata(); - } - - public SShow(String variable, String schema, String table) { - super(SShow.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SShow(Path<? extends SShow> path) { - super(path.getType(), path.getMetadata(), "null", "show_"); - addMetadata(); - } - - public SShow(PathMetadata<?> metadata) { - super(SShow.class, metadata, "null", "show_"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(-5).withSize(19).notNull()); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SShowActs.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SShowActs.java deleted file mode 100644 index 4cbe881f98..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SShowActs.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - - -/** - * SShowActs is a Querydsl query type for SShowActs - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SShowActs extends com.mysema.query.sql.RelationalPathBase<SShowActs> { - - private static final long serialVersionUID = 283130543; - - public static final SShowActs ShowActs = new SShowActs("Show_acts"); - - public final StringPath acts = createString("acts"); - - public final StringPath actsKEY = createString("actsKEY"); - - public final NumberPath<Long> showId = createNumber("showId", Long.class); - - public final com.mysema.query.sql.PrimaryKey<SShowActs> primary = createPrimaryKey(showId, actsKEY); - - public final com.mysema.query.sql.ForeignKey<SShow> fk5f6ee03ab40105c = createForeignKey(showId, "id"); - - public SShowActs(String variable) { - super(SShowActs.class, forVariable(variable), "null", "Show_acts"); - addMetadata(); - } - - public SShowActs(String variable, String schema, String table) { - super(SShowActs.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SShowActs(Path<? extends SShowActs> path) { - super(path.getType(), path.getMetadata(), "null", "Show_acts"); - addMetadata(); - } - - public SShowActs(PathMetadata<?> metadata) { - super(SShowActs.class, metadata, "null", "Show_acts"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(acts, ColumnMetadata.named("acts").withIndex(2).ofType(12).withSize(255)); - addMetadata(actsKEY, ColumnMetadata.named("acts_KEY").withIndex(3).ofType(12).withSize(255).notNull()); - addMetadata(showId, ColumnMetadata.named("Show_id").withIndex(1).ofType(-5).withSize(19).notNull()); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SStatus.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SStatus.java deleted file mode 100644 index d6029aced9..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SStatus.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - - -/** - * SStatus is a Querydsl query type for SStatus - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SStatus extends com.mysema.query.sql.RelationalPathBase<SStatus> { - - private static final long serialVersionUID = 755356828; - - public static final SStatus status_ = new SStatus("status_"); - - public final NumberPath<Long> id = createNumber("id", Long.class); - - public final StringPath name = createString("name"); - - public final com.mysema.query.sql.PrimaryKey<SStatus> primary = createPrimaryKey(id); - - public final com.mysema.query.sql.ForeignKey<SItem> _fk5fde7acd23307bc = createInvForeignKey(id, "status_id"); - - public final com.mysema.query.sql.ForeignKey<SItem> _fk5fde7ac9ea26263 = createInvForeignKey(id, "currentStatus_id"); - - public SStatus(String variable) { - super(SStatus.class, forVariable(variable), "null", "status_"); - addMetadata(); - } - - public SStatus(String variable, String schema, String table) { - super(SStatus.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SStatus(Path<? extends SStatus> path) { - super(path.getType(), path.getMetadata(), "null", "status_"); - addMetadata(); - } - - public SStatus(PathMetadata<?> metadata) { - super(SStatus.class, metadata, "null", "status_"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(-5).withSize(19).notNull()); - addMetadata(name, ColumnMetadata.named("name").withIndex(2).ofType(12).withSize(255)); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SStatuschange.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SStatuschange.java deleted file mode 100644 index 94da6dbeb0..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SStatuschange.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - - -/** - * SStatuschange is a Querydsl query type for SStatuschange - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SStatuschange extends com.mysema.query.sql.RelationalPathBase<SStatuschange> { - - private static final long serialVersionUID = 87971116; - - public static final SStatuschange statuschange_ = new SStatuschange("statuschange_"); - - public final NumberPath<Long> id = createNumber("id", Long.class); - - public final DateTimePath<java.sql.Timestamp> timeStamp = createDateTime("timeStamp", java.sql.Timestamp.class); - - public final com.mysema.query.sql.PrimaryKey<SStatuschange> primary = createPrimaryKey(id); - - public final com.mysema.query.sql.ForeignKey<SItem_statuschange> _fkcb99fb2ab2bd098d = createInvForeignKey(id, "statusChanges_id"); - - public SStatuschange(String variable) { - super(SStatuschange.class, forVariable(variable), "null", "statuschange_"); - addMetadata(); - } - - public SStatuschange(String variable, String schema, String table) { - super(SStatuschange.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SStatuschange(Path<? extends SStatuschange> path) { - super(path.getType(), path.getMetadata(), "null", "statuschange_"); - addMetadata(); - } - - public SStatuschange(PathMetadata<?> metadata) { - super(SStatuschange.class, metadata, "null", "statuschange_"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(-5).withSize(19).notNull()); - addMetadata(timeStamp, ColumnMetadata.named("timeStamp").withIndex(2).ofType(93).withSize(19)); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SStore.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SStore.java deleted file mode 100644 index 0649575905..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SStore.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - - -/** - * SStore is a Querydsl query type for SStore - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SStore extends com.mysema.query.sql.RelationalPathBase<SStore> { - - private static final long serialVersionUID = 856064975; - - public static final SStore store_ = new SStore("store_"); - - public final NumberPath<Long> id = createNumber("id", Long.class); - - public final NumberPath<Long> locationId = createNumber("locationId", Long.class); - - public final com.mysema.query.sql.PrimaryKey<SStore> primary = createPrimaryKey(id); - - public final com.mysema.query.sql.ForeignKey<SLocation> fkcad4239e8a55845c = createForeignKey(locationId, "id"); - - public final com.mysema.query.sql.ForeignKey<SStore_customer> _fk82ba2ce035d2d6bb = createInvForeignKey(id, "store__id"); - - public SStore(String variable) { - super(SStore.class, forVariable(variable), "null", "store_"); - addMetadata(); - } - - public SStore(String variable, String schema, String table) { - super(SStore.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SStore(Path<? extends SStore> path) { - super(path.getType(), path.getMetadata(), "null", "store_"); - addMetadata(); - } - - public SStore(PathMetadata<?> metadata) { - super(SStore.class, metadata, "null", "store_"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(-5).withSize(19).notNull()); - addMetadata(locationId, ColumnMetadata.named("location_id").withIndex(2).ofType(-5).withSize(19)); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SStore_customer.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SStore_customer.java deleted file mode 100644 index 9043fc462f..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SStore_customer.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - - -/** - * SStore_customer is a Querydsl query type for SStore_customer - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SStore_customer extends com.mysema.query.sql.RelationalPathBase<SStore_customer> { - - private static final long serialVersionUID = 1343082834; - - public static final SStore_customer store_customer_ = new SStore_customer("store__customer_"); - - public final NumberPath<Integer> customersId = createNumber("customersId", Integer.class); - - public final NumberPath<Long> store_id = createNumber("store_id", Long.class); - - public final com.mysema.query.sql.ForeignKey<SStore> fk82ba2ce035d2d6bb = createForeignKey(store_id, "id"); - - public final com.mysema.query.sql.ForeignKey<SCustomer> fk82ba2ce051f3c3e5 = createForeignKey(customersId, "id"); - - public SStore_customer(String variable) { - super(SStore_customer.class, forVariable(variable), "null", "store__customer_"); - addMetadata(); - } - - public SStore_customer(String variable, String schema, String table) { - super(SStore_customer.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SStore_customer(Path<? extends SStore_customer> path) { - super(path.getType(), path.getMetadata(), "null", "store__customer_"); - addMetadata(); - } - - public SStore_customer(PathMetadata<?> metadata) { - super(SStore_customer.class, metadata, "null", "store__customer_"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(customersId, ColumnMetadata.named("customers_id").withIndex(2).ofType(4).withSize(10).notNull()); - addMetadata(store_id, ColumnMetadata.named("store__id").withIndex(1).ofType(-5).withSize(19).notNull()); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SSurvey.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SSurvey.java deleted file mode 100644 index 1ed537616e..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SSurvey.java +++ /dev/null @@ -1,63 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - -import java.io.*; - -import java.io.File; - - -/** - * SSurvey is a Querydsl query type for SSurvey - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SSurvey extends com.mysema.query.sql.RelationalPathBase<SSurvey> { - - private static final long serialVersionUID = 857081739; - - public static final SSurvey survey = new SSurvey("SURVEY"); - - public final NumberPath<Integer> id = createNumber("id", Integer.class); - - public final StringPath name = createString("name"); - - public final StringPath name2 = createString("name2"); - - public final com.mysema.query.sql.PrimaryKey<SSurvey> primary = createPrimaryKey(id); - - public SSurvey(String variable) { - super(SSurvey.class, forVariable(variable), "null", "SURVEY"); - addMetadata(); - } - - public SSurvey(String variable, String schema, String table) { - super(SSurvey.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SSurvey(Path<? extends SSurvey> path) { - super(path.getType(), path.getMetadata(), "null", "SURVEY"); - addMetadata(); - } - - public SSurvey(PathMetadata<?> metadata) { - super(SSurvey.class, metadata, "null", "SURVEY"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(id, ColumnMetadata.named("ID").withIndex(1).ofType(4).withSize(10).notNull()); - addMetadata(name, ColumnMetadata.named("NAME").withIndex(2).ofType(12).withSize(30)); - addMetadata(name2, ColumnMetadata.named("NAME2").withIndex(3).ofType(12).withSize(30)); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/STest.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/STest.java deleted file mode 100644 index 874b45ec3d..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/STest.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - -import java.io.*; - -import java.io.File; - - -/** - * STest is a Querydsl query type for STest - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class STest extends com.mysema.query.sql.RelationalPathBase<STest> { - - private static final long serialVersionUID = -1389036285; - - public static final STest test = new STest("TEST"); - - public final StringPath name = createString("name"); - - public STest(String variable) { - super(STest.class, forVariable(variable), "null", "TEST"); - addMetadata(); - } - - public STest(String variable, String schema, String table) { - super(STest.class, forVariable(variable), schema, table); - addMetadata(); - } - - public STest(Path<? extends STest> path) { - super(path.getType(), path.getMetadata(), "null", "TEST"); - addMetadata(); - } - - public STest(PathMetadata<?> metadata) { - super(STest.class, metadata, "null", "TEST"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(name, ColumnMetadata.named("NAME").withIndex(1).ofType(12).withSize(255)); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/STimeTest.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/STimeTest.java deleted file mode 100644 index 3c5cd1182e..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/STimeTest.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - -import java.io.*; - -import java.io.File; - - -/** - * STimeTest is a Querydsl query type for STimeTest - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class STimeTest extends com.mysema.query.sql.RelationalPathBase<STimeTest> { - - private static final long serialVersionUID = -1454836496; - - public static final STimeTest timeTest1 = new STimeTest("TIME_TEST"); - - public final TimePath<java.sql.Time> timeTest = createTime("timeTest", java.sql.Time.class); - - public STimeTest(String variable) { - super(STimeTest.class, forVariable(variable), "null", "TIME_TEST"); - addMetadata(); - } - - public STimeTest(String variable, String schema, String table) { - super(STimeTest.class, forVariable(variable), schema, table); - addMetadata(); - } - - public STimeTest(Path<? extends STimeTest> path) { - super(path.getType(), path.getMetadata(), "null", "TIME_TEST"); - addMetadata(); - } - - public STimeTest(PathMetadata<?> metadata) { - super(STimeTest.class, metadata, "null", "TIME_TEST"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(timeTest, ColumnMetadata.named("TIME_TEST").withIndex(1).ofType(92).withSize(8)); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SUser.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SUser.java deleted file mode 100644 index 58b536778c..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SUser.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - - -/** - * SUser is a Querydsl query type for SUser - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SUser extends com.mysema.query.sql.RelationalPathBase<SUser> { - - private static final long serialVersionUID = -109124701; - - public static final SUser user_ = new SUser("user_"); - - public final NumberPath<Integer> companyId = createNumber("companyId", Integer.class); - - public final StringPath firstName = createString("firstName"); - - public final NumberPath<Long> id = createNumber("id", Long.class); - - public final StringPath lastName = createString("lastName"); - - public final StringPath userName = createString("userName"); - - public final com.mysema.query.sql.PrimaryKey<SUser> primary = createPrimaryKey(id); - - public final com.mysema.query.sql.ForeignKey<SCompany> fk6a68df4dc953998 = createForeignKey(companyId, "id"); - - public final com.mysema.query.sql.ForeignKey<SEmployee> _fk9d39ef712743b59c = createInvForeignKey(id, "user_id"); - - public SUser(String variable) { - super(SUser.class, forVariable(variable), "null", "user_"); - addMetadata(); - } - - public SUser(String variable, String schema, String table) { - super(SUser.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SUser(Path<? extends SUser> path) { - super(path.getType(), path.getMetadata(), "null", "user_"); - addMetadata(); - } - - public SUser(PathMetadata<?> metadata) { - super(SUser.class, metadata, "null", "user_"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(companyId, ColumnMetadata.named("company_id").withIndex(5).ofType(4).withSize(10)); - addMetadata(firstName, ColumnMetadata.named("firstName").withIndex(2).ofType(12).withSize(255)); - addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(-5).withSize(19).notNull()); - addMetadata(lastName, ColumnMetadata.named("lastName").withIndex(3).ofType(12).withSize(255)); - addMetadata(userName, ColumnMetadata.named("userName").withIndex(4).ofType(12).withSize(255)); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SUser2_userprop.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SUser2_userprop.java deleted file mode 100644 index e0f9aa9cc7..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SUser2_userprop.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - - -/** - * SUser2_userprop is a Querydsl query type for SUser2_userprop - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SUser2_userprop extends com.mysema.query.sql.RelationalPathBase<SUser2_userprop> { - - private static final long serialVersionUID = -598341912; - - public static final SUser2_userprop user2_userprop_ = new SUser2_userprop("user2__userprop_"); - - public final NumberPath<Long> propertiesId = createNumber("propertiesId", Long.class); - - public final NumberPath<Long> user2_id = createNumber("user2_id", Long.class); - - public final com.mysema.query.sql.PrimaryKey<SUser2_userprop> primary = createPrimaryKey(propertiesId, user2_id); - - public final com.mysema.query.sql.ForeignKey<SUser2> fk4611b46af21971a1 = createForeignKey(user2_id, "id"); - - public final com.mysema.query.sql.ForeignKey<SUserprop> fk4611b46aa56541dd = createForeignKey(propertiesId, "id"); - - public SUser2_userprop(String variable) { - super(SUser2_userprop.class, forVariable(variable), "null", "user2__userprop_"); - addMetadata(); - } - - public SUser2_userprop(String variable, String schema, String table) { - super(SUser2_userprop.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SUser2_userprop(Path<? extends SUser2_userprop> path) { - super(path.getType(), path.getMetadata(), "null", "user2__userprop_"); - addMetadata(); - } - - public SUser2_userprop(PathMetadata<?> metadata) { - super(SUser2_userprop.class, metadata, "null", "user2__userprop_"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(propertiesId, ColumnMetadata.named("properties_id").withIndex(2).ofType(-5).withSize(19).notNull()); - addMetadata(user2_id, ColumnMetadata.named("user2__id").withIndex(1).ofType(-5).withSize(19).notNull()); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SUserprop.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SUserprop.java deleted file mode 100644 index cbeecdc023..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SUserprop.java +++ /dev/null @@ -1,83 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - - -/** - * SUserprop is a Querydsl query type for SUserprop - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SUserprop extends com.mysema.query.sql.RelationalPathBase<SUserprop> { - - private static final long serialVersionUID = -1821152608; - - public static final SUserprop userprop_ = new SUserprop("userprop_"); - - public final StringPath categoryDescription = createString("categoryDescription"); - - public final StringPath categoryName = createString("categoryName"); - - public final NumberPath<Double> createdBy = createNumber("createdBy", Double.class); - - public final DateTimePath<java.sql.Timestamp> creationDate = createDateTime("creationDate", java.sql.Timestamp.class); - - public final DateTimePath<java.sql.Timestamp> deleteDate = createDateTime("deleteDate", java.sql.Timestamp.class); - - public final NumberPath<Double> deletedBy = createNumber("deletedBy", Double.class); - - public final NumberPath<Long> id = createNumber("id", Long.class); - - public final DateTimePath<java.sql.Timestamp> modificationDate = createDateTime("modificationDate", java.sql.Timestamp.class); - - public final NumberPath<Double> modifiedBy = createNumber("modifiedBy", Double.class); - - public final com.mysema.query.sql.PrimaryKey<SUserprop> primary = createPrimaryKey(id); - - public final com.mysema.query.sql.ForeignKey<SUserprop_category> _fk851f48d3904c19df = createInvForeignKey(id, "userprop__id"); - - public final com.mysema.query.sql.ForeignKey<SUserprop_categoryprop> _fke0fdb7d0904c19df = createInvForeignKey(id, "userprop__id"); - - public final com.mysema.query.sql.ForeignKey<SUser2_userprop> _fk4611b46aa56541dd = createInvForeignKey(id, "properties_id"); - - public SUserprop(String variable) { - super(SUserprop.class, forVariable(variable), "null", "userprop_"); - addMetadata(); - } - - public SUserprop(String variable, String schema, String table) { - super(SUserprop.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SUserprop(Path<? extends SUserprop> path) { - super(path.getType(), path.getMetadata(), "null", "userprop_"); - addMetadata(); - } - - public SUserprop(PathMetadata<?> metadata) { - super(SUserprop.class, metadata, "null", "userprop_"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(categoryDescription, ColumnMetadata.named("categoryDescription").withIndex(2).ofType(12).withSize(255)); - addMetadata(categoryName, ColumnMetadata.named("categoryName").withIndex(3).ofType(12).withSize(255)); - addMetadata(createdBy, ColumnMetadata.named("createdBy").withIndex(4).ofType(8).withSize(22).notNull()); - addMetadata(creationDate, ColumnMetadata.named("creationDate").withIndex(5).ofType(93).withSize(19)); - addMetadata(deleteDate, ColumnMetadata.named("deleteDate").withIndex(6).ofType(93).withSize(19)); - addMetadata(deletedBy, ColumnMetadata.named("deletedBy").withIndex(7).ofType(8).withSize(22).notNull()); - addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(-5).withSize(19).notNull()); - addMetadata(modificationDate, ColumnMetadata.named("modificationDate").withIndex(8).ofType(93).withSize(19)); - addMetadata(modifiedBy, ColumnMetadata.named("modifiedBy").withIndex(9).ofType(8).withSize(22).notNull()); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SUserprop_category.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SUserprop_category.java deleted file mode 100644 index b0f1cbf4c9..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SUserprop_category.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - - -/** - * SUserprop_category is a Querydsl query type for SUserprop_category - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SUserprop_category extends com.mysema.query.sql.RelationalPathBase<SUserprop_category> { - - private static final long serialVersionUID = 301952129; - - public static final SUserprop_category userprop_category_ = new SUserprop_category("userprop__category_"); - - public final NumberPath<Long> childCategoriesId = createNumber("childCategoriesId", Long.class); - - public final NumberPath<Long> userprop_id = createNumber("userprop_id", Long.class); - - public final com.mysema.query.sql.PrimaryKey<SUserprop_category> primary = createPrimaryKey(childCategoriesId, userprop_id); - - public final com.mysema.query.sql.ForeignKey<SUserprop> fk851f48d3904c19df = createForeignKey(userprop_id, "id"); - - public final com.mysema.query.sql.ForeignKey<SCategory> fk851f48d37ab543e8 = createForeignKey(childCategoriesId, "id"); - - public SUserprop_category(String variable) { - super(SUserprop_category.class, forVariable(variable), "null", "userprop__category_"); - addMetadata(); - } - - public SUserprop_category(String variable, String schema, String table) { - super(SUserprop_category.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SUserprop_category(Path<? extends SUserprop_category> path) { - super(path.getType(), path.getMetadata(), "null", "userprop__category_"); - addMetadata(); - } - - public SUserprop_category(PathMetadata<?> metadata) { - super(SUserprop_category.class, metadata, "null", "userprop__category_"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(childCategoriesId, ColumnMetadata.named("childCategories_id").withIndex(2).ofType(-5).withSize(19).notNull()); - addMetadata(userprop_id, ColumnMetadata.named("userprop__id").withIndex(1).ofType(-5).withSize(19).notNull()); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SUserprop_categoryprop.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SUserprop_categoryprop.java deleted file mode 100644 index 05ba82c95f..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SUserprop_categoryprop.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - - -/** - * SUserprop_categoryprop is a Querydsl query type for SUserprop_categoryprop - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SUserprop_categoryprop extends com.mysema.query.sql.RelationalPathBase<SUserprop_categoryprop> { - - private static final long serialVersionUID = -190294914; - - public static final SUserprop_categoryprop userprop_categoryprop_ = new SUserprop_categoryprop("userprop__categoryprop_"); - - public final NumberPath<Long> propertiesId = createNumber("propertiesId", Long.class); - - public final NumberPath<Long> userprop_id = createNumber("userprop_id", Long.class); - - public final com.mysema.query.sql.PrimaryKey<SUserprop_categoryprop> primary = createPrimaryKey(propertiesId, userprop_id); - - public final com.mysema.query.sql.ForeignKey<SCategoryprop> fke0fdb7d0fd94cd90 = createForeignKey(propertiesId, "id"); - - public final com.mysema.query.sql.ForeignKey<SUserprop> fke0fdb7d0904c19df = createForeignKey(userprop_id, "id"); - - public SUserprop_categoryprop(String variable) { - super(SUserprop_categoryprop.class, forVariable(variable), "null", "userprop__categoryprop_"); - addMetadata(); - } - - public SUserprop_categoryprop(String variable, String schema, String table) { - super(SUserprop_categoryprop.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SUserprop_categoryprop(Path<? extends SUserprop_categoryprop> path) { - super(path.getType(), path.getMetadata(), "null", "userprop__categoryprop_"); - addMetadata(); - } - - public SUserprop_categoryprop(PathMetadata<?> metadata) { - super(SUserprop_categoryprop.class, metadata, "null", "userprop__categoryprop_"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(propertiesId, ColumnMetadata.named("properties_id").withIndex(2).ofType(-5).withSize(19).notNull()); - addMetadata(userprop_id, ColumnMetadata.named("userprop__id").withIndex(1).ofType(-5).withSize(19).notNull()); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SWorld.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SWorld.java deleted file mode 100644 index fbf268949f..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SWorld.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - -import java.io.*; - -import java.io.File; - - -/** - * SWorld is a Querydsl query type for SWorld - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SWorld extends com.mysema.query.sql.RelationalPathBase<SWorld> { - - private static final long serialVersionUID = -107384511; - - public static final SWorld World = new SWorld("World"); - - public final NumberPath<Long> id = createNumber("id", Long.class); - - public final com.mysema.query.sql.PrimaryKey<SWorld> primary = createPrimaryKey(id); - - public final com.mysema.query.sql.ForeignKey<SWorldMammal> _fk4070aeecd3538cf8 = createInvForeignKey(id, "World_id"); - - public SWorld(String variable) { - super(SWorld.class, forVariable(variable), "null", "World"); - addMetadata(); - } - - public SWorld(String variable, String schema, String table) { - super(SWorld.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SWorld(Path<? extends SWorld> path) { - super(path.getType(), path.getMetadata(), "null", "World"); - addMetadata(); - } - - public SWorld(PathMetadata<?> metadata) { - super(SWorld.class, metadata, "null", "World"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(-5).withSize(19).notNull()); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SWorldMammal.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SWorldMammal.java deleted file mode 100644 index eb5c423795..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SWorldMammal.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.mysema.query.jpa.domain.sql; - -import static com.mysema.query.types.PathMetadataFactory.*; - -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; -import javax.annotation.Generated; -import com.mysema.query.types.Path; - -import com.mysema.query.sql.ColumnMetadata; - -import java.io.*; - -import java.io.File; - - -/** - * SWorldMammal is a Querydsl query type for SWorldMammal - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SWorldMammal extends com.mysema.query.sql.RelationalPathBase<SWorldMammal> { - - private static final long serialVersionUID = 979697152; - - public static final SWorldMammal WorldMammal = new SWorldMammal("World_Mammal"); - - public final NumberPath<Long> mammalsId = createNumber("mammalsId", Long.class); - - public final NumberPath<Long> worldId = createNumber("worldId", Long.class); - - public final com.mysema.query.sql.PrimaryKey<SWorldMammal> primary = createPrimaryKey(worldId, mammalsId); - - public final com.mysema.query.sql.ForeignKey<SMammal> fk4070aeece01c8ee7 = createForeignKey(mammalsId, "id"); - - public final com.mysema.query.sql.ForeignKey<SWorld> fk4070aeecd3538cf8 = createForeignKey(worldId, "id"); - - public SWorldMammal(String variable) { - super(SWorldMammal.class, forVariable(variable), "null", "World_Mammal"); - addMetadata(); - } - - public SWorldMammal(String variable, String schema, String table) { - super(SWorldMammal.class, forVariable(variable), schema, table); - addMetadata(); - } - - public SWorldMammal(Path<? extends SWorldMammal> path) { - super(path.getType(), path.getMetadata(), "null", "World_Mammal"); - addMetadata(); - } - - public SWorldMammal(PathMetadata<?> metadata) { - super(SWorldMammal.class, metadata, "null", "World_Mammal"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(mammalsId, ColumnMetadata.named("mammals_id").withIndex(2).ofType(-5).withSize(19).notNull()); - addMetadata(worldId, ColumnMetadata.named("World_id").withIndex(1).ofType(-5).withSize(19).notNull()); - } - -} - diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain2/Child.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain2/Child.java deleted file mode 100644 index 23c507d565..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain2/Child.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa.domain2; - -import javax.persistence.Embeddable; - -@Embeddable -public class Child { - - private String childName; - - public String getChildName() { - return childName; - } - - public void setChildName(String childName) { - this.childName = childName; - } - - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain2/Contact.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain2/Contact.java deleted file mode 100644 index a61b726379..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain2/Contact.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa.domain2; - -public class Contact { - - private long id; - - private String firstName, lastName, email; - - public long getId() { - return id; - } - - public void setId(long id) { - this.id = id; - } - - public String getFirstName() { - return firstName; - } - - public void setFirstName(String firstName) { - this.firstName = firstName; - } - - public String getLastName() { - return lastName; - } - - public void setLastName(String lastName) { - this.lastName = lastName; - } - - public String getEmail() { - return email; - } - - public void setEmail(String email) { - this.email = email; - } - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain2/Parent.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain2/Parent.java deleted file mode 100644 index 68071dfca8..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain2/Parent.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa.domain2; - -import javax.persistence.Embedded; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.Table; - -@Entity -@Table(name="parent_") -public class Parent { - - @Id - private long id; - - private String name; - - @Embedded - private Child child; - - public long getId() { - return id; - } - - public void setId(long id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public Child getChild() { - return child; - } - - public void setChild(Child child) { - this.child = child; - } - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain3/Store.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain3/Store.java deleted file mode 100644 index 1c4001bd47..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain3/Store.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa.domain3; - -import java.io.Serializable; - -public class Store implements Serializable { - - private static final long serialVersionUID = 7221730732392000227L; - - private String code; - - private String name; - - private String address; - - private String city; - - private String phoneDetails; - - private String faxDetails; - - private String zipCode; - - private String chainCode; - - public String getCode() { - return code; - } - - public void setCode(String code) { - this.code = code; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getAddress() { - return address; - } - - public void setAddress(String address) { - this.address = address; - } - - public String getCity() { - return city; - } - - public void setCity(String city) { - this.city = city; - } - - public String getPhoneDetails() { - return phoneDetails; - } - - public void setPhoneDetails(String phoneDetails) { - this.phoneDetails = phoneDetails; - } - - public String getFaxDetails() { - return faxDetails; - } - - public void setFaxDetails(String faxDetails) { - this.faxDetails = faxDetails; - } - - public String getZipCode() { - return zipCode; - } - - public void setZipCode(String zipCode) { - this.zipCode = zipCode; - } - - public String getChainCode() { - return chainCode; - } - - public void setChainCode(String chainCode) { - this.chainCode = chainCode; - } - -} \ No newline at end of file diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain4/BookDefinition.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain4/BookDefinition.java deleted file mode 100644 index bc56336fb6..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain4/BookDefinition.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa.domain4; - -import java.io.Serializable; -import java.util.List; - -import javax.persistence.Access; -import javax.persistence.AccessType; -import javax.persistence.Basic; -import javax.persistence.CollectionTable; -import javax.persistence.ElementCollection; -import javax.persistence.Embeddable; -import javax.persistence.OrderColumn; - -@Embeddable -@Access(AccessType.PROPERTY) -public class BookDefinition implements Serializable { - - private static final long serialVersionUID = 3570098308959717614L; - - private String name; - - private String description; - - private List<BookMark> bookMarks; - - @Basic - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - @Basic - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - @ElementCollection() - @CollectionTable(name = "book_bookmarks") - @OrderColumn() - public List<BookMark> getBookMarks() { - return bookMarks; - } - - public void setBookMarks(List<BookMark> bookMarks) { - this.bookMarks = bookMarks; - } - - @Override - public boolean equals(Object o) { - if (this == o) - return true; - if (o == null || getClass() != o.getClass()) - return false; - - BookDefinition that = (BookDefinition) o; - - if (name != null ? !name.equals(that.name) : that.name != null) - return false; - - return true; - } - - @Override - public int hashCode() { - return name != null ? name.hashCode() : 0; - } -} \ No newline at end of file diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain4/BookID.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain4/BookID.java deleted file mode 100644 index 7f5f37cdb1..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain4/BookID.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa.domain4; - -import java.io.Serializable; - -import javax.persistence.Access; -import javax.persistence.AccessType; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.Table; - -@Entity -@Table(name = "bookid_") -@Access(AccessType.PROPERTY) -public class BookID implements Serializable { - - private static final long serialVersionUID = -3205025118656391776L; - - private Long identity; - - @Id - @GeneratedValue(strategy = GenerationType.AUTO) - public Long getIdentity() { - return identity; - } - - public void setIdentity(Long identity) { - this.identity = identity; - } - - @Override - public boolean equals(Object o) { - if (this == o) - return true; - if (o == null || getClass() != o.getClass()) - return false; - - BookID bookID = (BookID) o; - - if (identity != null ? !identity.equals(bookID.identity) - : bookID.identity != null) - return false; - - return true; - } - - @Override - public int hashCode() { - return identity != null ? identity.hashCode() : 0; - } -} \ No newline at end of file diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain4/BookMark.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain4/BookMark.java deleted file mode 100644 index 7a0bffeb85..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain4/BookMark.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa.domain4; - -import java.io.Serializable; - -import javax.persistence.Access; -import javax.persistence.AccessType; -import javax.persistence.Basic; -import javax.persistence.Embeddable; - -@Embeddable -@Access(AccessType.PROPERTY) -public class BookMark implements Serializable { - - private static final long serialVersionUID = 8027009758015834551L; - - private Long page; - - private String comment; - - @Basic - public Long getPage() { - return page; - } - - public void setPage(Long page) { - this.page = page; - } - - @Basic - public String getComment() { - return comment; - } - - public void setComment(String comment) { - this.comment = comment; - } - - @Override - public boolean equals(Object o) { - if (this == o) - return true; - if (o == null || getClass() != o.getClass()) - return false; - - BookMark bookMark = (BookMark) o; - - if (page != null ? !page.equals(bookMark.page) : bookMark.page != null) - return false; - - return true; - } - - @Override - public int hashCode() { - return page != null ? page.hashCode() : 0; - } -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain4/BookVersion.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain4/BookVersion.java deleted file mode 100644 index 60d2ef27d7..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain4/BookVersion.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa.domain4; - -import java.io.Serializable; - -import javax.persistence.Access; -import javax.persistence.AccessType; -import javax.persistence.CascadeType; -import javax.persistence.Embedded; -import javax.persistence.EmbeddedId; -import javax.persistence.Entity; -import javax.persistence.ManyToOne; -import javax.persistence.MapsId; -import javax.persistence.Table; - -@Entity -@Table(name = "bookversion_") -@Access(AccessType.PROPERTY) -public class BookVersion implements Serializable { - - private static final long serialVersionUID = -1697470794339057030L; - - private BookID bookID; - - private BookVersionPK pk = new BookVersionPK(); - - private Library library; - - private BookDefinition definition; - - @EmbeddedId - public BookVersionPK getPk() { - return pk; - } - - public void setPk(BookVersionPK pk) { - this.pk = pk; - } - - @MapsId("bookID") - @ManyToOne(cascade = CascadeType.ALL) - public BookID getBookID() { - return bookID; - } - - public void setBookID(BookID bookID) { - this.bookID = bookID; - } - - @MapsId("library") - @ManyToOne(cascade = CascadeType.ALL) - public Library getLibrary() { - return library; - } - - public void setLibrary(Library library) { - this.library = library; - } - - @Embedded - public BookDefinition getDefinition() { - return definition; - } - - public void setDefinition(BookDefinition definition) { - this.definition = definition; - } - - @Override - public boolean equals(Object o) { - if (this == o) - return true; - if (o == null || getClass() != o.getClass()) - return false; - - BookVersion that = (BookVersion) o; - - if (bookID != null ? !bookID.equals(that.bookID) : that.bookID != null) - return false; - if (library != null ? !library.equals(that.library) - : that.library != null) - return false; - - return true; - } - - @Override - public int hashCode() { - int result = bookID != null ? bookID.hashCode() : 0; - result = 31 * result + (library != null ? library.hashCode() : 0); - return result; - } -} \ No newline at end of file diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain4/BookVersionPK.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain4/BookVersionPK.java deleted file mode 100644 index d0f3680492..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain4/BookVersionPK.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa.domain4; - -import java.io.Serializable; - -import javax.persistence.Embeddable; - -@Embeddable -public class BookVersionPK implements Serializable { - - private static final long serialVersionUID = 8483495681236266676L; - - private Long bookID; - - private Long library; - - public Long getBookID() { - return bookID; - } - - public void setBookID(Long bookID) { - this.bookID = bookID; - } - - public Long getLibrary() { - return library; - } - - public void setLibrary(Long library) { - this.library = library; - } - - @Override - public boolean equals(Object o) { - if (this == o) - return true; - if (o == null || getClass() != o.getClass()) - return false; - - BookVersionPK that = (BookVersionPK) o; - - if (bookID != null ? !bookID.equals(that.bookID) : that.bookID != null) - return false; - if (library != null ? !library.equals(that.library) - : that.library != null) - return false; - - return true; - } - - @Override - public int hashCode() { - int result = bookID != null ? bookID.hashCode() : 0; - result = 31 * result + (library != null ? library.hashCode() : 0); - return result; - } -} \ No newline at end of file diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain4/Library.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain4/Library.java deleted file mode 100644 index bbbb3cc736..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain4/Library.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa.domain4; - -import java.io.Serializable; - -import javax.persistence.Access; -import javax.persistence.AccessType; -import javax.persistence.Entity; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.Table; - -@Entity -@Table(name = "library_") -@Access(AccessType.PROPERTY) -public class Library implements Serializable { - - private static final long serialVersionUID = 6360420736014459567L; - - private Long identity; - - @Id - @GeneratedValue(strategy = GenerationType.AUTO) - public Long getIdentity() { - return identity; - } - - public void setIdentity(Long identity) { - this.identity = identity; - } - - @Override - public boolean equals(Object o) { - if (this == o) - return true; - if (o == null || getClass() != o.getClass()) - return false; - - Library library = (Library) o; - - if (identity != null ? !identity.equals(library.identity) - : library.identity != null) - return false; - - return true; - } - - @Override - public int hashCode() { - return identity != null ? identity.hashCode() : 0; - } -} \ No newline at end of file diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/support/ExtendedDerbyDialect.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/support/ExtendedDerbyDialect.java deleted file mode 100644 index d808a7a4f9..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/support/ExtendedDerbyDialect.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa.support; - -import java.util.Arrays; -import java.util.List; - -import org.hibernate.dialect.DerbyDialect; -import org.hibernate.dialect.function.CastFunction; -import org.hibernate.dialect.function.VarArgsSQLFunction; -import org.hibernate.engine.spi.SessionFactoryImplementor; -import org.hibernate.type.StandardBasicTypes; -import org.hibernate.type.Type; - -/** - * @author tiwe - * - */ -public class ExtendedDerbyDialect extends DerbyDialect{ - - private static final CastFunction castFunction = new CastFunction() { - @Override - public String render(Type columnType, List args, SessionFactoryImplementor factory) { - if (args.get(1).equals("string")) { - return super.render(columnType, Arrays.<Object>asList("char("+args.get(0)+")",args.get(1)), factory); - } else { - return super.render(columnType, args, factory); - } - } - }; - - public ExtendedDerbyDialect() { - registerFunction( "concat", new VarArgsSQLFunction( StandardBasicTypes.STRING, "cast ((","||",") as varchar(128))" ) ); - registerFunction( "cast", castFunction ); - } - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/support/ExtendedHSQLDialect.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/support/ExtendedHSQLDialect.java deleted file mode 100644 index 34820e6668..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/support/ExtendedHSQLDialect.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.jpa.support; - -import org.hibernate.dialect.HSQLDialect; -import org.hibernate.dialect.function.SQLFunctionTemplate; -import org.hibernate.type.StandardBasicTypes; - -/** - * @author tiwe - * - */ -public class ExtendedHSQLDialect extends HSQLDialect{ - - public ExtendedHSQLDialect() { - registerFunction( "trim", new SQLFunctionTemplate( StandardBasicTypes.STRING, "trim(both from ?1)" ) ); - } -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/support/ExtendedOracleDialect.java b/querydsl-jpa/src/test/java/com/mysema/query/jpa/support/ExtendedOracleDialect.java deleted file mode 100644 index d1750a8b06..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/support/ExtendedOracleDialect.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.mysema.query.jpa.support; - -import org.hibernate.dialect.Oracle10gDialect; -import org.hibernate.dialect.function.SQLFunctionTemplate; -import org.hibernate.type.StandardBasicTypes; - -/** - * @author tiwe - * - */ -public class ExtendedOracleDialect extends Oracle10gDialect { - - public ExtendedOracleDialect() { - // there fail otherwise with the time datatype - registerFunction( "second", new SQLFunctionTemplate(StandardBasicTypes.INTEGER, "to_number(to_char(?1,'SS'))") ); - registerFunction( "minute", new SQLFunctionTemplate(StandardBasicTypes.INTEGER, "to_number(to_char(?1,'MI'))") ); - registerFunction( "hour", new SQLFunctionTemplate(StandardBasicTypes.INTEGER, "to_number(to_char(?1,'HH24'))") ); - } - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/suites/AbstractJPASuite.java b/querydsl-jpa/src/test/java/com/mysema/query/suites/AbstractJPASuite.java deleted file mode 100644 index 3a6d9df574..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/suites/AbstractJPASuite.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.mysema.query.suites; - -import org.junit.AfterClass; -import org.junit.runner.RunWith; - -import com.mysema.query.Mode; -import com.mysema.testutil.CustomSuite; - -@RunWith(CustomSuite.class) -public abstract class AbstractJPASuite { - - @AfterClass - public static void tearDownClass() throws Exception { - Mode.mode.remove(); - Mode.target.remove(); - } - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/suites/AbstractSuite.java b/querydsl-jpa/src/test/java/com/mysema/query/suites/AbstractSuite.java deleted file mode 100644 index c0b6309102..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/suites/AbstractSuite.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.mysema.query.suites; - -import org.junit.AfterClass; -import org.junit.runner.RunWith; - -import com.mysema.query.Mode; -import com.mysema.testutil.CustomSuite; - -@RunWith(CustomSuite.class) -public abstract class AbstractSuite { - - @AfterClass - public static void tearDownClass() throws Exception { - Mode.mode.remove(); - Mode.target.remove(); - } - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/suites/DerbyEclipseLinkTest.java b/querydsl-jpa/src/test/java/com/mysema/query/suites/DerbyEclipseLinkTest.java deleted file mode 100644 index 88189abb5b..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/suites/DerbyEclipseLinkTest.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.mysema.query.suites; - -import org.junit.BeforeClass; - -import com.mysema.query.JPABase; -import com.mysema.query.JPASQLBase; -import com.mysema.query.Mode; -import com.mysema.query.Target; -import com.mysema.query.jpa.JPAIntegrationBase; -import com.mysema.query.jpa.SerializationBase; - -public class DerbyEclipseLinkTest extends AbstractJPASuite { - - public static class JPA extends JPABase { - @Override - public void Order_StringValue() { - // not supported in MySQL/EclipseLink - } - @Override - public void Order_StringValue_To_Integer() { - // not supported in MySQL/EclipseLink - } - @Override - public void Order_StringValue_ToLong() { - // not supported in MySQL/EclipseLink - } - @Override - public void Order_StringValue_ToBigInteger() { - // not supported in MySQL/EclipseLink - } - } - public static class JPASQL extends JPASQLBase {} - public static class JPAIntegration extends JPAIntegrationBase {} - public static class Serialization extends SerializationBase {} - - @BeforeClass - public static void setUp() throws Exception { - Mode.mode.set("derby-eclipselink"); - Mode.target.set(Target.DERBY); - } -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/suites/DerbySuiteTest.java b/querydsl-jpa/src/test/java/com/mysema/query/suites/DerbySuiteTest.java deleted file mode 100644 index 23dd6f3999..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/suites/DerbySuiteTest.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.mysema.query.suites; - -import org.junit.BeforeClass; - -import com.mysema.query.HibernateBase; -import com.mysema.query.HibernateSQLBase; -import com.mysema.query.JPABase; -import com.mysema.query.JPASQLBase; -import com.mysema.query.Mode; -import com.mysema.query.Target; -import com.mysema.query.jpa.JPAIntegrationBase; -import com.mysema.query.jpa.SerializationBase; - -public class DerbySuiteTest extends AbstractSuite { - - public static class JPA extends JPABase {} - public static class JPASQL extends JPASQLBase {} - public static class JPAIntegration extends JPAIntegrationBase {} - public static class Serialization extends SerializationBase {} - public static class Hibernate extends HibernateBase {} - public static class HibernateSQL extends HibernateSQLBase {} - - @BeforeClass - public static void setUp() throws Exception { - Mode.mode.set("derby"); - Mode.target.set(Target.DERBY); - } - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/suites/H2BatooTest.java b/querydsl-jpa/src/test/java/com/mysema/query/suites/H2BatooTest.java deleted file mode 100644 index 36d57e423c..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/suites/H2BatooTest.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.mysema.query.suites; - -import org.junit.BeforeClass; - -import com.mysema.query.JPABase; -import com.mysema.query.JPASQLBase; -import com.mysema.query.Mode; -import com.mysema.query.Target; -import com.mysema.query.jpa.JPAIntegrationBase; -import com.mysema.query.jpa.SerializationBase; - -public class H2BatooTest extends AbstractJPASuite { - - public static class JPA extends JPABase {} - public static class JPASQL extends JPASQLBase {} - public static class JPAIntegration extends JPAIntegrationBase {} - public static class Serialization extends SerializationBase {} - - @BeforeClass - public static void setUp() throws Exception { - Mode.mode.set("h2-batoo"); - Mode.target.set(Target.H2); - } - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/suites/H2EclipseLinkTest.java b/querydsl-jpa/src/test/java/com/mysema/query/suites/H2EclipseLinkTest.java deleted file mode 100644 index 4b001d60df..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/suites/H2EclipseLinkTest.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.mysema.query.suites; - -import org.junit.BeforeClass; - -import com.mysema.query.JPABase; -import com.mysema.query.JPASQLBase; -import com.mysema.query.Mode; -import com.mysema.query.Target; -import com.mysema.query.jpa.JPAIntegrationBase; -import com.mysema.query.jpa.SerializationBase; - -public class H2EclipseLinkTest extends AbstractJPASuite { - - public static class JPA extends JPABase {} - public static class JPASQL extends JPASQLBase {} - public static class JPAIntegration extends JPAIntegrationBase {} - public static class Serialization extends SerializationBase {} - - @BeforeClass - public static void setUp() throws Exception { - Mode.mode.set("h2-eclipselink"); - Mode.target.set(Target.H2); - } - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/suites/H2OpenJPATest.java b/querydsl-jpa/src/test/java/com/mysema/query/suites/H2OpenJPATest.java deleted file mode 100644 index b742577ccc..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/suites/H2OpenJPATest.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.mysema.query.suites; - -import org.junit.BeforeClass; -import org.junit.Ignore; - -import com.mysema.query.JPABase; -import com.mysema.query.JPASQLBase; -import com.mysema.query.Mode; -import com.mysema.query.Target; -import com.mysema.query.jpa.JPAIntegrationBase; -import com.mysema.query.jpa.SerializationBase; - -@Ignore -public class H2OpenJPATest extends AbstractJPASuite { - - public static class JPA extends JPABase {} - public static class JPASQL extends JPASQLBase {} - public static class JPAIntegration extends JPAIntegrationBase {} - public static class Serialization extends SerializationBase {} - - @BeforeClass - public static void setUp() throws Exception { - Mode.mode.set("h2-openjpa"); - Mode.target.set(Target.H2); - } - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/suites/H2SuiteTest.java b/querydsl-jpa/src/test/java/com/mysema/query/suites/H2SuiteTest.java deleted file mode 100644 index 66b7975936..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/suites/H2SuiteTest.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.mysema.query.suites; - -import org.junit.BeforeClass; - -import com.mysema.query.HibernateBase; -import com.mysema.query.HibernateSQLBase; -import com.mysema.query.JPABase; -import com.mysema.query.JPASQLBase; -import com.mysema.query.Mode; -import com.mysema.query.Target; -import com.mysema.query.jpa.JPAIntegrationBase; -import com.mysema.query.jpa.SerializationBase; - -public class H2SuiteTest extends AbstractSuite { - - public static class JPA extends JPABase {} - public static class JPASQL extends JPASQLBase {} - public static class JPAIntegration extends JPAIntegrationBase {} - public static class Serialization extends SerializationBase {} - public static class Hibernate extends HibernateBase {} - public static class HibernateSQL extends HibernateSQLBase {} - - @BeforeClass - public static void setUp() throws Exception { - Mode.mode.set("h2"); - Mode.target.set(Target.H2); - } - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/suites/HSQLDBEclipseLinkTest.java b/querydsl-jpa/src/test/java/com/mysema/query/suites/HSQLDBEclipseLinkTest.java deleted file mode 100644 index 91935a724b..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/suites/HSQLDBEclipseLinkTest.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.mysema.query.suites; - -import org.junit.BeforeClass; - -import com.mysema.query.JPABase; -import com.mysema.query.JPASQLBase; -import com.mysema.query.Mode; -import com.mysema.query.Target; -import com.mysema.query.jpa.JPAIntegrationBase; -import com.mysema.query.jpa.SerializationBase; - -public class HSQLDBEclipseLinkTest extends AbstractJPASuite { - - public static class JPA extends JPABase {} - public static class JPASQL extends JPASQLBase {} - public static class JPAIntegration extends JPAIntegrationBase {} - public static class Serialization extends SerializationBase {} - - @BeforeClass - public static void setUp() throws Exception { - Mode.mode.set("hsqldb-eclipselink"); - Mode.target.set(Target.HSQLDB); - } - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/suites/HSQLDBSuiteTest.java b/querydsl-jpa/src/test/java/com/mysema/query/suites/HSQLDBSuiteTest.java deleted file mode 100644 index 29b3b0e07d..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/suites/HSQLDBSuiteTest.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.mysema.query.suites; - -import org.junit.BeforeClass; - -import com.mysema.query.HibernateBase; -import com.mysema.query.HibernateSQLBase; -import com.mysema.query.JPABase; -import com.mysema.query.JPASQLBase; -import com.mysema.query.Mode; -import com.mysema.query.Target; -import com.mysema.query.jpa.JPAIntegrationBase; -import com.mysema.query.jpa.SerializationBase; - -public class HSQLDBSuiteTest extends AbstractSuite { - - public static class JPA extends JPABase {} - public static class JPASQL extends JPASQLBase {} - public static class JPAIntegration extends JPAIntegrationBase {} - public static class Serialization extends SerializationBase {} - public static class Hibernate extends HibernateBase {} - public static class HibernateSQL extends HibernateSQLBase {} - - @BeforeClass - public static void setUp() throws Exception { - Mode.mode.set("hsqldb"); - Mode.target.set(Target.HSQLDB); - } - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/suites/MSSQLSuiteTest.java b/querydsl-jpa/src/test/java/com/mysema/query/suites/MSSQLSuiteTest.java deleted file mode 100644 index 54ccc59f8e..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/suites/MSSQLSuiteTest.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.mysema.query.suites; - -import org.junit.BeforeClass; -import org.junit.experimental.categories.Category; - -import com.mysema.query.HibernateBase; -import com.mysema.query.HibernateSQLBase; -import com.mysema.query.JPABase; -import com.mysema.query.JPASQLBase; -import com.mysema.query.Mode; -import com.mysema.query.Target; -import com.mysema.query.jpa.JPAIntegrationBase; -import com.mysema.query.jpa.SerializationBase; -import com.mysema.testutil.ExternalDB; - -@Category(ExternalDB.class) -public class MSSQLSuiteTest extends AbstractSuite { - - public static class JPA extends JPABase {} - public static class JPASQL extends JPASQLBase {} - public static class JPAIntegration extends JPAIntegrationBase {} - public static class Serialization extends SerializationBase {} - public static class Hibernate extends HibernateBase {} - public static class HibernateSQL extends HibernateSQLBase {} - - @BeforeClass - public static void setUp() throws Exception { - Mode.mode.set("mssql"); - Mode.target.set(Target.SQLSERVER); - } - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/suites/MySQLEclipseLinkTest.java b/querydsl-jpa/src/test/java/com/mysema/query/suites/MySQLEclipseLinkTest.java deleted file mode 100644 index 603312932f..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/suites/MySQLEclipseLinkTest.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.mysema.query.suites; - -import org.junit.BeforeClass; -import org.junit.experimental.categories.Category; - -import com.mysema.query.JPABase; -import com.mysema.query.JPASQLBase; -import com.mysema.query.Mode; -import com.mysema.query.Target; -import com.mysema.query.jpa.JPAIntegrationBase; -import com.mysema.query.jpa.SerializationBase; -import com.mysema.testutil.ExternalDB; - -@Category(ExternalDB.class) -public class MySQLEclipseLinkTest extends AbstractJPASuite { - - public static class JPA extends JPABase { - @Override - public void Cast() { - // not supported in MySQL/EclipseLink - } - @Override - public void Order_StringValue() { - // not supported in MySQL/EclipseLink - } - @Override - public void Order_StringValue_To_Integer() { - // not supported in MySQL/EclipseLink - } - @Override - public void Order_StringValue_ToLong() { - // not supported in MySQL/EclipseLink - } - @Override - public void Order_StringValue_ToBigInteger() { - // not supported in MySQL/EclipseLink - } - @Override - public void Order_NullsFirst() { - // not supported in MySQL/EclipseLink - } - @Override - public void Order_NullsLast() { - // not supported in MySQL/EclipseLink - } - } - - public static class JPASQL extends JPASQLBase {} - public static class JPAIntegration extends JPAIntegrationBase {} - public static class Serialization extends SerializationBase {} - - @BeforeClass - public static void setUp() throws Exception { - Mode.mode.set("mysql-eclipselink"); - Mode.target.set(Target.MYSQL); - } - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/suites/MySQLSuiteTest.java b/querydsl-jpa/src/test/java/com/mysema/query/suites/MySQLSuiteTest.java deleted file mode 100644 index ff529228e6..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/suites/MySQLSuiteTest.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.mysema.query.suites; - -import org.junit.BeforeClass; -import org.junit.experimental.categories.Category; - -import com.mysema.query.HibernateBase; -import com.mysema.query.HibernateSQLBase; -import com.mysema.query.JPABase; -import com.mysema.query.JPASQLBase; -import com.mysema.query.Mode; -import com.mysema.query.Target; -import com.mysema.query.jpa.JPAIntegrationBase; -import com.mysema.query.jpa.SerializationBase; -import com.mysema.testutil.ExternalDB; - -@Category(ExternalDB.class) -public class MySQLSuiteTest extends AbstractSuite { - - public static class JPA extends JPABase { - @Override - public void Order_StringValue_ToLong() { - // not supported - } - } - public static class JPASQL extends JPASQLBase {} - public static class JPAIntegration extends JPAIntegrationBase {} - public static class Serialization extends SerializationBase {} - public static class Hibernate extends HibernateBase { - @Override - public void Order_StringValue_ToLong() { - // not supported - } - } - public static class HibernateSQL extends HibernateSQLBase {} - - @BeforeClass - public static void setUp() throws Exception { - Mode.mode.set("mysql"); - Mode.target.set(Target.MYSQL); - } - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/suites/OracleSuiteTest.java b/querydsl-jpa/src/test/java/com/mysema/query/suites/OracleSuiteTest.java deleted file mode 100644 index 944a17fd18..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/suites/OracleSuiteTest.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.mysema.query.suites; - -import org.junit.BeforeClass; -import org.junit.experimental.categories.Category; - -import com.mysema.query.HibernateBase; -import com.mysema.query.HibernateSQLBase; -import com.mysema.query.JPABase; -import com.mysema.query.JPASQLBase; -import com.mysema.query.Mode; -import com.mysema.query.Target; -import com.mysema.query.jpa.JPAIntegrationBase; -import com.mysema.query.jpa.SerializationBase; -import com.mysema.testutil.ExternalDB; - -@Category(ExternalDB.class) -public class OracleSuiteTest extends AbstractSuite { - - public static class JPA extends JPABase {} - public static class JPASQL extends JPASQLBase {} - public static class JPAIntegration extends JPAIntegrationBase {} - public static class Serialization extends SerializationBase {} - public static class Hibernate extends HibernateBase {} - public static class HibernateSQL extends HibernateSQLBase {} - - @BeforeClass - public static void setUp() throws Exception { - Mode.mode.set("oracle"); - Mode.target.set(Target.ORACLE); - } - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/suites/PostgresEclipseLinkSuiteTest.java b/querydsl-jpa/src/test/java/com/mysema/query/suites/PostgresEclipseLinkSuiteTest.java deleted file mode 100644 index df5d9be9b3..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/suites/PostgresEclipseLinkSuiteTest.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.mysema.query.suites; - -import org.junit.BeforeClass; -import org.junit.experimental.categories.Category; - -import com.mysema.query.JPABase; -import com.mysema.query.JPASQLBase; -import com.mysema.query.Mode; -import com.mysema.query.Target; -import com.mysema.query.jpa.JPAIntegrationBase; -import com.mysema.query.jpa.SerializationBase; -import com.mysema.testutil.ExternalDB; - -@Category(ExternalDB.class) -public class PostgresEclipseLinkSuiteTest extends AbstractJPASuite { - - public static class JPA extends JPABase {} - public static class JPASQL extends JPASQLBase {} - public static class JPAIntegration extends JPAIntegrationBase {} - public static class Serialization extends SerializationBase {} - - @BeforeClass - public static void setUp() throws Exception { - Mode.mode.set("postgres-eclipselink"); - Mode.target.set(Target.POSTGRES); - } - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/suites/PostgresSuiteTest.java b/querydsl-jpa/src/test/java/com/mysema/query/suites/PostgresSuiteTest.java deleted file mode 100644 index 69f1ffa81a..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/suites/PostgresSuiteTest.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.mysema.query.suites; - -import org.junit.BeforeClass; -import org.junit.experimental.categories.Category; - -import com.mysema.query.HibernateBase; -import com.mysema.query.HibernateSQLBase; -import com.mysema.query.JPABase; -import com.mysema.query.JPASQLBase; -import com.mysema.query.Mode; -import com.mysema.query.Target; -import com.mysema.query.jpa.JPAIntegrationBase; -import com.mysema.query.jpa.SerializationBase; -import com.mysema.testutil.ExternalDB; - -@Category(ExternalDB.class) -public class PostgresSuiteTest extends AbstractSuite { - - public static class JPA extends JPABase {} - public static class JPASQL extends JPASQLBase {} - public static class JPAIntegration extends JPAIntegrationBase {} - public static class Serialization extends SerializationBase {} - public static class Hibernate extends HibernateBase {} - public static class HibernateSQL extends HibernateSQLBase {} - - @BeforeClass - public static void setUp() throws Exception { - Mode.mode.set("postgres"); - Mode.target.set(Target.POSTGRES); - } - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/suites/Teradata.java b/querydsl-jpa/src/test/java/com/mysema/query/suites/Teradata.java deleted file mode 100644 index 2c58546768..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/suites/Teradata.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.mysema.query.suites; - -import javax.persistence.EntityManager; -import javax.persistence.EntityManagerFactory; -import javax.persistence.Persistence; - -public class Teradata { - - public static void main(String[] args) { - EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("teradata"); - try { - EntityManager entityManager = entityManagerFactory.createEntityManager(); - try { - entityManager.getTransaction().begin(); - entityManager.getTransaction().commit(); - } finally { - entityManager.close(); - } - } finally { - entityManagerFactory.close(); - } - } - -} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/suites/TeradataSuiteTest.java b/querydsl-jpa/src/test/java/com/mysema/query/suites/TeradataSuiteTest.java deleted file mode 100644 index ec417fac25..0000000000 --- a/querydsl-jpa/src/test/java/com/mysema/query/suites/TeradataSuiteTest.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.mysema.query.suites; - -import org.junit.BeforeClass; -import org.junit.experimental.categories.Category; - -import com.mysema.query.HibernateBase; -import com.mysema.query.HibernateSQLBase; -import com.mysema.query.JPABase; -import com.mysema.query.JPASQLBase; -import com.mysema.query.Mode; -import com.mysema.query.Target; -import com.mysema.query.jpa.JPAIntegrationBase; -import com.mysema.query.jpa.SerializationBase; -import com.mysema.testutil.ExternalDB; - -@Category(ExternalDB.class) -public class TeradataSuiteTest extends AbstractSuite { - - public static class JPA extends JPABase {} - public static class JPASQL extends JPASQLBase {} - public static class JPAIntegration extends JPAIntegrationBase {} - public static class Serialization extends SerializationBase {} - public static class Hibernate extends HibernateBase {} - public static class HibernateSQL extends HibernateSQLBase {} - - @BeforeClass - public static void setUp() throws Exception { - Mode.mode.set("teradata"); - Mode.target.set(Target.TERADATA); - } - -} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/AbstractJPATest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/AbstractJPATest.java new file mode 100644 index 0000000000..942e6f2174 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/AbstractJPATest.java @@ -0,0 +1,1833 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import static com.querydsl.core.Target.*; +import static com.querydsl.jpa.JPAExpressions.select; +import static org.junit.Assert.*; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.*; +import java.util.Calendar; +import java.util.Map.Entry; + +import org.hamcrest.Matchers; +import org.joda.time.DateTime; +import org.joda.time.LocalDate; +import org.joda.time.LocalTime; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; + +import com.mysema.commons.lang.Pair; +import com.querydsl.core.*; +import com.querydsl.core.group.Group; +import com.querydsl.core.group.GroupBy; +import com.querydsl.core.group.QPair; +import com.querydsl.core.group.MockTuple; +import com.querydsl.core.testutil.ExcludeIn; +import com.querydsl.core.types.*; +import com.querydsl.core.types.dsl.*; +import com.querydsl.jpa.domain.*; +import com.querydsl.jpa.domain.Company.Rating; +import com.querydsl.jpa.domain4.QBookMark; +import com.querydsl.jpa.domain4.QBookVersion; + +/** + * @author tiwe + * + */ +public abstract class AbstractJPATest { + + private static final Expression<?>[] NO_EXPRESSIONS = new Expression<?>[0]; + + private static final QCompany company = QCompany.company; + + private static final QAnimal animal = QAnimal.animal; + + private static final QCat cat = QCat.cat; + + private static final QCat otherCat = new QCat("otherCat"); + + private static final BooleanExpression cond1 = cat.name.length().gt(0); + + private static final BooleanExpression cond2 = otherCat.name.length().gt(0); + + private static final Predicate condition = ExpressionUtils.and( + (Predicate) ExpressionUtils.extract(cond1), + (Predicate) ExpressionUtils.extract(cond2)); + + private static final Date birthDate; + + private static final java.sql.Date date; + + private static final java.sql.Time time; + + private final List<Cat> savedCats = new ArrayList<Cat>(); + + static { + Calendar cal = Calendar.getInstance(); + cal.set(2000, 1, 2, 3, 4); + cal.set(Calendar.SECOND, 0); + cal.set(Calendar.MILLISECOND, 0); + birthDate = cal.getTime(); + date = new java.sql.Date(cal.getTimeInMillis()); + time = new java.sql.Time(cal.getTimeInMillis()); + } + + protected Target getTarget() { + return Mode.target.get(); + } + + protected abstract JPQLQuery<?> query(); + + protected abstract JPQLQuery<?> testQuery(); + + protected abstract void save(Object entity); + + @Before + public void setUp() { + if (query().from(cat).fetchCount() > 0) { + savedCats.addAll(query().from(cat).orderBy(cat.id.asc()).select(cat).fetch()); + return; + } + + Cat prev = null; + for (Cat cat : Arrays.asList( + new Cat("Bob123", 1, 1.0), + new Cat("Ruth123", 2, 2.0), + new Cat("Felix123", 3, 3.0), + new Cat("Allen123", 4, 4.0), + new Cat("Mary_123", 5, 5.0))) { + if (prev != null) { + cat.addKitten(prev); + } + cat.setBirthdate(birthDate); + cat.setDateField(date); + cat.setTimeField(time); + cat.setColor(Color.BLACK); + cat.setMate(prev); + save(cat); + savedCats.add(cat); + prev = cat; + } + + Animal animal = new Animal(10); + animal.setBodyWeight(10.5); + save(animal); + + Cat cat = new Cat("Some", 6, 6.0); + cat.setBirthdate(birthDate); + save(cat); + savedCats.add(cat); + + Show show = new Show(1); + show.acts = new HashMap<String,String>(); + show.acts.put("a","A"); + show.acts.put("b","B"); + save(show); + + Company company = new Company(); + company.name = "1234567890123456789012345678901234567890"; // 40 + company.id = 1; + company.ratingOrdinal = Company.Rating.A; + company.ratingString = Company.Rating.AA; + save(company); + + Employee employee = new Employee(); + employee.id = 1; + employee.lastName = "Smith"; + employee.jobFunctions.add(JobFunction.CODER); + save(employee); + + Employee employee2 = new Employee(); + employee2.id = 2; + employee2.lastName = "Doe"; + employee2.jobFunctions.add(JobFunction.CODER); + employee2.jobFunctions.add(JobFunction.CONSULTANT); + employee2.jobFunctions.add(JobFunction.CONTROLLER); + save(employee2); + + save(new Entity1(1)); + save(new Entity1(2)); + save(new Entity2(3)); + + Foo foo = new Foo(); + foo.id = 1; + foo.names = Arrays.asList("a","b"); + foo.bar = "München"; + save(foo); + + Numeric numeric = new Numeric(); + numeric.setValue(BigDecimal.valueOf(26.9)); + save(numeric); + } + + @Test + @ExcludeIn(ORACLE) + public void add_bigDecimal() { + QSimpleTypes entity = new QSimpleTypes("entity1"); + QSimpleTypes entity2 = new QSimpleTypes("entity2"); + NumberPath<BigDecimal> bigd1 = entity.bigDecimal; + NumberPath<BigDecimal> bigd2 = entity2.bigDecimal; + + assertEquals(Collections.emptyList(), + query().from(entity, entity2) + .where(bigd1.add(bigd2).loe(new BigDecimal("1.00"))) + .select(entity).fetch()); + } + + @Test + public void aggregates_list_max() { + assertEquals(Integer.valueOf(6), query().from(cat).select(cat.id.max()).fetchFirst()); + } + + @Test + public void aggregates_list_min() { + assertEquals(Integer.valueOf(1), query().from(cat).select(cat.id.min()).fetchFirst()); + } + + @Test + public void aggregates_uniqueResult_max() { + assertEquals(Integer.valueOf(6), query().from(cat).select(cat.id.max()).fetchFirst()); + } + + @Test + public void aggregates_uniqueResult_min() { + assertEquals(Integer.valueOf(1), query().from(cat).select(cat.id.min()).fetchFirst()); + } + + @Test + public void alias() { + assertEquals(6, query().from(cat).select(cat.id.as(cat.id)).fetch().size()); + } + + @Test + public void any_and_gt() { + assertEquals(0, query().from(cat).where( + cat.kittens.any().name.eq("Ruth123"), + cat.kittens.any().bodyWeight.gt(10.0)).fetchCount()); + } + + @Test + public void any_and_lt() { + assertEquals(1, query().from(cat).where( + cat.kittens.any().name.eq("Ruth123"), + cat.kittens.any().bodyWeight.lt(10.0)).fetchCount()); + } + + @Test + public void any_in_order() { + assertFalse(query().from(cat).orderBy(cat.kittens.any().name.asc()).select(cat).fetch().isEmpty()); + } + + @Test + public void any_in_projection() { + assertFalse(query().from(cat).select(cat.kittens.any()).fetch().isEmpty()); + } + + @Test + public void any_in_projection2() { + assertFalse(query().from(cat).select(cat.kittens.any().name).fetch().isEmpty()); + } + + @Test + public void any_in_projection3() { + assertFalse(query().from(cat).select(cat.kittens.any().name, cat.kittens.any().bodyWeight).fetch().isEmpty()); + } + + @Test + public void any_in1() { + //select cat from Cat cat where exists ( + // select cat_kittens from Cat cat_kittens where cat_kittens member of cat.kittens and cat_kittens in ?1) + assertFalse(query().from(cat).where(cat.kittens.any().in(savedCats)).select(cat).fetch().isEmpty()); + } + + @Test + public void any_in11() { + List<Integer> ids = new ArrayList<>(); + for (Cat cat : savedCats) { + ids.add(cat.getId()); + } + assertFalse(query().from(cat).where(cat.kittens.any().id.in(ids)).select(cat).fetch().isEmpty()); + } + + @Test + public void any_in2() { + assertFalse(query().from(cat).where( + cat.kittens.any().in(savedCats), + cat.kittens.any().in(savedCats.subList(0, 1)).not()) + .select(cat).fetch().isEmpty()); + } + + @Test + @NoBatooJPA + public void any_in3() { + QEmployee employee = QEmployee.employee; + assertFalse(query().from(employee).where( + employee.jobFunctions.any().in(JobFunction.CODER, JobFunction.CONSULTANT)) + .select(employee).fetch().isEmpty()); + } + + @Test + public void any_simple() { + assertEquals(1, query().from(cat).where(cat.kittens.any().name.eq("Ruth123")).fetchCount()); + } + + @Test + public void any_any() { + assertEquals(1, query().from(cat).where(cat.kittens.any().kittens.any().name.eq("Ruth123")).fetchCount()); + } + + @Test + public void arrayProjection() { + List<String[]> results = query().from(cat) + .select(new ArrayConstructorExpression<String>(String[].class, cat.name)).fetch(); + assertFalse(results.isEmpty()); + for (String[] result : results) { + assertNotNull(result[0]); + } + } + + @Test + public void as() { + assertTrue(query().from(QAnimal.animal.as(QCat.class)).fetchCount() > 0); + } + + @Test + public void between() { + assertEquals(Arrays.asList(2, 3, 4, 5), + query().from(cat).where(cat.id.between(2, 5)).orderBy(cat.id.asc()).select(cat.id).fetch()); + } + + @Test + @NoBatooJPA + public void case1() { + assertEquals(Arrays.asList(1, 2, 2, 2, 2, 2), + query().from(cat).orderBy(cat.id.asc()) + .select(cat.name.when("Bob123").then(1).otherwise(2)).fetch()); + } + + @Test + @NoBatooJPA + public void case1_long() { + assertEquals(Arrays.asList(1L, 2L, 2L, 2L, 2L, 2L), + query().from(cat).orderBy(cat.id.asc()) + .select(cat.name.when("Bob123").then(1L).otherwise(2L)).fetch()); + List<Integer> rv = query().from(cat).select(cat.name.when("Bob").then(1).otherwise(2)).fetch(); + assertInstancesOf(Integer.class, rv); + } + + @Test + @NoEclipseLink + @NoHibernate // https://hibernate.atlassian.net/browse/HHH-8653 + public void case1_date() { + List<LocalDate> rv = query().from(cat).select(cat.name.when("Bob").then(new LocalDate()) + .otherwise(new LocalDate().plusDays(1))).fetch(); + assertInstancesOf(LocalDate.class, rv); + } + + @Test + @NoHibernate // https://hibernate.atlassian.net/browse/HHH-8653 + @NoEclipseLink({MYSQL, POSTGRESQL}) + public void case1_date2() { + List<java.sql.Date> rv = query().from(cat).select(cat.name.when("Bob").then(new java.sql.Date(0)) + .otherwise(new java.sql.Date(0))).fetch(); + assertInstancesOf(java.sql.Date.class, rv); + } + + @Test + @NoEclipseLink + @NoHibernate // https://hibernate.atlassian.net/browse/HHH-8653 + public void case1_time() { + List<LocalTime> rv = query().from(cat).select(cat.name.when("Bob").then(new LocalTime()) + .otherwise(new LocalTime().plusHours(1))).fetch(); + assertInstancesOf(LocalTime.class, rv); + } + + @Test + @NoHibernate // https://hibernate.atlassian.net/browse/HHH-8653 + @NoEclipseLink({MYSQL, POSTGRESQL}) + public void case1_time2() { + List<java.sql.Time> rv = query().from(cat).select(cat.name.when("Bob").then(new java.sql.Time(0)) + .otherwise(new java.sql.Time(0))).fetch(); + assertInstancesOf(java.sql.Time.class, rv); + } + + @Test + @NoEclipseLink + @NoHibernate // https://hibernate.atlassian.net/browse/HHH-8653 + public void case1_timestamp() { + List<DateTime> rv = query().from(cat).select(cat.name.when("Bob").then(new DateTime()) + .otherwise(new DateTime().plusHours(1))).fetch(); + assertInstancesOf(DateTime.class, rv); + } + + @Test + @NoHibernate // https://hibernate.atlassian.net/browse/HHH-8653 + @NoEclipseLink({MYSQL, POSTGRESQL}) + public void case1_timestamp2() { + List<java.sql.Timestamp> rv = query().from(cat).select(cat.name.when("Bob").then(new java.sql.Timestamp(0)) + .otherwise(new java.sql.Timestamp(0))).fetch(); + assertInstancesOf(java.sql.Timestamp.class, rv); + } + + @Test + public void case2() { + assertEquals(Arrays.asList(4, 4, 4, 4, 4, 4), + query().from(cat) + .select(Expressions.cases().when(cat.toes.eq(2)).then(cat.id.multiply(2)) + .when(cat.toes.eq(3)).then(cat.id.multiply(3)) + .otherwise(4)).fetch()); + } + + @Test + public void case3() { + assertEquals(Arrays.asList(4, 4, 4, 4, 4, 4), + query().from(cat).select(Expressions.cases() + .when(cat.toes.in(2, 3)).then(cat.id.multiply(cat.toes)) + .otherwise(4)).fetch()); + } + + @Test + @ExcludeIn(MYSQL) // doesn't work in Eclipselink + public void case4() { + NumberExpression<Float> numExpression = cat.bodyWeight.floatValue().divide(otherCat.bodyWeight.floatValue()).multiply(100); + NumberExpression<Float> numExpression2 = cat.id.when(0).then(0.0F).otherwise(numExpression); + assertEquals(Arrays.asList(200, 150, 133, 125, 120), + query().from(cat, otherCat) + .where(cat.id.eq(otherCat.id.add(1))) + .orderBy(cat.id.asc(), otherCat.id.asc()) + .select(numExpression2.intValue()).fetch()); + } + + @Test + public void case5() { + assertEquals(Arrays.asList(1, 0, 1, 1, 1, 1), + query().from(cat).orderBy(cat.id.asc()) + .select(cat.mate.when(savedCats.get(0)).then(0).otherwise(1)).fetch()); + } + + private static <T> void assertInstancesOf(Class<T> clazz, Iterable<T> rows) { + for (T row : rows) { + assertEquals(row.toString(), clazz, row.getClass()); + } + } + + @Test + public void caseBuilder() { + QCat cat2 = new QCat("cat2"); + NumberExpression<Integer> casex = new CaseBuilder() + .when(cat.weight.isNull().and(cat.weight.isNull())).then(0) + .when(cat.weight.isNull()).then(cat2.weight) + .when(cat2.weight.isNull()).then(cat.weight) + .otherwise(cat.weight.add(cat2.weight)); + + query().from(cat, cat2).orderBy(casex.asc()).select(cat.id, cat2.id).fetch(); + query().from(cat, cat2).orderBy(casex.desc()).select(cat.id, cat2.id).fetch(); + } + + @Test + public void cast() { + List<Cat> cats = query().from(cat).select(cat).fetch(); + List<Integer> weights = query().from(cat).select(cat.bodyWeight.castToNum(Integer.class)).fetch(); + for (int i = 0; i < cats.size(); i++) { + assertEquals(Integer.valueOf((int) (cats.get(i).getBodyWeight())), weights.get(i)); + } + } + + @Test + @ExcludeIn(SQLSERVER) + public void cast_toString() { + for (Tuple tuple : query().from(cat).select(cat.breed, cat.breed.stringValue()).fetch()) { + assertEquals( + tuple.get(cat.breed).toString(), + tuple.get(cat.breed.stringValue())); + } + } + + @Test + @ExcludeIn(SQLSERVER) + public void cast_toString_append() { + for (Tuple tuple : query().from(cat).select(cat.breed, cat.breed.stringValue().append("test")).fetch()) { + assertEquals( + tuple.get(cat.breed).toString() + "test", + tuple.get(cat.breed.stringValue().append("test"))); + } + } + + @Test + public void collection_predicates() { + ListPath<Cat, QCat> path = cat.kittens; + // path.eq(savedCats), + // path.in(savedCats), + // path.isNotNull(), + // path.isNull(), + // path.ne(savedCats), + // path.notIn(savedCats) + // path.when(other) + List<Predicate> predicates = Collections.emptyList(); + for (Predicate pred : predicates) { + System.err.println(pred); + query().from(cat).where(pred).select(cat).fetch(); + } + } + + @Test + public void collection_projections() { + ListPath<Cat, QCat> path = cat.kittens; + // path.fetchCount(), + // path.countDistinct() + List<Expression<?>> projections = Collections.emptyList(); + for (Expression<?> proj : projections) { + System.err.println(proj); + query().from(cat).select(proj).fetch(); + } + } + + @Test + public void constant() { + //select cat.id, ?1 as const from Cat cat + List<Cat> cats = query().from(cat).select(cat).fetch(); + Path<String> path = Expressions.stringPath("const"); + List<Tuple> tuples = query().from(cat).select(cat.id, Expressions.constantAs("abc", path)).fetch(); + for (int i = 0; i < cats.size(); i++) { + assertEquals(Integer.valueOf(cats.get(i).getId()), tuples.get(i).get(cat.id)); + assertEquals("abc", tuples.get(i).get(path)); + } + } + + @Test + public void constant2() { + assertFalse(query().from(cat).select(cat.id, Expressions.constant("name")).fetch().isEmpty()); + } + + @Test + public void constructorProjection() { + List<Projection> projections = query().from(cat) + .select(Projections.constructor(Projection.class, cat.name, cat)).fetch(); + assertFalse(projections.isEmpty()); + for (Projection projection : projections) { + assertNotNull(projection); + } + } + + @Test + public void constructorProjection2() { + List<Projection> projections = query().from(cat).select(new QProjection(cat.name, cat)).fetch(); + assertFalse(projections.isEmpty()); + for (Projection projection : projections) { + assertNotNull(projection); + } + } + + @Test + public void constructorProjection3() { + List<Projection> projections = query().from(cat).select(new QProjection(cat.id, Expressions.FALSE)).fetch(); + assertFalse(projections.isEmpty()); + for (Projection projection : projections) { + assertNotNull(projection); + } + } + + @Test + public void contains_ic() { + QFoo foo = QFoo.foo; + assertEquals(1, query().from(foo).where(foo.bar.containsIgnoreCase("München")).fetchCount()); + } + + @Test + public void contains1() { + assertEquals(1, query().from(cat).where(cat.name.contains("eli")).fetchCount()); + } + + @Test + public void contains2() { + assertEquals(1L, query().from(cat).where(cat.kittens.contains(savedCats.get(0))).fetchCount()); + } + + @Test + public void contains3() { + assertEquals(1L, query().from(cat).where(cat.name.contains("_")).fetchCount()); + } + + @Test + public void contains4() { + QEmployee employee = QEmployee.employee; + assertEquals(Collections.emptyList(), + query().from(employee) + .where( + employee.jobFunctions.contains(JobFunction.CODER), + employee.jobFunctions.contains(JobFunction.CONSULTANT), + employee.jobFunctions.size().eq(2)) + .select(employee).fetch()); + } + + @Test + public void count() { + QShow show = QShow.show; + assertTrue(query().from(show).fetchCount() > 0); + } + + @Test + public void count_distinct() { + QCat cat = QCat.cat; + query().from(cat) + .groupBy(cat.id) + .select(cat.id, cat.breed.countDistinct()).fetch(); + } + + @Test + @NoBatooJPA + @NoHibernate + public void count_distinct2() { + QCat cat = QCat.cat; + query().from(cat) + .groupBy(cat.id) + .select(cat.id, cat.birthdate.dayOfMonth().countDistinct()).fetch(); + } + + @Test + @NoEclipseLink + @ExcludeIn(SQLSERVER) + public void distinct_orderBy() { + QCat cat = QCat.cat; + List<Tuple> result = query().select(cat.id, cat.mate.id) + .distinct() + .from(cat) + .orderBy( + cat.mate.id.asc().nullsFirst(), + cat.id.asc().nullsFirst() + ).fetch(); + assertThat(result, Matchers.<Tuple>contains( + new MockTuple(new Object[]{1, null}), + new MockTuple(new Object[]{6, null}), + new MockTuple(new Object[]{2, 1}), + new MockTuple(new Object[]{3, 2}), + new MockTuple(new Object[]{4, 3}), + new MockTuple(new Object[]{5, 4}) + )); + } + + @Test + @NoHibernate + @ExcludeIn(MYSQL) + public void distinct_orderBy2() { + QCat cat = QCat.cat; + List<Tuple> result = query().select(cat.id, cat.mate.id) + .distinct() + .from(cat) + .orderBy(cat.mate.id.asc().nullsFirst()).fetch(); + assertThat(result, Matchers.<Tuple>contains( + new MockTuple(new Object[]{2, 1}), + new MockTuple(new Object[]{3, 2}), + new MockTuple(new Object[]{4, 3}), + new MockTuple(new Object[]{5, 4}) + )); + } + + @Test + @NoEclipseLink(HSQLDB) + public void count_distinct3() { + QCat kitten = new QCat("kitten"); + assertEquals(4, query().from(cat).leftJoin(cat.kittens, kitten).select(kitten.countDistinct()).fetchOne().intValue()); + assertEquals(6, query().from(cat).leftJoin(cat.kittens, kitten).select(kitten.countDistinct()).fetchCount()); + } + + @Test + public void distinctResults() { + System.out.println("-- fetch results"); + QueryResults<Date> res = query().from(cat).limit(2).select(cat.birthdate).fetchResults(); + assertEquals(2, res.getResults().size()); + assertEquals(6L, res.getTotal()); + System.out.println(); + + System.out.println("-- fetch distinct results"); + res = query().from(cat).limit(2).distinct().select(cat.birthdate).fetchResults(); + assertEquals(1, res.getResults().size()); + assertEquals(1L, res.getTotal()); + System.out.println(); + + System.out.println("-- fetch distinct"); + assertEquals(1, query().from(cat).distinct().select(cat.birthdate).fetch().size()); + } + + @Test + public void date() { + assertEquals(2000, query().from(cat).select(cat.birthdate.year()).fetchFirst().intValue()); + assertEquals(200002, query().from(cat).select(cat.birthdate.yearMonth()).fetchFirst().intValue()); + assertEquals(2, query().from(cat).select(cat.birthdate.month()).fetchFirst().intValue()); + assertEquals(2, query().from(cat).select(cat.birthdate.dayOfMonth()).fetchFirst().intValue()); + assertEquals(3, query().from(cat).select(cat.birthdate.hour()).fetchFirst().intValue()); + assertEquals(4, query().from(cat).select(cat.birthdate.minute()).fetchFirst().intValue()); + assertEquals(0, query().from(cat).select(cat.birthdate.second()).fetchFirst().intValue()); + } + + @Test + @NoEclipseLink({DERBY, HSQLDB}) + @NoHibernate({DERBY, POSTGRESQL, SQLSERVER}) + public void date_yearWeek() { + int value = query().from(cat).select(cat.birthdate.yearWeek()).fetchFirst(); + assertTrue(value == 200006 || value == 200005); + } + + @Test + @NoEclipseLink({DERBY, HSQLDB}) + @NoHibernate({DERBY, POSTGRESQL, SQLSERVER}) + public void date_week() { + int value = query().from(cat).select(cat.birthdate.week()).fetchFirst(); + assertTrue(value == 6 || value == 5); + } + + @Test + @ExcludeIn(ORACLE) + public void divide() { + QSimpleTypes entity = new QSimpleTypes("entity1"); + QSimpleTypes entity2 = new QSimpleTypes("entity2"); + + assertEquals(Collections.emptyList(), + query().from(entity, entity2) + .where(entity.ddouble.divide(entity2.ddouble).loe(2.0)) + .select(entity).fetch()); + + assertEquals(Collections.emptyList(), + query().from(entity, entity2) + .where(entity.ddouble.divide(entity2.iint).loe(2.0)) + .select(entity).fetch()); + + assertEquals(Collections.emptyList(), + query().from(entity, entity2) + .where(entity.iint.divide(entity2.ddouble).loe(2.0)) + .select(entity).fetch()); + + assertEquals(Collections.emptyList(), + query().from(entity, entity2) + .where(entity.iint.divide(entity2.iint).loe(2)) + .select(entity).fetch()); + } + + @Test + @ExcludeIn(ORACLE) + public void divide_bigDecimal() { + QSimpleTypes entity = new QSimpleTypes("entity1"); + QSimpleTypes entity2 = new QSimpleTypes("entity2"); + NumberPath<BigDecimal> bigd1 = entity.bigDecimal; + NumberPath<BigDecimal> bigd2 = entity2.bigDecimal; + + assertEquals(Collections.emptyList(), + query().from(entity, entity2) + .where(bigd1.divide(bigd2).loe(new BigDecimal("1.00"))) + .select(entity).fetch()); + + assertEquals(Collections.emptyList(), + query().from(entity, entity2) + .where(entity.ddouble.divide(bigd2).loe(new BigDecimal("1.00"))) + .select(entity).fetch()); + + assertEquals(Collections.emptyList(), + query().from(entity, entity2) + .where(bigd1.divide(entity.ddouble).loe(new BigDecimal("1.00"))) + .select(entity).fetch()); + } + + @Test + public void endsWith() { + assertEquals(1, query().from(cat).where(cat.name.endsWith("h123")).fetchCount()); + } + + @Test + public void endsWith_ignoreCase() { + assertEquals(1, query().from(cat).where(cat.name.endsWithIgnoreCase("H123")).fetchCount()); + } + + @Test + public void endsWith2() { + assertEquals(0, query().from(cat).where(cat.name.endsWith("X")).fetchCount()); + } + + @Test + public void endsWith3() { + assertEquals(1, query().from(cat).where(cat.name.endsWith("_123")).fetchCount()); + } + + @Test + @NoBatooJPA + public void enum_eq() { + assertEquals(1, query().from(company).where(company.ratingOrdinal.eq(Rating.A)).fetchCount()); + assertEquals(1, query().from(company).where(company.ratingString.eq(Rating.AA)).fetchCount()); + } + + @Test + @NoBatooJPA + public void enum_in() { + assertEquals(1, query().from(company).where(company.ratingOrdinal.in(Rating.A, Rating.AA)).fetchCount()); + assertEquals(1, query().from(company).where(company.ratingString.in(Rating.A, Rating.AA)).fetchCount()); + } + + @Test + @NoBatooJPA + public void enum_in2() { + QEmployee employee = QEmployee.employee; + + JPQLQuery<?> query = query(); + query.from(employee).where(employee.lastName.eq("Smith"), employee.jobFunctions + .contains(JobFunction.CODER)); + assertEquals(1L, query.fetchCount()); + } + + @Test + @ExcludeIn(SQLSERVER) + public void enum_startsWith() { + assertEquals(1, query().from(company).where(company.ratingString.stringValue().startsWith("A")).fetchCount()); + } + + @Test + @NoEclipseLink(HSQLDB) + public void factoryExpressions() { + QCat cat = QCat.cat; + QCat cat2 = new QCat("cat2"); + QCat kitten = new QCat("kitten"); + JPQLQuery<Tuple> query = query().from(cat) + .leftJoin(cat.mate, cat2) + .leftJoin(cat2.kittens, kitten) + .select(Projections.tuple(cat.id, new QFamily(cat, cat2, kitten).skipNulls())); + assertEquals(6, query.fetch().size()); + assertNotNull(query.limit(1).fetchOne()); + } + + @Test + @NoEclipseLink @NoOpenJPA @NoBatooJPA + public void fetch() { + QMammal mammal = QMammal.mammal; + QHuman human = new QHuman("mammal"); + query().from(mammal) + .leftJoin(human.hairs).fetchJoin() + .select(mammal).fetch(); + } + + @Test + @NoEclipseLink @NoOpenJPA @NoBatooJPA + public void fetch2() { + QWorld world = QWorld.world; + QMammal mammal = QMammal.mammal; + QHuman human = new QHuman("mammal"); + query().from(world) + .leftJoin(world.mammals, mammal).fetchJoin() + .leftJoin(human.hairs).fetchJoin() + .select(world).fetch(); + } + + @Test + @ExcludeIn({MYSQL, DERBY}) + @NoBatooJPA + public void groupBy() { + QAuthor author = QAuthor.author; + QBook book = QBook.book; + + for (int i = 0; i < 10; i++) { + Author a = new Author(); + a.setName(String.valueOf(i)); + save(a); + for (int j = 0; j < 2; j++) { + Book b = new Book(); + b.setTitle(String.valueOf(i) + " " + String.valueOf(j)); + b.setAuthor(a); + save(b); + } + } + + Map<Long, List<Pair<Long, String>>> map = query() + .from(author) + .join(author.books, book) + .transform(GroupBy + .groupBy(author.id) + .as(GroupBy.list(QPair.create(book.id, book.title)))); + + for (Entry<Long, List<Pair<Long, String>>> entry : map.entrySet()) { + System.out.println("author = " + entry.getKey()); + + for (Pair<Long,String> pair : entry.getValue()) { + System.out.println(" book = " + pair.getFirst() + "," + pair.getSecond()); + } + } + } + + @Test + public void groupBy2() { +// select cat0_.name as col_0_0_, cat0_.breed as col_1_0_, sum(cat0_.bodyWeight) as col_2_0_ +// from animal_ cat0_ where cat0_.DTYPE in ('C', 'DC') and cat0_.bodyWeight>? +// group by cat0_.name, cat0_.breed + query().from(cat) + .where(cat.bodyWeight.gt(0)) + .groupBy(cat.name, cat.breed) + .select(cat.name, cat.breed, cat.bodyWeight.sum()).fetch(); + } + + @Test + @NoEclipseLink + public void groupBy_yearMonth() { + query().from(cat) + .groupBy(cat.birthdate.yearMonth()) + .orderBy(cat.birthdate.yearMonth().asc()) + .select(cat.id.count()).fetch(); + } + + @Test + @Ignore // FIXME + public void groupBy_count() { + List<Integer> ids = query().from(cat).groupBy(cat.id).select(cat.id).fetch(); + long count = query().from(cat).groupBy(cat.id).fetchCount(); + QueryResults<Integer> results = query().from(cat).groupBy(cat.id) + .limit(1).select(cat.id).fetchResults(); + + long catCount = query().from(cat).fetchCount(); + assertEquals(catCount, ids.size()); + assertEquals(catCount, count); + assertEquals(catCount, results.getResults().size()); + assertEquals(catCount, results.getTotal()); + } + + @Test + @Ignore // FIXME + public void groupBy_distinct_count() { + List<Integer> ids = query().from(cat).groupBy(cat.id).distinct().select(Expressions.ONE).fetch(); + QueryResults<Integer> results = query().from(cat).groupBy(cat.id) + .limit(1).distinct().select(Expressions.ONE).fetchResults(); + + assertEquals(1, ids.size()); + assertEquals(1, results.getResults().size()); + assertEquals(1, results.getTotal()); + } + + @Test + @NoHibernate // https://hibernate.atlassian.net/browse/HHH-1902 + public void groupBy_select() { + // select length(my_column) as column_size from my_table group by column_size + NumberPath<Integer> length = Expressions.numberPath(Integer.class, "len"); + assertEquals(Arrays.asList(4, 6, 7, 8), + query().select(cat.name.length().as(length)).from(cat).orderBy(length.asc()).groupBy(length).fetch()); + } + + @Test + public void groupBy_results() { + QueryResults<Integer> results = query().from(cat).groupBy(cat.id).select(cat.id).fetchResults(); + assertEquals(6, results.getTotal()); + assertEquals(6, results.getResults().size()); + } + + @Test + public void groupBy_results2() { + QueryResults<Integer> results = query().from(cat).groupBy(cat.birthdate).select(cat.id.max()).fetchResults(); + assertEquals(1, results.getTotal()); + assertEquals(1, results.getResults().size()); + } + + @Test + public void in() { + assertEquals(3L, query().from(cat).where(cat.name.in("Bob123", "Ruth123", "Felix123")).fetchCount()); + assertEquals(3L, query().from(cat).where(cat.id.in(Arrays.asList(1, 2, 3))).fetchCount()); + assertEquals(0L, query().from(cat).where(cat.name.in(Arrays.asList("A", "B", "C"))).fetchCount()); + } + + @Test + public void in2() { + assertEquals(3L, query().from(cat).where(cat.id.in(1, 2, 3)).fetchCount()); + assertEquals(0L, query().from(cat).where(cat.name.in("A", "B", "C")).fetchCount()); + } + + @Test + public void in3() { + assertEquals(0, query().from(cat).where(cat.name.in("A,B,C".split(","))).fetchCount()); + } + + @Test + public void in4() { + //$.parameterRelease.id.eq(releaseId).and($.parameterGroups.any().id.in(filter.getGroups())); + assertEquals(Collections.emptyList(), + query().from(cat).where(cat.id.eq(1), cat.kittens.any().id.in(1, 2, 3)).select(cat).fetch()); + } + + @Test + public void in5() { + assertEquals(4L, query().from(cat).where(cat.mate.in(savedCats)).fetchCount()); + } + + @Test + @Ignore + public void in6() { + //query().from(cat).where(cat.kittens.in(savedCats)).fetchCount(); + } + + @Test + public void in7() { + assertEquals(4L, query().from(cat).where(cat.kittens.any().in(savedCats)).fetchCount()); + } + + @Test + public void in_empty() { + assertEquals(0, query().from(cat).where(cat.name.in(Collections.emptyList())).fetchCount()); + } + + @Test + @NoOpenJPA + public void indexOf() { + assertEquals(Integer.valueOf(0), query().from(cat).where(cat.name.eq("Bob123")) + .select(cat.name.indexOf("B")).fetchFirst()); + } + + @Test + @NoOpenJPA + public void indexOf2() { + assertEquals(Integer.valueOf(1), query().from(cat).where(cat.name.eq("Bob123")) + .select(cat.name.indexOf("o")).fetchFirst()); + } + + @Test + public void instanceOf_cat() { + assertEquals(6L, query().from(cat).where(cat.instanceOf(Cat.class)).fetchCount()); + } + + @Test + public void instanceOf_domesticCat() { + assertEquals(0L, query().from(cat).where(cat.instanceOf(DomesticCat.class)).fetchCount()); + } + + @Test + public void instanceOf_entity1() { + QEntity1 entity1 = QEntity1.entity1; + assertEquals(2L, query().from(entity1).where(entity1.instanceOf(Entity1.class)).fetchCount()); + } + + @Test + public void instanceOf_entity2() { + QEntity1 entity1 = QEntity1.entity1; + assertEquals(1L, query().from(entity1).where(entity1.instanceOf(Entity2.class)).fetchCount()); + } + + @Test + @NoHibernate // https://hibernate.atlassian.net/browse/HHH-6686 + public void isEmpty_elementCollection() { + QEmployee employee = QEmployee.employee; + assertEquals(0, query().from(employee).where(employee.jobFunctions.isEmpty()).fetchCount()); + } + + @Test + public void isEmpty_relation() { + assertEquals(6L, query().from(cat).where(cat.kittensSet.isEmpty()).fetchCount()); + } + + @Test + @NoEclipseLink + @ExcludeIn({ORACLE, TERADATA}) + public void joinEmbeddable() { + QBookVersion bookVersion = QBookVersion.bookVersion; + QBookMark bookMark = QBookMark.bookMark; + + assertEquals(Collections.emptyList(), + query().from(bookVersion) + .join(bookVersion.definition.bookMarks, bookMark) + .where( + bookVersion.definition.bookMarks.size().eq(1), + bookMark.page.eq(2357L).or(bookMark.page.eq(2356L))) + .select(bookVersion).fetch()); + } + + @Test + public void length() { + assertEquals(6, query().from(cat).where(cat.name.length().gt(0)).fetchCount()); + } + + @Test + public void like() { + assertEquals(0, query().from(cat).where(cat.name.like("!")).fetchCount()); + assertEquals(0, query().from(cat).where(cat.name.like("\\")).fetchCount()); + } + + @Test + public void limit() { + List<String> names1 = Arrays.asList("Allen123","Bob123"); + assertEquals(names1, query().from(cat).orderBy(cat.name.asc()).limit(2).select(cat.name).fetch()); + } + + @Test + public void limit_and_offset() { + List<String> names3 = Arrays.asList("Felix123", "Mary_123"); + assertEquals(names3, query().from(cat).orderBy(cat.name.asc()).limit(2).offset(2).select(cat.name).fetch()); + } + + @Test + public void limit2() { + assertEquals(Collections.singletonList("Allen123"), + query().from(cat).orderBy(cat.name.asc()).limit(1).select(cat.name).fetch()); + } + + @Test + public void limit3() { + assertEquals(6, query().from(cat).limit(Long.MAX_VALUE).select(cat).fetch().size()); + } + + @Test + public void list_elementCollection_of_enum() { + QEmployee employee = QEmployee.employee; + //QJobFunction jobFunction = QJobFunction.jobFunction; + EnumPath<JobFunction> jobFunction = Expressions.enumPath(JobFunction.class, "jf"); + + List<JobFunction> jobFunctions = query().from(employee) + .innerJoin(employee.jobFunctions, jobFunction).select(jobFunction).fetch(); + assertEquals(4, jobFunctions.size()); + } + + @Test + @NoBatooJPA + public void list_elementCollection_of_string() { + QFoo foo = QFoo.foo; + StringPath str = Expressions.stringPath("str"); + + List<String> strings = query().from(foo).innerJoin(foo.names, str).select(str).fetch(); + assertEquals(2, strings.size()); + assertTrue(strings.contains("a")); + assertTrue(strings.contains("b")); + } + + @Test + @NoEclipseLink(HSQLDB) + public void list_order_get() { + QCat cat = QCat.cat; + assertEquals(6, query().from(cat).orderBy(cat.kittens.get(0).name.asc()).fetch().size()); + } + + @Test + @NoEclipseLink(HSQLDB) + public void list_order_get2() { + QCat cat = QCat.cat; + assertEquals(6, query().from(cat).orderBy(cat.mate.kittens.get(0).name.asc()).fetch().size()); + } + + @Test + public void map_get() { + QShow show = QShow.show; + assertEquals(Collections.singletonList("A"), query().from(show).select(show.acts.get("a")).fetch()); + } + + @Test + @NoHibernate + public void map_get2() { + QShow show = QShow.show; + assertEquals(1, query().from(show).where(show.acts.get("a").eq("A")).fetchCount()); + } + + @Test + @NoEclipseLink + public void map_order_get() { + QShow show = QShow.show; + assertEquals(1, query().from(show).orderBy(show.parent.acts.get("A").asc()).fetch().size()); + } + + @Test + @NoEclipseLink + public void map_order_get2() { + QShow show = QShow.show; + QShow parent = new QShow("parent"); + assertEquals(1, query().from(show).leftJoin(show.parent, parent) + .orderBy(parent.acts.get("A").asc()).fetch().size()); + } + + @Test + public void map_containsKey() { + QShow show = QShow.show; + assertEquals(1L, query().from(show).where(show.acts.containsKey("a")).fetchCount()); + } + + @Test + public void map_containsKey2() { + QShow show = QShow.show; + assertEquals(1L, query().from(show).where(show.acts.containsKey("b")).fetchCount()); + } + + @Test + public void map_containsKey3() { + QShow show = QShow.show; + assertEquals(0L, query().from(show).where(show.acts.containsKey("c")).fetchCount()); + } + + @Test + public void map_containsValue() { + QShow show = QShow.show; + assertEquals(1L, query().from(show).where(show.acts.containsValue("A")).fetchCount()); + } + + @Test + public void map_containsValue2() { + QShow show = QShow.show; + assertEquals(1L, query().from(show).where(show.acts.containsValue("B")).fetchCount()); + } + + @Test + public void map_containsValue3() { + QShow show = QShow.show; + assertEquals(0L, query().from(show).where(show.acts.containsValue("C")).fetchCount()); + } + + @Test + public void map_contains() { + QShow show = QShow.show; + assertEquals(1L, query().from(show).where(show.acts.contains("a", "A")).fetchCount()); + assertEquals(0L, query().from(show).where(show.acts.contains("X", "X")).fetchCount()); + } + + @Test + public void map_groupBy() { + QShow show = QShow.show; + assertEquals(1, query().from(show).select(show.acts.get("X")).groupBy(show.acts.get("a")).fetchCount()); + } + + @Test + @Ignore + public void map_join() { + //select m.text from Show s join s.acts a where key(a) = 'B' + QShow show = QShow.show; + StringPath act = Expressions.stringPath("act"); + assertEquals(Collections.emptyList(), query().from(show).join(show.acts, act).select(act).fetch()); + } + + @Test + public void max() { + assertEquals(6.0, query().from(cat).select(cat.bodyWeight.max()).fetchFirst(), 0.0001); + } + + @Test + public void min() { + assertEquals(1.0, query().from(cat).select(cat.bodyWeight.min()).fetchFirst(), 0.0001); + } + + @Test + @ExcludeIn(ORACLE) + public void multiply() { + QSimpleTypes entity = new QSimpleTypes("entity1"); + QSimpleTypes entity2 = new QSimpleTypes("entity2"); + + assertEquals(Collections.emptyList(), + query().from(entity, entity2) + .where(entity.ddouble.multiply(entity2.ddouble).loe(2.0)) + .select(entity).fetch()); + } + + @Test + @ExcludeIn(ORACLE) + public void multiply_bigDecimal() { + QSimpleTypes entity = new QSimpleTypes("entity1"); + QSimpleTypes entity2 = new QSimpleTypes("entity2"); + NumberPath<BigDecimal> bigd1 = entity.bigDecimal; + NumberPath<BigDecimal> bigd2 = entity2.bigDecimal; + + assertEquals(Collections.emptyList(), + query().from(entity, entity2) + .where(bigd1.multiply(bigd2).loe(new BigDecimal("1.00"))) + .select(entity).fetch()); + } + + @Test + public void nestedProjection() { + Concatenation concat = new Concatenation(cat.name, cat.name); + List<Tuple> tuples = query().from(cat).select(cat.name, concat).fetch(); + assertFalse(tuples.isEmpty()); + for (Tuple tuple : tuples) { + assertEquals( + tuple.get(concat), + tuple.get(cat.name) + tuple.get(cat.name)); + } + } + + @Test + public void not_in() { + long all = query().from(cat).fetchCount(); + assertEquals(all - 3L, query().from(cat).where(cat.name.notIn("Bob123", "Ruth123", "Felix123")).fetchCount()); + + assertEquals(3L, query().from(cat).where(cat.id.notIn(1, 2, 3)).fetchCount()); + assertEquals(6L, query().from(cat).where(cat.name.notIn("A", "B", "C")).fetchCount()); + } + + @Test + @NoBatooJPA + public void not_in_empty() { + long count = query().from(cat).fetchCount(); + assertEquals(count, query().from(cat).where(cat.name.notIn(Collections.<String>emptyList())).fetchCount()); + } + + @Test + public void null_as_uniqueResult() { + assertNull(query().from(cat).where(cat.name.eq(UUID.randomUUID().toString())) + .select(cat).fetchFirst()); + } + + @Test + @NoEclipseLink + public void numeric() { + QNumeric numeric = QNumeric.numeric; + BigDecimal singleResult = query().from(numeric).select(numeric.value).fetchFirst(); + assertEquals(26.9, singleResult.doubleValue(), 0.001); + } + + @Test + @NoOpenJPA + @NoBatooJPA // FIXME + public void offset1() { + List<String> names2 = Arrays.asList("Bob123", "Felix123", "Mary_123", "Ruth123", "Some"); + assertEquals(names2, query().from(cat).orderBy(cat.name.asc()).offset(1).select(cat.name).fetch()); + } + + @Test + @NoOpenJPA + @NoBatooJPA // FIXME + public void offset2() { + List<String> names2 = Arrays.asList("Felix123", "Mary_123", "Ruth123", "Some"); + assertEquals(names2, query().from(cat).orderBy(cat.name.asc()).offset(2).select(cat.name).fetch()); + } + + @Test + public void one_to_one() { + QEmployee employee = QEmployee.employee; + QUser user = QUser.user; + + JPQLQuery<?> query = query(); + query.from(employee); + query.innerJoin(employee.user, user); + query.select(employee).fetch(); + } + + @Test + public void order() { + NumberPath<Double> weight = Expressions.numberPath(Double.class, "weight"); + assertEquals(Arrays.asList(1.0, 2.0, 3.0, 4.0, 5.0, 6.0), + query().from(cat).orderBy(weight.asc()).select(cat.bodyWeight.as(weight)).fetch()); + } + + @Test + public void order_by_count() { + NumberPath<Long> count = Expressions.numberPath(Long.class, "c"); + query().from(cat) + .groupBy(cat.id) + .orderBy(count.asc()) + .select(cat.id, cat.id.count().as(count)).fetch(); + } + + @Test + public void order_stringValue() { + int count = (int) query().from(cat).fetchCount(); + assertEquals(count, query().from(cat).orderBy(cat.id.stringValue().asc()).select(cat).fetch().size()); + } + + @Test + @NoBatooJPA // can't be parsed + public void order_stringValue_to_integer() { + int count = (int) query().from(cat).fetchCount(); + assertEquals(count, query().from(cat).orderBy(cat.id.stringValue().castToNum(Integer.class).asc()).select(cat).fetch().size()); + } + + @Test + @NoBatooJPA // can't be parsed + public void order_stringValue_toLong() { + int count = (int) query().from(cat).fetchCount(); + assertEquals(count, query().from(cat).orderBy(cat.id.stringValue().castToNum(Long.class).asc()).select(cat).fetch().size()); + } + + @Test + @NoBatooJPA // can't be parsed + public void order_stringValue_toBigInteger() { + int count = (int) query().from(cat).fetchCount(); + assertEquals(count, query().from(cat).orderBy(cat.id.stringValue().castToNum(BigInteger.class).asc()).select(cat).fetch().size()); + } + + @Test + @NoBatooJPA + @ExcludeIn(SQLSERVER) + public void order_nullsFirst() { + assertNull(query().from(cat) + .orderBy(cat.dateField.asc().nullsFirst()) + .select(cat.dateField).fetchFirst()); + } + + @Test + @NoBatooJPA + @ExcludeIn(SQLSERVER) + public void order_nullsLast() { + assertNotNull(query().from(cat) + .orderBy(cat.dateField.asc().nullsLast()) + .select(cat.dateField).fetchFirst()); + } + + @Test + public void params() { + Param<String> name = new Param<String>(String.class,"name"); + assertEquals("Bob123", query().from(cat).where(cat.name.eq(name)).set(name, "Bob123") + .select(cat.name).fetchFirst()); + } + + @Test + public void params_anon() { + Param<String> name = new Param<String>(String.class); + assertEquals("Bob123",query().from(cat).where(cat.name.eq(name)).set(name, "Bob123") + .select(cat.name).fetchFirst()); + } + + @Test(expected = ParamNotSetException.class) + public void params_not_set() { + Param<String> name = new Param<String>(String.class,"name"); + assertEquals("Bob123", query().from(cat).where(cat.name.eq(name)).select(cat.name).fetchFirst()); + } + + @Test + public void precedence() { + StringPath str = cat.name; + Predicate where = str.like("Bob%").and(str.like("%ob123")) + .or(str.like("Ruth%").and(str.like("%uth123"))); + assertEquals(2L, query().from(cat).where(where).fetchCount()); + } + + @Test + public void precedence2() { + StringPath str = cat.name; + Predicate where = str.like("Bob%").and(str.like("%ob123") + .or(str.like("Ruth%"))).and(str.like("%uth123")); + assertEquals(0L, query().from(cat).where(where).fetchCount()); + } + + @Test + public void precedence3() { + Predicate where = cat.name.eq("Bob123").and(cat.id.eq(1)) + .or(cat.name.eq("Ruth123").and(cat.id.eq(2))); + assertEquals(2L, query().from(cat).where(where).fetchCount()); + } + + @Test + public void factoryExpression_in_groupBy() { + Expression<Cat> catBean = Projections.bean(Cat.class, cat.id, cat.name); + assertFalse(query().from(cat).groupBy(catBean).select(catBean).fetch().isEmpty()); + } + + @Test + @Ignore + public void size() { + // NOT SUPPORTED + query().from(cat).select(cat, cat.kittens.size()).fetch(); + } + + @Test + public void startsWith() { + assertEquals(1, query().from(cat).where(cat.name.startsWith("R")).fetchCount()); + } + + @Test + public void startsWith_ignoreCase() { + assertEquals(1, query().from(cat).where(cat.name.startsWithIgnoreCase("r")).fetchCount()); + } + + @Test + public void startsWith2() { + assertEquals(0, query().from(cat).where(cat.name.startsWith("X")).fetchCount()); + } + + @Test + public void startsWith3() { + assertEquals(1, query().from(cat).where(cat.name.startsWith("Mary_")).fetchCount()); + } + + @Test + @ExcludeIn({MYSQL, SQLSERVER, TERADATA}) + @NoOpenJPA + public void stringOperations() { + // NOTE : locate in MYSQL is case-insensitive + assertEquals(0, query().from(cat).where(cat.name.startsWith("r")).fetchCount()); + assertEquals(0, query().from(cat).where(cat.name.endsWith("H123")).fetchCount()); + assertEquals(Integer.valueOf(2), query().from(cat).where(cat.name.eq("Bob123")) + .select(cat.name.indexOf("b")).fetchFirst()); + } + + @Test + public void subQuery() { + QShow show = QShow.show; + QShow show2 = new QShow("show2"); + assertEquals(0, + query().from(show).where(select(show2.count()).from(show2) + .where(show2.id.ne(show.id)).gt(0L)).fetchCount()); + } + + @Test + public void subQuery2() { + QCat cat = QCat.cat; + QCat other = new QCat("other"); + assertEquals(savedCats, query().from(cat) + .where(cat.name.in(select(other.name).from(other) + .groupBy(other.name))) + .orderBy(cat.id.asc()) + .select(cat).fetch()); + } + + @Test + public void subQuery3() { + QCat cat = QCat.cat; + QCat other = new QCat("other"); + assertEquals(savedCats.subList(0, 1), query().from(cat) + .where(cat.name.eq(select(other.name).from(other) + .where(other.name.indexOf("B").eq(0)))) + .select(cat).fetch()); + } + + @Test + public void subQuery4() { + QCat cat = QCat.cat; + QCat other = new QCat("other"); + query().from(cat) + .select(cat.name, select(other.count()).from(other).where(other.name.eq(cat.name))).fetch(); + } + + @Test + public void subQuery5() { + QEmployee employee = QEmployee.employee; + QEmployee employee2 = new QEmployee("e2"); + assertEquals(2, query().from(employee) + .where(select(employee2.id.count()).from(employee2).gt(1L)) + .fetchCount()); + } + + @Test + public void substring() { + for (String str : query().from(cat).select(cat.name.substring(1,2)).fetch()) { + assertEquals(1, str.length()); + } + } + + @Test + @NoBatooJPA + @ExcludeIn({ORACLE, SQLSERVER, HSQLDB}) + public void substring2() { + QCompany company = QCompany.company; + StringExpression name = company.name; + Integer companyId = query().from(company).select(company.id).fetchFirst(); + JPQLQuery<?> query = query().from(company).where(company.id.eq(companyId)); + String str = query.select(company.name).fetchFirst(); + + assertEquals(Integer.valueOf(29), + query.select(name.length().subtract(11)).fetchFirst()); + + assertEquals(str.substring(0, 7), + query.select(name.substring(0, 7)).fetchFirst()); + + assertEquals(str.substring(15), + query.select(name.substring(15)).fetchFirst()); + + assertEquals(str.substring(str.length()), + query.select(name.substring(name.length())).fetchFirst()); + + assertEquals(str.substring(str.length() - 11), + query.select(name.substring(name.length().subtract(11))).fetchFirst()); + } + + @Test + @Ignore // FIXME + @ExcludeIn(DERBY) + public void substring_from_right() { + assertEquals(Collections.emptyList(), query().from(cat) + .where(cat.name.substring(-1, 1).eq(cat.name.substring(-2, 1))) + .select(cat).fetch()); + } + + @Test + @ExcludeIn({HSQLDB, DERBY}) + public void substring_from_right2() { + assertEquals(Collections.emptyList(), query().from(cat) + .where(cat.name.substring(cat.name.length().subtract(1), cat.name.length()) + .eq(cat.name.substring(cat.name.length().subtract(2), cat.name.length().subtract(1)))) + .select(cat).fetch()); + } + + @Test + @ExcludeIn(ORACLE) + public void subtract_bigDecimal() { + QSimpleTypes entity = new QSimpleTypes("entity1"); + QSimpleTypes entity2 = new QSimpleTypes("entity2"); + NumberPath<BigDecimal> bigd1 = entity.bigDecimal; + NumberPath<BigDecimal> bigd2 = entity2.bigDecimal; + + assertEquals(Collections.emptyList(), query().from(entity, entity2) + .where(bigd1.subtract(bigd2).loe(new BigDecimal("1.00"))) + .select(entity).fetch()); + } + + @Test + @Ignore + public void sum() { + // NOT SUPPORTED + query().from(cat).select(cat.kittens.size().sum()).fetch(); + } + + @Test + @Ignore + public void sum_2() { + // NOT SUPPORTED + query().from(cat).where(cat.kittens.size().sum().gt(0)).select(cat).fetch(); + } + + @Test + public void sum_3() { + assertEquals(21.0, query().from(cat).select(cat.bodyWeight.sum()).fetchFirst(), 0.0001); + } + + @Test + public void sum_3_projected() { + double val = query().from(cat).select(cat.bodyWeight.sum()).fetchFirst(); + DoubleProjection projection = query().from(cat) + .select(new QDoubleProjection(cat.bodyWeight.sum())).fetchFirst(); + assertEquals(val, projection.val, 0.001); + } + + @Test + public void sum_4() { + Double dbl = query().from(cat).select(cat.bodyWeight.sum().negate()).fetchFirst(); + assertNotNull(dbl); + } + + @Test + public void sum_5() { + QShow show = QShow.show; + Long lng = query().from(show).select(show.id.sum()).fetchFirst(); + assertNotNull(lng); + } + + @Test + public void sum_of_integer() { + QCat cat2 = new QCat("cat2"); + assertEquals(Collections.emptyList(), query().from(cat) + .where(select(cat2.breed.sum()) + .from(cat2).where(cat2.eq(cat.mate)).gt(0)) + .select(cat).fetch()); + } + + @Test + public void sum_of_float() { + QCat cat2 = new QCat("cat2"); + query().from(cat) + .where(select(cat2.floatProperty.sum()) + .from(cat2).where(cat2.eq(cat.mate)).gt(0.0f)) + .select(cat).fetch(); + } + + @Test + public void sum_of_double() { + QCat cat2 = new QCat("cat2"); + query().from(cat) + .where(select(cat2.bodyWeight.sum()) + .from(cat2).where(cat2.eq(cat.mate)).gt(0.0)) + .select(cat).fetch(); + } + + @Test + public void sum_as_float() { + float val = query().from(cat).select(cat.floatProperty.sum()).fetchFirst(); + assertTrue(val > 0); + } + + @Test + public void sum_as_float_projected() { + float val = query().from(cat).select(cat.floatProperty.sum()).fetchFirst(); + FloatProjection projection = query().from(cat) + .select(new QFloatProjection(cat.floatProperty.sum())).fetchFirst(); + assertEquals(val, projection.val, 0.001); + } + + @Test + public void sum_as_float2() { + float val = query().from(cat).select(cat.floatProperty.sum().negate()).fetchFirst(); + assertTrue(val < 0); + } + + @Test + public void sum_coalesce() { + int val = query().from(cat).select(cat.weight.sum().coalesce(0)).fetchFirst(); + assertEquals(0, val); + } + + @Test + public void sum_noRows_double() { + assertNull(query().from(cat) + .where(cat.name.eq(UUID.randomUUID().toString())) + .select(cat.bodyWeight.sum()).fetchFirst()); + } + + @Test + public void sum_noRows_float() { + assertNull(query().from(cat) + .where(cat.name.eq(UUID.randomUUID().toString())) + .select(cat.floatProperty.sum()).fetchFirst()); + } + + @Test + @NoEclipseLink @NoOpenJPA @NoBatooJPA + @ExcludeIn({ORACLE, SQLSERVER}) + public void test() { + Cat kitten = savedCats.get(0); + Cat noKitten = savedCats.get(savedCats.size() - 1); + + ProjectionsFactory projections = new ProjectionsFactory(QuerydslModule.JPA, getTarget()) { + @Override + public <A,Q extends SimpleExpression<A>> Collection<Expression<?>> list(ListPath<A,Q> expr, + ListExpression<A,Q> other, A knownElement) { + // NOTE : expr.get(0) is only supported in the where clause + return Collections.<Expression<?>>singleton(expr.size()); + } + }; + + final EntityPath<?>[] sources = {cat, otherCat}; + final Predicate[] conditions = {condition}; + final Expression<?>[] projection = {cat.name, otherCat.name}; + + QueryExecution standardTest = new QueryExecution( + projections, + new FilterFactory(projections, QuerydslModule.JPA, getTarget()), + new MatchingFiltersFactory(QuerydslModule.JPA, getTarget())) { + + @Override + protected Fetchable<?> createQuery() { + // NOTE : EclipseLink needs extra conditions cond1 and code2 + return testQuery().from(sources).where(conditions); + } + + @Override + protected Fetchable<?> createQuery(Predicate filter) { + // NOTE : EclipseLink needs extra conditions cond1 and code2 + return testQuery().from(sources).where(condition, filter).select(projection); + } + }; + + // standardTest.runArrayTests(cat.kittensArray, otherCat.kittensArray, kitten, noKitten); + standardTest.runBooleanTests(cat.name.isNull(), otherCat.kittens.isEmpty()); + standardTest.runCollectionTests(cat.kittens, otherCat.kittens, kitten, noKitten); + standardTest.runDateTests(cat.dateField, otherCat.dateField, date); + standardTest.runDateTimeTests(cat.birthdate, otherCat.birthdate, birthDate); + standardTest.runListTests(cat.kittens, otherCat.kittens, kitten, noKitten); + // standardTest.mapTests(cat.kittensByName, otherCat.kittensByName, "Kitty", kitten); + + // int + standardTest.runNumericCasts(cat.id, otherCat.id, 1); + standardTest.runNumericTests(cat.id, otherCat.id, 1); + + // double + standardTest.runNumericCasts(cat.bodyWeight, otherCat.bodyWeight, 1.0); + standardTest.runNumericTests(cat.bodyWeight, otherCat.bodyWeight, 1.0); + + standardTest.runStringTests(cat.name, otherCat.name, kitten.getName()); + standardTest.runTimeTests(cat.timeField, otherCat.timeField, time); + + standardTest.report(); + } + + @Test + public void tupleProjection() { + List<Tuple> tuples = query().from(cat).select(cat.name, cat).fetch(); + assertFalse(tuples.isEmpty()); + for (Tuple tuple : tuples) { + assertNotNull(tuple.get(cat.name)); + assertNotNull(tuple.get(cat)); + } + } + + @Test + public void tupleProjection_as_queryResults() { + QueryResults<Tuple> tuples = query().from(cat).limit(1) + .select(cat.name, cat).fetchResults(); + assertEquals(1, tuples.getResults().size()); + assertTrue(tuples.getTotal() > 0); + } + + @Test + @ExcludeIn(DERBY) + public void transform_groupBy() { + QCat kitten = new QCat("kitten"); + Map<Integer, Cat> result = query().from(cat).innerJoin(cat.kittens, kitten) + .transform(GroupBy.groupBy(cat.id) + .as(Projections.constructor(Cat.class, cat.name, cat.id, + GroupBy.list(Projections.constructor(Cat.class, kitten.name, kitten.id))))); + + for (Cat entry : result.values()) { + assertEquals(1, entry.getKittens().size()); + } + } + + @Test + @ExcludeIn(DERBY) + public void transform_groupBy2() { + QCat kitten = new QCat("kitten"); + Map<List<?>, Group> result = query().from(cat).innerJoin(cat.kittens, kitten) + .transform(GroupBy.groupBy(cat.id, kitten.id) + .as(cat, kitten)); + + assertFalse(result.isEmpty()); + for (Tuple row : query().from(cat).innerJoin(cat.kittens, kitten) + .select(cat, kitten).fetch()) { + assertNotNull(result.get(Arrays.asList(row.get(cat).getId(), row.get(kitten).getId()))); + } + } + + @Test + @ExcludeIn(DERBY) + public void transform_groupBy_alias() { + QCat kitten = new QCat("kitten"); + SimplePath<Cat> k = Expressions.path(Cat.class, "k"); + Map<Integer, Group> result = query().from(cat).innerJoin(cat.kittens, kitten) + .transform(GroupBy.groupBy(cat.id) + .as(cat.name, cat.id, + GroupBy.list(Projections.constructor(Cat.class, kitten.name, kitten.id).as(k)))); + + for (Group entry : result.values()) { + assertNotNull(entry.getOne(cat.id)); + assertNotNull(entry.getOne(cat.name)); + assertFalse(entry.getList(k).isEmpty()); + } + } + + @Test + @NoBatooJPA + public void treat() { + QDomesticCat domesticCat = QDomesticCat.domesticCat; + assertEquals(0, query().from(cat) + .innerJoin(cat.mate, domesticCat._super) + .where(domesticCat.name.eq("Bobby")) + .fetchCount()); + } + + @Test + @Ignore + public void type() { + assertEquals(Arrays.asList("C","C","C","C","C","C","A"), + query().from(animal).orderBy(animal.id.asc()).select(JPAExpressions.type(animal)).fetch()); + } + + @Test + @NoOpenJPA + public void type_order() { + assertEquals(Arrays.asList(10, 1, 2, 3, 4, 5, 6), + query().from(animal).orderBy(JPAExpressions.type(animal).asc(), animal.id.asc()) + .select(animal.id).fetch()); + } + + @Test + @ExcludeIn({DERBY, ORACLE}) + public void byte_array() { + QSimpleTypes simpleTypes = QSimpleTypes.simpleTypes; + assertEquals(Collections.emptyList(), query().from(simpleTypes) + .where(simpleTypes.byteArray.eq(new byte[]{0, 1})).select(simpleTypes).fetch()); + } +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/AbstractQueryTest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/AbstractQueryTest.java new file mode 100644 index 0000000000..6140589ef4 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/AbstractQueryTest.java @@ -0,0 +1,38 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import com.querydsl.core.types.Expression; + +public abstract class AbstractQueryTest { + + protected QueryHelper<?> query() { + return new QueryHelper<Void>(HQLTemplates.DEFAULT); + } + + protected static void assertToString(String expected, Expression<?> expr) { + JPQLSerializer serializer = new JPQLSerializer(HQLTemplates.DEFAULT, null); + assertEquals(expected, serializer.handle(expr).toString().replace("\n", " ")); + } + + protected static void assertMatches(String expected, Expression<?> expr) { + JPQLSerializer serializer = new JPQLSerializer(HQLTemplates.DEFAULT, null); + String str = serializer.handle(expr).toString().replace("\n", " "); + assertTrue(expected + "\n!=\n" + str, str.matches(expected)); + } + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/AbstractSQLTest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/AbstractSQLTest.java new file mode 100644 index 0000000000..95e78da9b3 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/AbstractSQLTest.java @@ -0,0 +1,387 @@ +package com.querydsl.jpa; + +import static com.querydsl.sql.SQLExpressions.select; +import static org.junit.Assert.*; + +import java.sql.SQLException; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.UUID; + +import org.junit.Ignore; +import org.junit.Test; + +import com.querydsl.core.QueryResults; +import com.querydsl.core.Target; +import com.querydsl.core.Tuple; +import com.querydsl.core.testutil.ExcludeIn; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.Projections; +import com.querydsl.core.types.SubQueryExpression; +import com.querydsl.core.types.dsl.DateExpression; +import com.querydsl.core.types.dsl.Wildcard; +import com.querydsl.jpa.domain.Cat; +import com.querydsl.jpa.domain.Color; +import com.querydsl.jpa.domain.QCat; +import com.querydsl.jpa.domain.QCompany; +import com.querydsl.jpa.domain.sql.SAnimal; + +public abstract class AbstractSQLTest { + + protected static final SAnimal cat = new SAnimal("cat"); + + protected abstract AbstractSQLQuery<?,?> query(); + + public static class CatDTO { + + Cat cat; + + public CatDTO(Cat cat) { + this.cat = cat; + } + + } + + @Test + public void count() { + assertEquals(6L, query().from(cat).where(cat.dtype.eq("C")).fetchCount()); + } + + @Test + public void count_via_unique() { + assertEquals(Long.valueOf(6), query().from(cat).where(cat.dtype.eq("C")) + .select(cat.id.count()).fetchFirst()); + } + + @Test + public void countDistinct() { + assertEquals(6L, query().from(cat).where(cat.dtype.eq("C")).distinct().fetchCount()); + } + + @Test + public void enum_binding() { + List<Cat> cats = query().from(cat) + .select(Projections.bean(Cat.class, QCat.cat.color)).fetch(); + assertFalse(cats.isEmpty()); + + for (Cat cat : cats) { + assertEquals(Color.BLACK, cat.getColor()); + } + } + + @Test + @Ignore + public void entityProjections() { + List<Cat> cats = query().from(cat).orderBy(cat.name.asc()) + .select(Projections.constructor(Cat.class, cat.name, cat.id)).fetch(); + assertEquals(6, cats.size()); + for (Cat c : cats) { + assertNotNull(c.getName()); + assertTrue(c.getId() > 0); + } + } + + @Test + public void entityQueries() { + QCat catEntity = QCat.cat; + + List<Cat> cats = query().from(cat).orderBy(cat.name.asc()).select(catEntity).fetch(); + assertEquals(6, cats.size()); + for (Cat c : cats) { + assertNotNull(c.getName()); + } + } + + @Test + public void entityQueries2() { + SAnimal mate = new SAnimal("mate"); + QCat catEntity = QCat.cat; + + List<Cat> cats = query().from(cat) + .innerJoin(mate).on(cat.mateId.eq(mate.id)) + .where(cat.dtype.eq("C"), mate.dtype.eq("C")) + .select(catEntity).fetch(); + assertTrue(cats.isEmpty()); + } + + @Test + public void entityQueries3() { + QCat catEntity = new QCat("animal_"); + assertEquals(0, query().from(catEntity).select(catEntity.toes.max()).fetchFirst().intValue()); + } + + @Test + @NoBatooJPA + @NoEclipseLink + public void entityQueries4() { + QCat catEntity = QCat.cat; + List<Tuple> cats = query().from(cat).select(catEntity, cat.name, cat.id).fetch(); + assertEquals(6, cats.size()); + + for (Tuple tuple : cats) { + assertTrue(tuple.get(catEntity) instanceof Cat); + assertTrue(tuple.get(cat.name) instanceof String); + assertTrue(tuple.get(cat.id) instanceof Integer); + } + } + + @Test + @NoBatooJPA + @NoEclipseLink + public void entityQueries5() { + QCat catEntity = QCat.cat; + SAnimal otherCat = new SAnimal("otherCat"); + QCat otherCatEntity = new QCat("otherCat"); + List<Tuple> cats = query().from(cat, otherCat).select(catEntity, otherCatEntity).fetch(); + assertEquals(36, cats.size()); + + for (Tuple tuple : cats) { + assertTrue(tuple.get(catEntity) instanceof Cat); + assertTrue(tuple.get(otherCatEntity) instanceof Cat); + } + } + + @Test + @NoBatooJPA + @NoEclipseLink + public void entityQueries6() { + QCat catEntity = QCat.cat; + List<CatDTO> results = query().from(cat).select(Projections.constructor(CatDTO.class, catEntity)).fetch(); + assertEquals(6, results.size()); + + for (CatDTO cat : results) { + assertTrue(cat.cat instanceof Cat); + } + } + + @Test + public void entityQueries7() { + QCompany company = QCompany.company; + assertEquals(Collections.emptyList(), + query().from(company).select(company.officialName).fetch()); + } + + @Test + public void in() { + assertEquals(6L, query().from(cat).where(cat.dtype.in("C", "CX")).fetchCount()); + } + + @Test + public void limit_offset() { + assertEquals(2, query().from(cat).orderBy(cat.id.asc()).limit(2).offset(2).select(cat.id, cat.name).fetch().size()); + } + + @Test + public void list() { + assertEquals(6, query().from(cat).where(cat.dtype.eq("C")).select(cat.id).fetch().size()); + } + + @Test + public void list_limit_and_offset() { + assertEquals(3, query().from(cat).orderBy(cat.id.asc()).offset(3).limit(3).select(cat.id).fetch().size()); + } + + @Test + public void list_limit_and_offset2() { + List<Tuple> tuples = query().from(cat).orderBy(cat.id.asc()).offset(3).limit(3).select(cat.id, cat.name).fetch(); + assertEquals(3, tuples.size()); + assertEquals(2, tuples.get(0).size()); + } + + @Test + public void list_limit_and_offset3() { + List<Tuple> tuples = query().from(cat).orderBy(cat.id.asc()).offset(3).limit(3).select(Projections.tuple(cat.id, cat.name)).fetch(); + assertEquals(3, tuples.size()); + assertEquals(2, tuples.get(0).size()); + } + + @Test + public void list_multiple() { + print(query().from(cat).where(cat.dtype.eq("C")).select(cat.id, cat.name, cat.bodyWeight).fetch()); + } + + @Test + public void list_non_path() { + assertEquals(6, query().from(cat).where(cat.dtype.eq("C")).select( + cat.birthdate.year(), + cat.birthdate.month(), + cat.birthdate.dayOfMonth()).fetch().size()); + } + + @Test + public void list_results() { + QueryResults<String> results = query().from(cat).limit(3).orderBy(cat.name.asc()) + .select(cat.name).fetchResults(); + assertEquals(Arrays.asList("Beck","Bobby","Harold"), results.getResults()); + assertEquals(6L, results.getTotal()); + } + + @Test + @ExcludeIn(Target.H2) + public void list_wildcard() { + assertEquals(6, query().from(cat).where(cat.dtype.eq("C")).select(Wildcard.all).fetch().size()); + } + + @Test + public void list_with_count() { + print(query().from(cat).where(cat.dtype.eq("C")).groupBy(cat.name) + .select(cat.name, cat.id.count()).fetch()); + } + + @Test + public void list_with_limit() { + assertEquals(3, query().from(cat).limit(3).select(cat.id).fetch().size()); + } + + @Test + @ExcludeIn({Target.H2, Target.MYSQL}) + public void list_with_offset() { + assertEquals(3, query().from(cat).orderBy(cat.id.asc()).offset(3).select(cat.id).fetch().size()); + } + + @Test + @ExcludeIn(Target.HSQLDB) + public void no_from() { + assertNotNull(query().select(DateExpression.currentDate()).fetchFirst()); + } + + @Test + public void null_as_uniqueResult() { + assertNull(query().from(cat).where(cat.name.eq(UUID.randomUUID().toString())) + .select(cat.name).fetchOne()); + } + + private void print(Iterable<Tuple> rows) { + for (Tuple row : rows) { + System.out.println(row); + } + } + + @Test + public void projections_duplicateColumns() { + SAnimal cat = new SAnimal("cat"); + assertEquals(1, query().from(cat).select(Projections.list(cat.count(), cat.count())).fetch().size()); + } + + @Test + public void single_result() { + query().from(cat).select(cat.id).fetchFirst(); + } + + @Test + public void single_result_multiple() { + assertEquals(1, query().from(cat).orderBy(cat.id.asc()).select(new Expression<?>[]{cat.id}).fetchFirst().get(cat.id).intValue()); + } + + @Test + @SuppressWarnings("unchecked") + public void union() throws SQLException { + SubQueryExpression<Integer> sq1 = select(cat.id.max()).from(cat); + SubQueryExpression<Integer> sq2 = select(cat.id.min()).from(cat); + List<Integer> list = query().union(sq1, sq2).list(); + assertFalse(list.isEmpty()); + } + + @Test + @SuppressWarnings("unchecked") + public void union_all() { + SubQueryExpression<Integer> sq1 = select(cat.id.max()).from(cat); + SubQueryExpression<Integer> sq2 = select(cat.id.min()).from(cat); + List<Integer> list = query().unionAll(sq1, sq2).list(); + assertFalse(list.isEmpty()); + } + + @SuppressWarnings("unchecked") + @Test + @ExcludeIn({Target.DERBY, Target.POSTGRESQL}) + @Ignore // FIXME + public void union2() { + List<Tuple> rows = query().union( + select(cat.name, cat.id).from(cat).where(cat.name.eq("Beck")).distinct(), + select(cat.name, null).from(cat).where(cat.name.eq("Kate")).distinct()) + .list(); + + assertEquals(2, rows.size()); + for (Tuple row : rows) { + System.err.println(row); + } + } + + @SuppressWarnings("unchecked") + @Test + @ExcludeIn(Target.DERBY) + @Ignore // FIXME + public void union3() { + SAnimal cat2 = new SAnimal("cat2"); + List<Tuple> rows = query().union( + select(cat.id, cat2.id).from(cat).innerJoin(cat2).on(cat2.id.eq(cat.id)), + select(cat.id, null).from(cat)) + .list(); + + assertEquals(12, rows.size()); + int nulls = 0; + for (Tuple row : rows) { + System.err.println(Collections.singletonList(row)); + if (row.get(1, Object.class) == null) { + nulls++; + } + } + assertEquals(6, nulls); + } + + @SuppressWarnings("unchecked") + @Test + @ExcludeIn({Target.DERBY, Target.POSTGRESQL}) + @Ignore // FIXME + public void union4() { + query().union(cat, + select(cat.name, cat.id).from(cat).where(cat.name.eq("Beck")).distinct(), + select(cat.name, null).from(cat).where(cat.name.eq("Kate")).distinct()) + .select(cat.name, cat.id).fetch(); + } + + @SuppressWarnings("unchecked") + @Test + @ExcludeIn({Target.DERBY, Target.ORACLE}) + public void union5() { + SAnimal cat2 = new SAnimal("cat2"); + List<Tuple> rows = query().union( + select(cat.id, cat2.id).from(cat).join(cat2).on(cat2.id.eq(cat.id.add(1))), + select(cat.id, cat2.id).from(cat).join(cat2).on(cat2.id.eq(cat.id.add(1)))) + .list(); + + assertEquals(5, rows.size()); + for (Tuple row : rows) { + int first = row.get(cat.id); + int second = row.get(cat2.id); + assertEquals(first + 1, second); + } + } + + @Test + public void unique_result() { + assertEquals(1, + query().from(cat).orderBy(cat.id.asc()).limit(1).select(cat.id).fetchOne().intValue()); + } + + @Test + public void unique_result_multiple() { + assertEquals(1, + query().from(cat).orderBy(cat.id.asc()).limit(1).select(new Expression<?>[]{cat.id}).fetchOne().get(cat.id).intValue()); + } + + @Test + @ExcludeIn(Target.H2) + public void wildcard() { + List<Tuple> rows = query().from(cat).select(cat.all()).fetch(); + assertEquals(6, rows.size()); + print(rows); + +// rows = query().from(cat).fetch(cat.id, cat.all()); +// assertEquals(6, rows.size()); +// print(rows); + } + + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/AggregationTest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/AggregationTest.java new file mode 100644 index 0000000000..ccc82bcd16 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/AggregationTest.java @@ -0,0 +1,47 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import static com.querydsl.jpa.Constants.*; + +import org.junit.Test; + +public class AggregationTest extends AbstractQueryTest { + + @Test + public void max() { + assertToString("max(cat.bodyWeight)", cat.bodyWeight.max()); + } + + @Test + public void min() { + assertToString("min(cat.bodyWeight)", cat.bodyWeight.min()); + } + + @Test + public void avg() { + assertToString("avg(cat.bodyWeight)", cat.bodyWeight.avg()); + } + + @Test + public void count() { + assertToString("count(cat)", cat.count()); + } + + @Test + public void countDistinct() { + assertToString("count(distinct cat)", cat.countDistinct()); + } + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/Article.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/Article.java new file mode 100644 index 0000000000..5481e6c689 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/Article.java @@ -0,0 +1,12 @@ +package com.querydsl.jpa; + + +public class Article { + + String name; + + Content content; + + Person author; + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/BooleanOperationsTest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/BooleanOperationsTest.java new file mode 100644 index 0000000000..75e4116046 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/BooleanOperationsTest.java @@ -0,0 +1,104 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import static com.querydsl.jpa.JPAExpressions.selectFrom; +import static com.querydsl.jpa.Constants.*; +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import com.querydsl.core.BooleanBuilder; + +public class BooleanOperationsTest extends AbstractQueryTest { + + @Test + public void booleanOperations_or() { + assertToString("cust is null or cat is null", cust.isNull().or(cat.isNull())); + } + + @Test + public void booleanOperations_and() { + assertToString("cust is null and cat is null", cust.isNull().and(cat.isNull())); + } + + + @Test + public void booleanOperations_not() { + assertToString("not cust is null", cust.isNull().not()); + } + + + @Test + public void booleanOperations2_and() { + cat.name.eq(cust.name.firstName).and(cat.bodyWeight.eq(kitten.bodyWeight)); + } + + @Test + public void booleanOperations2_or() { + cat.name.eq(cust.name.firstName).or(cat.bodyWeight.eq(kitten.bodyWeight)); + } + + @Test + public void logicalOperations_or() { + assertToString("cat = kitten or kitten = cat", cat.eq(kitten).or(kitten.eq(cat))); + } + + @Test + public void logicalOperations_and() { + assertToString("cat = kitten and kitten = cat", cat.eq(kitten).and(kitten.eq(cat))); + } + + @Test + public void logicalOperations_and2() { + assertToString("cat is null and (kitten is null or kitten.bodyWeight > ?1)", + cat.isNull().and(kitten.isNull().or(kitten.bodyWeight.gt(10)))); + } + + @Test + public void booleanBuilder1() { + BooleanBuilder bb1 = new BooleanBuilder(); + bb1.and(cat.eq(cat)); + + BooleanBuilder bb2 = new BooleanBuilder(); + bb2.or(cat.eq(cat)); + bb2.or(cat.eq(cat)); + + assertToString("cat = cat and (cat = cat or cat = cat)", bb1.and(bb2)); + } + + @Test + public void booleanBuilder2() { + BooleanBuilder bb1 = new BooleanBuilder(); + bb1.and(cat.eq(cat)); + + BooleanBuilder bb2 = new BooleanBuilder(); + bb2.or(cat.eq(cat)); + bb2.or(cat.eq(cat)); + + assertToString("cat = cat and (cat = cat or cat = cat)", bb1.and(bb2.getValue())); + } + + @Test + public void booleanBuilder_with_null_in_where() { + assertEquals("select cat\nfrom Cat cat", selectFrom(cat).where(new BooleanBuilder()).toString()); + } + + @Test + public void booleanBuilder_with_null_in_having() { + assertEquals("select cat\nfrom Cat cat\ngroup by cat.name", + selectFrom(cat).groupBy(cat.name).having(new BooleanBuilder()).toString()); + } + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/CastTest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/CastTest.java new file mode 100644 index 0000000000..19a26f34a3 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/CastTest.java @@ -0,0 +1,61 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberExpression; + +public class CastTest extends AbstractQueryTest { + + private static NumberExpression<Integer> expr = Expressions.numberPath(Integer.class, "int"); + + @Test + public void bytes() { + assertEquals(Byte.class, expr.byteValue().getType()); + } + + @Test + public void doubles() { + assertEquals(Double.class, expr.doubleValue().getType()); + } + + @Test + public void floats() { + assertEquals(Float.class, expr.floatValue().getType()); + } + + @Test + public void integers() { + assertEquals(Integer.class, expr.intValue().getType()); + } + + @Test + public void longs() { + assertEquals(Long.class, expr.longValue().getType()); + } + + @Test + public void shorts() { + assertEquals(Short.class, expr.shortValue().getType()); + } + + @Test + public void stringCast() { + assertEquals(String.class, expr.stringValue().getType()); + } +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/CollectionTest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/CollectionTest.java new file mode 100644 index 0000000000..dc7a46db10 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/CollectionTest.java @@ -0,0 +1,44 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import static com.querydsl.jpa.Constants.*; + +import org.junit.Test; + +import com.querydsl.jpa.domain.Cat; + +public class CollectionTest extends AbstractQueryTest { + + @Test + public void constant_inElements_set() { + assertToString("?1 member of cat.kittensSet", cat.kittensSet.contains(new Cat())); + } + + @Test + public void constant_inElements_list() { + assertToString("?1 member of cat.kittens", cat.kittens.contains(new Cat())); + } + + @Test + public void path_inElements_list() { + assertToString("cat member of cat1.kittens", cat.in(cat1.kittens)); + } + + @Test + public void path_inElements_set() { + assertToString("cat member of cat1.kittensSet", cat.in(cat1.kittensSet)); + } + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/ComparableTest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/ComparableTest.java new file mode 100644 index 0000000000..3f99593915 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/ComparableTest.java @@ -0,0 +1,55 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import static com.querydsl.jpa.Constants.*; + +import org.junit.Test; + +public class ComparableTest extends AbstractQueryTest { + + @Test + public void eq() { + assertToString("cat.bodyWeight = kitten.bodyWeight", cat.bodyWeight.eq(kitten.bodyWeight)); + } + + @Test + public void goe() { + assertToString("cat.bodyWeight >= kitten.bodyWeight", cat.bodyWeight.goe(kitten.bodyWeight)); + } + + @Test + public void gt() { + assertToString("cat.bodyWeight > kitten.bodyWeight", cat.bodyWeight.gt(kitten.bodyWeight)); + } + + @Test + public void loe() { + assertToString("cat.bodyWeight <= kitten.bodyWeight", cat.bodyWeight.loe(kitten.bodyWeight)); + } + + @Test + public void lt() { + assertToString("cat.bodyWeight < kitten.bodyWeight", cat.bodyWeight.lt(kitten.bodyWeight)); + } + + @Test + public void ne() { + assertToString("cat.bodyWeight <> kitten.bodyWeight", cat.bodyWeight.ne(kitten.bodyWeight)); + } + + + + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/Constants.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/Constants.java new file mode 100644 index 0000000000..c20bef949f --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/Constants.java @@ -0,0 +1,153 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import com.querydsl.jpa.domain.*; +import com.querydsl.jpa.domain.QPerson; + +public final class Constants { + + private Constants() { } + + static final QAccount account = new QAccount("account"); + + static final QAnimal an = new QAnimal("an"); + + static final QBar bar = new QBar("bar"); + + static final QCalendar calendar = new QCalendar("calendar"); + + // QCat + static final QCat cat = new QCat("cat"); + + static final QCat cat1 = new QCat("cat1"); + + static final QCat cat2 = new QCat("cat2"); + + static final QCat cat3 = new QCat("cat3"); + + static final QCat cat4 = new QCat("cat4"); + + static final QCat cat5 = new QCat("cat5"); + + // QCatalog + static final QCatalog catalog = new QCatalog("catalog"); + + static final QCat child = new QCat("child"); + // QCompany + static final QCompany company = new QCompany("company"); + + static final QCompany company1 = new QCompany("company1"); + + static final QCompany company2 = new QCompany("company2"); + + static final QCompany company3 = new QCompany("company3"); + + static final QCompany company4 = new QCompany("company4"); + + static final QCompany company5 = new QCompany("company5"); + + // Customer + static final QCustomer cust = new QCustomer("cust"); + +// Qdoofus d = new Qdoofus("d"); + + // QDocument + static final QDocument doc = new QDocument("doc"); + + // DomesticQCat + static final QDomesticCat domesticCat = new QDomesticCat("domesticCat"); + + static final QCat fatcat = new QCat("fatcat"); + + static final QFoo foo = new QFoo("foo"); + + static final QFormula form = new QFormula("form"); + // QItem + static final QItem item = new QItem("item"); + + static final QCat kit = new QCat("kit"); + + static final QCat kitten = new QCat("kitten"); + + static final QCat kitten2 = new QCat("kitten2"); + + static final QCat kittens = new QCat("kittens"); + + static final QNameList list = new QNameList("list"); + + // AuditLog + static final QAuditLog log = new QAuditLog("log"); + + static final QNamed m = new QNamed("m"); + + static final QCat mate = new QCat("mate"); + + static final QCat mother = new QCat("mother"); + + static final QNamed n = new QNamed("n"); + + static final QName name = new QName("name"); + + static final QCat offspr = new QCat("offspr"); + + static final QOrder ord = new QOrder("ord"); + // Order + static final QOrder order = new QOrder("order"); + + static final QPerson p = new QPerson("p"); + + static final QParameter param = new QParameter("param"); + + // Payment + static final QPayment payment = new QPayment("payment"); + + static final QPerson person = new QPerson("person"); + + static final QPlayer player = new QPlayer("player"); + + // Price + static final QPrice price = new QPrice("price"); + + static final QProduct prod = new QProduct("prod"); + + // Product + static final QProduct product = new QProduct("product"); + + static final QCat qat = new QCat("qat"); + + static final QCat rival = new QCat("rival"); + + static final QShow show = new QShow("show"); + + static final QStatus status = new QStatus("status"); + + static final QStatusChange statusChange = new QStatusChange("statusChange"); + + static final QStore store = new QStore("store"); + + // User + static final QUser user = new QUser("user"); + + static final QUser user1 = new QUser("user1"); + + static final QUser user2 = new QUser("user2"); + + static final QUser user3 = new QUser("user3"); + + static final QUser user4 = new QUser("user4"); + + static final QUser user5 = new QUser("user5"); + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/ConstructorsTest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/ConstructorsTest.java new file mode 100644 index 0000000000..4c3110a6c4 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/ConstructorsTest.java @@ -0,0 +1,52 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import static com.querydsl.jpa.Constants.*; + +import org.junit.Ignore; +import org.junit.Test; + +import com.querydsl.core.types.ConstructorExpression; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.Projections; + +public class ConstructorsTest extends AbstractQueryTest { + + public static final class BookmarkDTO { + + } + + public static final class QBookmarkDTO extends ConstructorExpression<BookmarkDTO> { + + private static final long serialVersionUID = 2664671413344744578L; + + public QBookmarkDTO(Expression<java.lang.String> address) { + super(BookmarkDTO.class, new Class<?>[] {String.class}, address); + } + } + + @Test + @Ignore + public void constructors() { + ConstructorExpression<com.querydsl.jpa.domain.Cat> c = + Projections.constructor( + com.querydsl.jpa.domain.Cat.class, + new Class<?>[]{String.class}, + cat.name); + assertToString("new " + com.querydsl.jpa.domain.Cat.class.getName() + "(cat.name)", c); + assertToString("new " + getClass().getName() + "$BookmarkDTO(cat.name)",new QBookmarkDTO(cat.name)); + } + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/Content.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/Content.java new file mode 100644 index 0000000000..cb96e86055 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/Content.java @@ -0,0 +1,8 @@ +package com.querydsl.jpa; + + +public class Content { + + Article article; + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/CustomExpressionsTest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/CustomExpressionsTest.java new file mode 100644 index 0000000000..b6a1462cc5 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/CustomExpressionsTest.java @@ -0,0 +1,42 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import static com.querydsl.jpa.Constants.*; + +import org.junit.Test; + +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.TemplateFactory; +import com.querydsl.core.types.dsl.StringTemplate; + +import java.util.Arrays; + +public class CustomExpressionsTest extends AbstractQueryTest { + + public static class MyCustomExpr extends StringTemplate { + + private static final long serialVersionUID = 1L; + + public MyCustomExpr(Expression<?>... args) { + super(TemplateFactory.DEFAULT.create("myCustom({0},{1})"), Arrays.asList(args)); + } + } + + @Test + public void customExpressions() { + assertToString("myCustom(cust,cat)", new MyCustomExpr(cust, cat)); + } + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/CustomFinder.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/CustomFinder.java new file mode 100644 index 0000000000..627603e2f9 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/CustomFinder.java @@ -0,0 +1,50 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import java.util.List; +import java.util.Map; + +import javax.persistence.EntityManager; + +import com.querydsl.core.BooleanBuilder; +import com.querydsl.core.types.EntityPath; +import com.querydsl.core.types.dsl.ComparablePath; +import com.querydsl.core.types.dsl.EntityPathBase; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.SimplePath; +import com.querydsl.jpa.impl.JPAQuery; + +/** + * @author tiwe + * + */ +public final class CustomFinder { + + private CustomFinder() { } + + @SuppressWarnings("unchecked") + public static <T> List<T> findCustom(EntityManager em, Class<T> entityClass,Map<String,?> filters, String sort) { + EntityPath<T> entityPath = new EntityPathBase<T>(entityClass, "entity"); + BooleanBuilder builder = new BooleanBuilder(); + for (Map.Entry<String, ?> entry : filters.entrySet()) { + SimplePath<Object> property = Expressions.path((Class) entry.getValue().getClass(), entityPath, entry.getKey()); + builder.and(property.eq(entry.getValue())); + } + ComparablePath<?> sortProperty = Expressions.comparablePath(Comparable.class, entityPath, sort); + return new JPAQuery<Void>(em).from(entityPath).where(builder.getValue()) + .orderBy(sortProperty.asc()).select(entityPath).fetch(); + } + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/DateTimeTest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/DateTimeTest.java new file mode 100644 index 0000000000..5ef6376ab8 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/DateTimeTest.java @@ -0,0 +1,69 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import static com.querydsl.jpa.Constants.*; + +import java.util.Date; + +import org.junit.Test; + +import com.querydsl.core.types.dsl.DateExpression; +import com.querydsl.core.types.dsl.DateTimeExpression; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.TimeExpression; + +public class DateTimeTest extends AbstractQueryTest { + + @Test + public void currentDate() { + assertToString("current_date", DateExpression.currentDate()); + } + + @Test + public void currentDate2() { + assertToString("current_date", DateTimeExpression.currentDate()); + } + + @Test + public void currentTime() { + assertToString("current_time", TimeExpression.currentTime()); + } + + @Test + public void currentTimestamp() { + assertToString("current_timestamp", DateTimeExpression.currentTimestamp()); + } + + @Test + public void dayOfMonth() { + assertToString("day(date)", Expressions.datePath(Date.class, "date").dayOfMonth()); + } + + @Test + public void dayOfMonth2() { + assertToString("day(date)", Expressions.dateTimePath(Date.class, "date").dayOfMonth()); + } + + @Test + public void dateOperations2() { +// catalog.effectiveDate.second(); +// catalog.effectiveDate.minute(); +// catalog.effectiveDate.hour(); + catalog.effectiveDate.dayOfMonth(); + catalog.effectiveDate.month(); + catalog.effectiveDate.year(); + } + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/DependenciesTest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/DependenciesTest.java new file mode 100644 index 0000000000..bb0459898d --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/DependenciesTest.java @@ -0,0 +1,40 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import static org.junit.Assert.assertFalse; + +import java.io.IOException; + +import org.junit.Test; + +import jdepend.framework.JDepend; + +public class DependenciesTest { + + @Test + public void test() throws IOException { + JDepend jdepend = new JDepend(); + jdepend.addDirectory("target/classes/com/querydsl/jpa"); + jdepend.addDirectory("target/classes/com/querydsl/jpa/hibernate"); + jdepend.addDirectory("target/classes/com/querydsl/jpa/hibernate/sql"); + jdepend.addDirectory("target/classes/com/querydsl/jpa/impl"); + jdepend.addDirectory("target/classes/com/querydsl/jpa/sql"); + + jdepend.analyze(); + assertFalse(jdepend.containsCycles()); + + } + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/DummySessionHolder.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/DummySessionHolder.java new file mode 100644 index 0000000000..055f647e64 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/DummySessionHolder.java @@ -0,0 +1,33 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import org.hibernate.query.Query; +import org.hibernate.query.NativeQuery; + +import com.querydsl.jpa.hibernate.SessionHolder; + +public class DummySessionHolder implements SessionHolder { + + @Override + public Query<?> createQuery(String queryString) { + throw new UnsupportedOperationException(); + } + + @Override + public NativeQuery<?> createSQLQuery(String queryString) { + throw new UnsupportedOperationException(); + } + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/EJBQLTest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/EJBQLTest.java new file mode 100644 index 0000000000..063a210af4 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/EJBQLTest.java @@ -0,0 +1,51 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import static com.querydsl.jpa.Constants.*; + +import org.junit.Test; + +public class EJBQLTest extends AbstractQueryTest { + + // Any function or operator defined by EJB-QL 3.0: substring(), trim(), + // lower(), upper(), length(), locate(), abs(), sqrt(), bit_length(), + // mod() + // substring(), + // trim(), + // lower(), + // upper(), + // length(), + // locate(), + // abs(), + // sqrt(), + // bit_length(), + // mod() + + @Test + public void trim() { + assertToString("trim(cat.name)", cat.name.trim()); + } + + @Test + public void lower() { + assertToString("lower(cat.name)", cat.name.lower()); + } + + @Test + public void upper() { + assertToString("upper(cat.name)", cat.name.upper()); + } + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/ExpressionSerializationTest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/ExpressionSerializationTest.java new file mode 100644 index 0000000000..b9eacb3475 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/ExpressionSerializationTest.java @@ -0,0 +1,30 @@ +package com.querydsl.jpa; + +import static com.querydsl.core.testutil.Serialization.serialize; +import static com.querydsl.jpa.JPAExpressions.selectFrom; +import static org.junit.Assert.assertEquals; + +import java.io.IOException; + +import org.junit.Test; + +import com.querydsl.core.types.Expression; +import com.querydsl.jpa.domain.QCat; + +public class ExpressionSerializationTest { + + @Test + public void serialize1() throws Exception { + Expression<?> expr = QCat.cat.name.eq("test"); + Expression<?> expr2 = serialize(expr); + + assertEquals(expr, expr2); + assertEquals(expr.hashCode(), expr2.hashCode()); + } + + @Test + public void query() throws ClassNotFoundException, IOException { + selectFrom(QCat.cat).where(serialize(QCat.cat.name.eq("test"))); + } + +} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/ExtDoubleType.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/ExtDoubleType.java similarity index 84% rename from querydsl-jpa/src/test/java/com/mysema/query/ExtDoubleType.java rename to querydsl-jpa/src/test/java/com/querydsl/jpa/ExtDoubleType.java index 39c4273e8c..71f86159f0 100644 --- a/querydsl-jpa/src/test/java/com/mysema/query/ExtDoubleType.java +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/ExtDoubleType.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,16 +11,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query; +package com.querydsl.jpa; import org.hibernate.type.DoubleType; @SuppressWarnings("serial") -public class ExtDoubleType extends DoubleType{ +public class ExtDoubleType extends DoubleType { // @Override // public void set(PreparedStatement st, Object value, int index) throws SQLException { // st.setDouble( index, ( (Number) value ).doubleValue() ); // } - + } diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/FeaturesTest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/FeaturesTest.java similarity index 79% rename from querydsl-jpa/src/test/java/com/mysema/query/jpa/FeaturesTest.java rename to querydsl-jpa/src/test/java/com/querydsl/jpa/FeaturesTest.java index 0fac8a307e..bac490f86f 100644 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/FeaturesTest.java +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/FeaturesTest.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,85 +11,85 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.jpa; +package com.querydsl.jpa; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; +import static org.junit.Assert.*; +import static com.querydsl.jpa.Constants.*; import org.junit.Test; -import com.mysema.query.jpa.domain.QAccount; -import com.mysema.query.jpa.domain.QInheritedProperties; -import com.mysema.query.types.path.NumberPath; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.jpa.domain.QAccount; +import com.querydsl.jpa.domain.QInheritedProperties; public class FeaturesTest extends AbstractQueryTest { @Test - public void DomainConstruction() { + public void domainConstruction() { QInheritedProperties i = new QInheritedProperties("i"); assertNotNull(i.superclassProperty); assertNotNull(i.classProperty); } - + @Test - public void DomainConstruction2() { + public void domainConstruction2() { QAccount a = new QAccount("a"); assertNotNull(a.embeddedData.someData); } @Test - public void BasicStructure() { + public void basicStructure() { assertNull(cat.getMetadata().getParent()); } - + @Test - public void BasicStructure2() { - assertEquals(cat, cat.alive.getMetadata().getParent()); + public void basicStructure2() { + assertEquals(cat, cat.alive.getMetadata().getParent()); } - + @Test - public void BasicStructure3() { + public void basicStructure3() { assertEquals("cat", cat.getMetadata().getName()); } @Test - public void ArgumentHandling() { + public void argumentHandling() { // Kitty is reused, so it should be used via one named parameter assertToString( - "cat.name = ?1 or cust.name.firstName = ?2 or kitten.name = ?1", + "cat.name = ?1 or cust.name.firstName = ?2 or kitten.name = ?3", cat.name.eq("Kitty").or(cust.name.firstName.eq("Hans")).or(kitten.name.eq("Kitty"))); } @Test - public void BasicOperations() { + public void basicOperations() { assertToString("cat.bodyWeight = kitten.bodyWeight", cat.bodyWeight.eq(kitten.bodyWeight)); } - + @Test - public void BasicOperations2() { + public void basicOperations2() { assertToString("cat.bodyWeight <> kitten.bodyWeight", cat.bodyWeight.ne(kitten.bodyWeight)); } - + @Test - public void BasicOperations3() { + public void basicOperations3() { assertToString( "cat.bodyWeight + kitten.bodyWeight = kitten.bodyWeight", - cat.bodyWeight.add(kitten.bodyWeight).eq(kitten.bodyWeight)); + cat.bodyWeight.add(kitten.bodyWeight).eq(kitten.bodyWeight)); } @Test - public void EqualsAndNotEqualsForAllExpressions() { - assertToString("cat.name = cust.name.firstName", cat.name.eq(cust.name.firstName)); + public void equalsAndNotEqualsForAllExpressions() { + assertToString("cat.name = cust.name.firstName", cat.name.eq(cust.name.firstName)); } - + @Test - public void EqualsAndNotEqualsForAllExpressions2() { + public void equalsAndNotEqualsForAllExpressions2() { assertToString("cat.name <> cust.name.firstName", cat.name.ne(cust.name.firstName)); } @Test - public void GroupingOperationsAndNullChecks() { + public void groupingOperationsAndNullChecks() { // in, not in, between, is null, is not null, is empty, is not empty, // member of and not member of // in, @@ -111,7 +111,7 @@ public void GroupingOperationsAndNullChecks() { } @Test - public void ToString() { + public void toString_() { assertToString("cat", cat); assertToString("cat.alive", cat.alive); assertToString("cat.bodyWeight", cat.bodyWeight); @@ -129,7 +129,7 @@ public void ToString() { // toString("cat.bodyWeight as bw", cat.bodyWeight.as("bw")); - assertToString("kitten in elements(cat.kittens)", kitten.in(cat.kittens)); + assertToString("kitten member of cat.kittens", kitten.in(cat.kittens)); // toString("distinct cat.bodyWeight", distinct(cat.bodyWeight)); } @@ -140,7 +140,7 @@ public void ToString() { // */ // @SuppressWarnings("unchecked") // @Test -// public void Bug326650() { +// public void bug326650() { // assertEquals(Long.class, sum(var(Byte.class)).getType()); // assertEquals(Long.class, sum(var(Short.class)).getType()); // assertEquals(Long.class, sum(var(Integer.class)).getType()); @@ -165,7 +165,7 @@ public void ToString() { // } private <D extends Number & Comparable<?>> NumberPath<D> var(Class<D> cl) { - return new NumberPath<D>(cl, "var"); + return Expressions.numberPath(cl, "var"); } } diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/HibernateBase.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/HibernateBase.java new file mode 100644 index 0000000000..be46c43930 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/HibernateBase.java @@ -0,0 +1,168 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import static org.junit.Assert.*; + +import java.io.IOException; +import java.util.List; + +import org.hibernate.LockMode; +import org.hibernate.Session; +import org.junit.ClassRule; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.junit.runner.RunWith; + +import com.mysema.commons.lang.CloseableIterator; +import com.querydsl.core.DefaultQueryMetadata; +import com.querydsl.core.Tuple; +import com.querydsl.core.types.EntityPath; +import com.querydsl.core.types.Expression; +import com.querydsl.jpa.domain.Cat; +import com.querydsl.jpa.domain.QCat; +import com.querydsl.jpa.domain.QGroup; +import com.querydsl.jpa.hibernate.DefaultSessionHolder; +import com.querydsl.jpa.hibernate.HibernateDeleteClause; +import com.querydsl.jpa.hibernate.HibernateQuery; +import com.querydsl.jpa.testutil.HibernateTestRunner; + +/** + * @author tiwe + * + */ +@RunWith(HibernateTestRunner.class) +public class HibernateBase extends AbstractJPATest implements HibernateTest { + + private static final QCat cat = QCat.cat; + + @Rule + @ClassRule + public static TestRule jpaProviderRule = new JPAProviderRule(); + + @Rule + @ClassRule + public static TestRule targetRule = new TargetRule(); + + private Session session; + + @Override + protected HibernateQuery<?> query() { + return new HibernateQuery<Void>(session, getTemplates()); + } + + protected HibernateDeleteClause delete(EntityPath<?> path) { + return new HibernateDeleteClause(session, path); + } + + @Override + protected HibernateQuery<?> testQuery() { + return new HibernateQuery<Void>(new DefaultSessionHolder(session), + getTemplates(), new DefaultQueryMetadata()); + } + + protected JPQLTemplates getTemplates() { + return HQLTemplates.DEFAULT; + } + + @Override + public void setSession(Session session) { + this.session = session; + } + + @Override + protected void save(Object entity) { + session.save(entity); + } + + @Test + public void query_exposure() { +// save(new Cat()); + List<Cat> results = query().from(cat).select(cat).createQuery().list(); + assertNotNull(results); + assertFalse(results.isEmpty()); + } + + @Test + public void delete() { + assertEquals(0, delete(QGroup.group).execute()); + } + + @Test + public void with_comment() { + query().from(cat).setComment("my comment").select(cat).fetch(); + } + + @Test + public void lockMode() { + query().from(cat).setLockMode(cat, LockMode.PESSIMISTIC_WRITE).select(cat).fetch(); + } + + @Test + public void flushMode() { + query().from(cat).setFlushMode(org.hibernate.FlushMode.AUTO).select(cat).fetch(); + } + + @Test + public void scroll() throws IOException { + CloseableIterator<Cat> cats = new ScrollableResultsIterator<Cat>(query().from(cat) + .select(cat).createQuery().scroll()); + assertTrue(cats.hasNext()); + while (cats.hasNext()) { + assertNotNull(cats.next()); + } + cats.close(); + } + + @Test + public void scrollTuple() throws IOException { + CloseableIterator<Tuple> rows = new ScrollableResultsIterator<Tuple>(query() + .from(cat) + .select(cat.name, cat.birthdate).createQuery().scroll()); + assertTrue(rows.hasNext()); + while (rows.hasNext()) { + Tuple row = rows.next(); + assertEquals(2, row.size()); + } + rows.close(); + } + + @SuppressWarnings("unchecked") + @Test + public void createQuery() { + List<Tuple> rows = query().from(cat).select(cat.id, cat.name).createQuery().list(); + for (Tuple row : rows) { + assertEquals(2, row.size()); + } + } + + @SuppressWarnings("unchecked") + @Test + public void createQuery2() { + List<Tuple> rows = query().from(cat).select(new Expression[]{cat.id, cat.name}).createQuery().list(); + for (Tuple row : rows) { + assertEquals(2, row.size()); + } + } + + @Test + public void createQuery3() { + List<String> rows = query().from(cat).select(cat.name).createQuery().list(); + for (String row : rows) { + assertTrue(row instanceof String); + } + } + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/HibernateHandlerTest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/HibernateHandlerTest.java new file mode 100644 index 0000000000..8f02b61a66 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/HibernateHandlerTest.java @@ -0,0 +1,149 @@ +package com.querydsl.jpa; + +import java.util.Iterator; +import java.util.List; + +import javax.persistence.PersistenceException; +import javax.persistence.Query; + +import org.batoo.jpa.core.impl.criteria.QueryImpl; +import org.eclipse.persistence.internal.localization.ExceptionLocalization; +import org.hibernate.query.NativeQuery; +import org.hibernate.query.spi.ScrollableResultsImplementor; +import org.hibernate.transform.ResultTransformer; +import org.junit.Test; + +import com.mysema.commons.lang.IteratorAdapter; +import com.querydsl.core.types.FactoryExpression; +import com.querydsl.jpa.domain4.Library; + +import static org.easymock.EasyMock.anyObject; +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.verify; +import static org.hamcrest.Matchers.instanceOf; +import static org.hibernate.ScrollMode.FORWARD_ONLY; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; + +public class HibernateHandlerTest { + + private final HibernateHandler hibernateHandler = new HibernateHandler(); + private final NativeQuery nativeQuery = createMock(NativeQuery.class); + private final String alias = "library"; + private final Class<Library> classType = Library.class; + + @Test + public void should_add_entity() { + expect(nativeQuery.unwrap(NativeQuery.class)).andReturn(nativeQuery); + expect(nativeQuery.addEntity(alias, classType)).andReturn(nativeQuery); + replay(nativeQuery); + + hibernateHandler.addEntity(nativeQuery, alias, classType); + + verify(nativeQuery); + } + + @Test(expected = PersistenceException.class) + public void addEntity_should_throw_persistence_exception_when_invalid_query_type() { + Query notSupportedQuery = createMock(QueryImpl.class); + PersistenceException expectedThrow = + new PersistenceException(ExceptionLocalization.buildMessage("unable_to_unwrap_jpa", + new String[]{Query.class.getName(), NativeQuery.class.getName()})); + + expect(notSupportedQuery.unwrap(NativeQuery.class)).andThrow(expectedThrow); + replay(notSupportedQuery); + + hibernateHandler.addEntity(notSupportedQuery, alias, classType); + } + + @Test + public void should_add_scalar() { + expect(nativeQuery.unwrap(NativeQuery.class)).andReturn(nativeQuery); + expect(nativeQuery.addScalar(alias)).andReturn(nativeQuery); + replay(nativeQuery); + + hibernateHandler.addScalar(nativeQuery, alias, classType); + + verify(nativeQuery); + } + + @Test(expected = PersistenceException.class) + public void addScalar_should_throw_persistence_exception_when_invalid_query_type() { + Query notSupportedQuery = createMock(QueryImpl.class); + PersistenceException expectedThrow = + new PersistenceException(ExceptionLocalization.buildMessage("unable_to_unwrap_jpa", + new String[]{Query.class.getName(), NativeQuery.class.getName()})); + + expect(notSupportedQuery.unwrap(NativeQuery.class)).andThrow(expectedThrow); + replay(notSupportedQuery); + + hibernateHandler.addScalar(notSupportedQuery, alias, classType); + } + + @Test + public void should_get_false_when_check_native_query_type() { + assertFalse(hibernateHandler.createNativeQueryTyped()); + } + + @Test + public void should_get_true_when_check_wrap_entity_projections_for_hibernate_query_syntax_by_using_curly_braces() { + assertTrue(hibernateHandler.wrapEntityProjections()); + } + + @Test + public void should_return_transforming_iterator_when_call_iterate_function() { + ScrollableResultsImplementor scrollableResultsImplementor = createMock(ScrollableResultsImplementor.class); + FactoryExpression<?> factoryExpression = createMock(FactoryExpression.class); + + expect(nativeQuery.unwrap(org.hibernate.query.Query.class)).andReturn(nativeQuery); + expect(nativeQuery.scroll(FORWARD_ONLY)).andReturn(scrollableResultsImplementor); + replay(nativeQuery); + + assertThat(hibernateHandler.iterate(nativeQuery, factoryExpression), instanceOf(TransformingIterator.class)); + } + + @Test + public void should_return_iterator_adapter_when_call_iterate_function() { + Query query = createMock(Query.class); + List queryResultList = createMock(List.class); + Iterator iterator = createMock(Iterator.class); + + expect(query.unwrap(org.hibernate.query.Query.class)).andThrow(new PersistenceException("Cannot unwrap Query")); + expect(query.getResultList()).andReturn(queryResultList); + expect(queryResultList.iterator()).andReturn(iterator); + replay(query); + + assertEquals(IteratorAdapter.class, hibernateHandler.iterate(query, null).getClass()); + } + + @Test + public void should_ReturnTransformingIterator_when_other_query_implementor() { + Query query = createMock(Query.class); + FactoryExpression<?> factoryExpression = createMock(FactoryExpression.class); + List queryResultList = createMock(List.class); + Iterator iterator = createMock(Iterator.class); + + expect(query.unwrap(org.hibernate.query.Query.class)).andThrow(new PersistenceException("Cannot unwrap Query")); + expect(query.getResultList()).andReturn(queryResultList); + expect(queryResultList.iterator()).andReturn(iterator); + replay(query); + + assertEquals(TransformingIterator.class, hibernateHandler.iterate(query, factoryExpression).getClass()); + } + + @Test + public void should_transform() { + FactoryExpression<?> projection = createMock(FactoryExpression.class); + + expect(nativeQuery.unwrap(org.hibernate.query.Query.class)).andReturn(nativeQuery); + expect(nativeQuery.setResultTransformer(anyObject(ResultTransformer.class))).andReturn(nativeQuery); + replay(nativeQuery); + + assertTrue(hibernateHandler.transform(nativeQuery, projection)); + } + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/HibernateQueryFactoryTest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/HibernateQueryFactoryTest.java new file mode 100644 index 0000000000..c891677b79 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/HibernateQueryFactoryTest.java @@ -0,0 +1,63 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import static org.junit.Assert.assertNotNull; + +import org.easymock.EasyMock; +import org.hibernate.Session; +import org.junit.Before; +import org.junit.Test; + +import com.querydsl.jpa.domain.QAnimal; +import com.querydsl.jpa.hibernate.HibernateQueryFactory; + +import java.util.function.Supplier; + +public class HibernateQueryFactoryTest { + + private HibernateQueryFactory queryFactory; + + @Before + public void setUp() { + Supplier<Session> provider = () -> EasyMock.<Session> createNiceMock(Session.class); + queryFactory = new HibernateQueryFactory(JPQLTemplates.DEFAULT, provider); + } + + @Test + public void query() { + assertNotNull(queryFactory.query()); + } + + @Test + public void from() { + assertNotNull(queryFactory.from(QAnimal.animal)); + } + + @Test + public void delete() { + assertNotNull(queryFactory.delete(QAnimal.animal)); + } + + @Test + public void update() { + assertNotNull(queryFactory.update(QAnimal.animal)); + } + + @Test + public void insert() { + assertNotNull(queryFactory.insert(QAnimal.animal)); + } + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/HibernateQueryMutabilityTest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/HibernateQueryMutabilityTest.java new file mode 100644 index 0000000000..b28c0ee082 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/HibernateQueryMutabilityTest.java @@ -0,0 +1,65 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import static org.junit.Assert.assertEquals; + +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; + +import org.hibernate.Session; +import org.junit.Ignore; +import org.junit.Test; +import org.junit.runner.RunWith; + +import com.querydsl.core.QueryMutability; +import com.querydsl.jpa.domain.QCat; +import com.querydsl.jpa.hibernate.HibernateQuery; +import com.querydsl.jpa.testutil.HibernateTestRunner; + +@Ignore +@RunWith(HibernateTestRunner.class) +public class HibernateQueryMutabilityTest implements HibernateTest { + + private Session session; + + protected HibernateQuery<?> query() { + return new HibernateQuery<Void>(session); + } + + @Override + public void setSession(Session session) { + this.session = session; + } + + @Test + public void test() throws SecurityException, IllegalArgumentException, + NoSuchMethodException, IllegalAccessException, + InvocationTargetException, IOException { + QCat cat = QCat.cat; + HibernateQuery<?> query = query().from(cat); + new QueryMutability(query).test(cat, cat.name); + } + + @Test + public void clone_() { + QCat cat = QCat.cat; + HibernateQuery<?> query = query().from(cat).where(cat.name.isNotNull()); + HibernateQuery<?> query2 = query.clone(session); + assertEquals(query.getMetadata().getJoins(), query2.getMetadata().getJoins()); + assertEquals(query.getMetadata().getWhere(), query2.getMetadata().getWhere()); + query2.select(cat).fetch(); + } + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/HibernateQueryTest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/HibernateQueryTest.java new file mode 100644 index 0000000000..10aaca634d --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/HibernateQueryTest.java @@ -0,0 +1,47 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import org.junit.Test; + +import com.querydsl.core.BooleanBuilder; +import com.querydsl.jpa.domain.QCat; +import com.querydsl.jpa.domain.QEmployee; +import com.querydsl.jpa.domain.QUser; +import com.querydsl.jpa.hibernate.HibernateQuery; + +public class HibernateQueryTest { + + @Test + public void clone_() { + QCat cat = QCat.cat; + BooleanBuilder emptyBooleanBuilder = new BooleanBuilder(); + HibernateQuery<?> hq = new HibernateQuery<Void>().from(cat).where(cat.name.isNull().and(emptyBooleanBuilder)); + HibernateQuery<?> hq2 = hq.clone(); + assertNotNull(hq2); + } + + @Test + public void innerJoin() { + HibernateQuery<?> hqlQuery = new HibernateQuery<Void>(); + QEmployee employee = QEmployee.employee; + hqlQuery.from(employee); + hqlQuery.innerJoin(employee.user, QUser.user); + assertEquals("select employee\nfrom Employee employee\n inner join employee.user as user", hqlQuery.toString()); + } + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/HibernateSQLBase.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/HibernateSQLBase.java new file mode 100644 index 0000000000..ac8ebe8efc --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/HibernateSQLBase.java @@ -0,0 +1,93 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import static org.junit.Assert.assertEquals; + +import org.hibernate.query.Query; +import org.hibernate.Session; +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.junit.runner.RunWith; + +import com.querydsl.core.Target; +import com.querydsl.core.testutil.ExcludeIn; +import com.querydsl.jpa.domain.Cat; +import com.querydsl.jpa.domain.Color; +import com.querydsl.jpa.domain.QCat; +import com.querydsl.jpa.domain.sql.SAnimal; +import com.querydsl.jpa.hibernate.sql.HibernateSQLQuery; +import com.querydsl.jpa.testutil.HibernateTestRunner; +import com.querydsl.sql.SQLTemplates; + +@RunWith(HibernateTestRunner.class) +public class HibernateSQLBase extends AbstractSQLTest implements HibernateTest { + + @Rule + @ClassRule + public static TestRule targetRule = new TargetRule(); + + private final SQLTemplates templates = Mode.getSQLTemplates(); + + private final SAnimal cat = new SAnimal("cat"); + + private Session session; + + @Override + protected HibernateSQLQuery<?> query() { + return new HibernateSQLQuery<Void>(session, templates); + } + + @Override + public void setSession(Session session) { + this.session = session; + } + + @Before + public void setUp() { + if (query().from(cat).fetchCount() == 0) { + session.save(new Cat("Beck", 1, Color.BLACK)); + session.save(new Cat("Kate", 2, Color.BLACK)); + session.save(new Cat("Kitty", 3, Color.BLACK)); + session.save(new Cat("Bobby", 4, Color.BLACK)); + session.save(new Cat("Harold", 5, Color.BLACK)); + session.save(new Cat("Tim", 6, Color.BLACK)); + session.flush(); + } + } + + @Test + public void entityQueries_createQuery() { + SAnimal cat = new SAnimal("cat"); + QCat catEntity = QCat.cat; + + Query query = query().from(cat).select(catEntity).createQuery(); + assertEquals(6, query.list().size()); + } + + @Test + @ExcludeIn(Target.MYSQL) + public void entityQueries_createQuery2() { + SAnimal cat = new SAnimal("CAT"); + QCat catEntity = QCat.cat; + + Query query = query().from(cat).select(catEntity).createQuery(); + assertEquals(6, query.list().size()); + } + + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/HibernateTest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/HibernateTest.java new file mode 100644 index 0000000000..b6b8c7612a --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/HibernateTest.java @@ -0,0 +1,27 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team). + * + * 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. + */ +package com.querydsl.jpa; + +import org.hibernate.Session; + +/** + * + * @author Shredder121 + */ +public interface HibernateTest { + + void setSession(Session session); +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/IntegrationBase.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/IntegrationBase.java new file mode 100644 index 0000000000..6c3c04847d --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/IntegrationBase.java @@ -0,0 +1,222 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import static org.junit.Assert.assertEquals; +import static com.querydsl.jpa.Constants.*; +import static org.junit.Assert.assertNotNull; + +import java.util.Arrays; +import java.util.List; + +import org.hibernate.query.Query; +import org.hibernate.ScrollMode; +import org.hibernate.ScrollableResults; +import org.hibernate.Session; +import org.junit.Test; +import org.junit.runner.RunWith; + +import com.querydsl.core.types.EntityPath; +import com.querydsl.jpa.domain.Cat; +import com.querydsl.jpa.domain.QCat; +import com.querydsl.jpa.hibernate.HibernateDeleteClause; +import com.querydsl.jpa.hibernate.HibernateQuery; +import com.querydsl.jpa.hibernate.HibernateInsertClause; +import com.querydsl.jpa.hibernate.HibernateUpdateClause; +import com.querydsl.jpa.hibernate.HibernateUtil; +import com.querydsl.jpa.testutil.HibernateTestRunner; + +import antlr.RecognitionException; +import antlr.TokenStreamException; + +@RunWith(HibernateTestRunner.class) +public class IntegrationBase extends ParsingTest implements HibernateTest { + + private Session session; + + @Override + protected QueryHelper<?> query() { + return new QueryHelper<Void>(HQLTemplates.DEFAULT) { + @Override + public void parse() throws RecognitionException, TokenStreamException { + try { + System.out.println("query : " + toString().replace('\n', ' ')); + JPQLSerializer serializer = new JPQLSerializer(HQLTemplates.DEFAULT); + serializer.serialize(getMetadata(), false, null); + Query query = session.createQuery(serializer.toString()); + HibernateUtil.setConstants(query, serializer.getConstants(), getMetadata().getParams()); + query.list(); + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException(e); + } finally { + System.out.println(); + } + } + }; + } + + @Override + @Test + public void groupBy() throws Exception { + // NOTE : commented out, because HQLSDB doesn't support these queries + } + + @Override + @Test + public void groupBy_2() throws Exception { + // NOTE : commented out, because HQLSDB doesn't support these queries + } + + @Override + @Test + public void orderBy() throws Exception { + // NOTE : commented out, because HQLSDB doesn't support these queries + } + + @Override + @Test + public void docoExamples910() throws Exception { + // NOTE : commented out, because HQLSDB doesn't support these queries + } + + private HibernateDeleteClause delete(EntityPath<?> entity) { + return new HibernateDeleteClause(session, entity); + } + + private HibernateUpdateClause update(EntityPath<?> entity) { + return new HibernateUpdateClause(session, entity); + } + + private HibernateInsertClause insert(EntityPath<?> entity) { + return new HibernateInsertClause(session, entity); + } + + + @Test + public void scroll() { + session.save(new Cat("Bob",10)); + session.save(new Cat("Steve",11)); + + QCat cat = QCat.cat; + HibernateQuery<?> query = new HibernateQuery<Void>(session); + ScrollableResults results = query.from(cat).select(cat).scroll(ScrollMode.SCROLL_INSENSITIVE); + while (results.next()) { + assertNotNull(results.get(0)); + } + results.close(); + } + + @Test + public void insert() { + session.save(new Cat("Bob",10)); + + QCat cat = QCat.cat; + long amount = insert(cat) + .set(cat.name, "Bobby") + .set(cat.alive, false) + .execute(); + assertEquals(1, amount); + + assertEquals(1L, query().from(cat).where(cat.name.eq("Bobby")).fetchCount()); + } + + @Test + public void insert2() { + session.save(new Cat("Bob",10)); + + QCat cat = QCat.cat; + long amount = insert(cat).columns(cat.name, cat.alive) + .values("Bobby", false) + .execute(); + assertEquals(1, amount); + + assertEquals(1L, query().from(cat).where(cat.name.eq("Bobby")).fetchCount()); + } + + @Test + public void insert3() { + session.save(new Cat("Bob",10)); + + QCat cat = QCat.cat; + QCat bob = new QCat("Bob"); + + long amount = insert(cat) + .columns(cat.name, cat.alive) + .select(JPAExpressions.select(bob.name, bob.alive).from(bob)) + .execute(); + assertEquals(1, amount); + + assertEquals(1L, query().from(cat).where(cat.name.eq("Bobby")).fetchCount()); + } + + @Test + public void update() { + session.save(new Cat("Bob",10)); + session.save(new Cat("Steve",11)); + + QCat cat = QCat.cat; + long amount = update(cat).where(cat.name.eq("Bob")) + .set(cat.name, "Bobby") + .set(cat.alive, false) + .execute(); + assertEquals(1, amount); + + assertEquals(0L, query().from(cat).where(cat.name.eq("Bob")).fetchCount()); + } + + @Test + public void update_with_null() { + session.save(new Cat("Bob",10)); + session.save(new Cat("Steve",11)); + + QCat cat = QCat.cat; + long amount = update(cat).where(cat.name.eq("Bob")) + .set(cat.name, (String) null) + .set(cat.alive, false) + .execute(); + assertEquals(1, amount); + } + + @Test + public void delete() { + session.save(new Cat("Bob",10)); + session.save(new Cat("Steve",11)); + + QCat cat = QCat.cat; + long amount = delete(cat).where(cat.name.eq("Bob")) + .execute(); + assertEquals(1, amount); + } + + @Test + public void collection() throws Exception { + List<Cat> cats = Arrays.asList(new Cat("Bob",10), new Cat("Steve",11)); + for (Cat cat : cats) { + session.save(cat); + } + + query().from(cat) + .innerJoin(cat.kittens, kitten) + .where(kitten.in(cats)) + .parse(); + + } + + @Override + public void setSession(Session session) { + this.session = session; + } + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/JPABase.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/JPABase.java new file mode 100644 index 0000000000..6e58551b23 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/JPABase.java @@ -0,0 +1,319 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import static com.querydsl.jpa.JPAExpressions.selectFrom; +import static com.querydsl.jpa.JPAExpressions.selectOne; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import java.sql.Connection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.persistence.EntityManager; +import javax.persistence.FlushModeType; +import javax.persistence.LockModeType; + +import com.querydsl.core.QueryResults; +import com.querydsl.core.Tuple; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.dsl.Expressions; +import org.junit.ClassRule; +import org.junit.Ignore; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.junit.runner.RunWith; + +import com.mysema.commons.lang.CloseableIterator; +import com.querydsl.core.DefaultQueryMetadata; +import com.querydsl.core.Target; +import com.querydsl.core.testutil.ExcludeIn; +import com.querydsl.core.types.EntityPath; +import com.querydsl.core.types.dsl.BooleanExpression; +import com.querydsl.jpa.domain.*; +import com.querydsl.jpa.impl.JPADeleteClause; +import com.querydsl.jpa.impl.JPAQuery; +import com.querydsl.jpa.testutil.JPATestRunner; + +/** + * @author tiwe + * + */ +@RunWith(JPATestRunner.class) +public class JPABase extends AbstractJPATest implements JPATest { + + private static final QCat cat = QCat.cat; + + @Rule + @ClassRule + public static TestRule targetRule = new TargetRule(); + + @Rule + @ClassRule + public static TestRule jpaProviderRule = new JPAProviderRule(); + + private EntityManager entityManager; + + @Override + protected JPAQuery<?> query() { + return new JPAQuery<Void>(entityManager); + } + + protected JPADeleteClause delete(EntityPath<?> path) { + return new JPADeleteClause(entityManager, path); + } + + @Override + protected JPAQuery<?> testQuery() { + return new JPAQuery<Void>(entityManager, new DefaultQueryMetadata()); + } + + @Override + public void setEntityManager(EntityManager entityManager) { + this.entityManager = entityManager; + } + + @Override + protected void save(Object entity) { + entityManager.persist(entity); + } + + @Test + @NoEclipseLink + @NoOpenJPA + @NoHibernate + public void connection_access() { + assertNotNull(query().from(cat).select(cat).createQuery().unwrap(Connection.class)); + } + + @Test + @Ignore + public void delete() { + delete(cat).execute(); + } + + @Test + public void delete2() { + assertEquals(0, delete(QGroup.group).execute()); + } + + @Test + @NoBatooJPA + public void delete_where() { + delete(cat).where(cat.name.eq("XXX")).execute(); + } + + @Test + @ExcludeIn(Target.MYSQL) + public void delete_where_any() { + delete(cat).where(cat.kittens.any().name.eq("XXX")).execute(); + } + + @Test + @NoBatooJPA + @ExcludeIn(Target.MYSQL) + public void delete_where_subQuery_exists() { + QCat parent = cat; + QCat child = new QCat("kitten"); + + delete(child) + .where(child.id.eq(-100), selectOne().from(parent) + .where(parent.id.eq(-200), + child.in(parent.kittens)).exists()) + .execute(); + } + + @Test + @NoBatooJPA + public void delete_where_subQuery2() { + QChild child = QChild.child; + QParent parent = QParent.parent; + + JPQLQuery<?> subQuery = selectFrom(parent) + .where(parent.id.eq(2), + child.parent.eq(parent)); + //child.in(parent.children)); + + delete(child) + .where(child.id.eq(1), subQuery.exists()) + .execute(); + } + + @Test + public void finder() { + Map<String,Object> conditions = new HashMap<String,Object>(); + conditions.put("name", "Bob123"); + + List<Cat> cats = CustomFinder.findCustom(entityManager, Cat.class, conditions, "name"); + assertEquals(1, cats.size()); + assertEquals("Bob123", cats.get(0).getName()); + } + + @Test + public void flushMode() { + assertFalse(query().from(cat).setFlushMode(FlushModeType.AUTO).select(cat).fetch().isEmpty()); + } + + @Test + @NoEclipseLink @NoOpenJPA + public void hint() { + javax.persistence.Query query = query().from(cat) + .setHint("org.hibernate.cacheable", true) + .select(cat).createQuery(); + + assertNotNull(query); + assertTrue(query.getHints().containsKey("org.hibernate.cacheable")); + assertFalse(query.getResultList().isEmpty()); + } + + @Test + public void hint2() { + assertFalse(query().from(cat).setHint("org.hibernate.cacheable", true) + .select(cat).fetch().isEmpty()); + } + + @Test @Ignore + @NoHibernate @NoOpenJPA @NoBatooJPA + public void hint3() { + javax.persistence.Query query = query().from(cat) + .setHint("eclipselink.batch.type", "IN") + .setHint("eclipselink.batch", "person.workAddress") + .setHint("eclipselink.batch", "person.homeAddress") + .select(cat).createQuery(); + + assertNotNull(query); + assertEquals("person.homeAddress", query.getHints().get("eclipselink.batch")); + } + + @Test + @ExcludeIn(Target.DERBY) + public void iterate() { + CloseableIterator<Cat> cats = query().from(cat).select(cat).iterate(); + while (cats.hasNext()) { + Cat cat = cats.next(); + assertNotNull(cat); + } + cats.close(); + } + + @Test + public void limit1_uniqueResult() { + assertNotNull(query().from(cat).limit(1).select(cat).fetchOne()); + } + + @Test + public void lockMode() { + javax.persistence.Query query = query().from(cat) + .setLockMode(LockModeType.PESSIMISTIC_READ) + .select(cat).createQuery(); + assertEquals(query.getLockMode(), LockModeType.PESSIMISTIC_READ); + assertFalse(query.getResultList().isEmpty()); + } + + @Test + public void lockMode2() { + assertFalse(query().from(cat).setLockMode(LockModeType.PESSIMISTIC_READ) + .select(cat).fetch().isEmpty()); + } + + @Test + public void queryExposure() { + //save(new Cat(20)); + List<Cat> results = query().from(cat).select(cat).createQuery().getResultList(); + assertNotNull(results); + assertFalse(results.isEmpty()); + } + + @Test + @Ignore // isn't a valid JPQL query + public void subquery_uniqueResult() { + QCat cat2 = new QCat("cat2"); + + BooleanExpression exists = selectOne().from(cat2).where(cat2.eyecolor.isNotNull()).exists(); + assertNotNull(query().from(cat) + .where(cat.breed.eq(0).not()) + .select(new QCatSummary(cat.breed.count(), exists)).fetchOne()); + } + + @SuppressWarnings("unchecked") + @Test + @NoEclipseLink + @NoBatooJPA + public void createQuery() { + List<Tuple> rows = query().from(cat) + .select(cat.id, cat.name).createQuery().getResultList(); + for (Tuple row : rows) { + assertEquals(2, row.size()); + } + } + + @SuppressWarnings("unchecked") + @Test + @NoEclipseLink + @NoBatooJPA + public void createQuery2() { + List<Tuple> rows = query().from(cat) + .select(cat.id, cat.name).createQuery().getResultList(); + for (Tuple row : rows) { + assertEquals(2, row.size()); + } + } + + @Test + public void createQuery3() { + List<String> rows = query().from(cat).select(cat.name).createQuery().getResultList(); + for (String row : rows) { + assertNotNull(row); + } + } + + @Test + @NoHibernate + @ExcludeIn(Target.DERBY) + public void createQuery4() { + List<Tuple> rows = query().from(cat).select(new Expression<?>[] {Expressions.nullExpression()}).fetch(); + for (Tuple row : rows) { + assertNotNull(row); + assertEquals(1, row.size()); + assertNull(row.get(Expressions.nullExpression())); + } + } + + @Test + public void fetchCountResultsGroupByWithMultipleFields() { + QueryResults<Tuple> results = query().from(cat) + .groupBy(cat.alive, cat.breed) + .select(cat.alive, cat.breed, cat.id.sum()) + .fetchResults(); + + assertEquals(1, results.getTotal()); + } + + @Test + public void fetchCountResultsGroupByWithHaving() { + QueryResults<Tuple> results = query().from(cat) + .groupBy(cat.alive) + .having(cat.id.sum().gt(5)) + .select(cat.alive, cat.id.sum()) + .fetchResults(); + + assertEquals(1, results.getTotal()); + } +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/JPACollectionAnyVisitorTest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/JPACollectionAnyVisitorTest.java new file mode 100644 index 0000000000..f513ca37fc --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/JPACollectionAnyVisitorTest.java @@ -0,0 +1,131 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import com.querydsl.core.support.Context; +import com.querydsl.core.types.ConstantImpl; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.ExpressionUtils; +import com.querydsl.core.types.Predicate; +import com.querydsl.jpa.domain.QCat; +import com.querydsl.jpa.domain.QCompany; +import com.querydsl.jpa.domain.QDomesticCat; +import com.querydsl.jpa.domain.QEmployee; + + +public class JPACollectionAnyVisitorTest { + + private QCat cat = QCat.cat; + + @Test + public void path() { + assertEquals("cat_kittens_0", serialize(cat.kittens.any())); + } + + @Test + public void longer_path() { + assertEquals("cat_kittens_0.name", serialize(cat.kittens.any().name)); + } + + @Test + public void nested_any_booleanOperation() { + QCompany company = QCompany.company; + Predicate predicate = company.departments.any().employees.any().firstName.eq("Bob"); + assertEquals("exists (select 1\n" + + "from company.departments as company_departments_0\n" + + " inner join company_departments_0.employees as company_departments_0_employees_1\n" + + "where company_departments_0_employees_1.firstName = ?1)", serialize(predicate)); + } + + @Test + public void simple_booleanOperation() { + Predicate predicate = cat.kittens.any().name.eq("Ruth123"); + assertEquals("exists (select 1\n" + + "from cat.kittens as cat_kittens_0\n" + + "where cat_kittens_0.name = ?1)", serialize(predicate)); + } + + @Test + public void simple_booleanOperation_longPath() { + Predicate predicate = cat.kittens.any().kittens.any().name.eq("Ruth123"); + assertEquals("exists (select 1\n" + + "from cat.kittens as cat_kittens_0\n" + + " inner join cat_kittens_0.kittens as cat_kittens_0_kittens_1\n" + + "where cat_kittens_0_kittens_1.name = ?1)", serialize(predicate)); + } + + @Test + public void simple_booleanOperation_elementCollection() { + QEmployee employee = QEmployee.employee; + Predicate predicate = employee.jobFunctions.any().stringValue().eq("CODER"); + assertEquals("exists (select 1\n" + + "from Employee employee_1463394548\n" + + " inner join employee_1463394548.jobFunctions as employee_jobFunctions_0\n" + + "where employee_1463394548 = employee and str(employee_jobFunctions_0) = ?1)", serialize(predicate)); + } + + @Test + public void simple_stringOperation() { + Predicate predicate = cat.kittens.any().name.substring(1).eq("uth123"); + assertEquals("exists (select 1\n" + + "from cat.kittens as cat_kittens_0\n" + + "where substring(cat_kittens_0.name,2) = ?1)", serialize(predicate)); + } + + @Test + public void and_operation() { + Predicate predicate = cat.kittens.any().name.eq("Ruth123").and(cat.kittens.any().bodyWeight.gt(10.0)); + assertEquals("exists (select 1\n" + + "from cat.kittens as cat_kittens_0\n" + + "where cat_kittens_0.name = ?1) and exists (select 1\n" + + "from cat.kittens as cat_kittens_1\n" + + "where cat_kittens_1.bodyWeight > ?2)", serialize(predicate)); + } + + @Test + public void template() { + Expression<Boolean> templateExpr = ExpressionUtils.template(Boolean.class, "{0} = {1}", + cat.kittens.any().name, ConstantImpl.create("Ruth123")); + assertEquals("exists (select 1\n" + + "from cat.kittens as cat_kittens_0\n" + + "where cat_kittens_0.name = ?1)", serialize(templateExpr)); + } + + @Test + public void cast() { +// JPAQuery query = new JPAQuery(em).from(QPerson.person); +// QDog anyDog = QPerson.person.animals.any().as(QDog.class); +// query.where(anyDog.gender.eq("M")); +// List<Person> foundOwners = query.fetch(QPerson.person); + + QDomesticCat anyCat = QCat.cat.kittens.any().as(QDomesticCat.class); + Predicate predicate = anyCat.name.eq("X"); + + assertEquals("exists (select 1\n" + + "from cat.kittens as cat_kittens_0\n" + + "where cat_kittens_0.name = ?1)", serialize(predicate)); + } + + private String serialize(Expression<?> expression) { + Expression<?> transformed = expression.accept(new JPACollectionAnyVisitor(), new Context()); + JPQLSerializer serializer = new JPQLSerializer(HQLTemplates.DEFAULT, null); + serializer.handle(transformed); + return serializer.toString(); + } + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/JPAIntegrationBase.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/JPAIntegrationBase.java new file mode 100644 index 0000000000..44efa70f29 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/JPAIntegrationBase.java @@ -0,0 +1,71 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import javax.persistence.EntityManager; +import javax.persistence.Query; + +import org.junit.ClassRule; +import org.junit.Rule; +import org.junit.rules.TestRule; +import org.junit.runner.RunWith; + +import com.querydsl.jpa.impl.JPAProvider; +import com.querydsl.jpa.impl.JPAUtil; +import com.querydsl.jpa.testutil.JPATestRunner; + +import antlr.RecognitionException; +import antlr.TokenStreamException; + +@RunWith(JPATestRunner.class) +public class JPAIntegrationBase extends ParsingTest implements JPATest { + + @Rule + @ClassRule + public static TestRule targetRule = new TargetRule(); + + @Rule + @ClassRule + public static TestRule hibernateOnly = new JPAProviderRule(); + + private EntityManager em; + + private JPQLTemplates templates; + + @Override + protected QueryHelper<?> query() { + return new QueryHelper<Void>(templates) { + @Override + public void parse() throws RecognitionException, TokenStreamException { + JPQLSerializer serializer = new JPQLSerializer(templates); + serializer.serialize(getMetadata(), false, null); + Query query = em.createQuery(serializer.toString()); + JPAUtil.setConstants(query, serializer.getConstants(), getMetadata().getParams()); + try { + query.getResultList(); + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException(e); + } + } + }; + } + + @Override + public void setEntityManager(EntityManager em) { + this.em = em; + this.templates = JPAProvider.getTemplates(em); + } + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/JPAProviderRule.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/JPAProviderRule.java new file mode 100644 index 0000000000..ab7578ff99 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/JPAProviderRule.java @@ -0,0 +1,43 @@ +package com.querydsl.jpa; + +import org.junit.rules.TestRule; +import org.junit.runner.Description; +import org.junit.runners.model.Statement; + +import com.querydsl.core.Target; +import com.querydsl.core.testutil.EmptyStatement; + +import java.util.Arrays; + +/** + * @author tiwe + * + */ +public class JPAProviderRule implements TestRule { + + @Override + public Statement apply(Statement base, Description description) { + NoEclipseLink noEclipseLink = description.getAnnotation(NoEclipseLink.class); + NoOpenJPA noOpenJPA = description.getAnnotation(NoOpenJPA.class); + NoBatooJPA noBatooJPA = description.getAnnotation(NoBatooJPA.class); + NoHibernate noHibernate = description.getAnnotation(NoHibernate.class); + String mode = Mode.mode.get(); + if (mode == null) { + return base; + } else if (noEclipseLink != null && applies(noEclipseLink.value()) && mode.contains("-eclipselink")) { + return EmptyStatement.DEFAULT; + } else if (noOpenJPA != null && applies(noOpenJPA.value()) && mode.contains("-openjpa")) { + return EmptyStatement.DEFAULT; + } else if (noBatooJPA != null && applies(noBatooJPA.value()) && mode.contains("-batoo")) { + return EmptyStatement.DEFAULT; + } else if (noHibernate != null && applies(noHibernate.value()) && !mode.contains("-")) { + return EmptyStatement.DEFAULT; + } else { + return base; + } + } + + private boolean applies(Target[] targets) { + return targets.length == 0 || Arrays.asList(targets).contains(Mode.target.get()); + } +} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/JPAProviderTest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/JPAProviderTest.java similarity index 85% rename from querydsl-jpa/src/test/java/com/mysema/query/jpa/JPAProviderTest.java rename to querydsl-jpa/src/test/java/com/querydsl/jpa/JPAProviderTest.java index 6e1b9f1585..0afa1321a3 100644 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/JPAProviderTest.java +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/JPAProviderTest.java @@ -1,4 +1,4 @@ -package com.mysema.query.jpa; +package com.querydsl.jpa; import static org.junit.Assert.assertEquals; @@ -14,7 +14,7 @@ import org.junit.Ignore; import org.junit.Test; -import com.mysema.query.jpa.impl.JPAProvider; +import com.querydsl.jpa.impl.JPAProvider; // 5.664 public class JPAProviderTest { @@ -34,15 +34,15 @@ public void tearDown() { } @Test - public void Hibernate() { + public void hibernate() { factory = Persistence.createEntityManagerFactory("h2"); em = factory.createEntityManager(); System.out.println(em.getDelegate().getClass()); - assertEquals(HQLTemplates.DEFAULT, JPAProvider.getTemplates(em)); + assertEquals(Hibernate5Templates.DEFAULT, JPAProvider.getTemplates(em)); } @Test - public void Hibernate_For_Proxy() { + public void hibernate_for_proxy() { factory = Persistence.createEntityManagerFactory("h2"); em = factory.createEntityManager(); InvocationHandler handler = new InvocationHandler() { @@ -53,13 +53,13 @@ public Object invoke(Object proxy, Method method, Object[] args) throws Throwabl }; EntityManager proxy = (EntityManager) Proxy.newProxyInstance( Thread.currentThread().getContextClassLoader(), - new Class[]{EntityManager.class}, + new Class<?>[]{EntityManager.class}, handler); - assertEquals(HQLTemplates.DEFAULT, JPAProvider.getTemplates(proxy)); + assertEquals(Hibernate5Templates.DEFAULT, JPAProvider.getTemplates(proxy)); } @Test - public void EclipseLink() { + public void eclipseLink() { factory = Persistence.createEntityManagerFactory("h2-eclipselink"); em = factory.createEntityManager(); System.out.println(em.getDelegate().getClass()); @@ -68,7 +68,7 @@ public void EclipseLink() { } @Test - public void EclipseLink_For_Proxy() { + public void eclipseLink_for_proxy() { factory = Persistence.createEntityManagerFactory("h2-eclipselink"); em = factory.createEntityManager(); InvocationHandler handler = new InvocationHandler() { @@ -79,14 +79,14 @@ public Object invoke(Object proxy, Method method, Object[] args) throws Throwabl }; EntityManager proxy = (EntityManager) Proxy.newProxyInstance( Thread.currentThread().getContextClassLoader(), - new Class[]{EntityManager.class}, + new Class<?>[]{EntityManager.class}, handler); assertEquals(EclipseLinkTemplates.DEFAULT, JPAProvider.getTemplates(proxy)); } @Test @Ignore // doesn't work on JDK 7 - public void OpenJPA() { + public void openJPA() { factory = Persistence.createEntityManagerFactory("derby-openjpa"); em = factory.createEntityManager(); System.out.println(em.getDelegate().getClass()); @@ -96,7 +96,7 @@ public void OpenJPA() { @Test @Ignore // temporarily ignored, since Batoo hangs on EntityManager creation - public void Batoo() { + public void batoo() { factory = Persistence.createEntityManagerFactory("h2-batoo"); em = factory.createEntityManager(); System.out.println(em.getDelegate().getClass()); diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/JPAQueryFactoryTest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/JPAQueryFactoryTest.java new file mode 100644 index 0000000000..0de6d42131 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/JPAQueryFactoryTest.java @@ -0,0 +1,164 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import static org.junit.Assert.assertNotNull; + +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.function.Supplier; + +import javax.persistence.EntityManager; +import javax.persistence.EntityManagerFactory; + +import org.easymock.EasyMock; +import org.junit.Before; +import org.junit.Test; + +import com.querydsl.jpa.domain.QAnimal; +import com.querydsl.jpa.impl.JPAQueryFactory; +import com.querydsl.sql.SQLExpressions; + +public class JPAQueryFactoryTest { + + private EntityManagerFactory factoryMock; + + private EntityManager mock; + + private JPAQueryFactory queryFactory; + + private JPQLQueryFactory queryFactory2; + + private JPAQueryFactory queryFactory3; + + private Map<String, Object> properties = new HashMap<>(); + + @Before + public void setUp() { + factoryMock = EasyMock.createMock(EntityManagerFactory.class); + mock = EasyMock.createMock(EntityManager.class); + Supplier<EntityManager> provider = () -> mock; + queryFactory = new JPAQueryFactory(JPQLTemplates.DEFAULT, provider); + queryFactory2 = queryFactory; + + queryFactory3 = new JPAQueryFactory(provider); + + } + + @Test + public void query() { + assertNotNull(queryFactory.query()); + } + + @Test + public void query2() { + queryFactory2.query().from(QAnimal.animal); + } + + @Test + public void query3() { + EasyMock.expect(mock.getEntityManagerFactory()).andReturn(factoryMock); + EasyMock.expect(factoryMock.getProperties()).andReturn(properties); + EasyMock.expect(mock.unwrap(EasyMock.anyObject(Class.class))).andReturn(mock).atLeastOnce(); + + EasyMock.replay(mock, factoryMock); + + queryFactory3.query().from(QAnimal.animal); + + EasyMock.verify(mock, factoryMock); + } + + @Test + public void from() { + assertNotNull(queryFactory.from(QAnimal.animal)); + } + + @Test + public void delete() { + assertNotNull(queryFactory.delete(QAnimal.animal)); + } + + @Test + public void delete2() { + queryFactory2.delete(QAnimal.animal) + .where(QAnimal.animal.bodyWeight.gt(0)); + } + + @Test + public void delete3() { + EasyMock.expect(mock.getEntityManagerFactory()).andReturn(factoryMock); + EasyMock.expect(factoryMock.getProperties()).andReturn(properties); + EasyMock.expect(mock.unwrap(EasyMock.anyObject(Class.class))).andReturn(mock).atLeastOnce(); + EasyMock.replay(mock, factoryMock); + + assertNotNull(queryFactory3.delete(QAnimal.animal)); + + EasyMock.verify(mock, factoryMock); + } + + @Test + public void update() { + assertNotNull(queryFactory.update(QAnimal.animal)); + } + + @Test + public void update2() { + queryFactory2.update(QAnimal.animal) + .set(QAnimal.animal.birthdate, new Date()) + .where(QAnimal.animal.birthdate.isNull()); + } + + @Test + public void update3() { + EasyMock.expect(mock.getEntityManagerFactory()).andReturn(factoryMock); + EasyMock.expect(factoryMock.getProperties()).andReturn(properties); + EasyMock.expect(mock.unwrap(EasyMock.anyObject(Class.class))).andReturn(mock).atLeastOnce(); + EasyMock.replay(mock, factoryMock); + + assertNotNull(queryFactory3.update(QAnimal.animal)); + + EasyMock.verify(mock, factoryMock); + } + + @Test + public void insert() { + assertNotNull(queryFactory.insert(QAnimal.animal)); + } + + @Test + public void insert2() { + queryFactory2.insert(QAnimal.animal) + .set(QAnimal.animal.birthdate, new Date()); + } + + @Test + public void insert3() { + EasyMock.expect(mock.getEntityManagerFactory()).andReturn(factoryMock); + EasyMock.expect(factoryMock.getProperties()).andReturn(properties); + EasyMock.expect(mock.unwrap(EasyMock.anyObject(Class.class))).andReturn(mock).atLeastOnce(); + EasyMock.replay(mock, factoryMock); + + assertNotNull(queryFactory3.insert(QAnimal.animal)); + + EasyMock.verify(mock, factoryMock); + } + + @Test + public void insert4() { + queryFactory.insert(QAnimal.animal).columns(QAnimal.animal.id, QAnimal.animal.birthdate) + .select(SQLExpressions.select(QAnimal.animal.id, QAnimal.animal.birthdate).from(QAnimal.animal)); + } + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/JPAQueryMixinTest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/JPAQueryMixinTest.java new file mode 100644 index 0000000000..9ff248a8df --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/JPAQueryMixinTest.java @@ -0,0 +1,230 @@ +package com.querydsl.jpa; + +import static org.junit.Assert.assertEquals; + +import java.util.Arrays; +import java.util.Collections; + +import org.junit.Test; + +import com.querydsl.core.JoinExpression; +import com.querydsl.core.JoinType; +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.types.OrderSpecifier; +import com.querydsl.core.types.Predicate; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.jpa.domain.QCat; +import com.querydsl.jpa.domain.QCompany; +import com.querydsl.jpa.domain.QDepartment; +import com.querydsl.jpa.domain.QEmployee; +import com.querydsl.jpa.domain4.QBookMark; +import com.querydsl.jpa.domain4.QBookVersion; + +public class JPAQueryMixinTest { + + private JPAQueryMixin<?> mixin = new JPAQueryMixin<Object>(); + + @Test + public void where_null() { + mixin.where((Predicate) null); + } + + @Test + public void orderBy() { + QCat cat = QCat.cat; + QCat catMate = new QCat("cat_mate"); + mixin.from(cat); + mixin.orderBy(cat.mate.name.asc()); + + QueryMetadata md = mixin.getMetadata(); + assertEquals(Arrays.asList( + new JoinExpression(JoinType.DEFAULT, cat), + new JoinExpression(JoinType.LEFTJOIN, cat.mate.as(catMate))), + md.getJoins()); + assertEquals(Collections.singletonList(catMate.name.asc()), + md.getOrderBy()); + } + + @Test + public void orderBy_nonRoot_twice() { + QDepartment department = QDepartment.department; + QCompany departmentCompany = new QCompany("department_company"); + QEmployee departmentCompanyCeo = new QEmployee("department_company_ceo"); + mixin.from(department); + mixin.orderBy(department.company.ceo.firstName.asc(), department.company.ceo.lastName.asc()); + + QueryMetadata md = mixin.getMetadata(); + assertEquals(Arrays.asList( + new JoinExpression(JoinType.DEFAULT, department), + new JoinExpression(JoinType.LEFTJOIN, department.company.as(departmentCompany)), + new JoinExpression(JoinType.LEFTJOIN, departmentCompany.ceo.as(departmentCompanyCeo))), + md.getJoins()); + assertEquals(Arrays.asList(departmentCompanyCeo.firstName.asc(), departmentCompanyCeo.lastName.asc()), + md.getOrderBy()); + } + + @Test + public void orderBy_where() { + QCat cat = QCat.cat; + mixin.from(cat); + mixin.where(cat.mate.name.isNotNull()); + mixin.orderBy(cat.mate.name.asc()); + + QueryMetadata md = mixin.getMetadata(); + assertEquals(Collections.singletonList(new JoinExpression(JoinType.DEFAULT, cat)), md.getJoins()); + assertEquals(Collections.singletonList(cat.mate.name.asc()), md.getOrderBy()); + } + + @Test + public void orderBy_groupBy() { + QCat cat = QCat.cat; + mixin.from(cat); + mixin.groupBy(cat.mate.name); + mixin.orderBy(cat.mate.name.asc()); + + QueryMetadata md = mixin.getMetadata(); + assertEquals(Collections.singletonList(new JoinExpression(JoinType.DEFAULT, cat)), md.getJoins()); + assertEquals(Collections.singletonList(cat.mate.name.asc()), md.getOrderBy()); + } + + @Test + public void orderBy_operation() { + QCat cat = QCat.cat; + QCat catMate = new QCat("cat_mate"); + mixin.from(cat); + mixin.orderBy(cat.mate.name.lower().asc()); + + QueryMetadata md = mixin.getMetadata(); + assertEquals(Arrays.asList( + new JoinExpression(JoinType.DEFAULT, cat), + new JoinExpression(JoinType.LEFTJOIN, cat.mate.as(catMate))), + md.getJoins()); + assertEquals(Collections.singletonList(catMate.name.lower().asc()), + md.getOrderBy()); + } + + @Test + public void orderBy_long() { + QCat cat = QCat.cat; + QCat catMate = new QCat("cat_mate"); + QCat catMateMate = new QCat("cat_mate_mate"); + mixin.from(cat); + mixin.orderBy(cat.mate.mate.name.asc()); + + QueryMetadata md = mixin.getMetadata(); + assertEquals(Arrays.asList( + new JoinExpression(JoinType.DEFAULT, cat), + new JoinExpression(JoinType.LEFTJOIN, cat.mate.as(catMate)), + new JoinExpression(JoinType.LEFTJOIN, catMate.mate.as(catMateMate))), + md.getJoins()); + assertEquals(Collections.singletonList(catMateMate.name.asc()), + md.getOrderBy()); + } + + @Test + public void orderBy_reuse() { + QCat cat = QCat.cat; + QCat mate = new QCat("mate"); + mixin.from(cat); + mixin.leftJoin(cat.mate, mate); + mixin.orderBy(cat.mate.name.asc()); + + QueryMetadata md = mixin.getMetadata(); + assertEquals(Arrays.asList( + new JoinExpression(JoinType.DEFAULT, cat), + new JoinExpression(JoinType.LEFTJOIN, cat.mate.as(mate))), + md.getJoins()); + assertEquals(Collections.singletonList(mate.name.asc()), + md.getOrderBy()); + } + + @Test + public void orderBy_long_reuse() { + QCat cat = QCat.cat; + QCat mate = new QCat("mate"); + QCat mateMate = new QCat("mate_mate"); + mixin.from(cat); + mixin.leftJoin(cat.mate, mate); + mixin.orderBy(cat.mate.mate.name.asc()); + + QueryMetadata md = mixin.getMetadata(); + assertEquals(Arrays.asList( + new JoinExpression(JoinType.DEFAULT, cat), + new JoinExpression(JoinType.LEFTJOIN, cat.mate.as(mate)), + new JoinExpression(JoinType.LEFTJOIN, mate.mate.as(mateMate))), + md.getJoins()); + assertEquals(Collections.singletonList(mateMate.name.asc()), + md.getOrderBy()); + } + + @Test + public void orderBy_any() { + QCat cat = QCat.cat; + QCat catKittens = new QCat("cat_kittens"); + mixin.from(cat); + mixin.orderBy(cat.kittens.any().name.asc()); + + QueryMetadata md = mixin.getMetadata(); + assertEquals(Arrays.asList( + new JoinExpression(JoinType.DEFAULT, cat), + new JoinExpression(JoinType.LEFTJOIN, cat.kittens.as(catKittens))), + md.getJoins()); + assertEquals(Collections.singletonList(catKittens.name.asc()), + md.getOrderBy()); + } + + @Test + public void orderBy_embeddable() { + QBookVersion bookVersion = QBookVersion.bookVersion; + mixin.from(bookVersion); + mixin.orderBy(bookVersion.definition.name.asc()); + + QueryMetadata md = mixin.getMetadata(); + assertEquals(Collections.singletonList(new JoinExpression(JoinType.DEFAULT, bookVersion)), + md.getJoins()); + assertEquals(Collections.singletonList(bookVersion.definition.name.asc()), + md.getOrderBy()); + } + + @SuppressWarnings("unchecked") + @Test + public void orderBy_embeddable2() { + QArticle article = QArticle.article; + QArticle articleContentArticle = new QArticle("article_content_article"); + mixin.from(article); + mixin.orderBy(article.content.article.name.asc()); + + QueryMetadata md = mixin.getMetadata(); + assertEquals(Arrays.asList( + new JoinExpression(JoinType.DEFAULT, article), + new JoinExpression(JoinType.LEFTJOIN, article.content.article.as(articleContentArticle))), + md.getJoins()); + assertEquals(Collections.singletonList(articleContentArticle.name.asc()), + md.getOrderBy()); + } + + @SuppressWarnings("unchecked") + @Test + public void orderBy_embeddable_collection() { + QBookVersion bookVersion = QBookVersion.bookVersion; + QBookMark bookMark = new QBookMark("bookVersion_definition_bookMarks"); + mixin.from(bookVersion); + mixin.orderBy(bookVersion.definition.bookMarks.any().comment.asc()); + + QueryMetadata md = mixin.getMetadata(); + assertEquals(Collections.singletonList(new JoinExpression(JoinType.DEFAULT, bookVersion)), + md.getJoins()); + assertEquals(Collections.singletonList(Expressions.stringPath(bookVersion.definition.bookMarks, "comment").asc()), + md.getOrderBy()); + } + + @Test + public void orderBy_nullsLast() { + QCat cat = QCat.cat; + mixin.from(cat); + mixin.orderBy(cat.mate.name.asc().nullsLast()); + assertEquals( + OrderSpecifier.NullHandling.NullsLast, + mixin.getMetadata().getOrderBy().get(0).getNullHandling()); + } +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/JPAQueryMutability2Test.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/JPAQueryMutability2Test.java new file mode 100644 index 0000000000..73ebe32040 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/JPAQueryMutability2Test.java @@ -0,0 +1,124 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import static com.querydsl.core.types.dsl.Expressions.numberOperation; +import static org.junit.Assert.assertEquals; + +import javax.persistence.EntityManager; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import com.querydsl.core.types.Operator; +import com.querydsl.jpa.domain.QCat; +import com.querydsl.jpa.impl.JPAQuery; +import com.querydsl.jpa.testutil.JPATestRunner; + +@RunWith(JPATestRunner.class) +public class JPAQueryMutability2Test implements JPATest { + + private EntityManager entityManager; + + private final Operator customOperator = new Operator() { + public String name() { + return "custom"; + } + public String toString() { + return name(); + } + public Class<?> getType() { + return Object.class; + } + }; + + private final JPQLTemplates customTemplates = new HQLTemplates() { + { + add(customOperator, "sign({0})"); + } + }; + + protected JPAQuery<?> query() { + return new JPAQuery<Void>(entityManager); + } + + protected JPAQuery<?> query(JPQLTemplates templates) { + return new JPAQuery<Void>(entityManager, templates); + } + + @Override + public void setEntityManager(EntityManager entityManager) { + this.entityManager = entityManager; + } + + @Test + public void test() { + QCat cat = QCat.cat; + JPAQuery<?> query = query().from(cat); + + query.fetchCount(); + query.distinct().fetchCount(); + + query.select(cat).iterate(); + query.select(cat, cat).iterate(); + query.distinct().select(cat).iterate(); + query.distinct().select(cat, cat).iterate(); + + query.select(cat).fetch(); + query.select(cat, cat).fetch(); + query.distinct().select(cat).fetch(); + query.distinct().select(cat, cat).fetch(); + + query.select(cat).fetchResults(); + query.distinct().select(cat).fetchResults(); + } + + @Test + public void clone_() { + QCat cat = QCat.cat; + JPAQuery<?> query = query().from(cat).where(cat.name.isNotNull()); + JPAQuery<?> query2 = query.clone(entityManager); + assertEquals(query.getMetadata().getJoins(), query2.getMetadata().getJoins()); + assertEquals(query.getMetadata().getWhere(), query2.getMetadata().getWhere()); + query2.select(cat).fetch(); + } + + @Test + public void clone_custom_templates() { + QCat cat = QCat.cat; + JPAQuery<?> query = query().from(cat); + //attach using the custom templates + query.clone(entityManager, customTemplates) + .select(numberOperation(Integer.class, customOperator, cat.floatProperty)).fetchOne(); + } + + @Test + public void clone_keep_templates() { + QCat cat = QCat.cat; + JPAQuery<?> query = query(customTemplates).from(cat); + //keep the original templates + query.clone() + .select(numberOperation(Integer.class, customOperator, cat.floatProperty)).fetchOne(); + } + + @Test(expected = IllegalArgumentException.class) + public void clone_lose_templates() { + QCat cat = QCat.cat; + JPAQuery<?> query = query(customTemplates).from(cat); + //clone using the entitymanager's default templates + query.clone(entityManager) + .select(numberOperation(Integer.class, customOperator, cat.floatProperty)).fetchOne(); + } + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/JPAQueryMutabilityTest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/JPAQueryMutabilityTest.java new file mode 100644 index 0000000000..d8de457521 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/JPAQueryMutabilityTest.java @@ -0,0 +1,74 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import static org.junit.Assert.assertEquals; + +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; + +import javax.persistence.EntityManager; + +import org.junit.Ignore; +import org.junit.Test; +import org.junit.runner.RunWith; + +import com.querydsl.core.QueryMutability; +import com.querydsl.jpa.domain.Cat; +import com.querydsl.jpa.domain.sql.SAnimal; +import com.querydsl.jpa.sql.JPASQLQuery; +import com.querydsl.jpa.testutil.JPATestRunner; +import com.querydsl.sql.DerbyTemplates; +import com.querydsl.sql.SQLTemplates; + +@Ignore +@RunWith(JPATestRunner.class) +public class JPAQueryMutabilityTest implements JPATest { + + private static final SQLTemplates derbyTemplates = new DerbyTemplates(); + + private EntityManager entityManager; + + protected JPASQLQuery<?> query() { + return new JPASQLQuery<Void>(entityManager, derbyTemplates); + } + + @Override + public void setEntityManager(EntityManager entityManager) { + this.entityManager = entityManager; + } + + @Test + public void test() throws SecurityException, IllegalArgumentException, + NoSuchMethodException, IllegalAccessException, + InvocationTargetException, IOException { + entityManager.persist(new Cat("Beck", 1)); + entityManager.flush(); + + SAnimal cat = new SAnimal("cat"); + JPASQLQuery<?> query = query().from(cat); + new QueryMutability(query).test(cat.id, cat.name); + } + + @Test + public void clone_() { + SAnimal cat = new SAnimal("cat"); + JPASQLQuery<?> query = query().from(cat).where(cat.name.isNotNull()); + JPASQLQuery<?> query2 = query.clone(entityManager); + assertEquals(query.getMetadata().getJoins(), query2.getMetadata().getJoins()); + assertEquals(query.getMetadata().getWhere(), query2.getMetadata().getWhere()); + query2.select(cat.id).fetch(); + } + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/JPASQLBase.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/JPASQLBase.java new file mode 100644 index 0000000000..e57053f376 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/JPASQLBase.java @@ -0,0 +1,160 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.Query; + +import org.junit.Before; +import org.junit.ClassRule; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.junit.runner.RunWith; + +import com.querydsl.core.Target; +import com.querydsl.core.testutil.ExcludeIn; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.Projections; +import com.querydsl.jpa.domain.Cat; +import com.querydsl.jpa.domain.Color; +import com.querydsl.jpa.domain.QCat; +import com.querydsl.jpa.domain.sql.SAnimal; +import com.querydsl.jpa.sql.JPASQLQuery; +import com.querydsl.jpa.testutil.JPATestRunner; +import com.querydsl.sql.SQLTemplates; + +import static org.junit.Assert.assertEquals; + +@RunWith(JPATestRunner.class) +public class JPASQLBase extends AbstractSQLTest implements JPATest { + + @Rule + @ClassRule + public static TestRule targetRule = new TargetRule(); + + @Rule + @ClassRule + public static TestRule hibernateOnly = new JPAProviderRule(); + + private final SQLTemplates templates = Mode.getSQLTemplates(); + + private EntityManager entityManager; + + private final SAnimal cat = new SAnimal("cat"); + private final QCat catEntity = QCat.cat; + + @Override + protected JPASQLQuery<?> query() { + return new JPASQLQuery<Void>(entityManager, templates); + } + + @Override + public void setEntityManager(EntityManager entityManager) { + this.entityManager = entityManager; + } + + @Before + public void setUp() { + if (query().from(cat).fetchCount() == 0) { + entityManager.persist(new Cat("Beck", 1, Color.BLACK)); + entityManager.persist(new Cat("Kate", 2, Color.BLACK)); + entityManager.persist(new Cat("Kitty", 3, Color.BLACK)); + entityManager.persist(new Cat("Bobby", 4, Color.BLACK)); + entityManager.persist(new Cat("Harold", 5, Color.BLACK)); + entityManager.persist(new Cat("Tim", 6, Color.BLACK)); + entityManager.flush(); + } + } + + private <T> void insertEntitiesForTest(final List<T> entities) { + for (T entity: entities) { + entityManager.persist(entity); + } + entityManager.flush(); + } + + private <T> void removeEntitiesForTest(final List<T> entities) { + for (T entity: entities) { + entityManager.remove(entity); + } + entityManager.flush(); + } + + @Test + public void entityQueries_createQuery() { + Query query = query().from(cat).select(catEntity).createQuery(); + assertEquals(6, query.getResultList().size()); + } + + @Test + @ExcludeIn(Target.MYSQL) + public void entityQueries_createQuery2() { + SAnimal cat = new SAnimal("CAT"); + + Query query = query().from(cat).select(catEntity).createQuery(); + assertEquals(6, query.getResultList().size()); + } + + @Test + public void should_fetch_results_with_factory_expression() { + final long expectedTotalResultCount = 6; + final HashMap<String, Expression<?>> bindings = new HashMap<String, Expression<?>>(); + bindings.put("name", cat.name); + + final long actualTotalResultCount = query().from(cat) + .select(Projections.bean(Cat.class, bindings)) + .fetchResults() + .getTotal(); + + assertEquals(expectedTotalResultCount, actualTotalResultCount); + } + + @Test + public void should_get_grouped_list_by_using_fetch_results() { + final long expectedCatColorKindCount = 1; + + final long actualCatColorKindCount = query().from(cat) + .select(catEntity.color) + .groupBy(catEntity.color) + .fetchResults() + .getTotal(); + + assertEquals(expectedCatColorKindCount, actualCatColorKindCount); + } + + @Test + public void should_get_black_cat_count_by_using_group_by_and_having() { + final long expectedTabbyCatCount = 2L; + final Cat tabbyColorCatFoo = new Cat("Foo", 7, Color.TABBY); + final Cat tabbyColorCatBar = new Cat("Bar", 8, Color.TABBY); + + insertEntitiesForTest(Arrays.asList(tabbyColorCatFoo, tabbyColorCatBar)); + + final long actualTabbyCatCount = query().from(cat) + .select(catEntity.name.count()) + .groupBy(catEntity.color) + .having(catEntity.name.count().eq(2L)) + .fetchOne(); + + removeEntitiesForTest(Arrays.asList(tabbyColorCatFoo, tabbyColorCatBar)); + + assertEquals(expectedTabbyCatCount, actualTabbyCatCount); + } + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/JPATest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/JPATest.java new file mode 100644 index 0000000000..ee1f0149b4 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/JPATest.java @@ -0,0 +1,27 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team). + * + * 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. + */ +package com.querydsl.jpa; + +import javax.persistence.EntityManager; + +/** + * + * @author Shredder121 + */ +public interface JPATest { + + void setEntityManager(EntityManager entityManager); +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/JPQLQueryTest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/JPQLQueryTest.java new file mode 100644 index 0000000000..14133534b1 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/JPQLQueryTest.java @@ -0,0 +1,76 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import static org.junit.Assert.assertEquals; + +import org.junit.Before; +import org.junit.Test; + +import com.querydsl.jpa.domain.QCat; +import com.querydsl.jpa.hibernate.HibernateQuery; +import com.querydsl.jpa.impl.JPAQuery; + +public class JPQLQueryTest { + + private QCat cat = QCat.cat; + + private HibernateQuery<?> query = new HibernateQuery<Void>(); + + @Before + public void setUp() { + query.from(cat); + } + + @Test(expected = IllegalArgumentException.class) + public void innerJoinPEntityOfPPEntityOfP() { + query.innerJoin(cat.mate, cat.mate); + } + + @Test(expected = IllegalArgumentException.class) + public void innerJoinPathOfQextendsCollectionOfPPathOfP() { + query.innerJoin(cat.kittens, cat.mate); + } + + @Test(expected = IllegalArgumentException.class) + public void joinPEntityOfPPEntityOfP() { + query.join(cat.mate, cat.mate); + } + + @Test(expected = IllegalArgumentException.class) + public void joinPathOfQextendsCollectionOfPPathOfP() { + query.join(cat.kittens, cat.mate); + } + + @Test(expected = IllegalArgumentException.class) + public void leftJoinPEntityOfPPEntityOfP() { + query.leftJoin(cat.mate, cat.mate); + } + + @Test(expected = IllegalArgumentException.class) + public void leftJoinPathOfQextendsCollectionOfPPathOfP() { + query.leftJoin(cat.kittens, cat.mate); + } + + @Test + public void toString_() { + assertEquals("", new HibernateQuery<Void>().toString()); + assertEquals("", new JPAQuery<Void>().toString()); + assertEquals("select cat", new HibernateQuery<Void>().select(cat).toString()); + assertEquals("select cat", new JPAQuery<Void>().select(cat).toString()); + assertEquals("select cat\nfrom Cat cat", new HibernateQuery<Void>().from(cat).toString()); + assertEquals("select cat\nfrom Cat cat", new JPAQuery<Void>().from(cat).toString()); + } + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/JPQLSerializerTest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/JPQLSerializerTest.java new file mode 100644 index 0000000000..e50a621f4e --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/JPQLSerializerTest.java @@ -0,0 +1,320 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import static com.querydsl.jpa.JPAExpressions.selectOne; +import static org.junit.Assert.assertEquals; + +import java.util.Arrays; + +import org.junit.Test; + +import com.querydsl.core.DefaultQueryMetadata; +import com.querydsl.core.JoinType; +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.domain.QAnimal; +import com.querydsl.core.domain.QCat; +import com.querydsl.core.types.EntityPath; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.Predicate; +import com.querydsl.core.types.dsl.EntityPathBase; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.jpa.domain.JobFunction; +import com.querydsl.jpa.domain.Location; +import com.querydsl.jpa.domain.QDomesticCat; +import com.querydsl.jpa.domain.QEmployee; + +public class JPQLSerializerTest { + + @Test + public void and_or() { + //A.a.id.eq(theId).and(B.b.on.eq(false).or(B.b.id.eq(otherId))); + QCat cat = QCat.cat; + Predicate pred = cat.id.eq(1).and(cat.name.eq("Kitty").or(cat.name.eq("Boris"))); + JPQLSerializer serializer = new JPQLSerializer(HQLTemplates.DEFAULT); + serializer.handle(pred); + assertEquals("cat.id = ?1 and (cat.name = ?2 or cat.name = ?3)", serializer.toString()); + assertEquals("cat.id = 1 && (cat.name = Kitty || cat.name = Boris)", pred.toString()); + } + + @Test + public void case1() { + QCat cat = QCat.cat; + JPQLSerializer serializer = new JPQLSerializer(JPQLTemplates.DEFAULT); + Expression<?> expr = Expressions.cases().when(cat.toes.eq(2)).then(2) + .when(cat.toes.eq(3)).then(3) + .otherwise(4); + serializer.handle(expr); + assertEquals("case when (cat.toes = ?1) then ?2 when (cat.toes = ?3) then ?4 else ?5 end", serializer.toString()); + } + + @Test + public void case1_hibernate() { + QCat cat = QCat.cat; + JPQLSerializer serializer = new JPQLSerializer(HQLTemplates.DEFAULT); + Expression<?> expr = Expressions.cases().when(cat.toes.eq(2)).then(2) + .when(cat.toes.eq(3)).then(3) + .otherwise(4); + serializer.handle(expr); + assertEquals("case when (cat.toes = ?1) then ?2 when (cat.toes = ?3) then ?4 else 4 end", serializer.toString()); + } + + @Test + public void case2() { + QCat cat = QCat.cat; + JPQLSerializer serializer = new JPQLSerializer(JPQLTemplates.DEFAULT); + Expression<?> expr = Expressions.cases().when(cat.toes.eq(2)).then(cat.id.multiply(2)) + .when(cat.toes.eq(3)).then(cat.id.multiply(3)) + .otherwise(4); + serializer.handle(expr); + assertEquals("case when (cat.toes = ?1) then (cat.id * ?2) when (cat.toes = ?3) then (cat.id * ?4) else ?5 end", serializer.toString()); + } + + @Test + public void case2_hibernate() { + QCat cat = QCat.cat; + JPQLSerializer serializer = new JPQLSerializer(HQLTemplates.DEFAULT); + Expression<?> expr = Expressions.cases().when(cat.toes.eq(2)).then(cat.id.multiply(2)) + .when(cat.toes.eq(3)).then(cat.id.multiply(3)) + .otherwise(4); + serializer.handle(expr); + assertEquals("case when (cat.toes = ?1) then (cat.id * ?2) when (cat.toes = ?3) then (cat.id * ?4) else 4 end", serializer.toString()); + } + + @Test + public void count() { + QCat cat = QCat.cat; + QueryMetadata md = new DefaultQueryMetadata(); + md.addJoin(JoinType.DEFAULT, cat); + md.setProjection(cat.mate.countDistinct()); + JPQLSerializer serializer1 = new JPQLSerializer(HQLTemplates.DEFAULT); + serializer1.serialize(md, true, null); + assertEquals("select count(count(distinct cat.mate))\n" + + "from Cat cat", serializer1.toString()); + + JPQLSerializer serializer2 = new JPQLSerializer(HQLTemplates.DEFAULT); + serializer2.serialize(md, false, null); + assertEquals("select count(distinct cat.mate)\n" + + "from Cat cat", serializer2.toString()); + } + + @Test + public void fromWithCustomEntityName() { + JPQLSerializer serializer = new JPQLSerializer(HQLTemplates.DEFAULT); + EntityPath<Location> entityPath = new EntityPathBase<Location>(Location.class, "entity"); + QueryMetadata md = new DefaultQueryMetadata(); + md.addJoin(JoinType.DEFAULT, entityPath); + serializer.serialize(md, false, null); + assertEquals("select entity\nfrom Location2 entity", serializer.toString()); + } + + @Test + public void join_with() { + QCat cat = QCat.cat; + JPQLSerializer serializer = new JPQLSerializer(HQLTemplates.DEFAULT); + QueryMetadata md = new DefaultQueryMetadata(); + md.addJoin(JoinType.DEFAULT, cat); + md.addJoin(JoinType.INNERJOIN, cat.mate); + md.addJoinCondition(cat.mate.alive); + serializer.serialize(md, false, null); + assertEquals("select cat\nfrom Cat cat\n inner join cat.mate with cat.mate.alive", serializer.toString()); + } + + @Test + public void normalizeNumericArgs() { + JPQLSerializer serializer = new JPQLSerializer(HQLTemplates.DEFAULT); + NumberPath<Double> doublePath = Expressions.numberPath(Double.class, "doublePath"); + serializer.handle(doublePath.add(1)); + serializer.handle(doublePath.between((float) 1.0, 1L)); + serializer.handle(doublePath.lt((byte) 1)); + for (Object constant : serializer.getConstants()) { + assertEquals(Double.class, constant.getClass()); + } + } + + @Test + public void delete_clause_uses_dELETE_fROM() { + QEmployee employee = QEmployee.employee; + JPQLSerializer serializer = new JPQLSerializer(HQLTemplates.DEFAULT); + QueryMetadata md = new DefaultQueryMetadata(); + md.addJoin(JoinType.DEFAULT, employee); + md.addWhere(employee.lastName.isNull()); + serializer.serializeForDelete(md); + assertEquals("delete from Employee employee\nwhere employee.lastName is null", serializer.toString()); + } + + @Test + public void delete_with_subQuery() { + QCat parent = QCat.cat; + QCat child = new QCat("kitten"); + + JPQLSerializer serializer = new JPQLSerializer(HQLTemplates.DEFAULT); + QueryMetadata md = new DefaultQueryMetadata(); + md.addJoin(JoinType.DEFAULT, child); + md.addWhere( + child.id.eq(1) + .and(selectOne() + .from(parent) + .where(parent.id.eq(2), child.in(parent.kittens)).exists())); + serializer.serializeForDelete(md); + assertEquals("delete from Cat kitten\n" + + "where kitten.id = ?1 and exists (select 1\n" + + "from Cat cat\nwhere cat.id = ?2 and kitten member of cat.kittens)", serializer.toString()); + } + + @Test + public void in() { + JPQLSerializer serializer = new JPQLSerializer(HQLTemplates.DEFAULT); + serializer.handle(Expressions.numberPath(Integer.class, "id").in(Arrays.asList(1, 2))); + assertEquals("id in (?1)", serializer.toString()); + } + + @Test + public void not_in() { + JPQLSerializer serializer = new JPQLSerializer(HQLTemplates.DEFAULT); + serializer.handle(Expressions.numberPath(Integer.class, "id").notIn(Arrays.asList(1, 2))); + assertEquals("id not in (?1)", serializer.toString()); + } + + @Test + public void like() { + JPQLSerializer serializer = new JPQLSerializer(HQLTemplates.DEFAULT); + serializer.handle(Expressions.stringPath("str").contains("abc!")); + assertEquals("str like ?1 escape '!'", serializer.toString()); + assertEquals("%abc!!%", serializer.getConstants().get(0).toString()); + } + + @Test + public void stringContainsIc() { + JPQLSerializer serializer = new JPQLSerializer(HQLTemplates.DEFAULT); + serializer.handle(Expressions.stringPath("str").containsIgnoreCase("ABc!")); + assertEquals("lower(str) like ?1 escape '!'", serializer.toString()); + assertEquals("%abc!!%", serializer.getConstants().get(0).toString()); + } + + @Test + public void substring() { + JPQLSerializer serializer = new JPQLSerializer(HQLTemplates.DEFAULT); + QCat cat = QCat.cat; + serializer.handle(cat.name.substring(cat.name.length().subtract(1), 1)); + assertEquals("substring(cat.name,length(cat.name) + ?1,?2 - (length(cat.name) - ?3))", serializer.toString()); + } + + @Test + public void nullsFirst() { + QCat cat = QCat.cat; + JPQLSerializer serializer = new JPQLSerializer(HQLTemplates.DEFAULT); + QueryMetadata md = new DefaultQueryMetadata(); + md.addJoin(JoinType.DEFAULT, cat); + md.addOrderBy(cat.name.asc().nullsFirst()); + serializer.serialize(md, false, null); + assertEquals("select cat\n" + + "from Cat cat\n" + + "order by cat.name asc nulls first", serializer.toString()); + } + + @Test + public void nullsLast() { + QCat cat = QCat.cat; + JPQLSerializer serializer = new JPQLSerializer(HQLTemplates.DEFAULT); + QueryMetadata md = new DefaultQueryMetadata(); + md.addJoin(JoinType.DEFAULT, cat); + md.addOrderBy(cat.name.asc().nullsLast()); + serializer.serialize(md, false, null); + assertEquals("select cat\n" + + "from Cat cat\n" + + "order by cat.name asc nulls last", serializer.toString()); + } + + @SuppressWarnings("unchecked") + @Test + public void treat() { + QCat cat = QCat.cat; + JPQLSerializer serializer = new JPQLSerializer(HQLTemplates.DEFAULT); + QueryMetadata md = new DefaultQueryMetadata(); + md.addJoin(JoinType.DEFAULT, cat); + md.addJoin(JoinType.JOIN, cat.mate.as((Path) QDomesticCat.domesticCat)); + md.setProjection(QDomesticCat.domesticCat); + serializer.serialize(md, false, null); + assertEquals("select domesticCat\n" + + "from Cat cat\n" + + " inner join treat(cat.mate as DomesticCat) as domesticCat", serializer.toString()); + } + + @Test + public void treated_path() { + QAnimal animal = QAnimal.animal; + JPQLSerializer serializer = new JPQLSerializer(HQLTemplates.DEFAULT); + QueryMetadata md = new DefaultQueryMetadata(); + md.addJoin(JoinType.DEFAULT, animal); + + md.addWhere(JPAExpressions.treat(animal, QCat.class).breed.eq(1)); + md.setProjection(animal); + serializer.serialize(md, false, null); + assertEquals("select animal\n" + + "from Animal animal\n" + + "where treat(animal as Cat).breed = ?1", serializer.toString()); + } + + @Test + public void openJPA_variables() { + QCat cat = QCat.cat; + JPQLSerializer serializer = new JPQLSerializer(OpenJPATemplates.DEFAULT); + QueryMetadata md = new DefaultQueryMetadata(); + md.addJoin(JoinType.DEFAULT, cat); + md.addJoin(JoinType.INNERJOIN, cat.mate); + md.addJoinCondition(cat.mate.alive); + serializer.serialize(md, false, null); + assertEquals("select cat_\nfrom Cat cat_\n inner join cat_.mate on cat_.mate.alive", + serializer.toString()); + } + + @Test + public void visitLiteral_boolean() { + JPQLSerializer serializer = new JPQLSerializer(HQLTemplates.DEFAULT); + serializer.visitLiteral(Boolean.TRUE); + assertEquals("true", serializer.toString()); + } + + @Test + public void visitLiteral_number() { + JPQLSerializer serializer = new JPQLSerializer(HQLTemplates.DEFAULT); + serializer.visitLiteral(1.543); + assertEquals("1.543", serializer.toString()); + } + + @Test + public void visitLiteral_string() { + JPQLSerializer serializer = new JPQLSerializer(HQLTemplates.DEFAULT); + serializer.visitLiteral("abc''def"); + assertEquals("'abc''''def'", serializer.toString()); + } + + @Test + public void visitLiteral_enum() { + JPQLSerializer serializer = new JPQLSerializer(HQLTemplates.DEFAULT); + serializer.visitLiteral(JobFunction.MANAGER); + assertEquals("com.querydsl.jpa.domain.JobFunction.MANAGER", serializer.toString()); + } + + @Test + public void substring_indexOf() { + QCat cat = QCat.cat; + JPQLSerializer serializer = new JPQLSerializer(HQLTemplates.DEFAULT); + cat.name.substring(cat.name.indexOf("")).accept(serializer, null); + assertEquals("substring(cat.name,locate(?1,cat.name)-1 + ?2)", serializer.toString()); + } +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/JPQLTemplatesTest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/JPQLTemplatesTest.java new file mode 100644 index 0000000000..a1cafe64ec --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/JPQLTemplatesTest.java @@ -0,0 +1,85 @@ +package com.querydsl.jpa; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; +import java.util.List; + +import org.junit.Test; + +import com.querydsl.core.types.Operator; +import com.querydsl.core.types.Ops; +import com.querydsl.core.types.Templates; +import com.querydsl.core.types.TemplatesTestUtils; + +public class JPQLTemplatesTest { + + @Test + public void escape() { + List<Templates> templates = Arrays.<Templates>asList( + new JPQLTemplates(), new HQLTemplates(), + new EclipseLinkTemplates(), new OpenJPATemplates() + ); + + for (Templates t : templates) { + assertEquals("{0} like {1} escape '!'", t.getTemplate(Ops.LIKE).toString()); + } + } + + @Test + public void custom_escape() { + List<Templates> templates = Arrays.<Templates>asList( + new JPQLTemplates('X'), new HQLTemplates('X'), + new EclipseLinkTemplates('X'), new OpenJPATemplates('X') + ); + + for (Templates t : templates) { + assertEquals("{0} like {1} escape 'X'", t.getTemplate(Ops.LIKE).toString()); + } + } + + @Test + public void precedence() { + // Navigation operator (.) + // +, - unary *, + int p1 = getPrecedence(Ops.NEGATE); + // / multiplication and division + int p2 = getPrecedence(Ops.MULT, Ops.DIV); + // +, - addition and subtraction + int p3 = getPrecedence(Ops.ADD, Ops.SUB); + // Comparison operators : =, >, >=, <, <=, <> (not equal), [NOT] BETWEEN, [NOT] LIKE, [NOT] IN, IS [NOT] NULL, IS [NOT] EMPTY, [NOT] MEMBER [OF] + int p4 = getPrecedence(Ops.EQ, Ops.GT, Ops.GOE, Ops.LT, Ops.LOE, Ops.NE, Ops.BETWEEN, Ops.LIKE, Ops.LIKE_ESCAPE, Ops.IN, + Ops.IS_NULL, Ops.IS_NOT_NULL, JPQLOps.MEMBER_OF, JPQLOps.NOT_MEMBER_OF); + // NOT + int p5 = getPrecedence(Ops.NOT); + // AND + int p6 = getPrecedence(Ops.AND); + // OR + int p7 = getPrecedence(Ops.OR); + + assertTrue(p1 < p2); + assertTrue(p2 < p3); + assertTrue(p3 < p4); + assertTrue(p4 < p5); + assertTrue(p5 < p6); + assertTrue(p6 < p7); + } + + protected int getPrecedence(Operator... ops) { + int precedence = JPQLTemplates.DEFAULT.getPrecedence(ops[0]); + for (int i = 1; i < ops.length; i++) { + assertEquals(ops[i].name(), precedence, JPQLTemplates.DEFAULT.getPrecedence(ops[i])); + } + return precedence; + } + + @Test + public void generic_precedence() { + for (JPQLTemplates templates : Arrays.asList( + JPQLTemplates.DEFAULT, HQLTemplates.DEFAULT, EclipseLinkTemplates.DEFAULT)) { + TemplatesTestUtils.testPrecedence(templates); + } + } + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/JoinFlagsTest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/JoinFlagsTest.java new file mode 100644 index 0000000000..073eb13172 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/JoinFlagsTest.java @@ -0,0 +1,46 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import static org.junit.Assert.assertEquals; +import static com.querydsl.jpa.Constants.*; + +import org.junit.Test; + +public class JoinFlagsTest extends AbstractQueryTest { + + @Test + public void fetchAll() { + QueryHelper query1 = query().from(cat).fetchAll().where(cat.name.isNotNull()); + assertEquals("select cat\nfrom Cat cat fetch all properties\nwhere cat.name is not null", query1.toString()); + } + + @Test + public void fetchAll2() { + QueryHelper query2 = query().from(cat).fetchAll().from(cat1).fetchAll(); + assertEquals("select cat\nfrom Cat cat fetch all properties, Cat cat1 fetch all properties", query2.toString()); + } + + @Test + public void fetch() { + QueryHelper query = query().from(cat).innerJoin(cat.mate, cat1).fetchJoin(); + assertEquals("select cat\nfrom Cat cat\n inner join fetch cat.mate as cat1", query.toString()); + } + + @Test + public void rightJoin() { + QueryHelper query = query().from(cat).rightJoin(cat.mate, cat1); + assertEquals("select cat\nfrom Cat cat\n right join cat.mate as cat1", query.toString()); + } +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/JoinTest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/JoinTest.java new file mode 100644 index 0000000000..60a8be2362 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/JoinTest.java @@ -0,0 +1,83 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import static com.querydsl.core.alias.Alias.$; +import static com.querydsl.jpa.JPAExpressions.selectOne; + +import java.util.List; + +import org.junit.Test; + +import com.querydsl.core.alias.Alias; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.StringPath; +import com.querydsl.jpa.hibernate.HibernateQuery; + +public class JoinTest { + + public interface Entity { + + List<String> getNames(); + } + + private final Entity alias = Alias.alias(Entity.class); + + private final StringPath path = Expressions.stringPath("path"); + private final JPQLQuery<?> subQuery = selectOne(); + private final HibernateQuery<?> query = new HibernateQuery<Void>(new DummySessionHolder(), HQLTemplates.DEFAULT); + + @Test + public void subQuery_innerJoin() { + subQuery.from($(alias)); + subQuery.innerJoin($(alias.getNames()), path); + // TODO : assertions + } + + @Test + public void subQuery_join() { + subQuery.from($(alias)); + subQuery.join($(alias.getNames()), path); + // TODO : assertions + } + + @Test + public void subQuery_leftJoin() { + subQuery.from($(alias)); + subQuery.leftJoin($(alias.getNames()), path); + // TODO : assertions + } + + @Test + public void query_innerJoin() { + query.from($(alias)); + query.innerJoin($(alias.getNames()), path); + // TODO : assertions + } + + @Test + public void query_join() { + query.from($(alias)); + query.join($(alias.getNames()), path); + // TODO : assertions + } + + @Test + public void query_leftJoin() { + query.from($(alias)); + query.leftJoin($(alias.getNames()), path); + // TODO : assertions + } + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/MapOperationsTest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/MapOperationsTest.java new file mode 100644 index 0000000000..3d405a3954 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/MapOperationsTest.java @@ -0,0 +1,30 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import static com.querydsl.jpa.Constants.*; +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import com.querydsl.jpa.impl.JPAQuery; + +public class MapOperationsTest extends AbstractQueryTest { + + @Test + public void map_with_groupBy() { + assertEquals("select show_acts_0\nfrom Show show\n left join show.acts as show_acts_0 on key(show_acts_0) = ?1\ngroup by show_acts_0", new JPAQuery<Void>().from(show).select(show.acts.get("A")).groupBy(show.acts.get("A")).toString()); + } + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/MathTest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/MathTest.java new file mode 100644 index 0000000000..3fdcf8fc7e --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/MathTest.java @@ -0,0 +1,113 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import static com.querydsl.jpa.Constants.*; + +import org.junit.Test; + +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.jpa.domain.QCat; + +public class MathTest extends AbstractQueryTest { + + @Test + public void test() { + NumberPath<Double> path = QCat.cat.bodyWeight; + assertToString("(cat.bodyWeight - sum(cat.bodyWeight)) * cat.bodyWeight", path.subtract(path.sum()).multiply(path)); + } + + @Test + public void add() { + assertToString("cat.bodyWeight + ?1", cat.bodyWeight.add(10)); + } + + @Test + public void subtract() { + assertToString("cat.bodyWeight - ?1", cat.bodyWeight.subtract(10)); + } + + @Test + public void multiply() { + assertToString("cat.bodyWeight * ?1", cat.bodyWeight.multiply(10)); + } + + @Test + public void divide() { + assertToString("cat.bodyWeight / ?1", cat.bodyWeight.divide(10)); + } + + @Test + public void add_and_compare() { + assertToString("cat.bodyWeight + ?1 < ?2", cat.bodyWeight.add(10.0).lt(10.0)); + } + + @Test + public void subtract_and_compare() { + assertToString("cat.bodyWeight - ?1 < ?2", cat.bodyWeight.subtract(10.0).lt(10.0)); + } + + @Test + public void multiply_and_compare() { + assertToString("cat.bodyWeight * ?1 < ?2", cat.bodyWeight.multiply(10.0).lt(10.0)); + } + + @Test + public void divide_and_compare() { + assertToString("cat.bodyWeight / ?1 < ?2", cat.bodyWeight.divide(10.0).lt(20.0)); + } + + @Test + public void add_and_multiply() { + assertToString("(cat.bodyWeight + ?1) * ?2", cat.bodyWeight.add(10).multiply(20)); + } + + @Test + public void subtract_and_multiply() { + assertToString("(cat.bodyWeight - ?1) * ?2", cat.bodyWeight.subtract(10).multiply(20)); + } + + + @Test + public void multiply_and_add() { + assertToString("cat.bodyWeight * ?1 + ?2", cat.bodyWeight.multiply(10).add(20)); + } + + + @Test + public void multiply_and_subtract() { + assertToString("cat.bodyWeight * ?1 - ?2", cat.bodyWeight.multiply(10).subtract(20)); + } + + + @Test + public void arithmetic_and_arithmetic2() { + QCat c1 = new QCat("c1"); + QCat c2 = new QCat("c2"); + QCat c3 = new QCat("c3"); + assertToString("c1.id + c2.id * c3.id", c1.id.add(c2.id.multiply(c3.id))); + assertToString("c1.id * (c2.id + c3.id)", c1.id.multiply(c2.id.add(c3.id))); + assertToString("(c1.id + c2.id) * c3.id", c1.id.add(c2.id).multiply(c3.id)); + } + + @Test + public void mathematicalOperations() { + // mathematical operators +, -, *, / + cat.bodyWeight.add(kitten.bodyWeight); + cat.bodyWeight.subtract(kitten.bodyWeight); + cat.bodyWeight.multiply(kitten.bodyWeight); + cat.bodyWeight.divide(kitten.bodyWeight); + } + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/Mode.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/Mode.java new file mode 100644 index 0000000000..e01433cedb --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/Mode.java @@ -0,0 +1,34 @@ +package com.querydsl.jpa; + +import com.querydsl.core.Target; +import com.querydsl.sql.*; + +/** + * @author tiwe + * + */ +public final class Mode { + + public static final ThreadLocal<String> mode = new ThreadLocal<String>(); + + public static final ThreadLocal<Target> target = new ThreadLocal<Target>(); + + public static SQLTemplates getSQLTemplates() { + switch (target.get()) { + case CUBRID: return new CUBRIDTemplates(); + case DERBY: return new DerbyTemplates(); + case H2: return new H2Templates(); + case HSQLDB: return new HSQLDBTemplates(); + case SQLSERVER: return new SQLServer2008Templates(); + case MYSQL: return new MySQLTemplates(); + case ORACLE: return new OracleTemplates(); + case POSTGRESQL: return new PostgreSQLTemplates(); + case SQLITE: return new SQLiteTemplates(); + case TERADATA: return new TeradataTemplates(); + } + throw new IllegalStateException("Unknown mode " + mode); + } + + private Mode() { } + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/NativeSQLSerializerTest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/NativeSQLSerializerTest.java new file mode 100644 index 0000000000..5cbf27f6ac --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/NativeSQLSerializerTest.java @@ -0,0 +1,73 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import static org.junit.Assert.assertEquals; + +import javax.persistence.Column; + +import org.junit.Test; + +import com.querydsl.core.DefaultQueryMetadata; +import com.querydsl.core.JoinType; +import com.querydsl.core.types.dsl.PathBuilder; +import com.querydsl.jpa.domain.sql.SAnimal; +import com.querydsl.sql.Configuration; +import com.querydsl.sql.MySQLTemplates; + + +public class NativeSQLSerializerTest { + + public static class Entity { + @Column + private String name; + + @Column(name = "first_name") + private String firstName; + } + + @Test + public void in() { + Configuration conf = new Configuration(new MySQLTemplates()); + NativeSQLSerializer serializer = new NativeSQLSerializer(conf, true); + DefaultQueryMetadata md = new DefaultQueryMetadata(); + SAnimal cat = SAnimal.animal_; + md.addJoin(JoinType.DEFAULT, cat); + md.addWhere(cat.name.in("X", "Y")); + md.setProjection(cat.id); + serializer.serialize(md, false); + assertEquals("select animal_.id\n" + + "from animal_ animal_\n" + + "where animal_.name in (?1, ?2)", serializer.toString()); + } + + @Test + public void path_column() { + PathBuilder<Entity> entity = new PathBuilder<Entity>(Entity.class,"entity"); + Configuration conf = new Configuration(new MySQLTemplates()); + NativeSQLSerializer serializer = new NativeSQLSerializer(conf, true); + serializer.handle(entity.get("name")); + assertEquals("entity.name", serializer.toString()); + } + + @Test + public void path_column2() { + PathBuilder<Entity> entity = new PathBuilder<Entity>(Entity.class,"entity"); + Configuration conf = new Configuration(new MySQLTemplates()); + NativeSQLSerializer serializer = new NativeSQLSerializer(conf, true); + serializer.handle(entity.get("firstName")); + assertEquals("entity.first_name", serializer.toString()); + } + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/NoBatooJPA.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/NoBatooJPA.java new file mode 100644 index 0000000000..70951b4fd2 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/NoBatooJPA.java @@ -0,0 +1,11 @@ +package com.querydsl.jpa; + +import java.lang.annotation.*; + +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.METHOD, ElementType.TYPE}) +@Inherited +public @interface NoBatooJPA { + + com.querydsl.core.Target[] value() default {}; +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/NoEclipseLink.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/NoEclipseLink.java new file mode 100644 index 0000000000..b19f206c14 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/NoEclipseLink.java @@ -0,0 +1,11 @@ +package com.querydsl.jpa; + +import java.lang.annotation.*; + +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.METHOD, ElementType.TYPE}) +@Inherited +public @interface NoEclipseLink { + + com.querydsl.core.Target[] value() default {}; +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/NoHibernate.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/NoHibernate.java new file mode 100644 index 0000000000..93d8537136 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/NoHibernate.java @@ -0,0 +1,11 @@ +package com.querydsl.jpa; + +import java.lang.annotation.*; + +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.METHOD, ElementType.TYPE}) +@Inherited +public @interface NoHibernate { + + com.querydsl.core.Target[] value() default {}; +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/NoOpenJPA.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/NoOpenJPA.java new file mode 100644 index 0000000000..a38d53470f --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/NoOpenJPA.java @@ -0,0 +1,11 @@ +package com.querydsl.jpa; + +import java.lang.annotation.*; + +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.METHOD, ElementType.TYPE}) +@Inherited +public @interface NoOpenJPA { + + com.querydsl.core.Target[] value() default {}; +} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/OrderExpressionsTest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/OrderExpressionsTest.java similarity index 79% rename from querydsl-jpa/src/test/java/com/mysema/query/jpa/OrderExpressionsTest.java rename to querydsl-jpa/src/test/java/com/querydsl/jpa/OrderExpressionsTest.java index 1423366a00..ade33aad2b 100644 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/OrderExpressionsTest.java +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/OrderExpressionsTest.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,14 +11,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.jpa; +package com.querydsl.jpa; + +import static com.querydsl.jpa.Constants.*; import org.junit.Test; public class OrderExpressionsTest extends AbstractQueryTest { @Test - public void OrderExpressionInFunctionalWay() { + public void orderExpressionInFunctionalWay() { cat.bodyWeight.asc(); cat.bodyWeight.add(kitten.bodyWeight).asc(); } diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/OrderHelper.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/OrderHelper.java new file mode 100644 index 0000000000..eaa07578ff --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/OrderHelper.java @@ -0,0 +1,60 @@ +package com.querydsl.jpa; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.regex.Pattern; + +import org.apache.commons.lang.StringUtils; + +import com.querydsl.core.types.EntityPath; +import com.querydsl.core.types.dsl.PathBuilder; + +public final class OrderHelper { + + private OrderHelper() { } + + private static final Pattern DOT = Pattern.compile("\\."); + + @SuppressWarnings("unchecked") + public static PathBuilder<?> join(JPQLQuery<?> query, PathBuilder<?> builder, Map<String, PathBuilder<?>> joins, String path) { + PathBuilder<?> rv = joins.get(path); + if (rv == null) { + if (path.contains(".")) { + String[] tokens = DOT.split(path); + String[] parent = new String[tokens.length - 1]; + System.arraycopy(tokens, 0, parent, 0, tokens.length - 1); + String parentKey = StringUtils.join(parent, "."); + builder = join(query, builder, joins, parentKey); + rv = new PathBuilder(Object.class, StringUtils.join(tokens, "_")); + query.leftJoin((EntityPath) builder.get(tokens[tokens.length - 1]), rv); + } else { + rv = new PathBuilder(Object.class, path); + query.leftJoin((EntityPath) builder.get(path), rv); + } + joins.put(path, rv); + } + return rv; + } + + @SuppressWarnings("unchecked") + public static void orderBy(JPQLQuery<?> query, EntityPath<?> entity, List<String> order) { + PathBuilder<?> builder = new PathBuilder(entity.getType(), entity.getMetadata()); + Map<String, PathBuilder<?>> joins = new HashMap<>(); + + for (String entry : order) { + String[] tokens = DOT.split(entry); + if (tokens.length > 1) { + String[] parent = new String[tokens.length - 1]; + System.arraycopy(tokens, 0, parent, 0, tokens.length - 1); + PathBuilder<?> parentAlias = join(query, builder, joins, StringUtils.join(parent, ".")); + query.orderBy(parentAlias.getString(tokens[tokens.length - 1]).asc()); + } else { + query.orderBy(builder.getString(tokens[0]).asc()); + } + } + } + +} + + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/OrderHelperTest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/OrderHelperTest.java new file mode 100644 index 0000000000..8891580ed8 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/OrderHelperTest.java @@ -0,0 +1,42 @@ +package com.querydsl.jpa; + +import static com.querydsl.jpa.JPAExpressions.select; +import static org.junit.Assert.assertEquals; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Test; + +import com.querydsl.core.types.dsl.PathBuilder; + +public class OrderHelperTest { + + @Test + public void order() { + PathBuilder<Object> entity = new PathBuilder<Object>(Object.class, "project"); + List<String> order = new ArrayList<>(); + order.add("customer.name"); + order.add("department.superior.name"); + order.add("customer.company.name"); + order.add("previousProject.customer.company.name"); + order.add("department.name"); + + JPQLQuery<?> query = select(entity); + query.from(entity); + OrderHelper.orderBy(query, entity, order); + assertEquals("select project\n" + + "from Object project\n" + + " left join project.customer as customer\n" + + " left join project.department as department\n" + + " left join department.superior as department_superior\n" + + " left join customer.company as customer_company\n" + + " left join project.previousProject as previousProject\n" + + " left join previousProject.customer as previousProject_customer\n" + + " left join previousProject_customer.company as previousProject_customer_company\n" + + "order by customer.name asc, department_superior.name asc, customer_company.name asc," + + " previousProject_customer_company.name asc, department.name asc", + query.toString()); + } + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/PackageVerification.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/PackageVerification.java new file mode 100644 index 0000000000..961139ff4c --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/PackageVerification.java @@ -0,0 +1,64 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.Scanner; + +import javax.persistence.Entity; + +import org.junit.Test; + +import com.querydsl.codegen.utils.CodeWriter; +import com.querydsl.apt.hibernate.HibernateAnnotationProcessor; +import com.querydsl.apt.jpa.JPAAnnotationProcessor; +import com.querydsl.codegen.CodegenModule; +import com.querydsl.core.types.Expression; + +public class PackageVerification { + + @Test + public void verify_package() throws Exception { + String version = System.getProperty("version"); + verify(new File("target/querydsl-jpa-" + version + "-apt-hibernate-one-jar.jar"), true); + verify(new File("target/querydsl-jpa-" + version + "-apt-one-jar.jar"), false); + } + + private void verify(File oneJar, boolean hibernateDeps) throws Exception { + assertTrue(oneJar.getPath() + " doesn't exist", oneJar.exists()); + // verify classLoader + URLClassLoader oneJarClassLoader = new URLClassLoader(new URL[]{oneJar.toURI().toURL()}); + oneJarClassLoader.loadClass(Expression.class.getName()); // querydsl-core + oneJarClassLoader.loadClass(CodeWriter.class.getName()); // codegen + oneJarClassLoader.loadClass(CodegenModule.class.getName()).newInstance(); + oneJarClassLoader.loadClass(Entity.class.getName()); // jpa + Class<?> processor; + if (hibernateDeps) { + oneJarClassLoader.loadClass(org.hibernate.annotations.Type.class.getName()); // hibernate + processor = HibernateAnnotationProcessor.class; + } else { + processor = JPAAnnotationProcessor.class; + } + Class cl = oneJarClassLoader.loadClass(processor.getName()); // querydsl-apt + cl.newInstance(); + String resourceKey = "META-INF/services/javax.annotation.processing.Processor"; + assertEquals(processor.getName(), new Scanner(oneJarClassLoader.findResource(resourceKey).openStream()).nextLine()); + } + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/ParsingTest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/ParsingTest.java new file mode 100644 index 0000000000..fb8bcd74d0 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/ParsingTest.java @@ -0,0 +1,719 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import static com.querydsl.jpa.Constants.*; + +import static com.querydsl.core.Target.*; +import static com.querydsl.core.alias.Alias.$; +import static com.querydsl.core.alias.Alias.alias; +import static com.querydsl.jpa.JPAExpressions.select; +import static com.querydsl.jpa.JPAExpressions.selectFrom; +import static org.junit.Assert.assertEquals; + +import org.junit.Ignore; +import org.junit.Test; + +import com.querydsl.core.testutil.ExcludeIn; +import com.querydsl.core.types.dsl.ComparableExpression; +import com.querydsl.core.types.dsl.DateExpression; +import com.querydsl.core.types.dsl.NumberExpression; +import com.querydsl.jpa.domain.*; + +import antlr.RecognitionException; +import antlr.TokenStreamException; + +public class ParsingTest extends AbstractQueryTest { + + @Test + @Ignore + public void arrayExpr() throws Exception { + query().from(ord).where(ord.items(0).id.eq(1234L)).parse(); + } + + @Test + public void basic() throws RecognitionException, TokenStreamException { + query().from(cat, fatcat).select(cat.name, fatcat.name).parse(); + } + + @Test + @ExcludeIn(SQLSERVER) + public void beforeAndAfter() throws RecognitionException, TokenStreamException { + ComparableExpression<java.util.Date> ed = catalog.effectiveDate; + query() + .from(catalog) + .where( + ed.gt(DateExpression.currentDate()), + ed.goe(DateExpression.currentDate()), + ed.lt(DateExpression.currentDate()), + ed.loe(DateExpression.currentDate())) + .select(catalog).parse(); + } + + @Test + @ExcludeIn(ORACLE) + public void complexConstructor() throws Exception { + query().from(bar).select(new QFooDTO(bar.count())).parse(); + } + + @Test + public void docoExamples910() throws Exception { + query().from(cat) + .groupBy(cat.color) + .select(cat.color, cat.weight.sum(), cat.count()).parse(); + } + + @Test + public void docoExamples910_2() throws Exception { + query().from(cat) + .groupBy(cat.color) + .having(cat.color.in(Color.TABBY, Color.BLACK)) + .select(cat.color, cat.weight.sum(), cat.count()).parse(); + } + + @Test + @Ignore + public void docoExamples910_3() throws Exception { + query().from(cat).join(cat.kittens, kitten) + .groupBy(cat) + .having(kitten.weight.avg().gt(100.0)) + .orderBy(kitten.count().asc(), kitten.weight.sum().desc()) + .select(cat) + .parse(); + } + + @Test + public void docoExamples911() throws Exception { + query().from(fatcat).where( + fatcat.weight.gt(select(cat.weight.avg()).from(cat))) + .parse(); + } + + @Test + public void docoExamples911_2() throws Exception { + query().from(cat).where( + cat.name.eqAny(select(name.nickName).from(name))) + .parse(); + } + + @Test + public void docoExamples911_3() throws Exception { + query().from(cat).where( + select(mate).from(mate).where(mate.mate.eq(cat)).notExists()) + .parse(); + } + + @Test + public void docoExamples911_4() throws Exception { + query().from(cat).where( + selectFrom(mate).where(mate.mate.eq(cat)).exists()) + .parse(); + } + + @Test + public void docoExamples911_5() throws Exception { + query().from(cat).where( + cat.name.notIn(select(name.nickName).from(name))) + .parse(); + } + + @Test + public void docoExamples912() throws Exception { + query().from(ord, cust) + .join(ord.lineItems, item).join(item.product, product) + .from(catalog).join(catalog.prices, price).where( + ord.paid.not().and(ord.customer.eq(cust)).and( + price.product.eq(product)).and( + catalog.effectiveDate.gt(DateExpression.currentDate())).and( + catalog.effectiveDate.gtAny( + select(catalog.effectiveDate).from(catalog).where( + catalog.effectiveDate.lt(DateExpression.currentDate()))))) + .groupBy(ord).having(price.amount.sum().gt(0L)) + .orderBy(price.amount.sum().desc()) + .select(ord.id, price.amount.sum(), item.count()); + + Customer c1 = new Customer(); + Catalog c2 = new Catalog(); + + query().from(ord) + .join(ord.lineItems, item).join(item.product, product) + .from(catalog).join(catalog.prices, price).where( + ord.paid.not().and(ord.customer.eq(c1)).and( + price.product.eq(product)).and(catalog.eq(c2))) + .groupBy(ord).having(price.amount.sum().gt(0L)) + .orderBy(price.amount.sum().desc()) + .select(ord.id, price.amount.sum(), item.count()); + + } + + @Test + public void docoExamples92() throws Exception { + query().from(cat).parse(); + } + + @Test + public void docoExamples92_2() throws Exception { + query().from(cat).parse(); + } + + @Test + public void docoExamples92_3() throws Exception { + query().from(form, param).parse(); + } + + @Test + public void docoExamples93() throws Exception { + query().from(cat).innerJoin(cat.mate, mate).leftJoin(cat.kittens, kitten).parse(); + } + + @Test + public void docoExamples93_2() throws Exception { + query().from(cat).leftJoin(cat.mate.kittens, kitten).parse(); + } + + @Test + public void docoExamples93_3() throws Exception { + query().from(cat).join(cat.mate, mate).leftJoin(cat.kittens, kitten).parse(); + } + + @Test + public void docoExamples93_4() throws Exception { + query().from(cat).innerJoin(cat.mate, mate).leftJoin(cat.kittens, kitten).parse(); + } + + @Test + public void docoExamples93_viaAlias() throws Exception { + Cat c = alias(Cat.class, "cat"); + Cat k = alias(Cat.class, "kittens"); + Cat m = alias(Cat.class, "mate"); + + query().from($(c)).innerJoin($(c.getMate()),$(m)).leftJoin($(c.getKittens()),$(k)).parse(); + } + + @Test + public void docoExamples93_viaAlias2() throws Exception { + Cat c = alias(Cat.class, "cat"); + Cat k = alias(Cat.class, "kittens"); + + query().from($(c)).leftJoin($(c.getMate().getKittens()),$(k)).parse(); + } + + @Test + public void docoExamples93_viaAlias3() throws Exception { + Cat c = alias(Cat.class, "cat"); + Cat k = alias(Cat.class, "kittens"); + Cat m = alias(Cat.class, "mate"); + + query().from($(c)).innerJoin($(c.getMate()),$(m)).leftJoin($(c.getKittens()),$(k)).parse(); + } + + @Test + public void docoExamples93_viaAlias4() throws Exception { + Cat c = alias(Cat.class, "cat"); + Cat k = alias(Cat.class, "kittens"); + Cat m = alias(Cat.class, "mate"); + + query().from($(c)).innerJoin($(c.getMate()),$(m)).leftJoin($(c.getKittens()),$(k)).parse(); + } + + @Test + public void docoExamples94() throws Exception { + query().from(cat).innerJoin(cat.mate, mate).select(cat.mate).parse(); + } + + @Test + public void docoExamples94_2() throws Exception { + query().from(cat).select(cat.mate).parse(); + } + + @Test + @NoOpenJPA @NoBatooJPA + public void docoExamples94_3() throws Exception { + query().from(cat).select(cat.kittens).parse(); + } + + @Test + public void docoExamples94_4() throws Exception { + query().from(cust).select(cust.name.firstName).parse(); + } + + @Test + public void docoExamples94_5() throws Exception { + query().from(mother) + .innerJoin(mother.mate, mate) + .leftJoin(mother.kittens, offspr) + .select(mother, offspr, mate).parse(); + } + + @Test + public void docoExamples94_6() throws Exception { + query().from(mother) + .innerJoin(mother.mate, mate) + .leftJoin(mother.kittens, kitten) + .select(new QFamily(mother, mate, kitten)).parse(); + } + + @Test + public void docoExamples95() throws Exception { + query().from(cat) + .select(cat.weight.avg(), cat.weight.sum(), cat.weight.max(), cat.count()) + .parse(); + } + + @Test + public void docoExamples96() throws Exception { + query().from(cat).parse(); + } + + @Test + public void docoExamples96_2() throws Exception { + query().from(m, n).where(n.name.eq(m.name)).parse(); + } + + @Test + @ExcludeIn(ORACLE) + public void docoExamples97() throws Exception { + query().from(foo, bar).where(foo.startDate.eq(bar.date)).select(foo).parse(); + } + + @Test + public void docoExamples97_2() throws Exception { + query().from(cat).where(cat.mate.name.isNotNull()).parse(); + } + + @Test + public void docoExamples97_3() throws Exception { + query().from(cat, rival).where(cat.mate.eq(rival.mate)).parse(); + } + + @Test + public void docoExamples97_4() throws Exception { + query().from(cat, mate).where(cat.mate.eq(mate)).select(cat, mate).parse(); + } + + @Test + public void docoExamples97_5() throws Exception { + query().from(cat).where(cat.id.eq(123)).parse(); + } + + @Test + public void docoExamples97_6() throws Exception { + query().from(cat).where(cat.mate.id.eq(69)).parse(); + } + + @Test + public void docoExamples97_7() throws Exception { + query().from(person).where( + person.pid.country.eq("AU"), + person.pid.medicareNumber.eq(123456)).parse(); + } + + @Test + public void docoExamples97_8() throws Exception { + query().from(account).where(account.owner.pid.medicareNumber.eq(123456)).parse(); + } + + @Test + public void docoExamples97_9() throws Exception { + query().from(cat).where(cat.instanceOf(DomesticCat.class)).parse(); + } + + @Test + @Ignore + //@NoEclipseLink + public void docoExamples97_10() throws Exception { + query().from(log, payment).where( + log.item.instanceOf(Payment.class), + log.item.id.eq(payment.id)).parse(); + } + + @Test + public void docoExamples97_10_2() throws Exception { + query().from(log, payment).innerJoin(log.item, item).where( + item.instanceOf(Payment.class), + item.id.eq(payment.id)).parse(); + } + + @Test + public void docoExamples98_1() throws Exception { + query().from(cat).where(cat.name.between("A", "B")).parse(); + } + + @Test + public void docoExamples98_2() throws Exception { + query().from(cat).where(cat.name.in("Foo", "Bar", "Baz")).parse(); + } + + @Test + public void docoExamples98_3() throws Exception { + query().from(cat).where(cat.name.notBetween("A", "B")).parse(); + } + + @Test + public void docoExamples98_4() throws Exception { + query().from(cat).where(cat.name.notIn("Foo", "Bar", "Baz")).parse(); + } + + @Test + public void docoExamples98_5() throws Exception { + query().from(cat).where(cat.kittens.size().gt(0)).parse(); + } + + @Test + public void docoExamples98_6() throws Exception { + query().from(mother, kit).select(mother).where(kit.in(mother.kittens)).parse(); + } + + @Test + @NoEclipseLink + public void docoExamples98_7() throws Exception { + query().from(list, p).select(p).where(p.name.eqAny(list.names)).parse(); + } + + @Test + public void docoExamples98_8() throws Exception { + query().from(cat).where(cat.kittens.isNotEmpty()).parse(); + } + + @Test + public void docoExamples98_9() throws Exception { + query().from(person, calendar).select(person).where( + calendar.holidays("national holiday").eq(person.birthDay), + person.nationality.calendar.eq(calendar)).parse(); + } + + @Test + @ExcludeIn({DERBY, HSQLDB, ORACLE}) + public void docoExamples98_10() throws Exception { + query().from(item, ord).select(item).where( + ord.items(ord.deliveredItemIndices(0)).eq(item), + ord.id.eq(1L)).parse(); + } + + @Test + @NoEclipseLink + @ExcludeIn({DERBY, HSQLDB, H2, MYSQL, ORACLE, POSTGRESQL}) + @Ignore + public void docoExamples98_11() throws Exception { + query().from(item, ord).select(item).where( + ord.items(ord.items.size().subtract(1)).eq(item)) + .parse(); + } + + @Test + @NoEclipseLink @NoOpenJPA @NoBatooJPA + @ExcludeIn({DERBY, HSQLDB, ORACLE}) + public void docoExamples98_12() throws Exception { + query() + .from(prod, store) + .innerJoin(store.customers, cust) + .select(cust) + .where( + prod.name.eq("widget"), + store.location.name.in("Melbourne", "Sydney"), + prod.eqAll(cust.currentOrder.lineItems)) + .parse(); + + } + + @Test + public void docoExamples98() throws Exception { + prod.eq(new Product()); + prod.eq(new QProduct("p")); + prod.eq(new QItem("p")); + + } + + @Test + public void docoExamples99() throws Exception { + query().from(cat).orderBy(cat.name.asc(), cat.weight.desc(), + cat.birthdate.asc()).parse(); + } + + @Test + public void doubleLiteral() throws Exception { + query().from(cat).where(cat.weight.lt((int) 3.1415)).parse(); + } + + @Test + public void doubleLiteral2() throws Exception { + query().from(cat).where(cat.weight.gt((int) 3.1415e3)).parse(); + } + + @Test + @NoOpenJPA + public void fetch() throws RecognitionException, TokenStreamException { + query().from(cat).innerJoin(cat.mate, mate).fetchJoin().parse(); + } + + @Test + @NoOpenJPA + public void fetch2() throws RecognitionException, TokenStreamException { + query().from(cat).innerJoin(cat.mate, mate).fetchJoin().fetchJoin().parse(); + } + + @Test + public void in() throws Exception { + query().from(foo).where(foo.bar.in("a", "b", "c")).parse(); + } + + @Test + public void notIn() throws Exception { + query().from(foo).where(foo.bar.notIn("a", "b", "c")).parse(); + } + + @Test + @NoEclipseLink @NoOpenJPA + public void joinFlags1() throws RecognitionException, TokenStreamException { + query().from(cat).fetchAll().parse(); + } + + @Test + @NoEclipseLink @NoOpenJPA @NoBatooJPA + public void joinFlags2() throws RecognitionException, TokenStreamException { + query().from(cat).fetchAll().from(cat1).fetchAll().parse(); + } + + @Test + @NoEclipseLink @NoOpenJPA @NoBatooJPA + public void joinFlags3() throws RecognitionException, TokenStreamException { + query().from(cat).fetchAll().from(cat1).fetchAll().parse(); + } + + @Test + public void joins() throws RecognitionException, TokenStreamException { + query().from(cat).join(cat.mate, mate).select(cat).parse(); + } + + @Test + public void innerJoin() throws RecognitionException, TokenStreamException { + query().from(cat).innerJoin(cat.mate, mate).select(cat).parse(); + } + + @Test + public void leftJoin() throws RecognitionException, TokenStreamException { + query().from(cat).leftJoin(cat.mate, mate).select(cat).parse(); + } + + @Test + @NoOpenJPA @NoBatooJPA + public void joins2() throws RecognitionException, TokenStreamException { + query().from(cat).join(cat.mate, mate).on(mate.name.eq("Bob")).parse(); + } + + @Test + public void multipleFromClasses() throws Exception { + query().from(qat, foo).parse(); + } + + @Test + public void serialization() { + QueryHelper query = query(); + + query.from(cat); + assertEquals("select cat\nfrom Cat cat", query.toString()); + + query.from(fatcat); + assertEquals("select cat\nfrom Cat cat, Cat fatcat", query.toString()); + } + + @Test + @NoEclipseLink @NoOpenJPA + @ExcludeIn(MYSQL) + public void casts_byte() throws Exception { + NumberExpression<Double> bw = cat.bodyWeight; + query().from(cat).select(bw.byteValue()).parse(); + } + + @Test + @NoOpenJPA + public void casts_double() throws Exception { + NumberExpression<Double> bw = cat.bodyWeight; + query().from(cat).select(bw.doubleValue()).parse(); + } + + @Test + @NoOpenJPA + @ExcludeIn(MYSQL) + public void casts_float() throws Exception { + NumberExpression<Double> bw = cat.bodyWeight; + query().from(cat).select(bw.floatValue()).parse(); + } + + @Test + @NoOpenJPA + @ExcludeIn(MYSQL) + public void casts_int() throws Exception { + NumberExpression<Double> bw = cat.bodyWeight; + query().from(cat).select(bw.intValue()).parse(); + } + + @Test + @NoOpenJPA + @ExcludeIn({DERBY, HSQLDB, MYSQL}) + public void casts_long() throws Exception { + NumberExpression<Double> bw = cat.bodyWeight; + query().from(cat).select(bw.longValue()).parse(); + } + + @Test + @NoEclipseLink @NoOpenJPA + @ExcludeIn(MYSQL) + public void casts_short() throws Exception { + NumberExpression<Double> bw = cat.bodyWeight; + query().from(cat).select(bw.shortValue()).parse(); + } + + @Test + @NoOpenJPA + @ExcludeIn({DERBY, HSQLDB, MYSQL}) + public void casts_string() throws Exception { + NumberExpression<Double> bw = cat.bodyWeight; + query().from(cat).select(bw.stringValue()).parse(); + } + + @Test + @NoEclipseLink @NoOpenJPA + @ExcludeIn(MYSQL) + public void casts_2() throws Exception { + NumberExpression<Double> bw = cat.bodyWeight; + query().from(cat).select(bw.castToNum(Byte.class)).parse(); + } + + @Test + @Ignore + public void groupBy() throws Exception { + query().from(qat).groupBy(qat.breed).parse(); + } + + @Test + @Ignore + public void groupBy_2() throws Exception { + query().from(qat).groupBy(qat.breed, qat.eyecolor).parse(); + } + + @Test + public void not() throws Exception { + query().from(cat).where(cat.kittens.size().lt(1).not()).parse(); + } + + @Test + public void not_2() throws Exception { + query().from(cat).where(cat.kittens.size().gt(1).not()).parse(); + } + + @Test + public void not_3() throws Exception { + query().from(cat).where(cat.kittens.size().goe(1).not()).parse(); + } + + @Test + public void not_4() throws Exception { + query().from(cat).where(cat.kittens.size().loe(1).not()).parse(); + } + + @Test + public void not_5() throws Exception { + query().from(cat).where(cat.name.between("A", "B").not()).parse(); + } + + @Test + public void not_6() throws Exception { + query().from(cat).where(cat.name.notBetween("A", "B").not()).parse(); + } + + @Test + public void not_7() throws Exception { + query().from(cat).where(cat.kittens.size().loe(1).not().not()).parse(); + } + + @Test + public void not_8() throws Exception { + query().from(cat).where(cat.kittens.size().loe(1).not().not().not()).parse(); + } + + + @Test + @Ignore + public void orderBy() throws Exception { + // NOT SUPPORTED + query().from(qat).orderBy(qat.toes.avg().asc()).parse(); + } + + @Test + @NoOpenJPA + public void orderBy_2() throws Exception { + query().from(an).orderBy(an.bodyWeight.sqrt().divide(2.0).asc()).parse(); + } + + @Test + public void select1() throws Exception { +// query().select(Ops.AggOps.COUNT_ALL_AGG_EXPR).from(qat).parse(); + + query().from(qat).select(qat.weight.avg()).parse(); + } + + @Test + @Ignore + public void sum() throws RecognitionException, TokenStreamException { + // NOT SUPPORTED + query().from(cat).select(cat.kittens.size().sum()).parse(); + } + + @Test + @Ignore + public void sum_2() throws RecognitionException, TokenStreamException { + // NOT SUPPORTED + query().from(cat).where(cat.kittens.size().sum().gt(0)).select(cat).parse(); + } + + @Test + public void sum_3() throws RecognitionException, TokenStreamException { + query().from(cat).where(cat.kittens.isEmpty()).select(cat).parse(); + } + + @Test + public void sum_4() throws RecognitionException, TokenStreamException { + query().from(cat).where(cat.kittens.isNotEmpty()).select(cat).parse(); + } + + @Test + public void where() throws Exception { + query().from(qat).where(qat.name.in("crater", "bean", "fluffy")).parse(); + } + + @Test + public void where_2() throws Exception { + query().from(qat).where(qat.name.notIn("crater", "bean", "fluffy")).parse(); + } + + @Test + public void where_3() throws Exception { + query().from(an).where(an.bodyWeight.sqrt().gt(10.0)).parse(); + } + + @Test + public void where_4() throws Exception { + query().from(an).where(an.bodyWeight.sqrt().divide(2d).gt(10.0)).parse(); + } + + @Test + public void where_5() throws Exception { + query().from(an).where( + an.bodyWeight.gt(10), + an.bodyWeight.lt(100).or(an.bodyWeight.isNull())) + .parse(); + } + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/Person.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/Person.java new file mode 100644 index 0000000000..f3476a96b3 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/Person.java @@ -0,0 +1,7 @@ +package com.querydsl.jpa; + + +public class Person { + + String firstName, lastName; +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/Projection.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/Projection.java new file mode 100644 index 0000000000..7db9108c7d --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/Projection.java @@ -0,0 +1,11 @@ +package com.querydsl.jpa; + +import com.querydsl.jpa.domain.Cat; + +public class Projection { + + public Projection(String str, Cat cat) { } + + public Projection(int i, boolean b) { } + +} \ No newline at end of file diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/QArticle.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/QArticle.java new file mode 100644 index 0000000000..9b48d6056d --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/QArticle.java @@ -0,0 +1,55 @@ +package com.querydsl.jpa; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.EntityPathBase; +import com.querydsl.core.types.dsl.PathInits; +import com.querydsl.core.types.dsl.StringPath; + + +/** + * QArticle is a Querydsl query type for Article + */ +@Generated("com.querydsl.codegen.EntitySerializer") +public class QArticle extends EntityPathBase<Article> { + + private static final long serialVersionUID = 1732636838L; + + private static final PathInits INITS = PathInits.DIRECT2; + + public static final QArticle article = new QArticle("article"); + + public final QPerson author; + + public final QContent content; + + public final StringPath name = createString("name"); + + public QArticle(String variable) { + this(Article.class, forVariable(variable), INITS); + } + + public QArticle(Path<? extends Article> path) { + this(path.getType(), path.getMetadata(), path.getMetadata().isRoot() ? INITS : PathInits.DEFAULT); + } + + public QArticle(PathMetadata metadata) { + this(metadata, metadata.isRoot() ? INITS : PathInits.DEFAULT); + } + + public QArticle(PathMetadata metadata, PathInits inits) { + this(Article.class, metadata, inits); + } + + public QArticle(Class<? extends Article> type, PathMetadata metadata, PathInits inits) { + super(type, metadata, inits); + this.author = inits.isInitialized("author") ? new QPerson(forProperty("author")) : null; + this.content = inits.isInitialized("content") ? new QContent(forProperty("content"), inits.get("content")) : null; + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/QContent.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/QContent.java new file mode 100644 index 0000000000..1ef2c49df1 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/QContent.java @@ -0,0 +1,49 @@ +package com.querydsl.jpa; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.BeanPath; +import com.querydsl.core.types.dsl.PathInits; + + +/** + * QContent is a Querydsl query type for Content + */ +@Generated("com.querydsl.codegen.EmbeddableSerializer") +public class QContent extends BeanPath<Content> { + + private static final long serialVersionUID = -878421975L; + + private static final PathInits INITS = PathInits.DIRECT2; + + public static final QContent content = new QContent("content"); + + public final QArticle article; + + public QContent(String variable) { + this(Content.class, forVariable(variable), INITS); + } + + public QContent(Path<? extends Content> path) { + this(path.getType(), path.getMetadata(), path.getMetadata().isRoot() ? INITS : PathInits.DEFAULT); + } + + public QContent(PathMetadata metadata) { + this(metadata, metadata.isRoot() ? INITS : PathInits.DEFAULT); + } + + public QContent(PathMetadata metadata, PathInits inits) { + this(Content.class, metadata, inits); + } + + public QContent(Class<? extends Content> type, PathMetadata metadata, PathInits inits) { + super(type, metadata, inits); + this.article = inits.isInitialized("article") ? new QArticle(forProperty("article"), inits.get("article")) : null; + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/QPerson.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/QPerson.java new file mode 100644 index 0000000000..c760fc4613 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/QPerson.java @@ -0,0 +1,40 @@ +package com.querydsl.jpa; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.EntityPathBase; +import com.querydsl.core.types.dsl.StringPath; + + +/** + * QPerson is a Querydsl query type for Person + */ +@Generated("com.querydsl.codegen.EntitySerializer") +public class QPerson extends EntityPathBase<Person> { + + private static final long serialVersionUID = -219463259L; + + public static final QPerson person = new QPerson("person"); + + public final StringPath firstName = createString("firstName"); + + public final StringPath lastName = createString("lastName"); + + public QPerson(String variable) { + super(Person.class, forVariable(variable)); + } + + public QPerson(Path<? extends Person> path) { + super(path.getType(), path.getMetadata()); + } + + public QPerson(PathMetadata metadata) { + super(Person.class, metadata); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/QProjection.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/QProjection.java new file mode 100644 index 0000000000..1c48505621 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/QProjection.java @@ -0,0 +1,25 @@ +package com.querydsl.jpa; + +import com.querydsl.core.types.ConstructorExpression; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.dsl.BooleanExpression; +import com.querydsl.core.types.dsl.NumberExpression; +import com.querydsl.core.types.dsl.StringExpression; +import com.querydsl.jpa.domain.Cat; +import com.querydsl.jpa.domain.QCat; + +public class QProjection extends ConstructorExpression<Projection> { + + private static final long serialVersionUID = -5866362075090550839L; + + public QProjection(StringExpression str, QCat cat) { + super(Projection.class, + new Class<?>[]{String.class, Cat.class}, new Expression[]{str, cat}); + } + + public QProjection(NumberExpression<Integer> i, BooleanExpression b) { + super(Projection.class, + new Class<?>[]{int.class, boolean.class}, new Expression[]{i, b}); + } + +} \ No newline at end of file diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/QueryHandlerTest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/QueryHandlerTest.java similarity index 87% rename from querydsl-jpa/src/test/java/com/mysema/query/jpa/QueryHandlerTest.java rename to querydsl-jpa/src/test/java/com/querydsl/jpa/QueryHandlerTest.java index 5b48f887d1..04e1e23ebb 100644 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/QueryHandlerTest.java +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/QueryHandlerTest.java @@ -1,13 +1,13 @@ -package com.mysema.query.jpa; +package com.querydsl.jpa; import static org.junit.Assert.assertEquals; import org.junit.Test; public class QueryHandlerTest { - + @Test - public void Types() { + public void types() { assertEquals(EclipseLinkHandler.class, EclipseLinkTemplates.DEFAULT.getQueryHandler().getClass()); assertEquals(HibernateHandler.class, HQLTemplates.DEFAULT.getQueryHandler().getClass()); assertEquals(DefaultQueryHandler.class, JPQLTemplates.DEFAULT.getQueryHandler().getClass()); diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/QueryHelper.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/QueryHelper.java new file mode 100644 index 0000000000..0c8b26e48d --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/QueryHelper.java @@ -0,0 +1,115 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import static org.junit.Assert.assertEquals; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.util.logging.Logger; + +import org.jetbrains.annotations.Nullable; + +import org.hibernate.hql.internal.ast.HqlParser; + +import com.mysema.commons.lang.CloseableIterator; +import com.querydsl.core.DefaultQueryMetadata; +import com.querydsl.core.NonUniqueResultException; +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.QueryResults; +import com.querydsl.core.Tuple; +import com.querydsl.core.types.Expression; + +import antlr.RecognitionException; +import antlr.TokenStreamException; +import antlr.collections.AST; + +class QueryHelper<T> extends JPAQueryBase<T, QueryHelper<T>> { + + private static final Logger logger = Logger.getLogger(QueryHelper.class.getName()); + + QueryHelper(JPQLTemplates templates) { + this(new DefaultQueryMetadata(), templates); + } + + QueryHelper(QueryMetadata metadata, JPQLTemplates templates) { + super(metadata, templates); + } + + @Override + protected JPQLSerializer createSerializer() { + return new JPQLSerializer(getTemplates()); + } + + @Override + protected void reset() { + // do nothing + } + + public long fetchCount() { + return 0; + } + + + @Nullable + public CloseableIterator<T> iterate() { + throw new UnsupportedOperationException(); + } + + @Nullable + public QueryResults<T> fetchResults() { + throw new UnsupportedOperationException(); + } + + public void parse() throws RecognitionException, TokenStreamException { + String input = toString(); + logger.fine("input: " + input.replace('\n', ' ')); + HqlParser parser = HqlParser.getInstance(input); + parser.setFilter(false); + parser.statement(); + AST ast = parser.getAST(); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + parser.showAst(ast, new PrintStream(baos)); + assertEquals("At least one error occurred during parsing " + input, + 0, parser.getParseErrorHandler().getErrorCount()); + } + + @Override + public T fetchOne() throws NonUniqueResultException { + throw new UnsupportedOperationException(); + } + + @Override + public QueryHelper<T> clone() { + return new QueryHelper<T>(getMetadata().clone(), getTemplates()); + } + + + @Override + public <U> QueryHelper<U> select(Expression<U> expr) { + queryMixin.setProjection(expr); + @SuppressWarnings("unchecked") // This is the new type + QueryHelper<U> newType = (QueryHelper<U>) this; + return newType; + } + + @Override + public QueryHelper<Tuple> select(Expression<?>... exprs) { + queryMixin.setProjection(exprs); + @SuppressWarnings("unchecked") // This is the new type + QueryHelper<Tuple> newType = (QueryHelper<Tuple>) this; + return newType; + } + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/QueryMutabilityTest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/QueryMutabilityTest.java new file mode 100644 index 0000000000..2aaa446545 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/QueryMutabilityTest.java @@ -0,0 +1,65 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import static org.junit.Assert.assertEquals; + +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; + +import org.hibernate.Session; +import org.junit.Ignore; +import org.junit.Test; + +import com.querydsl.core.QueryMutability; +import com.querydsl.jpa.domain.sql.SAnimal; +import com.querydsl.jpa.hibernate.sql.HibernateSQLQuery; +import com.querydsl.sql.DerbyTemplates; +import com.querydsl.sql.SQLTemplates; + +public class QueryMutabilityTest { + + private static final SQLTemplates derbyTemplates = new DerbyTemplates(); + + private Session session; + + protected HibernateSQLQuery<?> query() { + return new HibernateSQLQuery<Void>(session, derbyTemplates); + } + + public void setSession(Session session) { + this.session = session; + } + + @Test + @Ignore + public void queryMutability() throws SecurityException, IllegalArgumentException, + NoSuchMethodException, IllegalAccessException, + InvocationTargetException, IOException { + SAnimal cat = new SAnimal("cat"); + HibernateSQLQuery<?> query = query().from(cat); + new QueryMutability(query).test(cat.id, cat.name); + } + + @Test + public void clone_() { + SAnimal cat = new SAnimal("cat"); + HibernateSQLQuery<?> query = query().from(cat).where(cat.name.isNotNull()); + HibernateSQLQuery<?> query2 = query.clone(session); + assertEquals(query.getMetadata().getJoins(), query2.getMetadata().getJoins()); + assertEquals(query.getMetadata().getWhere(), query2.getMetadata().getWhere()); + //query2.fetch(cat.id); + } + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/QueryPerformanceTest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/QueryPerformanceTest.java new file mode 100644 index 0000000000..cbc79d3710 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/QueryPerformanceTest.java @@ -0,0 +1,106 @@ +package com.querydsl.jpa; + +import static org.junit.Assert.assertNotNull; + +import javax.persistence.EntityManager; + +import org.junit.*; +import org.junit.experimental.categories.Category; +import org.junit.runner.RunWith; + +import com.querydsl.core.Target; +import com.querydsl.core.Tuple; +import com.querydsl.core.testutil.Performance; +import com.querydsl.jpa.domain.Cat; +import com.querydsl.jpa.domain.QCat; +import com.querydsl.jpa.impl.JPAQuery; +import com.querydsl.jpa.testutil.JPATestRunner; + +@RunWith(JPATestRunner.class) +@Ignore +@Category(Performance.class) +public class QueryPerformanceTest implements JPATest { + + private static final int iterations = 1000; + + private EntityManager entityManager; + + @BeforeClass + public static void setUpClass() { + Mode.mode.set("h2perf"); + Mode.target.set(Target.H2); + } + + @AfterClass + public static void tearDownClass() { + Mode.mode.remove(); + Mode.target.remove(); + } + + private JPAQuery<?> query() { + return new JPAQuery<Void>(entityManager); + } + + @Before + public void setUp() { + if (query().from(QCat.cat).fetchCount() == 0) { + for (int i = 0; i < iterations; i++) { + entityManager.persist(new Cat(String.valueOf(i), i + 100)); + } + entityManager.flush(); + } + } + + @Test + public void byId_raw() { + long start = System.currentTimeMillis(); + for (int i = 0; i < iterations; i++) { + Cat cat = (Cat) entityManager.createQuery("select cat from Cat cat where id = ?") + .setParameter(1, i + 100).getSingleResult(); + assertNotNull(cat); + } + System.err.println("by id - raw" + (System.currentTimeMillis() - start)); + } + + @Test + public void byId_qdsl() { + long start = System.currentTimeMillis(); + for (int i = 0; i < iterations; i++) { + QCat cat = QCat.cat; + Cat c = query().from(cat).where(cat.id.eq(i + 100)).select(cat).fetchOne(); + assertNotNull(c); + } + System.err.println("by id - dsl" + (System.currentTimeMillis() - start)); + } + + @Test + public void byId_twoCols_raw() { + long start = System.currentTimeMillis(); + for (int i = 0; i < iterations; i++) { + Object[] row = (Object[]) entityManager.createQuery( + "select cat.id, cat.name from Cat cat where id = ?") + .setParameter(1, i + 100).getSingleResult(); + assertNotNull(row); + } + System.err.println("by id - 2 cols - raw" + (System.currentTimeMillis() - start)); + } + + @Test + public void byId_twoCols_qdsl() { + long start = System.currentTimeMillis(); + for (int i = 0; i < iterations; i++) { + QCat cat = QCat.cat; + Tuple row = query().from(cat).where(cat.id.eq(i + 100)).select(cat.id, cat.name).fetchOne(); + assertNotNull(row); + } + System.err.println("by id - 2 cols - dsl" + (System.currentTimeMillis() - start)); + } + + + @Override + public void setEntityManager(EntityManager entityManager) { + this.entityManager = entityManager; + } + + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/RelationalFunctionCallTest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/RelationalFunctionCallTest.java new file mode 100644 index 0000000000..400d9631a1 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/RelationalFunctionCallTest.java @@ -0,0 +1,63 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import static com.querydsl.sql.SQLExpressions.select; +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import com.querydsl.core.types.PathMetadataFactory; +import com.querydsl.core.types.SubQueryExpression; +import com.querydsl.core.types.dsl.PathBuilder; +import com.querydsl.core.types.dsl.StringPath; +import com.querydsl.sql.*; + +public class RelationalFunctionCallTest { + +// @Schema("PUBLIC") +// @Table("SURVEY") + public class QSurvey extends RelationalPathBase<QSurvey> { + + private static final long serialVersionUID = -7427577079709192842L; + + public final StringPath name = createString("NAME"); + + public QSurvey(String path) { + super(QSurvey.class, PathMetadataFactory.forVariable(path), "PUBLIC", "SURVEY"); + } + + } + + @Test + public void functionCall() { + //select tab.col from Table tab join TableValuedFunction('parameter') func on tab.col not like func.col + + QSurvey table = new QSurvey("SURVEY"); + RelationalFunctionCall<String> func = SQLExpressions.relationalFunctionCall(String.class, "TableValuedFunction", "parameter"); + PathBuilder<String> funcAlias = new PathBuilder<String>(String.class, "tokFunc"); + SubQueryExpression<?> expr = select(table.name).from(table) + .join(func, funcAlias).on(table.name.like(funcAlias.getString("prop")).not()); + + Configuration conf = new Configuration(new SQLServerTemplates()); + SQLSerializer serializer = new NativeSQLSerializer(conf, true); + serializer.serialize(expr.getMetadata(), false); + assertEquals("select SURVEY.NAME\n" + + "from SURVEY SURVEY\n" + + "join TableValuedFunction(?1) as tokFunc\n" + + "on not (SURVEY.NAME like tokFunc.prop escape '\\')", serializer.toString()); + + } + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/SerializationBase.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/SerializationBase.java new file mode 100644 index 0000000000..5b8c8c196e --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/SerializationBase.java @@ -0,0 +1,101 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import static org.junit.Assert.*; + +import java.io.*; + +import javax.persistence.EntityManager; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.testutil.Serialization; +import com.querydsl.core.types.Predicate; +import com.querydsl.jpa.domain.QCat; +import com.querydsl.jpa.impl.JPAQuery; +import com.querydsl.jpa.testutil.JPATestRunner; + +@RunWith(JPATestRunner.class) +public class SerializationBase implements JPATest { + + private QCat cat = QCat.cat; + + private EntityManager entityManager; + + @Test + public void test() throws IOException, ClassNotFoundException { + // create query + JPAQuery<?> query = query(); + query.from(cat).where(cat.name.eq("Kate")).select(cat).fetch(); + + QueryMetadata metadata = query.getMetadata(); + assertFalse(metadata.getJoins().isEmpty()); + assertTrue(metadata.getWhere() != null); + assertTrue(metadata.getProjection() != null); + QueryMetadata metadata2 = Serialization.serialize(metadata); + + // validate it + assertEquals(metadata.getJoins(), metadata2.getJoins()); + assertEquals(metadata.getWhere(), metadata2.getWhere()); + assertEquals(metadata.getProjection(), metadata2.getProjection()); + + // create new query + JPAQuery<?> query2 = new JPAQuery<Void>(entityManager, metadata2); + assertEquals("select cat\nfrom Cat cat\nwhere cat.name = ?1", query2.toString()); + query2.select(cat).fetch(); + } + + @Test + public void any_serialized() throws Exception { + Predicate where = cat.kittens.any().name.eq("Ruth234"); + Predicate where2 = Serialization.serialize(where); + + assertEquals(0, query().from(cat).where(where).fetchCount()); + assertEquals(0, query().from(cat).where(where2).fetchCount()); + } + + @Test + public void any_serialized2() throws Exception { + Predicate where = cat.kittens.any().name.eq("Ruth234"); + + File file = new File("target", "predicate.ser"); + if (!file.exists()) { + // serialize predicate on first run + FileOutputStream fileOutputStream = new FileOutputStream(file); + ObjectOutputStream out = new ObjectOutputStream(fileOutputStream); + out.writeObject(where); + out.close(); + assertEquals(0, query().from(cat).where(where).fetchCount()); + } else { + // deserialize predicate on second run + FileInputStream fileInputStream = new FileInputStream(file); + ObjectInputStream in = new ObjectInputStream(fileInputStream); + Predicate where2 = (Predicate) in.readObject(); + in.close(); + assertEquals(0, query().from(cat).where(where2).fetchCount()); + } + } + + private JPAQuery<?> query() { + return new JPAQuery<Void>(entityManager); + } + + @Override + public void setEntityManager(EntityManager entityManager) { + this.entityManager = entityManager; + } +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/SignatureTest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/SignatureTest.java new file mode 100644 index 0000000000..3bc5f24873 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/SignatureTest.java @@ -0,0 +1,35 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import org.junit.Test; + +import com.querydsl.core.FilteredClause; +import com.querydsl.jpa.hibernate.HibernateQuery; +import com.querydsl.jpa.impl.JPAQuery; + +public class SignatureTest { + + @Test + public void test() { + meet((JPAQuery) null); + meet((HibernateQuery) null); + meet((JPQLQuery) null); + } + + public static <T extends FilteredClause<? super T>> T meet(T query) { + return null; + } + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/StringOperationsTest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/StringOperationsTest.java new file mode 100644 index 0000000000..87697bb38d --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/StringOperationsTest.java @@ -0,0 +1,65 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import static com.querydsl.jpa.Constants.*; + +import org.junit.Test; + +import com.querydsl.core.domain.QCat; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.Ops; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.StringPath; + +public class StringOperationsTest extends AbstractQueryTest { + + @Test + public void stringConcatenations() { + assertToString("concat(cat.name,kitten.name)", cat.name.concat(kitten.name)); + } + + @Test + public void stringConversionOperations() { + assertToString("str(cat.bodyWeight)", cat.bodyWeight.stringValue()); + } + + @Test + public void stringOperationsInFunctionalWay() { + assertToString("concat(cat.name,cust.name.firstName)", cat.name.concat(cust.name.firstName)); + assertToString("lower(cat.name)", cat.name.lower()); + } + + @Test + @SuppressWarnings("rawtypes") + public void indexOf() { + Path path = QCat.cat.name; + Expression startIndex = Expressions.constant(0); + Expression endIndex = Expressions.numberOperation(Integer.class, Ops.INDEX_OF, path, Expressions.constant("x")); + Expression substr = Expressions.stringOperation(Ops.SUBSTR_2ARGS, path, startIndex, endIndex); + assertToString("substring(cat.name,1,locate(?1,cat.name)-1 - ?2)", substr); + } + + @Test + public void indexOf2() { + StringPath str = QCat.cat.name; + assertToString("substring(cat.name,1,locate(?1,cat.name)-1 - ?2)", str.substring(0, str.indexOf("x"))); + } + + @Test + public void indexOf3() { + assertToString("substring(cat.name,2,1)", QCat.cat.name.substring(1,2)); + } +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/SubQueryTest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/SubQueryTest.java new file mode 100644 index 0000000000..6c580f11ac --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/SubQueryTest.java @@ -0,0 +1,194 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import static com.querydsl.jpa.Constants.*; +import static com.querydsl.jpa.JPAExpressions.*; +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import com.querydsl.core.domain.QCat; +import com.querydsl.jpa.domain.QEmployee; +import com.querydsl.jpa.domain.QUser; + +public class SubQueryTest extends AbstractQueryTest { + + @Test + public void single_source() { + JPQLQuery<?> query = selectFrom(cat); + assertEquals("select cat\nfrom Cat cat", query.toString()); + } + + @Test + public void multiple_sources() { + JPQLQuery<?> query = select(cat).from(cat, fatcat); + assertEquals("select cat\nfrom Cat cat, Cat fatcat", + query.toString()); + } + + @Test + public void in() { + cat.in(selectFrom(cat)); + } + + @Test + public void innerJoin() { + assertEquals("select cat\nfrom Cat cat\n inner join cat.mate", + selectFrom(cat).innerJoin(cat.mate).toString()); + } + + @Test + public void innerJoin2() { + QEmployee employee = QEmployee.employee; + QUser user = QUser.user; + assertEquals("select employee\nfrom Employee employee\n inner join employee.user as user", + selectFrom(employee).innerJoin(employee.user, user).toString()); + } + + @Test + public void leftJoin() { + assertEquals("select cat\nfrom Cat cat\n left join cat.mate", + selectFrom(cat).leftJoin(cat.mate).toString()); + } + + @Test + public void join() { + assertEquals("select cat\nfrom Cat cat\n inner join cat.mate", + selectFrom(cat).join(cat.mate).toString()); + } + + @Test + public void uniqueProjection() { + assertToString("(select cat from Cat cat)", + selectFrom(cat)); + } + + @Test + public void listProjection() { + assertToString("(select cat from Cat cat)", + selectFrom(cat)); + } + + @Test + public void listContains() { + assertToString("cat in (select cat from Cat cat)", + cat.in(selectFrom(cat))); + } + + @Test + public void exists() { + assertToString("exists (select 1 from Cat cat)", + selectOne().from(cat).exists()); + } + + @Test + public void exists_where() { + assertToString("exists (select 1 from Cat cat where cat.weight < ?1)", + selectFrom(cat).where(cat.weight.lt(1)).exists()); + } + + @Test + public void exists_via_unique() { + assertToString("exists (select 1 from Cat cat where cat.weight < ?1)", + selectOne().from(cat).where(cat.weight.lt(1)).exists()); + } + + @Test + public void notExists() { + assertToString("not exists (select 1 from Cat cat)", + selectOne().from(cat).notExists()); + } + + @Test + public void notExists_where() { + assertToString("not exists (select 1 from Cat cat where cat.weight < ?1)", + selectOne().from(cat).where(cat.weight.lt(1)).notExists()); + } + + @Test + public void notExists_via_unique() { + assertToString("not exists (select 1 from Cat cat where cat.weight < ?1)", + selectOne().from(cat).where(cat.weight.lt(1)).notExists()); + } + + @Test + public void count() { + assertToString("(select count(cat) from Cat cat)", + select(cat.count()).from(cat)); + } + + @Test + public void count_via_list() { + assertToString("(select count(cat) from Cat cat)", + select(cat.count()).from(cat)); + } + + @Test + public void count_name() { + assertToString("(select count(cat.name) from Cat cat)", + select(cat.name.count()).from(cat)); + } + + @Test + public void count_multiple_sources() { + QCat other = new QCat("other"); + assertToString("(select count(cat) from Cat cat, Cat other)", + + select(cat.count()).from(cat, other)); + } + + @Test + public void count_multiple_sources_via_list() { + QCat other = new QCat("other"); + assertToString("(select count(cat) from Cat cat, Cat other)", + + select(cat.count()).from(cat, other)); + } + + @Test + public void indexed_access() { + assertMatches("\\(select count\\(cat\\) from Cat cat " + + "left join cat.kittens as cat_kittens_\\w+ " + + "with index\\(cat_kittens_\\w+\\) = \\?1 where cat_kittens_\\w+.name = \\?2\\)", + + select(cat.count()).from(cat).where(cat.kittens.get(0).name.eq("Kate"))); + } + + @Test + public void indexed_access_without_constant() { + assertMatches("\\(select count\\(cat\\) from Cat cat " + + "left join cat.kittens as cat_kittens_\\w+ " + + "with index\\(cat_kittens_\\w+\\) = cat.id where cat_kittens_\\w+.name = \\?1\\)", + + select(cat.count()).from(cat).where(cat.kittens.get(cat.id).name.eq("Kate"))); + } + + @Test + public void indexOf() { + assertToString("(select count(cat) from Cat cat where locate(?1,cat.name)-1 = ?2)", + select(cat.count()).from(cat).where(cat.name.indexOf("a").eq(1))); + } + +// @Test +// public void orderBy() { +// JPQLQuery<Void> query = query().from(cat1).where(cat1.alive); +// SubQueryExpression<Double> subquery = sub().from(cat).where(cat.mate.id.eq(cat1.id)).select(cat.floatProperty.avg()); +// query.orderBy(subquery.subtract(-1.0f).asc()); +// +// assertEquals("select cat1 from Cat cat1 where cat1.alive order by (select avg(cat.floatProperty) from Cat cat where cat.mate.id = cat1.id) - ?1 asc", +// query.toString().replace("\n", " ")); +// } + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/TargetRule.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/TargetRule.java new file mode 100644 index 0000000000..07755bf889 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/TargetRule.java @@ -0,0 +1,41 @@ +package com.querydsl.jpa; + +import java.util.Arrays; + +import org.junit.rules.TestRule; +import org.junit.runner.Description; +import org.junit.runners.model.Statement; + +import com.querydsl.core.Target; +import com.querydsl.core.testutil.EmptyStatement; +import com.querydsl.core.testutil.ExcludeIn; +import com.querydsl.core.testutil.IncludeIn; + +/** + * @author tiwe + * + */ +public class TargetRule implements TestRule { + + @Override + public Statement apply(Statement base, Description description) { + Target target = Mode.target.get(); + boolean run = target == null || isExecuted(description, target); + return run ? base : EmptyStatement.DEFAULT; + } + + private boolean isExecuted(Description description, Target target) { + ExcludeIn ex = description.getAnnotation(ExcludeIn.class); + // excluded in given targets + if (ex != null && Arrays.asList(ex.value()).contains(target)) { + return false; + } + // included only in given targets + IncludeIn in = description.getAnnotation(IncludeIn.class); + if (in != null && !Arrays.asList(in.value()).contains(target)) { + return false; + } + return true; + } + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/TemplatesTest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/TemplatesTest.java new file mode 100644 index 0000000000..9360228cde --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/TemplatesTest.java @@ -0,0 +1,22 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team). + * + * 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. + */ +package com.querydsl.jpa; + +import com.querydsl.core.TemplatesTestBase; + +public class TemplatesTest extends TemplatesTestBase { + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/TupleTest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/TupleTest.java new file mode 100644 index 0000000000..8249fa94be --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/TupleTest.java @@ -0,0 +1,44 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import static com.querydsl.jpa.JPAExpressions.select; + +import org.junit.Ignore; +import org.junit.Test; + +import com.querydsl.core.types.Projections; +import com.querydsl.core.types.SubQueryExpression; +import com.querydsl.jpa.domain.QCat; + +public class TupleTest extends AbstractQueryTest { + + @Test + @Ignore // FIXME + public void test() { + QCat cat = QCat.cat; + + SubQueryExpression<?> subQuery = select(cat.birthdate, cat.name, cat.mate).from(cat) + .where(select(cat.mate, cat.birthdate.max()) + .from(cat) + .groupBy(cat.mate) + .contains(Projections.tuple(cat.mate, cat.birthdate))); + + assertToString( + "(select cat.birthdate, cat.name, cat.mate from Cat cat " + + "where (cat.mate, cat.birthdate) in " + + "(select cat.mate, max(cat.birthdate) from Cat cat group by cat.mate))", subQuery); + } + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/TypeCastTest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/TypeCastTest.java new file mode 100644 index 0000000000..b6d744d10a --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/TypeCastTest.java @@ -0,0 +1,74 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import com.querydsl.jpa.domain.*; + +public class TypeCastTest { + + @Test + public void mappedSuperclass() { + QInheritedProperties subClass = QInheritedProperties.inheritedProperties; + QSuperclass superClass = subClass._super; + + assertEquals(InheritedProperties.class, superClass.getType()); +// assertEquals(InheritedProperties.class.getSimpleName(), superClass.getEntityName()); + assertEquals("inheritedProperties", superClass.toString()); + } + +// @Test +// public void mappedSuperclass2() { +// QInheritedProperties subClass = QInheritedProperties.inheritedProperties; +// QSuperclass superClass = new QSuperclass(subClass.getMetadata()); +// +// assertEquals(Superclass.class, superClass.getType()); +// assertEquals(Superclass.class.getSimpleName(), superClass.getEntityName()); +// assertEquals("inheritedProperties", superClass.toString()); +// } + + @Test + public void subClassToSuper() { + QCat cat = QCat.cat; + QAnimal animal = new QAnimal(cat); + + assertEquals(Cat.class, animal.getType()); +// assertEquals(Cat.class.getSimpleName(), animal.getEntityName()); + assertEquals("cat", animal.toString()); + } + + @Test + public void subClassToSuper2() { + QCat cat = QCat.cat; + QAnimal animal = new QAnimal(cat.getMetadata()); + + assertEquals(Animal.class, animal.getType()); +// assertEquals(Animal.class.getSimpleName(), animal.getEntityName()); + assertEquals("cat", animal.toString()); + } + + @Test + public void superClassToSub() { + QAnimal animal = QAnimal.animal; + QCat cat = new QCat(animal.getMetadata()); + + assertEquals(Cat.class, cat.getType()); +// assertEquals(Cat.class.getSimpleName(), cat.getEntityName()); + assertEquals("animal", cat.toString()); + } + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/UniqueResultsTest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/UniqueResultsTest.java new file mode 100644 index 0000000000..4c400688e7 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/UniqueResultsTest.java @@ -0,0 +1,56 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa; + +import static com.querydsl.jpa.domain.QCat.cat; +import static org.junit.Assert.assertEquals; + +import org.hibernate.Session; +import org.junit.Ignore; +import org.junit.Test; +import org.junit.runner.RunWith; + +import com.querydsl.jpa.domain.Cat; +import com.querydsl.jpa.hibernate.HibernateQuery; +import com.querydsl.jpa.testutil.HibernateTestRunner; + +@Ignore +@RunWith(HibernateTestRunner.class) +public class UniqueResultsTest implements HibernateTest { + + private Session session; + + @Test + public void test() { + session.save(new Cat("Bob1", 1)); + session.save(new Cat("Bob2", 2)); + session.save(new Cat("Bob3", 3)); + + assertEquals(Integer.valueOf(1), query().from(cat).orderBy(cat.name.asc()).offset(0).limit(1).select(cat.id).fetchOne()); + assertEquals(Integer.valueOf(2), query().from(cat).orderBy(cat.name.asc()).offset(1).limit(1).select(cat.id).fetchOne()); + assertEquals(Integer.valueOf(3), query().from(cat).orderBy(cat.name.asc()).offset(2).limit(1).select(cat.id).fetchOne()); + + assertEquals(Long.valueOf(3), query().from(cat).select(cat.count()).fetchOne()); + } + + private HibernateQuery<?> query() { + return new HibernateQuery<Void>(session); + } + + @Override + public void setSession(Session session) { + this.session = session; + } + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Account.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Account.java new file mode 100644 index 0000000000..3c2ade9269 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Account.java @@ -0,0 +1,62 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.domain; + +import static org.junit.Assert.fail; + +import java.io.Serializable; + +import javax.persistence.*; + +import org.junit.Test; + +import com.querydsl.core.annotations.QueryInit; + +/** + * The Class Account. + */ +@SuppressWarnings("serial") +@Entity +@Table(name = "account_") +public class Account implements Serializable { + + @Transient + public int transientField; + + @Id + long id; + + @ManyToOne + @QueryInit("pid") + Person owner; + + @Embedded + EmbeddedType embeddedData; + + @Test + public void test() { + try { + QAccount.class.getField("serialVersionUID"); + fail("Got serialVersionUID"); + } catch (Exception e) { + // expected + } + try { + QAccount.class.getField("transientField"); + fail("Got transientField"); + } catch (Exception e) { + // expected + } + } +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Animal.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Animal.java new file mode 100644 index 0000000000..980450d6d6 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Animal.java @@ -0,0 +1,148 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.domain; + +import java.util.Date; + +import javax.persistence.*; + +import org.hibernate.annotations.Type; + +/** + * The Class Animal. + */ +@Entity +@Table(name = "animal_") +@DiscriminatorValue("A") +public class Animal { + private boolean alive; + + @Temporal(TemporalType.TIMESTAMP) + private java.util.Date birthdate; + + private int weight, toes; + + // needed for JPA tests + @Type(type = "com.querydsl.jpa.ExtDoubleType") + private double bodyWeight; + + private float floatProperty; + + private Color color; + +// @Temporal(TemporalType.DATE) + private java.sql.Date dateField; + + @Id + private int id; + + private String name; + + private java.sql.Time timeField; + + public Animal() { } + + public Animal(int id) { + setId(id); + } + + public java.util.Date getBirthdate() { + return new Date(birthdate.getTime()); + } + + public double getBodyWeight() { + return bodyWeight; + } + + public Color getColor() { + return color; + } + + public java.sql.Date getDateField() { + return new java.sql.Date(dateField.getTime()); + } + + public int getId() { + return id; + } + + public String getName() { + return name; + } + + public java.sql.Time getTimeField() { + return timeField; + } + + public int getToes() { + return toes; + } + + public int getWeight() { + return weight; + } + + public boolean isAlive() { + return alive; + } + + public void setAlive(boolean alive) { + this.alive = alive; + } + + public void setBirthdate(java.util.Date birthdate) { + this.birthdate = new java.util.Date(birthdate.getTime()); + } + + public void setBodyWeight(double bodyWeight) { + this.bodyWeight = bodyWeight; + } + + public void setColor(Color color) { + this.color = color; + } + + public void setDateField(java.sql.Date dateField) { + this.dateField = new java.sql.Date(dateField.getTime()); + } + + public void setId(int id) { + this.id = id; + } + + public void setName(String name) { + this.name = name; + } + + public void setTimeField(java.sql.Time timeField) { + this.timeField = timeField; + } + + public void setToes(int toes) { + this.toes = toes; + } + + public void setWeight(int weight) { + this.weight = weight; + } + + public float getFloatProperty() { + return floatProperty; + } + + public void setFloatProperty(float floatProperty) { + this.floatProperty = floatProperty; + } + +} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/AuditLog.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/AuditLog.java similarity index 85% rename from querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/AuditLog.java rename to querydsl-jpa/src/test/java/com/querydsl/jpa/domain/AuditLog.java index 57a129186e..a515e1720e 100644 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/AuditLog.java +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/AuditLog.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.jpa.domain; +package com.querydsl.jpa.domain; import javax.persistence.Entity; import javax.persistence.Id; @@ -22,7 +22,7 @@ * The Class AuditLog. */ @Entity -@Table(name="auditlog_") +@Table(name = "auditlog_") public class AuditLog { @Id int id; diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Author.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Author.java new file mode 100644 index 0000000000..0104376c0a --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Author.java @@ -0,0 +1,47 @@ +package com.querydsl.jpa.domain; + +import java.io.Serializable; +import java.util.Set; + +import javax.persistence.*; + +@Entity +@Table(name = "author_") +public class Author implements Serializable { + + private static final long serialVersionUID = -1893968697250846661L; + + @Id + @GeneratedValue + private Long id; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @OneToMany(mappedBy = "author") + @OrderBy("title") + private Set<Book> books; + + public Set<Book> getBooks() { + return books; + } + + public void setBooks(Set<Book> books) { + this.books = books; + } +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Bar.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Bar.java new file mode 100644 index 0000000000..969ff52670 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Bar.java @@ -0,0 +1,29 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.domain; + +import javax.persistence.*; + +/** + * The Class Bar. + */ +@Entity +@Table(name = "bar_") +public class Bar { + @Temporal(TemporalType.DATE) + java.util.Date date; + + @Id + int id; +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Book.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Book.java new file mode 100644 index 0000000000..a2ddd40184 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Book.java @@ -0,0 +1,46 @@ +package com.querydsl.jpa.domain; + +import java.io.Serializable; + +import javax.persistence.*; + +@Entity +@Table(name = "book_") +public class Book implements Serializable { + + private static final long serialVersionUID = -9029792723035681319L; + + @Id + @GeneratedValue + private Long id; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + private String title; + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + @ManyToOne + @JoinColumn(name = "AUTHOR_ID") + private Author author; + + public Author getAuthor() { + return author; + } + + public void setAuthor(Author author) { + this.author = author; + } +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Calendar.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Calendar.java new file mode 100644 index 0000000000..00617f87ab --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Calendar.java @@ -0,0 +1,37 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.domain; + +import java.io.Serializable; +import java.util.Map; + +import javax.persistence.*; + + + +/** + * The Class Calendar. + */ +@SuppressWarnings("serial") +@Entity +@Table(name = "calendar_") +public class Calendar implements Serializable { + @ElementCollection + @Temporal(TemporalType.DATE) + @MapKeyColumn(name = "holidays_key") + Map<String, java.util.Date> holidays; + + @Id + int id; +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Cat.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Cat.java new file mode 100644 index 0000000000..67b3a0a5f8 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Cat.java @@ -0,0 +1,117 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.domain; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import javax.persistence.*; + +/** + * The Class Cat. + */ +@Entity +@DiscriminatorValue("C") +public class Cat extends Animal { + + private int breed; + + private Color eyecolor; + + @OneToMany + @JoinTable(name = "kittens", joinColumns = @JoinColumn(name = "cat_id"), inverseJoinColumns = @JoinColumn(name = "kitten_id")) + @OrderColumn(name = "ind") + private List<Cat> kittens = new ArrayList<Cat>(); + + @OneToMany + @JoinTable(name = "kittens_set", joinColumns = @JoinColumn(name = "cat_id"), inverseJoinColumns = @JoinColumn(name = "kitten_id")) + private Set<Cat> kittensSet; + +// @OneToMany +// @JoinTable(name="kittens_array") +// @IndexColumn(name = "arrayIndex") +// private Cat[] kittensArray = new Cat[0]; + + @ManyToOne + private Cat mate; + + public Cat() { } + + public Cat(int id) { + setId(id); + } + + public Cat(String name, int id) { + setId(id); + setName(name); + } + + public Cat(String name, int id, Color color) { + setId(id); + setName(name); + setColor(color); + } + + public Cat(String name, int id, List<Cat> k) { + setId(id); + setName(name); + kittens.addAll(k); + } + + public Cat(String name, int id, double bodyWeight) { + this(name, id); + setBodyWeight(bodyWeight); + setFloatProperty((float) bodyWeight); + } + + public int getBreed() { + return breed; + } + + public Color getEyecolor() { + return eyecolor; + } + + public List<Cat> getKittens() { + return kittens; + } + + public Cat getMate() { + return mate; + } + +// public Cat[] getKittensArray() { +// return kittensArray; +// } + + public void addKitten(Cat kitten) { + kittens.add(kitten); +// kittensArray = new Cat[]{kitten}; + } + + public Set<Cat> getKittensSet() { + return kittensSet; + } + + public void setKittensSet(Set<Cat> kittensSet) { + this.kittensSet = kittensSet; + } + + public void setMate(Cat mate) { + this.mate = mate; + } + +} + diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/CatSummary.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/CatSummary.java similarity index 87% rename from querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/CatSummary.java rename to querydsl-jpa/src/test/java/com/querydsl/jpa/domain/CatSummary.java index 9f18bd708e..e758c719c0 100644 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/CatSummary.java +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/CatSummary.java @@ -1,6 +1,6 @@ -package com.mysema.query.jpa.domain; +package com.querydsl.jpa.domain; -import com.mysema.query.annotations.QueryProjection; +import com.querydsl.core.annotations.QueryProjection; public class CatSummary { diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Catalog.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Catalog.java new file mode 100644 index 0000000000..5caa676610 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Catalog.java @@ -0,0 +1,35 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.domain; + +import java.util.Date; +import java.util.Set; + +import javax.persistence.*; + +/** + * The Class Catalog. + */ +@Entity +@Table(name = "catalog_") +public class Catalog { + @Temporal(TemporalType.DATE) + Date effectiveDate; + + @Id + int id; + + @OneToMany + Set<Price> prices; +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Child.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Child.java new file mode 100644 index 0000000000..2b309a91a6 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Child.java @@ -0,0 +1,16 @@ +package com.querydsl.jpa.domain; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.ManyToOne; + +@Entity(name = "Child2") +public class Child { + + @Id + int id; + + @ManyToOne + Parent parent; + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Color.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Color.java new file mode 100644 index 0000000000..9777ece6ca --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Color.java @@ -0,0 +1,21 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.domain; + +/** + * The Enum Color. + */ +public enum Color { + BLACK, TABBY +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Company.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Company.java new file mode 100644 index 0000000000..e42fb01e1a --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Company.java @@ -0,0 +1,51 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.domain; + +import java.util.List; + +import javax.persistence.*; + +import org.batoo.jpa.annotations.Index; + +/** + * The Class Company. + */ +@Entity +@Table(name = "company_") +public class Company { + + public enum Rating { A, AA, AAA } + + @Enumerated + public Rating ratingOrdinal; + + @Enumerated(EnumType.STRING) + public Rating ratingString; + + @ManyToOne + public Employee ceo; + + @OneToMany + @Index(name = "_index") + public List<Department> departments; + + @Id + public int id; + + public String name; + + @Column(name = "official_name") + public String officialName; +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Customer.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Customer.java new file mode 100644 index 0000000000..609fedb460 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Customer.java @@ -0,0 +1,35 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.domain; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.ManyToOne; +import javax.persistence.Table; + +/** + * The Class Customer. + */ +@Entity +@Table(name = "customer_") +public class Customer { + @ManyToOne + Order currentOrder; + + @Id + int id; + + @ManyToOne + Name name; +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Department.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Department.java new file mode 100644 index 0000000000..4bc584fea0 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Department.java @@ -0,0 +1,39 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.domain; + +import java.util.List; + +import javax.persistence.*; + +import org.batoo.jpa.annotations.Index; + +/** + * The Class Department. + */ +@Entity +@Table(name = "department_") +public class Department { + @ManyToOne + Company company; + + @OneToMany + @Index(name = "_index") + List<Employee> employees; + + @Id + int id; + + String name; +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Document.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Document.java new file mode 100644 index 0000000000..0455563cf7 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Document.java @@ -0,0 +1,33 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.domain; + +import java.util.Date; + +import javax.persistence.*; + +/** + * The Class Document. + */ +@Entity +@Table(name = "document_") +public class Document { + @Id + int id; + + String name; + + @Temporal(TemporalType.DATE) + Date validTo; +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Dolphin.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Dolphin.java new file mode 100644 index 0000000000..e1762acd08 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Dolphin.java @@ -0,0 +1,8 @@ +package com.querydsl.jpa.domain; + +import javax.persistence.Entity; + +@Entity +public class Dolphin extends Mammal { + +} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Domain.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Domain.java similarity index 76% rename from querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Domain.java rename to querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Domain.java index f544fabfbb..b072a5f93d 100644 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Domain.java +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Domain.java @@ -1,5 +1,5 @@ /* - * Copyright 2011, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,19 +11,23 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.jpa.domain; +package com.querydsl.jpa.domain; import java.util.Arrays; import java.util.List; -import com.mysema.query.jpa.domain4.BookID; -import com.mysema.query.jpa.domain4.BookMark; -import com.mysema.query.jpa.domain4.BookVersion; -import com.mysema.query.jpa.domain4.Library; +import com.querydsl.jpa.domain4.BookID; +import com.querydsl.jpa.domain4.BookMark; +import com.querydsl.jpa.domain4.BookVersion; +import com.querydsl.jpa.domain4.Library; +import com.querydsl.jpa.domain5.MyEmbeddedAttribute; +import com.querydsl.jpa.domain5.MyEntity; +import com.querydsl.jpa.domain5.MyMappedSuperclass; +import com.querydsl.jpa.domain5.MyOtherEntity; public final class Domain { - private Domain() {} + private Domain() { } public static final List<Class<?>> classes = Arrays.<Class<?>>asList( Account.class, @@ -51,6 +55,7 @@ private Domain() {} Family.class, Foo.class, Formula.class, + Group.class, Human.class, InheritedProperties.class, Item.class, @@ -84,6 +89,11 @@ private Domain() {} BookID.class, BookMark.class, BookVersion.class, - Library.class + Library.class, + + MyEmbeddedAttribute.class, + MyEntity.class, + MyMappedSuperclass.class, + MyOtherEntity.class ); } diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/DomesticCat.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/DomesticCat.java similarity index 87% rename from querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/DomesticCat.java rename to querydsl-jpa/src/test/java/com/querydsl/jpa/domain/DomesticCat.java index ca0aec218b..d28a280a10 100644 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/DomesticCat.java +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/DomesticCat.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.jpa.domain; +package com.querydsl.jpa.domain; import javax.persistence.DiscriminatorValue; import javax.persistence.Entity; diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/DoubleProjection.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/DoubleProjection.java new file mode 100644 index 0000000000..ab0fff0e06 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/DoubleProjection.java @@ -0,0 +1,14 @@ +package com.querydsl.jpa.domain; + +import com.querydsl.core.annotations.QueryProjection; + +public class DoubleProjection { + + public double val; + + @QueryProjection + public DoubleProjection(double val) { + this.val = val; + } + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/EmbeddedType.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/EmbeddedType.java new file mode 100644 index 0000000000..36bb9f5f01 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/EmbeddedType.java @@ -0,0 +1,26 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.domain; + +import java.io.Serializable; + +import javax.persistence.Embeddable; + +@SuppressWarnings("serial") +@Embeddable +public class EmbeddedType implements Serializable { + + String someData; + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Employee.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Employee.java new file mode 100644 index 0000000000..ab00f89dfb --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Employee.java @@ -0,0 +1,43 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.domain; + +import java.util.Collection; +import java.util.HashSet; + +import javax.persistence.*; + +/** + * The Class Employee. + */ +@Entity +@Table(name = "employee_") +public class Employee { + @ManyToOne + public Company company; + + @OneToOne + public User user; + + public String firstName, lastName; + + @Id + public int id; + + @Enumerated(EnumType.STRING) + @Column(name = "jobfunction") + @ElementCollection (fetch = FetchType.EAGER) + public Collection<JobFunction> jobFunctions = new HashSet<JobFunction>(); + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Entity1.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Entity1.java new file mode 100644 index 0000000000..3f86c20928 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Entity1.java @@ -0,0 +1,19 @@ +package com.querydsl.jpa.domain; + +import javax.persistence.Entity; +import javax.persistence.Id; + +@Entity +public class Entity1 { + + public Entity1() { } + + public Entity1(int id) { + this.id = id; + } + + @Id + public int id; + + public String property; +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Entity2.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Entity2.java new file mode 100644 index 0000000000..eb79dfa651 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Entity2.java @@ -0,0 +1,15 @@ +package com.querydsl.jpa.domain; + +import javax.persistence.Entity; + +@Entity +public class Entity2 extends Entity1 { + + public Entity2() { } + + public Entity2(int id) { + this.id = id; + } + + public String property2; +} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/EvilType.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/EvilType.java similarity index 77% rename from querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/EvilType.java rename to querydsl-jpa/src/test/java/com/querydsl/jpa/domain/EvilType.java index 57f3d60351..db8dd5a3a4 100644 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/EvilType.java +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/EvilType.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,19 +11,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.jpa.domain; +package com.querydsl.jpa.domain; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.Table; +import javax.persistence.*; /** * The Class EvilType. */ @Entity -@Table(name="eviltype_") +@Table(name = "eviltype_") public class EvilType { @ManyToOne @JoinColumn(name = "_asc") diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Family.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Family.java similarity index 81% rename from querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Family.java rename to querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Family.java index 61d8bc563e..58423b6373 100644 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Family.java +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Family.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,9 +11,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.jpa.domain; +package com.querydsl.jpa.domain; -import com.mysema.query.annotations.QueryProjection; +import com.querydsl.core.annotations.QueryProjection; /** * The Class Family. diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/FloatProjection.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/FloatProjection.java new file mode 100644 index 0000000000..aded5a0eb0 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/FloatProjection.java @@ -0,0 +1,14 @@ +package com.querydsl.jpa.domain; + +import com.querydsl.core.annotations.QueryProjection; + +public class FloatProjection { + + public float val; + + @QueryProjection + public FloatProjection(float val) { + this.val = val; + } + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Foo.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Foo.java new file mode 100644 index 0000000000..0887aa6e9d --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Foo.java @@ -0,0 +1,38 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.domain; + +import java.util.List; + +import javax.persistence.*; + +/** + * The Class Foo. + */ +@Entity +@Table(name = "foo_") +public class Foo { + public String bar; + + @Id + //@GeneratedValue(strategy=GenerationType.AUTO) + public int id; + + @ElementCollection + @CollectionTable(name = "foo_names", joinColumns = {@JoinColumn(name = "foo_id")}) + public List<String> names; + + @Temporal(TemporalType.DATE) + public java.util.Date startDate; +} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/FooDTO.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/FooDTO.java similarity index 86% rename from querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/FooDTO.java rename to querydsl-jpa/src/test/java/com/querydsl/jpa/domain/FooDTO.java index 11d0dccddf..30e6bb0648 100644 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/FooDTO.java +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/FooDTO.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.jpa.domain; +package com.querydsl.jpa.domain; import java.util.List; @@ -20,7 +20,7 @@ import javax.persistence.Temporal; import javax.persistence.TemporalType; -import com.mysema.query.annotations.QueryProjection; +import com.querydsl.core.annotations.QueryProjection; public class FooDTO { String bar; diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Formula.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Formula.java similarity index 87% rename from querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Formula.java rename to querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Formula.java index 7c95edd231..8e47727f0d 100644 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Formula.java +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Formula.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.jpa.domain; +package com.querydsl.jpa.domain; import javax.persistence.Entity; import javax.persistence.Id; @@ -22,7 +22,7 @@ * The Class Formula. */ @Entity -@Table(name="formula_") +@Table(name = "formula_") public class Formula { @Id int id; diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Group.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Group.java new file mode 100644 index 0000000000..e32bc68e4a --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Group.java @@ -0,0 +1,27 @@ +/* + * Copyright 2016, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.domain; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "group_") +public class Group { + @Id + int id; + + String name; +} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Human.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Human.java similarity index 83% rename from querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Human.java rename to querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Human.java index c76b6188e6..2a3af1e3c4 100644 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Human.java +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Human.java @@ -1,4 +1,4 @@ -package com.mysema.query.jpa.domain; +package com.querydsl.jpa.domain; import java.util.Collection; @@ -10,5 +10,5 @@ public class Human extends Mammal { @ElementCollection Collection<Integer> hairs; - + } diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/InheritedProperties.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/InheritedProperties.java similarity index 84% rename from querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/InheritedProperties.java rename to querydsl-jpa/src/test/java/com/querydsl/jpa/domain/InheritedProperties.java index 57f464d5d7..efe5b746ad 100644 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/InheritedProperties.java +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/InheritedProperties.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,14 +11,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.jpa.domain; +package com.querydsl.jpa.domain; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table; @Entity -@Table(name="inheritedproperties_") +@Table(name = "inheritedproperties_") public class InheritedProperties extends Superclass { @Id long id; diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Item.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Item.java new file mode 100644 index 0000000000..570027ecee --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Item.java @@ -0,0 +1,32 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.domain; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.ManyToOne; +import javax.persistence.Table; + +/** + * The Class Item. + */ +@Entity +@Table(name = "item_") +public class Item { + @Id + long id; + + @ManyToOne + Product product; +} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/JobFunction.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/JobFunction.java similarity index 85% rename from querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/JobFunction.java rename to querydsl-jpa/src/test/java/com/querydsl/jpa/domain/JobFunction.java index d5d09e0030..fe44f9e771 100644 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/JobFunction.java +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/JobFunction.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.jpa.domain; +package com.querydsl.jpa.domain; public enum JobFunction { diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Location.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Location.java new file mode 100644 index 0000000000..09901e3962 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Location.java @@ -0,0 +1,30 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.domain; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +/** + * The Class Location. + */ +@Entity(name = "Location2") +@Table(name = "location_") +public class Location { + @Id + long id; + + String name; +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Mammal.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Mammal.java new file mode 100644 index 0000000000..d0529f1aac --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Mammal.java @@ -0,0 +1,12 @@ +package com.querydsl.jpa.domain; + +import javax.persistence.Entity; +import javax.persistence.Id; + +@Entity +public class Mammal { + + @Id + Long id; + +} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Name.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Name.java similarity index 85% rename from querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Name.java rename to querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Name.java index 60ad26a379..257636df66 100644 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Name.java +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Name.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.jpa.domain; +package com.querydsl.jpa.domain; import javax.persistence.Entity; import javax.persistence.Id; @@ -21,7 +21,7 @@ * The Class Name. */ @Entity -@Table(name="name_") +@Table(name = "name_") public class Name { String firstName, lastName, nickName; diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/NameList.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/NameList.java similarity index 86% rename from querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/NameList.java rename to querydsl-jpa/src/test/java/com/querydsl/jpa/domain/NameList.java index 903ed8912d..bb4f1af576 100644 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/NameList.java +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/NameList.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.jpa.domain; +package com.querydsl.jpa.domain; import java.util.Collection; @@ -24,11 +24,11 @@ * The Class NameList. */ @Entity -@Table(name="namelist_") +@Table(name = "namelist_") public class NameList { @Id long id; - + @ElementCollection Collection<String> names; } diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Named.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Named.java similarity index 85% rename from querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Named.java rename to querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Named.java index de2fa04f46..220d3e4e49 100644 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Named.java +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Named.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.jpa.domain; +package com.querydsl.jpa.domain; import javax.persistence.Entity; import javax.persistence.Id; @@ -21,7 +21,7 @@ * The Class Named. */ @Entity -@Table(name="named_") +@Table(name = "named_") public class Named { @Id long id; diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Nationality.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Nationality.java similarity index 82% rename from querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Nationality.java rename to querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Nationality.java index 5083c177c9..30e37913ef 100644 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Nationality.java +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Nationality.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.jpa.domain; +package com.querydsl.jpa.domain; import java.io.Serializable; @@ -25,8 +25,8 @@ */ @SuppressWarnings("serial") @Entity -@Table(name="nationality_") -public class Nationality implements Serializable{ +@Table(name = "nationality_") +public class Nationality implements Serializable { @ManyToOne Calendar calendar; diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Novel.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Novel.java similarity index 76% rename from querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Novel.java rename to querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Novel.java index a8f0c5e49a..09ebef91d9 100644 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Novel.java +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Novel.java @@ -1,10 +1,10 @@ -package com.mysema.query.jpa.domain; +package com.querydsl.jpa.domain; import javax.persistence.Entity; @Entity public class Novel extends Book { - private static final long serialVersionUID = 4711598115423737544L; + private static final long serialVersionUID = 4711598115423737544L; } diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Numeric.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Numeric.java similarity index 91% rename from querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Numeric.java rename to querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Numeric.java index afcf3f6a86..bcb865a4c2 100644 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Numeric.java +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Numeric.java @@ -1,4 +1,4 @@ -package com.mysema.query.jpa.domain; +package com.querydsl.jpa.domain; import java.io.Serializable; import java.math.BigDecimal; @@ -9,7 +9,7 @@ import javax.persistence.Table; @Entity -@Table(name="numeric_") +@Table(name = "numeric_") public class Numeric implements Serializable { private static final long serialVersionUID = 1L; diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Order.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Order.java new file mode 100644 index 0000000000..c37ea0cece --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Order.java @@ -0,0 +1,52 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.domain; + +import java.util.List; +import java.util.Map; + +import javax.persistence.*; + +/** + * The Class Order. + */ +@Entity +@Table(name = "order_") +public class Order { + @ManyToOne + Customer customer; + + @ElementCollection + @OrderColumn(name = "_index") + List<Integer> deliveredItemIndices; + + @Id + long id; + + @OneToMany + @OrderColumn(name = "_index") + List<Item> items; + + @OneToMany + @JoinTable(name = "LineItems") + @OrderColumn(name = "_index") + List<Item> lineItems; + + @OneToMany + @JoinTable(name = "LineItems2") + @MapKey(name = "id") + Map<Integer, Item> lineItemsMap; + + boolean paid; +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Parameter.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Parameter.java new file mode 100644 index 0000000000..4985a99696 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Parameter.java @@ -0,0 +1,28 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.domain; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +/** + * The Class Parameter. + */ +@Entity +@Table(name = "parameter_") +public class Parameter { + @Id + long id; +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Parent.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Parent.java new file mode 100644 index 0000000000..1d97452d74 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Parent.java @@ -0,0 +1,18 @@ +package com.querydsl.jpa.domain; + +import java.util.Set; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.OneToMany; + +@Entity(name = "Parent2") +public class Parent { + + @Id + int id; + + @OneToMany(mappedBy = "parent") + Set<Child> children; + +} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Payment.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Payment.java similarity index 90% rename from querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Payment.java rename to querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Payment.java index 63e22a5818..3f07efb7dd 100644 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Payment.java +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Payment.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.jpa.domain; +package com.querydsl.jpa.domain; import java.util.Collection; diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/PaymentStatus.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/PaymentStatus.java similarity index 86% rename from querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/PaymentStatus.java rename to querydsl-jpa/src/test/java/com/querydsl/jpa/domain/PaymentStatus.java index c6c44a64c8..d53c7cc38b 100644 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/PaymentStatus.java +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/PaymentStatus.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.jpa.domain; +package com.querydsl.jpa.domain; /** * The Enum PaymentStatus. diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Person.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Person.java new file mode 100644 index 0000000000..b8998c3903 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Person.java @@ -0,0 +1,43 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.domain; + +import java.io.Serializable; + +import javax.persistence.*; + +import com.querydsl.core.annotations.QueryInit; + +/** + * The Class Person. + */ +@SuppressWarnings("serial") +@Entity +@Table(name = "person_") +public class Person implements Serializable { + @Temporal(TemporalType.DATE) + java.util.Date birthDay; + + @Id + long i; + + @ManyToOne + PersonId pid; + + String name; + + @ManyToOne + @QueryInit("calendar") + Nationality nationality; +} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/PersonId.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/PersonId.java similarity index 81% rename from querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/PersonId.java rename to querydsl-jpa/src/test/java/com/querydsl/jpa/domain/PersonId.java index 29e08bfa4e..64663db21a 100644 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/PersonId.java +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/PersonId.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.jpa.domain; +package com.querydsl.jpa.domain; import java.io.Serializable; @@ -24,8 +24,8 @@ */ @SuppressWarnings("serial") @Entity -@Table(name="personid_") -public class PersonId implements Serializable{ +@Table(name = "personid_") +public class PersonId implements Serializable { String country; @Id diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Player.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Player.java similarity index 86% rename from querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Player.java rename to querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Player.java index 14385d6a46..3f50ab56e0 100644 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Player.java +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Player.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.jpa.domain; +package com.querydsl.jpa.domain; import java.util.List; @@ -24,7 +24,7 @@ * The Class Player. */ @Entity -@Table(name="player_") +@Table(name = "player_") public class Player { @Id long id; diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Price.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Price.java similarity index 84% rename from querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Price.java rename to querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Price.java index 393966d1c6..3c92d6c41e 100644 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/Price.java +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Price.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.jpa.domain; +package com.querydsl.jpa.domain; import javax.persistence.Entity; import javax.persistence.Id; @@ -22,8 +22,8 @@ * The Class Price. */ @Entity -@Table(name="price_") -public class Price{ +@Table(name = "price_") +public class Price { long amount; @Id diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Product.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Product.java new file mode 100644 index 0000000000..c2db3c9694 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Product.java @@ -0,0 +1,25 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.domain; + +import javax.persistence.Entity; + +/** + * The Class Product. + */ +@Entity +public class Product extends Item { + // @Id long id; + String name; +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Show.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Show.java new file mode 100644 index 0000000000..be6e9e1697 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Show.java @@ -0,0 +1,43 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.domain; + +import java.util.Map; + +import javax.persistence.*; + +/** + * The Class Show. + */ +@Entity +@Table(name = "show_") +public class Show { + + @Id + long id; + + @ElementCollection + @MapKeyColumn(name = "acts_key") + public Map<String, String> acts; + + @ManyToOne + public Show parent; + + public Show() { } + + public Show(int id) { + this.id = id; + } + +} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/SimpleTypes.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/SimpleTypes.java similarity index 81% rename from querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/SimpleTypes.java rename to querydsl-jpa/src/test/java/com/querydsl/jpa/domain/SimpleTypes.java index d1bb413f21..5da707c061 100644 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/SimpleTypes.java +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/SimpleTypes.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,20 +11,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.jpa.domain; +package com.querydsl.jpa.domain; import java.math.BigDecimal; import java.util.Date; import java.util.Locale; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.Table; -import javax.persistence.Temporal; -import javax.persistence.TemporalType; +import javax.persistence.*; @Entity -@Table(name="simpletypes_") +@Table(name = "simpletypes_") public class SimpleTypes { transient int test; @Id @@ -68,4 +64,6 @@ public class SimpleTypes { // @Temporal(TemporalType.TIMESTAMP) java.sql.Timestamp timestamp; + + byte[] byteArray; } diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Status.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Status.java new file mode 100644 index 0000000000..5b5092db3c --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Status.java @@ -0,0 +1,30 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.domain; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +/** + * The Class Status. + */ +@Entity +@Table(name = "status_") +public class Status { + @Id + long id; + + String name; +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/StatusChange.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/StatusChange.java new file mode 100644 index 0000000000..20384e000f --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/StatusChange.java @@ -0,0 +1,29 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.domain; + +import javax.persistence.*; + +/** + * The Class StatusChange. + */ +@Entity +@Table(name = "statuschange_") +public class StatusChange { + @Id + long id; + + @Temporal(TemporalType.TIMESTAMP) + java.util.Date timeStamp; +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Store.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Store.java new file mode 100644 index 0000000000..47982a0694 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Store.java @@ -0,0 +1,34 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.domain; + +import java.util.List; + +import javax.persistence.*; + +/** + * The Class Store. + */ +@Entity +@Table(name = "store_") +public class Store { + @OneToMany + List<Customer> customers; + + @Id + long id; + + @ManyToOne + Location location; +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Superclass.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Superclass.java new file mode 100644 index 0000000000..29366dcb04 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/Superclass.java @@ -0,0 +1,36 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.domain; + +import javax.persistence.MappedSuperclass; + +import com.querydsl.core.annotations.PropertyType; +import com.querydsl.core.annotations.QueryType; + +@MappedSuperclass +public class Superclass { + String superclassProperty; + + @QueryType(PropertyType.SIMPLE) + private String stringAsSimple; + + public String getStringAsSimple() { + return stringAsSimple; + } + + public void setStringAsSimple(String stringAsSimple) { + this.stringAsSimple = stringAsSimple; + } + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/User.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/User.java new file mode 100644 index 0000000000..33cdceeacb --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/User.java @@ -0,0 +1,34 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.domain; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.ManyToOne; +import javax.persistence.Table; + +/** + * The Class User. + */ +@Entity +@Table(name = "user_") +public class User { + @ManyToOne + Company company; + + @Id + long id; + + String userName, firstName, lastName; +} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/World.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/World.java similarity index 82% rename from querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/World.java rename to querydsl-jpa/src/test/java/com/querydsl/jpa/domain/World.java index 158f78cab4..3f741b4a7f 100644 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/World.java +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/World.java @@ -1,4 +1,4 @@ -package com.mysema.query.jpa.domain; +package com.querydsl.jpa.domain; import java.util.Set; @@ -11,8 +11,8 @@ public class World { @Id Long id; - + @OneToMany Set<Mammal> mammals; - + } diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/package-info.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/package-info.java new file mode 100644 index 0000000000..0a6f9de574 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/package-info.java @@ -0,0 +1,4 @@ +@Config(listAccessors = true, mapAccessors = true) +package com.querydsl.jpa.domain; +import com.querydsl.core.annotations.Config; + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SAccount.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SAccount.java new file mode 100644 index 0000000000..3063d2afcb --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SAccount.java @@ -0,0 +1,61 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.StringPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SAccount is a Querydsl query type for SAccount + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SAccount extends com.querydsl.sql.RelationalPathBase<SAccount> { + + private static final long serialVersionUID = -1514613821; + + public static final SAccount account_ = new SAccount("account_"); + + public final NumberPath<Long> id = createNumber("id", Long.class); + + public final NumberPath<Long> ownerI = createNumber("ownerI", Long.class); + + public final StringPath someData = createString("someData"); + + public final com.querydsl.sql.PrimaryKey<SAccount> primary = createPrimaryKey(id); + + public final com.querydsl.sql.ForeignKey<SPerson> fk809dbbd28cfac74 = createForeignKey(ownerI, "i"); + + public SAccount(String variable) { + super(SAccount.class, forVariable(variable), "", "account_"); + addMetadata(); + } + + public SAccount(String variable, String schema, String table) { + super(SAccount.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SAccount(Path<? extends SAccount> path) { + super(path.getType(), path.getMetadata(), "", "account_"); + addMetadata(); + } + + public SAccount(PathMetadata metadata) { + super(SAccount.class, metadata, "", "account_"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(-5).withSize(19).notNull()); + addMetadata(ownerI, ColumnMetadata.named("owner_i").withIndex(3).ofType(-5).withSize(19)); + addMetadata(someData, ColumnMetadata.named("someData").withIndex(2).ofType(12).withSize(255)); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SAnimal.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SAnimal.java new file mode 100644 index 0000000000..fd5e002fb0 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SAnimal.java @@ -0,0 +1,110 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import java.sql.Date; +import java.sql.Time; +import java.sql.Timestamp; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.*; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SAnimal is a Querydsl query type for SAnimal + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SAnimal extends com.querydsl.sql.RelationalPathBase<SAnimal> { + + private static final long serialVersionUID = 1795545042; + + public static final SAnimal animal_ = new SAnimal("animal_"); + + public final BooleanPath alive = createBoolean("alive"); + + public final DateTimePath<Timestamp> birthdate = createDateTime("birthdate", java.sql.Timestamp.class); + + public final NumberPath<Double> bodyWeight = createNumber("bodyWeight", Double.class); + + public final NumberPath<Integer> breed = createNumber("breed", Integer.class); + + public final NumberPath<Integer> color = createNumber("color", Integer.class); + + public final DatePath<Date> dateField = createDate("dateField", java.sql.Date.class); + + public final StringPath dtype = createString("dtype"); + + public final NumberPath<Integer> eyecolor = createNumber("eyecolor", Integer.class); + + public final NumberPath<Float> floatProperty = createNumber("floatProperty", Float.class); + + public final NumberPath<Integer> id = createNumber("id", Integer.class); + + public final NumberPath<Integer> mateId = createNumber("mateId", Integer.class); + + public final StringPath name = createString("name"); + + public final TimePath<Time> timeField = createTime("timeField", java.sql.Time.class); + + public final NumberPath<Integer> toes = createNumber("toes", Integer.class); + + public final NumberPath<Integer> weight = createNumber("weight", Integer.class); + + public final com.querydsl.sql.PrimaryKey<SAnimal> primary = createPrimaryKey(id); + + public final com.querydsl.sql.ForeignKey<SAnimal> fkccec31e312a37469 = createForeignKey(mateId, "id"); + + public final com.querydsl.sql.ForeignKey<SKittens> _fkd60087cc3881aaa7 = createInvForeignKey(id, "kitten_id"); + + public final com.querydsl.sql.ForeignKey<SAnimal> _fkccec31e312a37469 = createInvForeignKey(id, "mate_id"); + + public final com.querydsl.sql.ForeignKey<SKittensSet> _fk4fccad6f8f00fdf8 = createInvForeignKey(id, "cat_id"); + + public final com.querydsl.sql.ForeignKey<SKittens> _fkd60087cc8f00fdf8 = createInvForeignKey(id, "cat_id"); + + public final com.querydsl.sql.ForeignKey<SKittensSet> _fk4fccad6f3881aaa7 = createInvForeignKey(id, "kitten_id"); + + public SAnimal(String variable) { + super(SAnimal.class, forVariable(variable), "", "animal_"); + addMetadata(); + } + + public SAnimal(String variable, String schema, String table) { + super(SAnimal.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SAnimal(Path<? extends SAnimal> path) { + super(path.getType(), path.getMetadata(), "", "animal_"); + addMetadata(); + } + + public SAnimal(PathMetadata metadata) { + super(SAnimal.class, metadata, "", "animal_"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(alive, ColumnMetadata.named("alive").withIndex(3).ofType(-7).notNull()); + addMetadata(birthdate, ColumnMetadata.named("birthdate").withIndex(4).ofType(93).withSize(19)); + addMetadata(bodyWeight, ColumnMetadata.named("bodyWeight").withIndex(5).ofType(8).withSize(22).notNull()); + addMetadata(breed, ColumnMetadata.named("breed").withIndex(13).ofType(4).withSize(10)); + addMetadata(color, ColumnMetadata.named("color").withIndex(6).ofType(4).withSize(10)); + addMetadata(dateField, ColumnMetadata.named("dateField").withIndex(7).ofType(91).withSize(10)); + addMetadata(dtype, ColumnMetadata.named("DTYPE").withIndex(1).ofType(12).withSize(31).notNull()); + addMetadata(eyecolor, ColumnMetadata.named("eyecolor").withIndex(14).ofType(4).withSize(10)); + addMetadata(floatProperty, ColumnMetadata.named("floatProperty").withIndex(8).ofType(7).withSize(12).notNull()); + addMetadata(id, ColumnMetadata.named("id").withIndex(2).ofType(4).withSize(10).notNull()); + addMetadata(mateId, ColumnMetadata.named("mate_id").withIndex(15).ofType(4).withSize(10)); + addMetadata(name, ColumnMetadata.named("name").withIndex(9).ofType(12).withSize(255)); + addMetadata(timeField, ColumnMetadata.named("timeField").withIndex(10).ofType(92).withSize(8)); + addMetadata(toes, ColumnMetadata.named("toes").withIndex(11).ofType(4).withSize(10).notNull()); + addMetadata(weight, ColumnMetadata.named("weight").withIndex(12).ofType(4).withSize(10).notNull()); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SAuditlog.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SAuditlog.java new file mode 100644 index 0000000000..6452f3f43e --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SAuditlog.java @@ -0,0 +1,57 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SAuditlog is a Querydsl query type for SAuditlog + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SAuditlog extends com.querydsl.sql.RelationalPathBase<SAuditlog> { + + private static final long serialVersionUID = -1982799323; + + public static final SAuditlog auditlog_ = new SAuditlog("auditlog_"); + + public final NumberPath<Integer> id = createNumber("id", Integer.class); + + public final NumberPath<Long> itemId = createNumber("itemId", Long.class); + + public final com.querydsl.sql.PrimaryKey<SAuditlog> primary = createPrimaryKey(id); + + public final com.querydsl.sql.ForeignKey<SItem> fkb88fbf6ae26109c = createForeignKey(itemId, "id"); + + public SAuditlog(String variable) { + super(SAuditlog.class, forVariable(variable), "", "auditlog_"); + addMetadata(); + } + + public SAuditlog(String variable, String schema, String table) { + super(SAuditlog.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SAuditlog(Path<? extends SAuditlog> path) { + super(path.getType(), path.getMetadata(), "", "auditlog_"); + addMetadata(); + } + + public SAuditlog(PathMetadata metadata) { + super(SAuditlog.class, metadata, "", "auditlog_"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(4).withSize(10).notNull()); + addMetadata(itemId, ColumnMetadata.named("item_id").withIndex(2).ofType(-5).withSize(19)); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SAuthor.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SAuthor.java new file mode 100644 index 0000000000..8f0bbcc537 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SAuthor.java @@ -0,0 +1,58 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.StringPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SAuthor is a Querydsl query type for SAuthor + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SAuthor extends com.querydsl.sql.RelationalPathBase<SAuthor> { + + private static final long serialVersionUID = 2005972515; + + public static final SAuthor author_ = new SAuthor("author_"); + + public final NumberPath<Long> id = createNumber("id", Long.class); + + public final StringPath name = createString("name"); + + public final com.querydsl.sql.PrimaryKey<SAuthor> primary = createPrimaryKey(id); + + public final com.querydsl.sql.ForeignKey<SBook> _fk599229686eaf51c = createInvForeignKey(id, "AUTHOR_ID"); + + public SAuthor(String variable) { + super(SAuthor.class, forVariable(variable), "", "author_"); + addMetadata(); + } + + public SAuthor(String variable, String schema, String table) { + super(SAuthor.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SAuthor(Path<? extends SAuthor> path) { + super(path.getType(), path.getMetadata(), "", "author_"); + addMetadata(); + } + + public SAuthor(PathMetadata metadata) { + super(SAuthor.class, metadata, "", "author_"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(-5).withSize(19).notNull()); + addMetadata(name, ColumnMetadata.named("name").withIndex(2).ofType(12).withSize(255)); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SBar.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SBar.java new file mode 100644 index 0000000000..9f766be25e --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SBar.java @@ -0,0 +1,56 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.DatePath; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SBar is a Querydsl query type for SBar + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SBar extends com.querydsl.sql.RelationalPathBase<SBar> { + + private static final long serialVersionUID = -1389576419; + + public static final SBar bar_ = new SBar("bar_"); + + public final DatePath<java.sql.Date> date = createDate("date", java.sql.Date.class); + + public final NumberPath<Integer> id = createNumber("id", Integer.class); + + public final com.querydsl.sql.PrimaryKey<SBar> primary = createPrimaryKey(id); + + public SBar(String variable) { + super(SBar.class, forVariable(variable), "", "bar_"); + addMetadata(); + } + + public SBar(String variable, String schema, String table) { + super(SBar.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SBar(Path<? extends SBar> path) { + super(path.getType(), path.getMetadata(), "", "bar_"); + addMetadata(); + } + + public SBar(PathMetadata metadata) { + super(SBar.class, metadata, "", "bar_"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(date, ColumnMetadata.named("date").withIndex(2).ofType(91).withSize(10)); + addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(4).withSize(10).notNull()); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SBook.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SBook.java new file mode 100644 index 0000000000..880c5a72b6 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SBook.java @@ -0,0 +1,64 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.StringPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SBook is a Querydsl query type for SBook + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SBook extends com.querydsl.sql.RelationalPathBase<SBook> { + + private static final long serialVersionUID = -126781371; + + public static final SBook book_ = new SBook("book_"); + + public final NumberPath<Long> authorId = createNumber("authorId", Long.class); + + public final StringPath dtype = createString("dtype"); + + public final NumberPath<Long> id = createNumber("id", Long.class); + + public final StringPath title = createString("title"); + + public final com.querydsl.sql.PrimaryKey<SBook> primary = createPrimaryKey(id); + + public final com.querydsl.sql.ForeignKey<SAuthor> fk599229686eaf51c = createForeignKey(authorId, "id"); + + public SBook(String variable) { + super(SBook.class, forVariable(variable), "", "book_"); + addMetadata(); + } + + public SBook(String variable, String schema, String table) { + super(SBook.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SBook(Path<? extends SBook> path) { + super(path.getType(), path.getMetadata(), "", "book_"); + addMetadata(); + } + + public SBook(PathMetadata metadata) { + super(SBook.class, metadata, "", "book_"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(authorId, ColumnMetadata.named("AUTHOR_ID").withIndex(4).ofType(-5).withSize(19)); + addMetadata(dtype, ColumnMetadata.named("DTYPE").withIndex(1).ofType(12).withSize(31).notNull()); + addMetadata(id, ColumnMetadata.named("id").withIndex(2).ofType(-5).withSize(19).notNull()); + addMetadata(title, ColumnMetadata.named("title").withIndex(3).ofType(12).withSize(255)); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SBookBookmarks.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SBookBookmarks.java new file mode 100644 index 0000000000..6b17b53134 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SBookBookmarks.java @@ -0,0 +1,69 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import java.util.Arrays; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.StringPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SBookBookmarks is a Querydsl query type for SBookBookmarks + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SBookBookmarks extends com.querydsl.sql.RelationalPathBase<SBookBookmarks> { + + private static final long serialVersionUID = -312126525; + + public static final SBookBookmarks bookBookmarks = new SBookBookmarks("book_bookmarks"); + + public final NumberPath<Integer> bookMarksORDER = createNumber("bookMarksORDER", Integer.class); + + public final NumberPath<Long> bookVersionBookIDIdentity = createNumber("bookVersionBookIDIdentity", Long.class); + + public final NumberPath<Long> bookVersionLibraryIdentity = createNumber("bookVersionLibraryIdentity", Long.class); + + public final StringPath comment = createString("comment"); + + public final NumberPath<Long> page = createNumber("page", Long.class); + + public final com.querydsl.sql.PrimaryKey<SBookBookmarks> primary = createPrimaryKey(bookVersionBookIDIdentity, bookVersionLibraryIdentity, bookMarksORDER); + + public final com.querydsl.sql.ForeignKey<SBookversion> fk94026827e33d3be4 = createForeignKey(Arrays.asList(bookVersionBookIDIdentity, bookVersionLibraryIdentity), Arrays.asList("bookID_identity", "library_identity")); + + public SBookBookmarks(String variable) { + super(SBookBookmarks.class, forVariable(variable), "", "book_bookmarks"); + addMetadata(); + } + + public SBookBookmarks(String variable, String schema, String table) { + super(SBookBookmarks.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SBookBookmarks(Path<? extends SBookBookmarks> path) { + super(path.getType(), path.getMetadata(), "", "book_bookmarks"); + addMetadata(); + } + + public SBookBookmarks(PathMetadata metadata) { + super(SBookBookmarks.class, metadata, "", "book_bookmarks"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(bookMarksORDER, ColumnMetadata.named("bookMarks_ORDER").withIndex(5).ofType(4).withSize(10).notNull()); + addMetadata(bookVersionBookIDIdentity, ColumnMetadata.named("BookVersion_bookID_identity").withIndex(1).ofType(-5).withSize(19).notNull()); + addMetadata(bookVersionLibraryIdentity, ColumnMetadata.named("BookVersion_library_identity").withIndex(2).ofType(-5).withSize(19).notNull()); + addMetadata(comment, ColumnMetadata.named("comment").withIndex(3).ofType(12).withSize(255)); + addMetadata(page, ColumnMetadata.named("page").withIndex(4).ofType(-5).withSize(19)); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SBookid.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SBookid.java new file mode 100644 index 0000000000..495a04f65f --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SBookid.java @@ -0,0 +1,54 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SBookid is a Querydsl query type for SBookid + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SBookid extends com.querydsl.sql.RelationalPathBase<SBookid> { + + private static final long serialVersionUID = -1577800438; + + public static final SBookid bookid_ = new SBookid("bookid_"); + + public final NumberPath<Long> identity = createNumber("identity", Long.class); + + public final com.querydsl.sql.PrimaryKey<SBookid> primary = createPrimaryKey(identity); + + public final com.querydsl.sql.ForeignKey<SBookversion> _fkef4bc0704dd5d6c3 = createInvForeignKey(identity, "bookID_identity"); + + public SBookid(String variable) { + super(SBookid.class, forVariable(variable), "", "bookid_"); + addMetadata(); + } + + public SBookid(String variable, String schema, String table) { + super(SBookid.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SBookid(Path<? extends SBookid> path) { + super(path.getType(), path.getMetadata(), "", "bookid_"); + addMetadata(); + } + + public SBookid(PathMetadata metadata) { + super(SBookid.class, metadata, "", "bookid_"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(identity, ColumnMetadata.named("identity").withIndex(1).ofType(-5).withSize(19).notNull()); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SBookversion.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SBookversion.java new file mode 100644 index 0000000000..a6bb0ffb42 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SBookversion.java @@ -0,0 +1,70 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import java.util.Arrays; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.StringPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SBookversion is a Querydsl query type for SBookversion + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SBookversion extends com.querydsl.sql.RelationalPathBase<SBookversion> { + + private static final long serialVersionUID = 1615296481; + + public static final SBookversion bookversion_ = new SBookversion("bookversion_"); + + public final NumberPath<Long> bookIDIdentity = createNumber("bookIDIdentity", Long.class); + + public final StringPath description = createString("description"); + + public final NumberPath<Long> libraryIdentity = createNumber("libraryIdentity", Long.class); + + public final StringPath name = createString("name"); + + public final com.querydsl.sql.PrimaryKey<SBookversion> primary = createPrimaryKey(bookIDIdentity, libraryIdentity); + + public final com.querydsl.sql.ForeignKey<SBookid> fkef4bc0704dd5d6c3 = createForeignKey(bookIDIdentity, "identity"); + + public final com.querydsl.sql.ForeignKey<SLibrary> fkef4bc070e364cd17 = createForeignKey(libraryIdentity, "identity"); + + public final com.querydsl.sql.ForeignKey<SBookBookmarks> _fk94026827e33d3be4 = createInvForeignKey(Arrays.asList(bookIDIdentity, libraryIdentity), Arrays.asList("BookVersion_bookID_identity", "BookVersion_library_identity")); + + public SBookversion(String variable) { + super(SBookversion.class, forVariable(variable), "", "bookversion_"); + addMetadata(); + } + + public SBookversion(String variable, String schema, String table) { + super(SBookversion.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SBookversion(Path<? extends SBookversion> path) { + super(path.getType(), path.getMetadata(), "", "bookversion_"); + addMetadata(); + } + + public SBookversion(PathMetadata metadata) { + super(SBookversion.class, metadata, "", "bookversion_"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(bookIDIdentity, ColumnMetadata.named("bookID_identity").withIndex(3).ofType(-5).withSize(19).notNull()); + addMetadata(description, ColumnMetadata.named("description").withIndex(1).ofType(12).withSize(255)); + addMetadata(libraryIdentity, ColumnMetadata.named("library_identity").withIndex(4).ofType(-5).withSize(19).notNull()); + addMetadata(name, ColumnMetadata.named("name").withIndex(2).ofType(12).withSize(255)); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SCalendar.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SCalendar.java new file mode 100644 index 0000000000..3c1c83d11d --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SCalendar.java @@ -0,0 +1,56 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SCalendar is a Querydsl query type for SCalendar + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SCalendar extends com.querydsl.sql.RelationalPathBase<SCalendar> { + + private static final long serialVersionUID = 885543696; + + public static final SCalendar calendar_ = new SCalendar("calendar_"); + + public final NumberPath<Integer> id = createNumber("id", Integer.class); + + public final com.querydsl.sql.PrimaryKey<SCalendar> primary = createPrimaryKey(id); + + public final com.querydsl.sql.ForeignKey<SCalendarHolidays> _fk31ce1edc591ebbc = createInvForeignKey(id, "Calendar_id"); + + public final com.querydsl.sql.ForeignKey<SNationality> _fkab8efa23591ebbc = createInvForeignKey(id, "calendar_id"); + + public SCalendar(String variable) { + super(SCalendar.class, forVariable(variable), "", "calendar_"); + addMetadata(); + } + + public SCalendar(String variable, String schema, String table) { + super(SCalendar.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SCalendar(Path<? extends SCalendar> path) { + super(path.getType(), path.getMetadata(), "", "calendar_"); + addMetadata(); + } + + public SCalendar(PathMetadata metadata) { + super(SCalendar.class, metadata, "", "calendar_"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(4).withSize(10).notNull()); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SCalendarHolidays.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SCalendarHolidays.java new file mode 100644 index 0000000000..1bd6864afc --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SCalendarHolidays.java @@ -0,0 +1,62 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.DatePath; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.StringPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SCalendarHolidays is a Querydsl query type for SCalendarHolidays + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SCalendarHolidays extends com.querydsl.sql.RelationalPathBase<SCalendarHolidays> { + + private static final long serialVersionUID = 850508650; + + public static final SCalendarHolidays CalendarHolidays = new SCalendarHolidays("Calendar_holidays"); + + public final NumberPath<Integer> calendarId = createNumber("calendarId", Integer.class); + + public final DatePath<java.sql.Date> holidays = createDate("holidays", java.sql.Date.class); + + public final StringPath holidaysKEY = createString("holidaysKEY"); + + public final com.querydsl.sql.PrimaryKey<SCalendarHolidays> primary = createPrimaryKey(calendarId, holidaysKEY); + + public final com.querydsl.sql.ForeignKey<SCalendar> fk31ce1edc591ebbc = createForeignKey(calendarId, "id"); + + public SCalendarHolidays(String variable) { + super(SCalendarHolidays.class, forVariable(variable), "", "Calendar_holidays"); + addMetadata(); + } + + public SCalendarHolidays(String variable, String schema, String table) { + super(SCalendarHolidays.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SCalendarHolidays(Path<? extends SCalendarHolidays> path) { + super(path.getType(), path.getMetadata(), "", "Calendar_holidays"); + addMetadata(); + } + + public SCalendarHolidays(PathMetadata metadata) { + super(SCalendarHolidays.class, metadata, "", "Calendar_holidays"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(calendarId, ColumnMetadata.named("Calendar_id").withIndex(1).ofType(4).withSize(10).notNull()); + addMetadata(holidays, ColumnMetadata.named("holidays").withIndex(2).ofType(91).withSize(10)); + addMetadata(holidaysKEY, ColumnMetadata.named("holidays_KEY").withIndex(3).ofType(12).withSize(255).notNull()); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SCatalog.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SCatalog.java new file mode 100644 index 0000000000..cfb7e80c78 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SCatalog.java @@ -0,0 +1,58 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.DatePath; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SCatalog is a Querydsl query type for SCatalog + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SCatalog extends com.querydsl.sql.RelationalPathBase<SCatalog> { + + private static final long serialVersionUID = 669498199; + + public static final SCatalog catalog_ = new SCatalog("catalog_"); + + public final DatePath<java.sql.Date> effectiveDate = createDate("effectiveDate", java.sql.Date.class); + + public final NumberPath<Integer> id = createNumber("id", Integer.class); + + public final com.querydsl.sql.PrimaryKey<SCatalog> primary = createPrimaryKey(id); + + public final com.querydsl.sql.ForeignKey<SCatalog_price> _fkaa04532fbb9021ab = createInvForeignKey(id, "catalog__id"); + + public SCatalog(String variable) { + super(SCatalog.class, forVariable(variable), "", "catalog_"); + addMetadata(); + } + + public SCatalog(String variable, String schema, String table) { + super(SCatalog.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SCatalog(Path<? extends SCatalog> path) { + super(path.getType(), path.getMetadata(), "", "catalog_"); + addMetadata(); + } + + public SCatalog(PathMetadata metadata) { + super(SCatalog.class, metadata, "", "catalog_"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(effectiveDate, ColumnMetadata.named("effectiveDate").withIndex(2).ofType(91).withSize(10)); + addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(4).withSize(10).notNull()); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SCatalog_price.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SCatalog_price.java new file mode 100644 index 0000000000..cada9216a3 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SCatalog_price.java @@ -0,0 +1,59 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SCatalog_price is a Querydsl query type for SCatalog_price + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SCatalog_price extends com.querydsl.sql.RelationalPathBase<SCatalog_price> { + + private static final long serialVersionUID = 1271141965; + + public static final SCatalog_price catalog_price_ = new SCatalog_price("catalog__price_"); + + public final NumberPath<Integer> catalog_id = createNumber("catalog_id", Integer.class); + + public final NumberPath<Long> pricesId = createNumber("pricesId", Long.class); + + public final com.querydsl.sql.PrimaryKey<SCatalog_price> primary = createPrimaryKey(catalog_id, pricesId); + + public final com.querydsl.sql.ForeignKey<SCatalog> fkaa04532fbb9021ab = createForeignKey(catalog_id, "id"); + + public final com.querydsl.sql.ForeignKey<SPrice> fkaa04532f5222eaf7 = createForeignKey(pricesId, "id"); + + public SCatalog_price(String variable) { + super(SCatalog_price.class, forVariable(variable), "", "catalog__price_"); + addMetadata(); + } + + public SCatalog_price(String variable, String schema, String table) { + super(SCatalog_price.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SCatalog_price(Path<? extends SCatalog_price> path) { + super(path.getType(), path.getMetadata(), "", "catalog__price_"); + addMetadata(); + } + + public SCatalog_price(PathMetadata metadata) { + super(SCatalog_price.class, metadata, "", "catalog__price_"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(catalog_id, ColumnMetadata.named("catalog__id").withIndex(1).ofType(4).withSize(10).notNull()); + addMetadata(pricesId, ColumnMetadata.named("prices_id").withIndex(2).ofType(-5).withSize(19).notNull()); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SCategory.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SCategory.java new file mode 100644 index 0000000000..b34d7c40b5 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SCategory.java @@ -0,0 +1,86 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.DateTimePath; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.StringPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SCategory is a Querydsl query type for SCategory + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SCategory extends com.querydsl.sql.RelationalPathBase<SCategory> { + + private static final long serialVersionUID = -610481840; + + public static final SCategory category_ = new SCategory("category_"); + + public final StringPath categoryDescription = createString("categoryDescription"); + + public final StringPath categoryName = createString("categoryName"); + + public final NumberPath<Double> createdBy = createNumber("createdBy", Double.class); + + public final DateTimePath<java.sql.Timestamp> creationDate = createDateTime("creationDate", java.sql.Timestamp.class); + + public final DateTimePath<java.sql.Timestamp> deleteDate = createDateTime("deleteDate", java.sql.Timestamp.class); + + public final NumberPath<Double> deletedBy = createNumber("deletedBy", Double.class); + + public final NumberPath<Long> id = createNumber("id", Long.class); + + public final DateTimePath<java.sql.Timestamp> modificationDate = createDateTime("modificationDate", java.sql.Timestamp.class); + + public final NumberPath<Double> modifiedBy = createNumber("modifiedBy", Double.class); + + public final com.querydsl.sql.PrimaryKey<SCategory> primary = createPrimaryKey(id); + + public final com.querydsl.sql.ForeignKey<SCategory_category> _fkc4e60b83561378ab = createInvForeignKey(id, "parentId"); + + public final com.querydsl.sql.ForeignKey<SUserprop_category> _fk851f48d37ab543e8 = createInvForeignKey(id, "childCategories_id"); + + public final com.querydsl.sql.ForeignKey<SCategory_categoryprop> _fk8543a2802974945f = createInvForeignKey(id, "category__id"); + + public final com.querydsl.sql.ForeignKey<SCategory_category> _fkc4e60b833c83109d = createInvForeignKey(id, "childId"); + + public SCategory(String variable) { + super(SCategory.class, forVariable(variable), "", "category_"); + addMetadata(); + } + + public SCategory(String variable, String schema, String table) { + super(SCategory.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SCategory(Path<? extends SCategory> path) { + super(path.getType(), path.getMetadata(), "", "category_"); + addMetadata(); + } + + public SCategory(PathMetadata metadata) { + super(SCategory.class, metadata, "", "category_"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(categoryDescription, ColumnMetadata.named("categoryDescription").withIndex(2).ofType(12).withSize(255)); + addMetadata(categoryName, ColumnMetadata.named("categoryName").withIndex(3).ofType(12).withSize(255)); + addMetadata(createdBy, ColumnMetadata.named("createdBy").withIndex(4).ofType(8).withSize(22).notNull()); + addMetadata(creationDate, ColumnMetadata.named("creationDate").withIndex(5).ofType(93).withSize(19)); + addMetadata(deleteDate, ColumnMetadata.named("deleteDate").withIndex(6).ofType(93).withSize(19)); + addMetadata(deletedBy, ColumnMetadata.named("deletedBy").withIndex(7).ofType(8).withSize(22).notNull()); + addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(-5).withSize(19).notNull()); + addMetadata(modificationDate, ColumnMetadata.named("modificationDate").withIndex(8).ofType(93).withSize(19)); + addMetadata(modifiedBy, ColumnMetadata.named("modifiedBy").withIndex(9).ofType(8).withSize(22).notNull()); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SCategory_category.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SCategory_category.java new file mode 100644 index 0000000000..3a9dae7325 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SCategory_category.java @@ -0,0 +1,59 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SCategory_category_ is a Querydsl query type for SCategory_category_ + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SCategory_category extends com.querydsl.sql.RelationalPathBase<SCategory_category> { + + private static final long serialVersionUID = -771910703; + + public static final SCategory_category category_category_ = new SCategory_category("category__category_"); + + public final NumberPath<Long> childId = createNumber("childId", Long.class); + + public final NumberPath<Long> parentId = createNumber("parentId", Long.class); + + public final com.querydsl.sql.PrimaryKey<SCategory_category> primary = createPrimaryKey(childId, parentId); + + public final com.querydsl.sql.ForeignKey<SCategory> fkc4e60b83561378ab = createForeignKey(parentId, "id"); + + public final com.querydsl.sql.ForeignKey<SCategory> fkc4e60b833c83109d = createForeignKey(childId, "id"); + + public SCategory_category(String variable) { + super(SCategory_category.class, forVariable(variable), "", "category__category_"); + addMetadata(); + } + + public SCategory_category(String variable, String schema, String table) { + super(SCategory_category.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SCategory_category(Path<? extends SCategory_category> path) { + super(path.getType(), path.getMetadata(), "", "category__category_"); + addMetadata(); + } + + public SCategory_category(PathMetadata metadata) { + super(SCategory_category.class, metadata, "", "category__category_"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(childId, ColumnMetadata.named("childId").withIndex(2).ofType(-5).withSize(19).notNull()); + addMetadata(parentId, ColumnMetadata.named("parentId").withIndex(1).ofType(-5).withSize(19).notNull()); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SCategory_categoryprop.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SCategory_categoryprop.java new file mode 100644 index 0000000000..4273074ce3 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SCategory_categoryprop.java @@ -0,0 +1,59 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SCategory_categoryprop is a Querydsl query type for SCategory_categoryprop + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SCategory_categoryprop extends com.querydsl.sql.RelationalPathBase<SCategory_categoryprop> { + + private static final long serialVersionUID = -1348316210; + + public static final SCategory_categoryprop category_categoryprop_ = new SCategory_categoryprop("category__categoryprop_"); + + public final NumberPath<Long> category_id = createNumber("category_id", Long.class); + + public final NumberPath<Long> propertiesId = createNumber("propertiesId", Long.class); + + public final com.querydsl.sql.PrimaryKey<SCategory_categoryprop> primary = createPrimaryKey(category_id, propertiesId); + + public final com.querydsl.sql.ForeignKey<SCategoryprop> fk8543a280fd94cd90 = createForeignKey(propertiesId, "id"); + + public final com.querydsl.sql.ForeignKey<SCategory> fk8543a2802974945f = createForeignKey(category_id, "id"); + + public SCategory_categoryprop(String variable) { + super(SCategory_categoryprop.class, forVariable(variable), "", "category__categoryprop_"); + addMetadata(); + } + + public SCategory_categoryprop(String variable, String schema, String table) { + super(SCategory_categoryprop.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SCategory_categoryprop(Path<? extends SCategory_categoryprop> path) { + super(path.getType(), path.getMetadata(), "", "category__categoryprop_"); + addMetadata(); + } + + public SCategory_categoryprop(PathMetadata metadata) { + super(SCategory_categoryprop.class, metadata, "", "category__categoryprop_"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(category_id, ColumnMetadata.named("category__id").withIndex(1).ofType(-5).withSize(19).notNull()); + addMetadata(propertiesId, ColumnMetadata.named("properties_id").withIndex(2).ofType(-5).withSize(19).notNull()); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SCategoryprop.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SCategoryprop.java new file mode 100644 index 0000000000..00ae5577b3 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SCategoryprop.java @@ -0,0 +1,66 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.StringPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SCategoryprop is a Querydsl query type for SCategoryprop + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SCategoryprop extends com.querydsl.sql.RelationalPathBase<SCategoryprop> { + + private static final long serialVersionUID = -1013141043; + + public static final SCategoryprop categoryprop_ = new SCategoryprop("categoryprop_"); + + public final NumberPath<Long> categoryId = createNumber("categoryId", Long.class); + + public final NumberPath<Long> id = createNumber("id", Long.class); + + public final StringPath propName = createString("propName"); + + public final StringPath propValue = createString("propValue"); + + public final com.querydsl.sql.PrimaryKey<SCategoryprop> primary = createPrimaryKey(id); + + public final com.querydsl.sql.ForeignKey<SUserprop_categoryprop> _fke0fdb7d0fd94cd90 = createInvForeignKey(id, "properties_id"); + + public final com.querydsl.sql.ForeignKey<SCategory_categoryprop> _fk8543a280fd94cd90 = createInvForeignKey(id, "properties_id"); + + public SCategoryprop(String variable) { + super(SCategoryprop.class, forVariable(variable), "", "categoryprop_"); + addMetadata(); + } + + public SCategoryprop(String variable, String schema, String table) { + super(SCategoryprop.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SCategoryprop(Path<? extends SCategoryprop> path) { + super(path.getType(), path.getMetadata(), "", "categoryprop_"); + addMetadata(); + } + + public SCategoryprop(PathMetadata metadata) { + super(SCategoryprop.class, metadata, "", "categoryprop_"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(categoryId, ColumnMetadata.named("categoryId").withIndex(2).ofType(-5).withSize(19).notNull()); + addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(-5).withSize(19).notNull()); + addMetadata(propName, ColumnMetadata.named("propName").withIndex(3).ofType(12).withSize(255)); + addMetadata(propValue, ColumnMetadata.named("propValue").withIndex(4).ofType(12).withSize(255)); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SChild2.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SChild2.java new file mode 100644 index 0000000000..38f541bbce --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SChild2.java @@ -0,0 +1,57 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SChild2 is a Querydsl query type for SChild2 + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SChild2 extends com.querydsl.sql.RelationalPathBase<SChild2> { + + private static final long serialVersionUID = 386731719; + + public static final SChild2 Child2 = new SChild2("Child2"); + + public final NumberPath<Integer> id = createNumber("id", Integer.class); + + public final NumberPath<Integer> parentId = createNumber("parentId", Integer.class); + + public final com.querydsl.sql.PrimaryKey<SChild2> primary = createPrimaryKey(id); + + public final com.querydsl.sql.ForeignKey<SParent2> fk783f9ab6c2dbacbc = createForeignKey(parentId, "id"); + + public SChild2(String variable) { + super(SChild2.class, forVariable(variable), "", "Child2"); + addMetadata(); + } + + public SChild2(String variable, String schema, String table) { + super(SChild2.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SChild2(Path<? extends SChild2> path) { + super(path.getType(), path.getMetadata(), "", "Child2"); + addMetadata(); + } + + public SChild2(PathMetadata metadata) { + super(SChild2.class, metadata, "", "Child2"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(4).withSize(10).notNull()); + addMetadata(parentId, ColumnMetadata.named("parent_id").withIndex(2).ofType(4).withSize(10)); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SCompany.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SCompany.java new file mode 100644 index 0000000000..89674d2f19 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SCompany.java @@ -0,0 +1,75 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.StringPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SCompany is a Querydsl query type for SCompany + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SCompany extends com.querydsl.sql.RelationalPathBase<SCompany> { + + private static final long serialVersionUID = 22768499; + + public static final SCompany company_ = new SCompany("company_"); + + public final NumberPath<Integer> ceoId = createNumber("ceoId", Integer.class); + + public final NumberPath<Integer> id = createNumber("id", Integer.class); + + public final StringPath name = createString("name"); + + public final NumberPath<Integer> ratingOrdinal = createNumber("ratingOrdinal", Integer.class); + + public final StringPath ratingString = createString("ratingString"); + + public final com.querydsl.sql.PrimaryKey<SCompany> primary = createPrimaryKey(id); + + public final com.querydsl.sql.ForeignKey<SEmployee> fkdc405382edf003bd = createForeignKey(ceoId, "id"); + + public final com.querydsl.sql.ForeignKey<SEmployee> _fk9d39ef71dc953998 = createInvForeignKey(id, "company_id"); + + public final com.querydsl.sql.ForeignKey<SUser> _fk6a68df4dc953998 = createInvForeignKey(id, "company_id"); + + public final com.querydsl.sql.ForeignKey<SCompany_department> _fk100ba610f0d30873 = createInvForeignKey(id, "company__id"); + + public final com.querydsl.sql.ForeignKey<SDepartment> _fk1f3a274ddc953998 = createInvForeignKey(id, "company_id"); + + public SCompany(String variable) { + super(SCompany.class, forVariable(variable), "", "company_"); + addMetadata(); + } + + public SCompany(String variable, String schema, String table) { + super(SCompany.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SCompany(Path<? extends SCompany> path) { + super(path.getType(), path.getMetadata(), "", "company_"); + addMetadata(); + } + + public SCompany(PathMetadata metadata) { + super(SCompany.class, metadata, "", "company_"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(ceoId, ColumnMetadata.named("ceo_id").withIndex(5).ofType(4).withSize(10)); + addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(4).withSize(10).notNull()); + addMetadata(name, ColumnMetadata.named("name").withIndex(2).ofType(12).withSize(255)); + addMetadata(ratingOrdinal, ColumnMetadata.named("ratingOrdinal").withIndex(3).ofType(4).withSize(10)); + addMetadata(ratingString, ColumnMetadata.named("ratingString").withIndex(4).ofType(12).withSize(255)); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SCompany_department.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SCompany_department.java new file mode 100644 index 0000000000..7c6f176706 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SCompany_department.java @@ -0,0 +1,57 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SCompany_department is a Querydsl query type for SCompany_department + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SCompany_department extends com.querydsl.sql.RelationalPathBase<SCompany_department> { + + private static final long serialVersionUID = -68475398; + + public static final SCompany_department company_department_ = new SCompany_department("company__department_"); + + public final NumberPath<Integer> company_id = createNumber("company_id", Integer.class); + + public final NumberPath<Integer> departmentsId = createNumber("departmentsId", Integer.class); + + public final com.querydsl.sql.ForeignKey<SDepartment> fk100ba6107d36c84d = createForeignKey(departmentsId, "id"); + + public final com.querydsl.sql.ForeignKey<SCompany> fk100ba610f0d30873 = createForeignKey(company_id, "id"); + + public SCompany_department(String variable) { + super(SCompany_department.class, forVariable(variable), "", "company__department_"); + addMetadata(); + } + + public SCompany_department(String variable, String schema, String table) { + super(SCompany_department.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SCompany_department(Path<? extends SCompany_department> path) { + super(path.getType(), path.getMetadata(), "", "company__department_"); + addMetadata(); + } + + public SCompany_department(PathMetadata metadata) { + super(SCompany_department.class, metadata, "", "company__department_"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(company_id, ColumnMetadata.named("company__id").withIndex(1).ofType(4).withSize(10).notNull()); + addMetadata(departmentsId, ColumnMetadata.named("departments_id").withIndex(2).ofType(4).withSize(10).notNull()); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SCustomer.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SCustomer.java new file mode 100644 index 0000000000..43ce811947 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SCustomer.java @@ -0,0 +1,66 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SCustomer is a Querydsl query type for SCustomer + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SCustomer extends com.querydsl.sql.RelationalPathBase<SCustomer> { + + private static final long serialVersionUID = -564764048; + + public static final SCustomer customer_ = new SCustomer("customer_"); + + public final NumberPath<Long> currentOrderId = createNumber("currentOrderId", Long.class); + + public final NumberPath<Integer> id = createNumber("id", Integer.class); + + public final NumberPath<Long> nameId = createNumber("nameId", Long.class); + + public final com.querydsl.sql.PrimaryKey<SCustomer> primary = createPrimaryKey(id); + + public final com.querydsl.sql.ForeignKey<SName> fk600e7c4196a83d9c = createForeignKey(nameId, "id"); + + public final com.querydsl.sql.ForeignKey<SOrder> fk600e7c419cc457f1 = createForeignKey(currentOrderId, "id"); + + public final com.querydsl.sql.ForeignKey<SStore_customer> _fk82ba2ce051f3c3e5 = createInvForeignKey(id, "customers_id"); + + public final com.querydsl.sql.ForeignKey<SOrder> _fkc3df62d1b29c27bc = createInvForeignKey(id, "customer_id"); + + public SCustomer(String variable) { + super(SCustomer.class, forVariable(variable), "", "customer_"); + addMetadata(); + } + + public SCustomer(String variable, String schema, String table) { + super(SCustomer.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SCustomer(Path<? extends SCustomer> path) { + super(path.getType(), path.getMetadata(), "", "customer_"); + addMetadata(); + } + + public SCustomer(PathMetadata metadata) { + super(SCustomer.class, metadata, "", "customer_"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(currentOrderId, ColumnMetadata.named("currentOrder_id").withIndex(2).ofType(-5).withSize(19)); + addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(4).withSize(10).notNull()); + addMetadata(nameId, ColumnMetadata.named("name_id").withIndex(3).ofType(-5).withSize(19)); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SDateTest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SDateTest.java new file mode 100644 index 0000000000..cf5ef076b4 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SDateTest.java @@ -0,0 +1,50 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.DatePath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SDateTest is a Querydsl query type for SDateTest + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SDateTest extends com.querydsl.sql.RelationalPathBase<SDateTest> { + + private static final long serialVersionUID = -1879688879; + + public static final SDateTest dateTest1 = new SDateTest("DATE_TEST"); + + public final DatePath<java.sql.Date> dateTest = createDate("dateTest", java.sql.Date.class); + + public SDateTest(String variable) { + super(SDateTest.class, forVariable(variable), "", "DATE_TEST"); + addMetadata(); + } + + public SDateTest(String variable, String schema, String table) { + super(SDateTest.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SDateTest(Path<? extends SDateTest> path) { + super(path.getType(), path.getMetadata(), "", "DATE_TEST"); + addMetadata(); + } + + public SDateTest(PathMetadata metadata) { + super(SDateTest.class, metadata, "", "DATE_TEST"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(dateTest, ColumnMetadata.named("DATE_TEST").withIndex(1).ofType(91).withSize(10)); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SDepartment.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SDepartment.java new file mode 100644 index 0000000000..02a635223f --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SDepartment.java @@ -0,0 +1,65 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.StringPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SDepartment is a Querydsl query type for SDepartment + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SDepartment extends com.querydsl.sql.RelationalPathBase<SDepartment> { + + private static final long serialVersionUID = 723598780; + + public static final SDepartment department_ = new SDepartment("department_"); + + public final NumberPath<Integer> companyId = createNumber("companyId", Integer.class); + + public final NumberPath<Integer> id = createNumber("id", Integer.class); + + public final StringPath name = createString("name"); + + public final com.querydsl.sql.PrimaryKey<SDepartment> primary = createPrimaryKey(id); + + public final com.querydsl.sql.ForeignKey<SCompany> fk1f3a274ddc953998 = createForeignKey(companyId, "id"); + + public final com.querydsl.sql.ForeignKey<SCompany_department> _fk100ba6107d36c84d = createInvForeignKey(id, "departments_id"); + + public final com.querydsl.sql.ForeignKey<SDepartment_employee> _fkc33a14ff7d2db0e1 = createInvForeignKey(id, "department__id"); + + public SDepartment(String variable) { + super(SDepartment.class, forVariable(variable), "", "department_"); + addMetadata(); + } + + public SDepartment(String variable, String schema, String table) { + super(SDepartment.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SDepartment(Path<? extends SDepartment> path) { + super(path.getType(), path.getMetadata(), "", "department_"); + addMetadata(); + } + + public SDepartment(PathMetadata metadata) { + super(SDepartment.class, metadata, "", "department_"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(companyId, ColumnMetadata.named("company_id").withIndex(3).ofType(4).withSize(10)); + addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(4).withSize(10).notNull()); + addMetadata(name, ColumnMetadata.named("name").withIndex(2).ofType(12).withSize(255)); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SDepartment_employee.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SDepartment_employee.java new file mode 100644 index 0000000000..4464fef5e2 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SDepartment_employee.java @@ -0,0 +1,57 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SDepartment_employee is a Querydsl query type for SDepartment_employee + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SDepartment_employee extends com.querydsl.sql.RelationalPathBase<SDepartment_employee> { + + private static final long serialVersionUID = 1293706549; + + public static final SDepartment_employee department_employee_ = new SDepartment_employee("department__employee_"); + + public final NumberPath<Integer> department_id = createNumber("department_id", Integer.class); + + public final NumberPath<Integer> employeesId = createNumber("employeesId", Integer.class); + + public final com.querydsl.sql.ForeignKey<SEmployee> fkc33a14ffd846a985 = createForeignKey(employeesId, "id"); + + public final com.querydsl.sql.ForeignKey<SDepartment> fkc33a14ff7d2db0e1 = createForeignKey(department_id, "id"); + + public SDepartment_employee(String variable) { + super(SDepartment_employee.class, forVariable(variable), "", "department__employee_"); + addMetadata(); + } + + public SDepartment_employee(String variable, String schema, String table) { + super(SDepartment_employee.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SDepartment_employee(Path<? extends SDepartment_employee> path) { + super(path.getType(), path.getMetadata(), "", "department__employee_"); + addMetadata(); + } + + public SDepartment_employee(PathMetadata metadata) { + super(SDepartment_employee.class, metadata, "", "department__employee_"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(department_id, ColumnMetadata.named("department__id").withIndex(1).ofType(4).withSize(10).notNull()); + addMetadata(employeesId, ColumnMetadata.named("employees_id").withIndex(2).ofType(4).withSize(10).notNull()); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SDocument.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SDocument.java new file mode 100644 index 0000000000..35a4adefd1 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SDocument.java @@ -0,0 +1,60 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.DatePath; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.StringPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SDocument is a Querydsl query type for SDocument + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SDocument extends com.querydsl.sql.RelationalPathBase<SDocument> { + + private static final long serialVersionUID = -1232783149; + + public static final SDocument document_ = new SDocument("document_"); + + public final NumberPath<Integer> id = createNumber("id", Integer.class); + + public final StringPath name = createString("name"); + + public final DatePath<java.sql.Date> validTo = createDate("validTo", java.sql.Date.class); + + public final com.querydsl.sql.PrimaryKey<SDocument> primary = createPrimaryKey(id); + + public SDocument(String variable) { + super(SDocument.class, forVariable(variable), "", "document_"); + addMetadata(); + } + + public SDocument(String variable, String schema, String table) { + super(SDocument.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SDocument(Path<? extends SDocument> path) { + super(path.getType(), path.getMetadata(), "", "document_"); + addMetadata(); + } + + public SDocument(PathMetadata metadata) { + super(SDocument.class, metadata, "", "document_"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(4).withSize(10).notNull()); + addMetadata(name, ColumnMetadata.named("name").withIndex(2).ofType(12).withSize(255)); + addMetadata(validTo, ColumnMetadata.named("validTo").withIndex(3).ofType(91).withSize(10)); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SDocument2.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SDocument2.java similarity index 79% rename from querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SDocument2.java rename to querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SDocument2.java index 9333895c9b..3a680da13a 100644 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SDocument2.java +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SDocument2.java @@ -1,21 +1,22 @@ -package com.mysema.query.jpa.domain.sql; +package com.querydsl.jpa.domain.sql; -import static com.mysema.query.types.PathMetadataFactory.*; +import static com.querydsl.core.types.PathMetadataFactory.forVariable; -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; import javax.annotation.Generated; -import com.mysema.query.types.Path; -import com.mysema.query.sql.ColumnMetadata; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.DateTimePath; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.StringPath; +import com.querydsl.sql.ColumnMetadata; /** * SDocument2 is a Querydsl query type for SDocument2 */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SDocument2 extends com.mysema.query.sql.RelationalPathBase<SDocument2> { +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SDocument2 extends com.querydsl.sql.RelationalPathBase<SDocument2> { private static final long serialVersionUID = 438426745; @@ -47,10 +48,10 @@ public class SDocument2 extends com.mysema.query.sql.RelationalPathBase<SDocumen public final NumberPath<Double> modifiedBy = createNumber("modifiedBy", Double.class); - public final com.mysema.query.sql.PrimaryKey<SDocument2> primary = createPrimaryKey(id); + public final com.querydsl.sql.PrimaryKey<SDocument2> primary = createPrimaryKey(id); public SDocument2(String variable) { - super(SDocument2.class, forVariable(variable), "null", "document2_"); + super(SDocument2.class, forVariable(variable), "", "document2_"); addMetadata(); } @@ -60,12 +61,12 @@ public SDocument2(String variable, String schema, String table) { } public SDocument2(Path<? extends SDocument2> path) { - super(path.getType(), path.getMetadata(), "null", "document2_"); + super(path.getType(), path.getMetadata(), "", "document2_"); addMetadata(); } - public SDocument2(PathMetadata<?> metadata) { - super(SDocument2.class, metadata, "null", "document2_"); + public SDocument2(PathMetadata metadata) { + super(SDocument2.class, metadata, "", "document2_"); addMetadata(); } diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SDocumentprop.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SDocumentprop.java new file mode 100644 index 0000000000..d8ffd45dd4 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SDocumentprop.java @@ -0,0 +1,65 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.StringPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SDocumentprop is a Querydsl query type for SDocumentprop + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SDocumentprop extends com.querydsl.sql.RelationalPathBase<SDocumentprop> { + + private static final long serialVersionUID = 233547728; + + public static final SDocumentprop documentprop_ = new SDocumentprop("documentprop_"); + + public final NumberPath<Double> documentId = createNumber("documentId", Double.class); + + public final NumberPath<Long> id = createNumber("id", Long.class); + + public final StringPath propName = createString("propName"); + + public final StringPath propValue = createString("propValue"); + + public final StringPath propValueDetails = createString("propValueDetails"); + + public final com.querydsl.sql.PrimaryKey<SDocumentprop> primary = createPrimaryKey(id); + + public SDocumentprop(String variable) { + super(SDocumentprop.class, forVariable(variable), "", "documentprop_"); + addMetadata(); + } + + public SDocumentprop(String variable, String schema, String table) { + super(SDocumentprop.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SDocumentprop(Path<? extends SDocumentprop> path) { + super(path.getType(), path.getMetadata(), "", "documentprop_"); + addMetadata(); + } + + public SDocumentprop(PathMetadata metadata) { + super(SDocumentprop.class, metadata, "", "documentprop_"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(documentId, ColumnMetadata.named("documentId").withIndex(2).ofType(8).withSize(22).notNull()); + addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(-5).withSize(19).notNull()); + addMetadata(propName, ColumnMetadata.named("propName").withIndex(3).ofType(12).withSize(255)); + addMetadata(propValue, ColumnMetadata.named("propValue").withIndex(4).ofType(12).withSize(255)); + addMetadata(propValueDetails, ColumnMetadata.named("propValueDetails").withIndex(5).ofType(12).withSize(255)); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SEmployee.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SEmployee.java new file mode 100644 index 0000000000..f2efb024b8 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SEmployee.java @@ -0,0 +1,75 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.StringPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SEmployee is a Querydsl query type for SEmployee + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SEmployee extends com.querydsl.sql.RelationalPathBase<SEmployee> { + + private static final long serialVersionUID = 461493664; + + public static final SEmployee employee_ = new SEmployee("employee_"); + + public final NumberPath<Integer> companyId = createNumber("companyId", Integer.class); + + public final StringPath firstName = createString("firstName"); + + public final NumberPath<Integer> id = createNumber("id", Integer.class); + + public final StringPath lastName = createString("lastName"); + + public final NumberPath<Long> userId = createNumber("userId", Long.class); + + public final com.querydsl.sql.PrimaryKey<SEmployee> primary = createPrimaryKey(id); + + public final com.querydsl.sql.ForeignKey<SCompany> fk9d39ef71dc953998 = createForeignKey(companyId, "id"); + + public final com.querydsl.sql.ForeignKey<SUser> fk9d39ef712743b59c = createForeignKey(userId, "id"); + + public final com.querydsl.sql.ForeignKey<SCompany> _fkdc405382edf003bd = createInvForeignKey(id, "ceo_id"); + + public final com.querydsl.sql.ForeignKey<SEmployeeJobFunctions> _fk49690e2f75b8f5bc = createInvForeignKey(id, "Employee_id"); + + public final com.querydsl.sql.ForeignKey<SDepartment_employee> _fkc33a14ffd846a985 = createInvForeignKey(id, "employees_id"); + + public SEmployee(String variable) { + super(SEmployee.class, forVariable(variable), "", "employee_"); + addMetadata(); + } + + public SEmployee(String variable, String schema, String table) { + super(SEmployee.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SEmployee(Path<? extends SEmployee> path) { + super(path.getType(), path.getMetadata(), "", "employee_"); + addMetadata(); + } + + public SEmployee(PathMetadata metadata) { + super(SEmployee.class, metadata, "", "employee_"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(companyId, ColumnMetadata.named("company_id").withIndex(4).ofType(4).withSize(10)); + addMetadata(firstName, ColumnMetadata.named("firstName").withIndex(2).ofType(12).withSize(255)); + addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(4).withSize(10).notNull()); + addMetadata(lastName, ColumnMetadata.named("lastName").withIndex(3).ofType(12).withSize(255)); + addMetadata(userId, ColumnMetadata.named("user_id").withIndex(5).ofType(-5).withSize(19)); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SEmployeeJobFunctions.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SEmployeeJobFunctions.java new file mode 100644 index 0000000000..82c1978b49 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SEmployeeJobFunctions.java @@ -0,0 +1,56 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.StringPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SEmployeeJobFunctions is a Querydsl query type for SEmployeeJobFunctions + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SEmployeeJobFunctions extends com.querydsl.sql.RelationalPathBase<SEmployeeJobFunctions> { + + private static final long serialVersionUID = -666645347; + + public static final SEmployeeJobFunctions EmployeeJobFunctions = new SEmployeeJobFunctions("Employee_jobFunctions"); + + public final NumberPath<Integer> employeeId = createNumber("employeeId", Integer.class); + + public final StringPath jobfunction = createString("jobfunction"); + + public final com.querydsl.sql.ForeignKey<SEmployee> fk49690e2f75b8f5bc = createForeignKey(employeeId, "id"); + + public SEmployeeJobFunctions(String variable) { + super(SEmployeeJobFunctions.class, forVariable(variable), "", "Employee_jobFunctions"); + addMetadata(); + } + + public SEmployeeJobFunctions(String variable, String schema, String table) { + super(SEmployeeJobFunctions.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SEmployeeJobFunctions(Path<? extends SEmployeeJobFunctions> path) { + super(path.getType(), path.getMetadata(), "", "Employee_jobFunctions"); + addMetadata(); + } + + public SEmployeeJobFunctions(PathMetadata metadata) { + super(SEmployeeJobFunctions.class, metadata, "", "Employee_jobFunctions"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(employeeId, ColumnMetadata.named("Employee_id").withIndex(1).ofType(4).withSize(10).notNull()); + addMetadata(jobfunction, ColumnMetadata.named("jobfunction").withIndex(2).ofType(12).withSize(255)); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SEntity1.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SEntity1.java new file mode 100644 index 0000000000..01fb772b08 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SEntity1.java @@ -0,0 +1,62 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.StringPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SEntity1 is a Querydsl query type for SEntity1 + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SEntity1 extends com.querydsl.sql.RelationalPathBase<SEntity1> { + + private static final long serialVersionUID = 1060650653; + + public static final SEntity1 Entity1 = new SEntity1("Entity1"); + + public final StringPath dtype = createString("dtype"); + + public final NumberPath<Integer> id = createNumber("id", Integer.class); + + public final StringPath property = createString("property"); + + public final StringPath property2 = createString("property2"); + + public final com.querydsl.sql.PrimaryKey<SEntity1> primary = createPrimaryKey(id); + + public SEntity1(String variable) { + super(SEntity1.class, forVariable(variable), "", "Entity1"); + addMetadata(); + } + + public SEntity1(String variable, String schema, String table) { + super(SEntity1.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SEntity1(Path<? extends SEntity1> path) { + super(path.getType(), path.getMetadata(), "", "Entity1"); + addMetadata(); + } + + public SEntity1(PathMetadata metadata) { + super(SEntity1.class, metadata, "", "Entity1"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(dtype, ColumnMetadata.named("DTYPE").withIndex(1).ofType(12).withSize(31).notNull()); + addMetadata(id, ColumnMetadata.named("id").withIndex(2).ofType(4).withSize(10).notNull()); + addMetadata(property, ColumnMetadata.named("property").withIndex(3).ofType(12).withSize(255)); + addMetadata(property2, ColumnMetadata.named("property2").withIndex(4).ofType(12).withSize(255)); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SEviltype.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SEviltype.java new file mode 100644 index 0000000000..01ef815754 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SEviltype.java @@ -0,0 +1,143 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SEviltype is a Querydsl query type for SEviltype + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SEviltype extends com.querydsl.sql.RelationalPathBase<SEviltype> { + + private static final long serialVersionUID = 1348954496; + + public static final SEviltype eviltype_ = new SEviltype("eviltype_"); + + public final NumberPath<Integer> _asc = createNumber("_asc", Integer.class); + + public final NumberPath<Integer> _desc = createNumber("_desc", Integer.class); + + public final NumberPath<Integer> getClassId = createNumber("getClassId", Integer.class); + + public final NumberPath<Integer> getId = createNumber("getId", Integer.class); + + public final NumberPath<Integer> getMetadataId = createNumber("getMetadataId", Integer.class); + + public final NumberPath<Integer> getTypeId = createNumber("getTypeId", Integer.class); + + public final NumberPath<Integer> hashCodeId = createNumber("hashCodeId", Integer.class); + + public final NumberPath<Integer> id = createNumber("id", Integer.class); + + public final NumberPath<Integer> isnotnullId = createNumber("isnotnullId", Integer.class); + + public final NumberPath<Integer> isnullId = createNumber("isnullId", Integer.class); + + public final NumberPath<Integer> notifyAllId = createNumber("notifyAllId", Integer.class); + + public final NumberPath<Integer> notifyId = createNumber("notifyId", Integer.class); + + public final NumberPath<Integer> toStringId = createNumber("toStringId", Integer.class); + + public final NumberPath<Integer> waitId = createNumber("waitId", Integer.class); + + public final com.querydsl.sql.PrimaryKey<SEviltype> primary = createPrimaryKey(id); + + public final com.querydsl.sql.ForeignKey<SEviltype> fkd21f83516787cd9e = createForeignKey(toStringId, "id"); + + public final com.querydsl.sql.ForeignKey<SEviltype> fkd21f835114c0ad20 = createForeignKey(_desc, "id"); + + public final com.querydsl.sql.ForeignKey<SEviltype> fkd21f835151e065d5 = createForeignKey(waitId, "id"); + + public final com.querydsl.sql.ForeignKey<SEviltype> fkd21f83517e62bab2 = createForeignKey(notifyAllId, "id"); + + public final com.querydsl.sql.ForeignKey<SEviltype> fkd21f8351c4df9054 = createForeignKey(getId, "id"); + + public final com.querydsl.sql.ForeignKey<SEviltype> fkd21f835112489019 = createForeignKey(isnullId, "id"); + + public final com.querydsl.sql.ForeignKey<SEviltype> fkd21f8351b09c8448 = createForeignKey(getClassId, "id"); + + public final com.querydsl.sql.ForeignKey<SEviltype> fkd21f835180b69f81 = createForeignKey(notifyId, "id"); + + public final com.querydsl.sql.ForeignKey<SEviltype> fkd21f8351b71279da = createForeignKey(getTypeId, "id"); + + public final com.querydsl.sql.ForeignKey<SEviltype> fkd21f8351226ee98f = createForeignKey(hashCodeId, "id"); + + public final com.querydsl.sql.ForeignKey<SEviltype> fkd21f8351f5ec12fa = createForeignKey(isnotnullId, "id"); + + public final com.querydsl.sql.ForeignKey<SEviltype> fkd21f8351f839f62 = createForeignKey(_asc, "id"); + + public final com.querydsl.sql.ForeignKey<SEviltype> fkd21f83512d7708c5 = createForeignKey(getMetadataId, "id"); + + public final com.querydsl.sql.ForeignKey<SEviltype> _fkd21f83516787cd9e = createInvForeignKey(id, "toString_id"); + + public final com.querydsl.sql.ForeignKey<SEviltype> _fkd21f835114c0ad20 = createInvForeignKey(id, "_desc"); + + public final com.querydsl.sql.ForeignKey<SEviltype> _fkd21f835151e065d5 = createInvForeignKey(id, "wait_id"); + + public final com.querydsl.sql.ForeignKey<SEviltype> _fkd21f83517e62bab2 = createInvForeignKey(id, "notifyAll_id"); + + public final com.querydsl.sql.ForeignKey<SEviltype> _fkd21f8351c4df9054 = createInvForeignKey(id, "get_id"); + + public final com.querydsl.sql.ForeignKey<SEviltype> _fkd21f835112489019 = createInvForeignKey(id, "isnull_id"); + + public final com.querydsl.sql.ForeignKey<SEviltype> _fkd21f8351b09c8448 = createInvForeignKey(id, "getClass_id"); + + public final com.querydsl.sql.ForeignKey<SEviltype> _fkd21f835180b69f81 = createInvForeignKey(id, "notify_id"); + + public final com.querydsl.sql.ForeignKey<SEviltype> _fkd21f8351b71279da = createInvForeignKey(id, "getType_id"); + + public final com.querydsl.sql.ForeignKey<SEviltype> _fkd21f8351226ee98f = createInvForeignKey(id, "hashCode_id"); + + public final com.querydsl.sql.ForeignKey<SEviltype> _fkd21f8351f5ec12fa = createInvForeignKey(id, "isnotnull_id"); + + public final com.querydsl.sql.ForeignKey<SEviltype> _fkd21f8351f839f62 = createInvForeignKey(id, "_asc"); + + public final com.querydsl.sql.ForeignKey<SEviltype> _fkd21f83512d7708c5 = createInvForeignKey(id, "getMetadata_id"); + + public SEviltype(String variable) { + super(SEviltype.class, forVariable(variable), "", "eviltype_"); + addMetadata(); + } + + public SEviltype(String variable, String schema, String table) { + super(SEviltype.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SEviltype(Path<? extends SEviltype> path) { + super(path.getType(), path.getMetadata(), "", "eviltype_"); + addMetadata(); + } + + public SEviltype(PathMetadata metadata) { + super(SEviltype.class, metadata, "", "eviltype_"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(_asc, ColumnMetadata.named("_asc").withIndex(2).ofType(4).withSize(10)); + addMetadata(_desc, ColumnMetadata.named("_desc").withIndex(3).ofType(4).withSize(10)); + addMetadata(getClassId, ColumnMetadata.named("getClass_id").withIndex(5).ofType(4).withSize(10)); + addMetadata(getId, ColumnMetadata.named("get_id").withIndex(4).ofType(4).withSize(10)); + addMetadata(getMetadataId, ColumnMetadata.named("getMetadata_id").withIndex(6).ofType(4).withSize(10)); + addMetadata(getTypeId, ColumnMetadata.named("getType_id").withIndex(7).ofType(4).withSize(10)); + addMetadata(hashCodeId, ColumnMetadata.named("hashCode_id").withIndex(8).ofType(4).withSize(10)); + addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(4).withSize(10).notNull()); + addMetadata(isnotnullId, ColumnMetadata.named("isnotnull_id").withIndex(9).ofType(4).withSize(10)); + addMetadata(isnullId, ColumnMetadata.named("isnull_id").withIndex(10).ofType(4).withSize(10)); + addMetadata(notifyAllId, ColumnMetadata.named("notifyAll_id").withIndex(12).ofType(4).withSize(10)); + addMetadata(notifyId, ColumnMetadata.named("notify_id").withIndex(11).ofType(4).withSize(10)); + addMetadata(toStringId, ColumnMetadata.named("toString_id").withIndex(13).ofType(4).withSize(10)); + addMetadata(waitId, ColumnMetadata.named("wait_id").withIndex(14).ofType(4).withSize(10)); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SFoo.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SFoo.java new file mode 100644 index 0000000000..924656ba21 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SFoo.java @@ -0,0 +1,62 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.DatePath; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.StringPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SFoo is a Querydsl query type for SFoo + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SFoo extends com.querydsl.sql.RelationalPathBase<SFoo> { + + private static final long serialVersionUID = -1389443894; + + public static final SFoo foo_ = new SFoo("foo_"); + + public final StringPath bar = createString("bar"); + + public final NumberPath<Integer> id = createNumber("id", Integer.class); + + public final DatePath<java.sql.Date> startDate = createDate("startDate", java.sql.Date.class); + + public final com.querydsl.sql.PrimaryKey<SFoo> primary = createPrimaryKey(id); + + public final com.querydsl.sql.ForeignKey<SFooNames> _fkb6129a8f94e297f8 = createInvForeignKey(id, "foo_id"); + + public SFoo(String variable) { + super(SFoo.class, forVariable(variable), "", "foo_"); + addMetadata(); + } + + public SFoo(String variable, String schema, String table) { + super(SFoo.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SFoo(Path<? extends SFoo> path) { + super(path.getType(), path.getMetadata(), "", "foo_"); + addMetadata(); + } + + public SFoo(PathMetadata metadata) { + super(SFoo.class, metadata, "", "foo_"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(bar, ColumnMetadata.named("bar").withIndex(2).ofType(12).withSize(255)); + addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(4).withSize(10).notNull()); + addMetadata(startDate, ColumnMetadata.named("startDate").withIndex(3).ofType(91).withSize(10)); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SFooNames.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SFooNames.java new file mode 100644 index 0000000000..cf11c23edb --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SFooNames.java @@ -0,0 +1,56 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.StringPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SFooNames is a Querydsl query type for SFooNames + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SFooNames extends com.querydsl.sql.RelationalPathBase<SFooNames> { + + private static final long serialVersionUID = 982089235; + + public static final SFooNames fooNames = new SFooNames("foo_names"); + + public final NumberPath<Integer> fooId = createNumber("fooId", Integer.class); + + public final StringPath names = createString("names"); + + public final com.querydsl.sql.ForeignKey<SFoo> fkb6129a8f94e297f8 = createForeignKey(fooId, "id"); + + public SFooNames(String variable) { + super(SFooNames.class, forVariable(variable), "", "foo_names"); + addMetadata(); + } + + public SFooNames(String variable, String schema, String table) { + super(SFooNames.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SFooNames(Path<? extends SFooNames> path) { + super(path.getType(), path.getMetadata(), "", "foo_names"); + addMetadata(); + } + + public SFooNames(PathMetadata metadata) { + super(SFooNames.class, metadata, "", "foo_names"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(fooId, ColumnMetadata.named("foo_id").withIndex(1).ofType(4).withSize(10).notNull()); + addMetadata(names, ColumnMetadata.named("names").withIndex(2).ofType(12).withSize(255)); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SFormula.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SFormula.java new file mode 100644 index 0000000000..3499b98074 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SFormula.java @@ -0,0 +1,57 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SFormula is a Querydsl query type for SFormula + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SFormula extends com.querydsl.sql.RelationalPathBase<SFormula> { + + private static final long serialVersionUID = 1097200554; + + public static final SFormula formula_ = new SFormula("formula_"); + + public final NumberPath<Integer> id = createNumber("id", Integer.class); + + public final NumberPath<Long> parameterId = createNumber("parameterId", Long.class); + + public final com.querydsl.sql.PrimaryKey<SFormula> primary = createPrimaryKey(id); + + public final com.querydsl.sql.ForeignKey<SParameter> fk1c4adbb924189298 = createForeignKey(parameterId, "id"); + + public SFormula(String variable) { + super(SFormula.class, forVariable(variable), "", "formula_"); + addMetadata(); + } + + public SFormula(String variable, String schema, String table) { + super(SFormula.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SFormula(Path<? extends SFormula> path) { + super(path.getType(), path.getMetadata(), "", "formula_"); + addMetadata(); + } + + public SFormula(PathMetadata metadata) { + super(SFormula.class, metadata, "", "formula_"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(4).withSize(10).notNull()); + addMetadata(parameterId, ColumnMetadata.named("parameter_id").withIndex(2).ofType(-5).withSize(19)); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SGeneratedKeys.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SGeneratedKeys.java new file mode 100644 index 0000000000..c932818f7a --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SGeneratedKeys.java @@ -0,0 +1,56 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.StringPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SGeneratedKeys is a Querydsl query type for SGeneratedKeys + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SGeneratedKeys extends com.querydsl.sql.RelationalPathBase<SGeneratedKeys> { + + private static final long serialVersionUID = 379851474; + + public static final SGeneratedKeys generatedKeys = new SGeneratedKeys("GENERATED_KEYS"); + + public final NumberPath<Integer> id = createNumber("id", Integer.class); + + public final StringPath name = createString("name"); + + public final com.querydsl.sql.PrimaryKey<SGeneratedKeys> primary = createPrimaryKey(id); + + public SGeneratedKeys(String variable) { + super(SGeneratedKeys.class, forVariable(variable), "", "GENERATED_KEYS"); + addMetadata(); + } + + public SGeneratedKeys(String variable, String schema, String table) { + super(SGeneratedKeys.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SGeneratedKeys(Path<? extends SGeneratedKeys> path) { + super(path.getType(), path.getMetadata(), "", "GENERATED_KEYS"); + addMetadata(); + } + + public SGeneratedKeys(PathMetadata metadata) { + super(SGeneratedKeys.class, metadata, "", "GENERATED_KEYS"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(id, ColumnMetadata.named("ID").withIndex(1).ofType(4).withSize(10).notNull()); + addMetadata(name, ColumnMetadata.named("NAME").withIndex(2).ofType(12).withSize(30)); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SHumanHairs.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SHumanHairs.java new file mode 100644 index 0000000000..be0a7cf7b7 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SHumanHairs.java @@ -0,0 +1,55 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SHumanHairs is a Querydsl query type for SHumanHairs + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SHumanHairs extends com.querydsl.sql.RelationalPathBase<SHumanHairs> { + + private static final long serialVersionUID = 1372028757; + + public static final SHumanHairs HumanHairs = new SHumanHairs("Human_hairs"); + + public final NumberPath<Integer> hairs = createNumber("hairs", Integer.class); + + public final NumberPath<Long> humanId = createNumber("humanId", Long.class); + + public final com.querydsl.sql.ForeignKey<SMammal> fk6649531ff097e318 = createForeignKey(humanId, "id"); + + public SHumanHairs(String variable) { + super(SHumanHairs.class, forVariable(variable), "", "Human_hairs"); + addMetadata(); + } + + public SHumanHairs(String variable, String schema, String table) { + super(SHumanHairs.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SHumanHairs(Path<? extends SHumanHairs> path) { + super(path.getType(), path.getMetadata(), "", "Human_hairs"); + addMetadata(); + } + + public SHumanHairs(PathMetadata metadata) { + super(SHumanHairs.class, metadata, "", "Human_hairs"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(hairs, ColumnMetadata.named("hairs").withIndex(2).ofType(4).withSize(10)); + addMetadata(humanId, ColumnMetadata.named("Human_id").withIndex(1).ofType(-5).withSize(19).notNull()); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SInheritedproperties.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SInheritedproperties.java new file mode 100644 index 0000000000..fe6a272ad3 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SInheritedproperties.java @@ -0,0 +1,62 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.StringPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SInheritedproperties is a Querydsl query type for SInheritedproperties + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SInheritedproperties extends com.querydsl.sql.RelationalPathBase<SInheritedproperties> { + + private static final long serialVersionUID = -992601885; + + public static final SInheritedproperties inheritedproperties_ = new SInheritedproperties("inheritedproperties_"); + + public final StringPath classProperty = createString("classProperty"); + + public final NumberPath<Long> id = createNumber("id", Long.class); + + public final StringPath stringAsSimple = createString("stringAsSimple"); + + public final StringPath superclassProperty = createString("superclassProperty"); + + public final com.querydsl.sql.PrimaryKey<SInheritedproperties> primary = createPrimaryKey(id); + + public SInheritedproperties(String variable) { + super(SInheritedproperties.class, forVariable(variable), "", "inheritedproperties_"); + addMetadata(); + } + + public SInheritedproperties(String variable, String schema, String table) { + super(SInheritedproperties.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SInheritedproperties(Path<? extends SInheritedproperties> path) { + super(path.getType(), path.getMetadata(), "", "inheritedproperties_"); + addMetadata(); + } + + public SInheritedproperties(PathMetadata metadata) { + super(SInheritedproperties.class, metadata, "", "inheritedproperties_"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(classProperty, ColumnMetadata.named("classProperty").withIndex(4).ofType(12).withSize(255)); + addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(-5).withSize(19).notNull()); + addMetadata(stringAsSimple, ColumnMetadata.named("stringAsSimple").withIndex(2).ofType(12).withSize(255)); + addMetadata(superclassProperty, ColumnMetadata.named("superclassProperty").withIndex(3).ofType(12).withSize(255)); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SItem.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SItem.java new file mode 100644 index 0000000000..c006b2e24a --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SItem.java @@ -0,0 +1,89 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.StringPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SItem is a Querydsl query type for SItem + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SItem extends com.querydsl.sql.RelationalPathBase<SItem> { + + private static final long serialVersionUID = -120177317; + + public static final SItem item_ = new SItem("item_"); + + public final NumberPath<Long> currentStatusId = createNumber("currentStatusId", Long.class); + + public final StringPath dtype = createString("dtype"); + + public final NumberPath<Long> id = createNumber("id", Long.class); + + public final StringPath name = createString("name"); + + public final NumberPath<Integer> paymentStatus = createNumber("paymentStatus", Integer.class); + + public final NumberPath<Long> productId = createNumber("productId", Long.class); + + public final NumberPath<Long> statusId = createNumber("statusId", Long.class); + + public final com.querydsl.sql.PrimaryKey<SItem> primary = createPrimaryKey(id); + + public final com.querydsl.sql.ForeignKey<SStatus> fk5fde7acd23307bc = createForeignKey(statusId, "id"); + + public final com.querydsl.sql.ForeignKey<SStatus> fk5fde7ac9ea26263 = createForeignKey(currentStatusId, "id"); + + public final com.querydsl.sql.ForeignKey<SItem> fk5fde7ac2c7f0c58 = createForeignKey(productId, "id"); + + public final com.querydsl.sql.ForeignKey<SAuditlog> _fkb88fbf6ae26109c = createInvForeignKey(id, "item_id"); + + public final com.querydsl.sql.ForeignKey<SItem> _fk5fde7ac2c7f0c58 = createInvForeignKey(id, "product_id"); + + public final com.querydsl.sql.ForeignKey<SOrder_item> _fk1b5e8cbe7640c8cf = createInvForeignKey(id, "items_id"); + + public final com.querydsl.sql.ForeignKey<SPrice> _fkc59678362c7f0c58 = createInvForeignKey(id, "product_id"); + + public final com.querydsl.sql.ForeignKey<SItem_statuschange> _fkcb99fb2aedc50192 = createInvForeignKey(id, "item__id"); + + public final com.querydsl.sql.ForeignKey<SLineItems> _fkb2e400c3d8e44c3 = createInvForeignKey(id, "lineItems_id"); + + public SItem(String variable) { + super(SItem.class, forVariable(variable), "", "item_"); + addMetadata(); + } + + public SItem(String variable, String schema, String table) { + super(SItem.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SItem(Path<? extends SItem> path) { + super(path.getType(), path.getMetadata(), "", "item_"); + addMetadata(); + } + + public SItem(PathMetadata metadata) { + super(SItem.class, metadata, "", "item_"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(currentStatusId, ColumnMetadata.named("currentStatus_id").withIndex(6).ofType(-5).withSize(19)); + addMetadata(dtype, ColumnMetadata.named("DTYPE").withIndex(1).ofType(12).withSize(31).notNull()); + addMetadata(id, ColumnMetadata.named("id").withIndex(2).ofType(-5).withSize(19).notNull()); + addMetadata(name, ColumnMetadata.named("name").withIndex(4).ofType(12).withSize(255)); + addMetadata(paymentStatus, ColumnMetadata.named("paymentStatus").withIndex(3).ofType(4).withSize(10)); + addMetadata(productId, ColumnMetadata.named("product_id").withIndex(5).ofType(-5).withSize(19)); + addMetadata(statusId, ColumnMetadata.named("status_id").withIndex(7).ofType(-5).withSize(19)); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SItem_statuschange.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SItem_statuschange.java new file mode 100644 index 0000000000..29fab8e749 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SItem_statuschange.java @@ -0,0 +1,57 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SItem_statuschange is a Querydsl query type for SItem_statuschange + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SItem_statuschange extends com.querydsl.sql.RelationalPathBase<SItem_statuschange> { + + private static final long serialVersionUID = 210676994; + + public static final SItem_statuschange item_statuschange_ = new SItem_statuschange("item__statuschange_"); + + public final NumberPath<Long> item_id = createNumber("item_id", Long.class); + + public final NumberPath<Long> statusChangesId = createNumber("statusChangesId", Long.class); + + public final com.querydsl.sql.ForeignKey<SStatuschange> fkcb99fb2ab2bd098d = createForeignKey(statusChangesId, "id"); + + public final com.querydsl.sql.ForeignKey<SItem> fkcb99fb2aedc50192 = createForeignKey(item_id, "id"); + + public SItem_statuschange(String variable) { + super(SItem_statuschange.class, forVariable(variable), "", "item__statuschange_"); + addMetadata(); + } + + public SItem_statuschange(String variable, String schema, String table) { + super(SItem_statuschange.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SItem_statuschange(Path<? extends SItem_statuschange> path) { + super(path.getType(), path.getMetadata(), "", "item__statuschange_"); + addMetadata(); + } + + public SItem_statuschange(PathMetadata metadata) { + super(SItem_statuschange.class, metadata, "", "item__statuschange_"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(item_id, ColumnMetadata.named("item__id").withIndex(1).ofType(-5).withSize(19).notNull()); + addMetadata(statusChangesId, ColumnMetadata.named("statusChanges_id").withIndex(2).ofType(-5).withSize(19).notNull()); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SKittens.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SKittens.java new file mode 100644 index 0000000000..624480f79a --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SKittens.java @@ -0,0 +1,62 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SKittens is a Querydsl query type for SKittens + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SKittens extends com.querydsl.sql.RelationalPathBase<SKittens> { + + private static final long serialVersionUID = 1947872699; + + public static final SKittens kittens = new SKittens("kittens"); + + public final NumberPath<Integer> catId = createNumber("catId", Integer.class); + + public final NumberPath<Integer> ind = createNumber("ind", Integer.class); + + public final NumberPath<Integer> kittenId = createNumber("kittenId", Integer.class); + + public final com.querydsl.sql.PrimaryKey<SKittens> primary = createPrimaryKey(catId, ind); + + public final com.querydsl.sql.ForeignKey<SAnimal> fkd60087cc3881aaa7 = createForeignKey(kittenId, "id"); + + public final com.querydsl.sql.ForeignKey<SAnimal> fkd60087cc8f00fdf8 = createForeignKey(catId, "id"); + + public SKittens(String variable) { + super(SKittens.class, forVariable(variable), "", "kittens"); + addMetadata(); + } + + public SKittens(String variable, String schema, String table) { + super(SKittens.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SKittens(Path<? extends SKittens> path) { + super(path.getType(), path.getMetadata(), "", "kittens"); + addMetadata(); + } + + public SKittens(PathMetadata metadata) { + super(SKittens.class, metadata, "", "kittens"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(catId, ColumnMetadata.named("cat_id").withIndex(1).ofType(4).withSize(10).notNull()); + addMetadata(ind, ColumnMetadata.named("ind").withIndex(3).ofType(4).withSize(10).notNull()); + addMetadata(kittenId, ColumnMetadata.named("kitten_id").withIndex(2).ofType(4).withSize(10).notNull()); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SKittensSet.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SKittensSet.java new file mode 100644 index 0000000000..d3d2ca93ec --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SKittensSet.java @@ -0,0 +1,59 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SKittensSet is a Querydsl query type for SKittensSet + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SKittensSet extends com.querydsl.sql.RelationalPathBase<SKittensSet> { + + private static final long serialVersionUID = -227477337; + + public static final SKittensSet kittensSet = new SKittensSet("kittens_set"); + + public final NumberPath<Integer> catId = createNumber("catId", Integer.class); + + public final NumberPath<Integer> kittenId = createNumber("kittenId", Integer.class); + + public final com.querydsl.sql.PrimaryKey<SKittensSet> primary = createPrimaryKey(catId, kittenId); + + public final com.querydsl.sql.ForeignKey<SAnimal> fk4fccad6f8f00fdf8 = createForeignKey(catId, "id"); + + public final com.querydsl.sql.ForeignKey<SAnimal> fk4fccad6f3881aaa7 = createForeignKey(kittenId, "id"); + + public SKittensSet(String variable) { + super(SKittensSet.class, forVariable(variable), "", "kittens_set"); + addMetadata(); + } + + public SKittensSet(String variable, String schema, String table) { + super(SKittensSet.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SKittensSet(Path<? extends SKittensSet> path) { + super(path.getType(), path.getMetadata(), "", "kittens_set"); + addMetadata(); + } + + public SKittensSet(PathMetadata metadata) { + super(SKittensSet.class, metadata, "", "kittens_set"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(catId, ColumnMetadata.named("cat_id").withIndex(1).ofType(4).withSize(10).notNull()); + addMetadata(kittenId, ColumnMetadata.named("kitten_id").withIndex(2).ofType(4).withSize(10).notNull()); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SLibrary.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SLibrary.java new file mode 100644 index 0000000000..932ff4988c --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SLibrary.java @@ -0,0 +1,54 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SLibrary is a Querydsl query type for SLibrary + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SLibrary extends com.querydsl.sql.RelationalPathBase<SLibrary> { + + private static final long serialVersionUID = 1480035061; + + public static final SLibrary library_ = new SLibrary("library_"); + + public final NumberPath<Long> identity = createNumber("identity", Long.class); + + public final com.querydsl.sql.PrimaryKey<SLibrary> primary = createPrimaryKey(identity); + + public final com.querydsl.sql.ForeignKey<SBookversion> _fkef4bc070e364cd17 = createInvForeignKey(identity, "library_identity"); + + public SLibrary(String variable) { + super(SLibrary.class, forVariable(variable), "", "library_"); + addMetadata(); + } + + public SLibrary(String variable, String schema, String table) { + super(SLibrary.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SLibrary(Path<? extends SLibrary> path) { + super(path.getType(), path.getMetadata(), "", "library_"); + addMetadata(); + } + + public SLibrary(PathMetadata metadata) { + super(SLibrary.class, metadata, "", "library_"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(identity, ColumnMetadata.named("identity").withIndex(1).ofType(-5).withSize(19).notNull()); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SLineItems.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SLineItems.java new file mode 100644 index 0000000000..806285ed6b --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SLineItems.java @@ -0,0 +1,62 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SLineItems is a Querydsl query type for SLineItems + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SLineItems extends com.querydsl.sql.RelationalPathBase<SLineItems> { + + private static final long serialVersionUID = 302253659; + + public static final SLineItems LineItems = new SLineItems("LineItems"); + + public final NumberPath<Integer> _index = createNumber("_index", Integer.class); + + public final NumberPath<Long> lineItemsId = createNumber("lineItemsId", Long.class); + + public final NumberPath<Long> order_id = createNumber("order_id", Long.class); + + public final com.querydsl.sql.PrimaryKey<SLineItems> primary = createPrimaryKey(_index, order_id); + + public final com.querydsl.sql.ForeignKey<SOrder> fkb2e400cb968f515 = createForeignKey(order_id, "id"); + + public final com.querydsl.sql.ForeignKey<SItem> fkb2e400c3d8e44c3 = createForeignKey(lineItemsId, "id"); + + public SLineItems(String variable) { + super(SLineItems.class, forVariable(variable), "", "LineItems"); + addMetadata(); + } + + public SLineItems(String variable, String schema, String table) { + super(SLineItems.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SLineItems(Path<? extends SLineItems> path) { + super(path.getType(), path.getMetadata(), "", "LineItems"); + addMetadata(); + } + + public SLineItems(PathMetadata metadata) { + super(SLineItems.class, metadata, "", "LineItems"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(_index, ColumnMetadata.named("_index").withIndex(3).ofType(4).withSize(10).notNull()); + addMetadata(lineItemsId, ColumnMetadata.named("lineItems_id").withIndex(2).ofType(-5).withSize(19).notNull()); + addMetadata(order_id, ColumnMetadata.named("order__id").withIndex(1).ofType(-5).withSize(19).notNull()); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SLocation.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SLocation.java new file mode 100644 index 0000000000..026eaf493d --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SLocation.java @@ -0,0 +1,58 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.StringPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SLocation is a Querydsl query type for SLocation + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SLocation extends com.querydsl.sql.RelationalPathBase<SLocation> { + + private static final long serialVersionUID = 921451897; + + public static final SLocation location_ = new SLocation("location_"); + + public final NumberPath<Long> id = createNumber("id", Long.class); + + public final StringPath name = createString("name"); + + public final com.querydsl.sql.PrimaryKey<SLocation> primary = createPrimaryKey(id); + + public final com.querydsl.sql.ForeignKey<SStore> _fkcad4239e8a55845c = createInvForeignKey(id, "location_id"); + + public SLocation(String variable) { + super(SLocation.class, forVariable(variable), "", "location_"); + addMetadata(); + } + + public SLocation(String variable, String schema, String table) { + super(SLocation.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SLocation(Path<? extends SLocation> path) { + super(path.getType(), path.getMetadata(), "", "location_"); + addMetadata(); + } + + public SLocation(PathMetadata metadata) { + super(SLocation.class, metadata, "", "location_"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(-5).withSize(19).notNull()); + addMetadata(name, ColumnMetadata.named("name").withIndex(2).ofType(12).withSize(255)); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SMammal.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SMammal.java new file mode 100644 index 0000000000..afdef21a20 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SMammal.java @@ -0,0 +1,60 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.StringPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SMammal is a Querydsl query type for SMammal + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SMammal extends com.querydsl.sql.RelationalPathBase<SMammal> { + + private static final long serialVersionUID = 666678672; + + public static final SMammal Mammal = new SMammal("Mammal"); + + public final StringPath dtype = createString("dtype"); + + public final NumberPath<Long> id = createNumber("id", Long.class); + + public final com.querydsl.sql.PrimaryKey<SMammal> primary = createPrimaryKey(id); + + public final com.querydsl.sql.ForeignKey<SHumanHairs> _fk6649531ff097e318 = createInvForeignKey(id, "Human_id"); + + public final com.querydsl.sql.ForeignKey<SWorldMammal> _fk4070aeece01c8ee7 = createInvForeignKey(id, "mammals_id"); + + public SMammal(String variable) { + super(SMammal.class, forVariable(variable), "", "Mammal"); + addMetadata(); + } + + public SMammal(String variable, String schema, String table) { + super(SMammal.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SMammal(Path<? extends SMammal> path) { + super(path.getType(), path.getMetadata(), "", "Mammal"); + addMetadata(); + } + + public SMammal(PathMetadata metadata) { + super(SMammal.class, metadata, "", "Mammal"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(dtype, ColumnMetadata.named("DTYPE").withIndex(1).ofType(12).withSize(31).notNull()); + addMetadata(id, ColumnMetadata.named("id").withIndex(2).ofType(-5).withSize(19).notNull()); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SName.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SName.java new file mode 100644 index 0000000000..acc6c42f8a --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SName.java @@ -0,0 +1,64 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.StringPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SName is a Querydsl query type for SName + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SName extends com.querydsl.sql.RelationalPathBase<SName> { + + private static final long serialVersionUID = -116118301; + + public static final SName name_ = new SName("name_"); + + public final StringPath firstName = createString("firstName"); + + public final NumberPath<Long> id = createNumber("id", Long.class); + + public final StringPath lastName = createString("lastName"); + + public final StringPath nickName = createString("nickName"); + + public final com.querydsl.sql.PrimaryKey<SName> primary = createPrimaryKey(id); + + public final com.querydsl.sql.ForeignKey<SCustomer> _fk600e7c4196a83d9c = createInvForeignKey(id, "name_id"); + + public SName(String variable) { + super(SName.class, forVariable(variable), "", "name_"); + addMetadata(); + } + + public SName(String variable, String schema, String table) { + super(SName.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SName(Path<? extends SName> path) { + super(path.getType(), path.getMetadata(), "", "name_"); + addMetadata(); + } + + public SName(PathMetadata metadata) { + super(SName.class, metadata, "", "name_"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(firstName, ColumnMetadata.named("firstName").withIndex(2).ofType(12).withSize(255)); + addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(-5).withSize(19).notNull()); + addMetadata(lastName, ColumnMetadata.named("lastName").withIndex(3).ofType(12).withSize(255)); + addMetadata(nickName, ColumnMetadata.named("nickName").withIndex(4).ofType(12).withSize(255)); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SNameListNames.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SNameListNames.java new file mode 100644 index 0000000000..df457ebea3 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SNameListNames.java @@ -0,0 +1,56 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.StringPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SNameListNames is a Querydsl query type for SNameListNames + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SNameListNames extends com.querydsl.sql.RelationalPathBase<SNameListNames> { + + private static final long serialVersionUID = 150303150; + + public static final SNameListNames NameListNames = new SNameListNames("NameList_names"); + + public final NumberPath<Long> nameListId = createNumber("nameListId", Long.class); + + public final StringPath names = createString("names"); + + public final com.querydsl.sql.ForeignKey<SNamelist> fkd6c82d7217b6c3fc = createForeignKey(nameListId, "id"); + + public SNameListNames(String variable) { + super(SNameListNames.class, forVariable(variable), "", "NameList_names"); + addMetadata(); + } + + public SNameListNames(String variable, String schema, String table) { + super(SNameListNames.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SNameListNames(Path<? extends SNameListNames> path) { + super(path.getType(), path.getMetadata(), "", "NameList_names"); + addMetadata(); + } + + public SNameListNames(PathMetadata metadata) { + super(SNameListNames.class, metadata, "", "NameList_names"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(nameListId, ColumnMetadata.named("NameList_id").withIndex(1).ofType(-5).withSize(19).notNull()); + addMetadata(names, ColumnMetadata.named("names").withIndex(2).ofType(12).withSize(255)); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SNamed.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SNamed.java new file mode 100644 index 0000000000..d1411fbe04 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SNamed.java @@ -0,0 +1,56 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.StringPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SNamed is a Querydsl query type for SNamed + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SNamed extends com.querydsl.sql.RelationalPathBase<SNamed> { + + private static final long serialVersionUID = 695300215; + + public static final SNamed named_ = new SNamed("named_"); + + public final NumberPath<Long> id = createNumber("id", Long.class); + + public final StringPath name = createString("name"); + + public final com.querydsl.sql.PrimaryKey<SNamed> primary = createPrimaryKey(id); + + public SNamed(String variable) { + super(SNamed.class, forVariable(variable), "", "named_"); + addMetadata(); + } + + public SNamed(String variable, String schema, String table) { + super(SNamed.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SNamed(Path<? extends SNamed> path) { + super(path.getType(), path.getMetadata(), "", "named_"); + addMetadata(); + } + + public SNamed(PathMetadata metadata) { + super(SNamed.class, metadata, "", "named_"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(-5).withSize(19).notNull()); + addMetadata(name, ColumnMetadata.named("name").withIndex(2).ofType(12).withSize(255)); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SNamelist.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SNamelist.java new file mode 100644 index 0000000000..39295e4407 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SNamelist.java @@ -0,0 +1,54 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SNamelist is a Querydsl query type for SNamelist + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SNamelist extends com.querydsl.sql.RelationalPathBase<SNamelist> { + + private static final long serialVersionUID = -930763259; + + public static final SNamelist namelist_ = new SNamelist("namelist_"); + + public final NumberPath<Long> id = createNumber("id", Long.class); + + public final com.querydsl.sql.PrimaryKey<SNamelist> primary = createPrimaryKey(id); + + public final com.querydsl.sql.ForeignKey<SNameListNames> _fkd6c82d7217b6c3fc = createInvForeignKey(id, "NameList_id"); + + public SNamelist(String variable) { + super(SNamelist.class, forVariable(variable), "", "namelist_"); + addMetadata(); + } + + public SNamelist(String variable, String schema, String table) { + super(SNamelist.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SNamelist(Path<? extends SNamelist> path) { + super(path.getType(), path.getMetadata(), "", "namelist_"); + addMetadata(); + } + + public SNamelist(PathMetadata metadata) { + super(SNamelist.class, metadata, "", "namelist_"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(-5).withSize(19).notNull()); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SNationality.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SNationality.java new file mode 100644 index 0000000000..7c24728631 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SNationality.java @@ -0,0 +1,59 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SNationality is a Querydsl query type for SNationality + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SNationality extends com.querydsl.sql.RelationalPathBase<SNationality> { + + private static final long serialVersionUID = 478851476; + + public static final SNationality nationality_ = new SNationality("nationality_"); + + public final NumberPath<Integer> calendarId = createNumber("calendarId", Integer.class); + + public final NumberPath<Long> id = createNumber("id", Long.class); + + public final com.querydsl.sql.PrimaryKey<SNationality> primary = createPrimaryKey(id); + + public final com.querydsl.sql.ForeignKey<SCalendar> fkab8efa23591ebbc = createForeignKey(calendarId, "id"); + + public final com.querydsl.sql.ForeignKey<SPerson> _fkd78fcfaaf6578e38 = createInvForeignKey(id, "nationality_id"); + + public SNationality(String variable) { + super(SNationality.class, forVariable(variable), "", "nationality_"); + addMetadata(); + } + + public SNationality(String variable, String schema, String table) { + super(SNationality.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SNationality(Path<? extends SNationality> path) { + super(path.getType(), path.getMetadata(), "", "nationality_"); + addMetadata(); + } + + public SNationality(PathMetadata metadata) { + super(SNationality.class, metadata, "", "nationality_"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(calendarId, ColumnMetadata.named("calendar_id").withIndex(2).ofType(4).withSize(10)); + addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(-5).withSize(19).notNull()); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SNumeric.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SNumeric.java new file mode 100644 index 0000000000..bcdc9c3f99 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SNumeric.java @@ -0,0 +1,58 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SNumeric is a Querydsl query type for SNumeric + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SNumeric extends com.querydsl.sql.RelationalPathBase<SNumeric> { + + private static final long serialVersionUID = -1260757277; + + public static final SNumeric numeric_ = new SNumeric("numeric_"); + + public final NumberPath<Long> id = createNumber("id", Long.class); + + public final NumberPath<java.math.BigDecimal> value = createNumber("value", java.math.BigDecimal.class); + + public final NumberPath<java.math.BigDecimal> value_ = createNumber("value_", java.math.BigDecimal.class); + + public final com.querydsl.sql.PrimaryKey<SNumeric> primary = createPrimaryKey(id); + + public SNumeric(String variable) { + super(SNumeric.class, forVariable(variable), "", "numeric_"); + addMetadata(); + } + + public SNumeric(String variable, String schema, String table) { + super(SNumeric.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SNumeric(Path<? extends SNumeric> path) { + super(path.getType(), path.getMetadata(), "", "numeric_"); + addMetadata(); + } + + public SNumeric(PathMetadata metadata) { + super(SNumeric.class, metadata, "", "numeric_"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(-5).withSize(19).notNull()); + addMetadata(value, ColumnMetadata.named("value").withIndex(2).ofType(3).withSize(19).withDigits(2)); + addMetadata(value_, ColumnMetadata.named("value_").withIndex(3).ofType(3).withSize(19).withDigits(2)); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SOrder.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SOrder.java new file mode 100644 index 0000000000..fba9be5ba0 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SOrder.java @@ -0,0 +1,69 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.BooleanPath; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SOrder is a Querydsl query type for SOrder + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SOrder extends com.querydsl.sql.RelationalPathBase<SOrder> { + + private static final long serialVersionUID = 739361538; + + public static final SOrder order_ = new SOrder("order_"); + + public final NumberPath<Integer> customerId = createNumber("customerId", Integer.class); + + public final NumberPath<Long> id = createNumber("id", Long.class); + + public final BooleanPath paid = createBoolean("paid"); + + public final com.querydsl.sql.PrimaryKey<SOrder> primary = createPrimaryKey(id); + + public final com.querydsl.sql.ForeignKey<SCustomer> fkc3df62d1b29c27bc = createForeignKey(customerId, "id"); + + public final com.querydsl.sql.ForeignKey<SOrder_item> _fk1b5e8cbeb968f515 = createInvForeignKey(id, "order__id"); + + public final com.querydsl.sql.ForeignKey<SCustomer> _fk600e7c419cc457f1 = createInvForeignKey(id, "currentOrder_id"); + + public final com.querydsl.sql.ForeignKey<SOrderDeliveredItemIndices> _fk30cbd6611a4d2378 = createInvForeignKey(id, "Order_id"); + + public final com.querydsl.sql.ForeignKey<SLineItems> _fkb2e400cb968f515 = createInvForeignKey(id, "order__id"); + + public SOrder(String variable) { + super(SOrder.class, forVariable(variable), "", "order_"); + addMetadata(); + } + + public SOrder(String variable, String schema, String table) { + super(SOrder.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SOrder(Path<? extends SOrder> path) { + super(path.getType(), path.getMetadata(), "", "order_"); + addMetadata(); + } + + public SOrder(PathMetadata metadata) { + super(SOrder.class, metadata, "", "order_"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(customerId, ColumnMetadata.named("customer_id").withIndex(3).ofType(4).withSize(10)); + addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(-5).withSize(19).notNull()); + addMetadata(paid, ColumnMetadata.named("paid").withIndex(2).ofType(-7).notNull()); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SOrderDeliveredItemIndices.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SOrderDeliveredItemIndices.java new file mode 100644 index 0000000000..1c12a71c90 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SOrderDeliveredItemIndices.java @@ -0,0 +1,60 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SOrderDeliveredItemIndices is a Querydsl query type for SOrderDeliveredItemIndices + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SOrderDeliveredItemIndices extends com.querydsl.sql.RelationalPathBase<SOrderDeliveredItemIndices> { + + private static final long serialVersionUID = 860822157; + + public static final SOrderDeliveredItemIndices OrderDeliveredItemIndices = new SOrderDeliveredItemIndices("Order_deliveredItemIndices"); + + public final NumberPath<Integer> _index = createNumber("_index", Integer.class); + + public final NumberPath<Integer> deliveredItemIndices = createNumber("deliveredItemIndices", Integer.class); + + public final NumberPath<Long> orderId = createNumber("orderId", Long.class); + + public final com.querydsl.sql.PrimaryKey<SOrderDeliveredItemIndices> primary = createPrimaryKey(orderId, _index); + + public final com.querydsl.sql.ForeignKey<SOrder> fk30cbd6611a4d2378 = createForeignKey(orderId, "id"); + + public SOrderDeliveredItemIndices(String variable) { + super(SOrderDeliveredItemIndices.class, forVariable(variable), "", "Order_deliveredItemIndices"); + addMetadata(); + } + + public SOrderDeliveredItemIndices(String variable, String schema, String table) { + super(SOrderDeliveredItemIndices.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SOrderDeliveredItemIndices(Path<? extends SOrderDeliveredItemIndices> path) { + super(path.getType(), path.getMetadata(), "", "Order_deliveredItemIndices"); + addMetadata(); + } + + public SOrderDeliveredItemIndices(PathMetadata metadata) { + super(SOrderDeliveredItemIndices.class, metadata, "", "Order_deliveredItemIndices"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(_index, ColumnMetadata.named("_index").withIndex(3).ofType(4).withSize(10).notNull()); + addMetadata(deliveredItemIndices, ColumnMetadata.named("deliveredItemIndices").withIndex(2).ofType(4).withSize(10)); + addMetadata(orderId, ColumnMetadata.named("Order_id").withIndex(1).ofType(-5).withSize(19).notNull()); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SOrder_item.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SOrder_item.java new file mode 100644 index 0000000000..3f99a58a36 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SOrder_item.java @@ -0,0 +1,62 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SOrder_item is a Querydsl query type for SOrder_item + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SOrder_item extends com.querydsl.sql.RelationalPathBase<SOrder_item> { + + private static final long serialVersionUID = -2131249686; + + public static final SOrder_item order_item_ = new SOrder_item("order__item_"); + + public final NumberPath<Integer> _index = createNumber("_index", Integer.class); + + public final NumberPath<Long> itemsId = createNumber("itemsId", Long.class); + + public final NumberPath<Long> order_id = createNumber("order_id", Long.class); + + public final com.querydsl.sql.PrimaryKey<SOrder_item> primary = createPrimaryKey(_index, order_id); + + public final com.querydsl.sql.ForeignKey<SItem> fk1b5e8cbe7640c8cf = createForeignKey(itemsId, "id"); + + public final com.querydsl.sql.ForeignKey<SOrder> fk1b5e8cbeb968f515 = createForeignKey(order_id, "id"); + + public SOrder_item(String variable) { + super(SOrder_item.class, forVariable(variable), "", "order__item_"); + addMetadata(); + } + + public SOrder_item(String variable, String schema, String table) { + super(SOrder_item.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SOrder_item(Path<? extends SOrder_item> path) { + super(path.getType(), path.getMetadata(), "", "order__item_"); + addMetadata(); + } + + public SOrder_item(PathMetadata metadata) { + super(SOrder_item.class, metadata, "", "order__item_"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(_index, ColumnMetadata.named("_index").withIndex(3).ofType(4).withSize(10).notNull()); + addMetadata(itemsId, ColumnMetadata.named("items_id").withIndex(2).ofType(-5).withSize(19).notNull()); + addMetadata(order_id, ColumnMetadata.named("order__id").withIndex(1).ofType(-5).withSize(19).notNull()); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SParameter.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SParameter.java new file mode 100644 index 0000000000..a4dcda3c26 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SParameter.java @@ -0,0 +1,54 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SParameter is a Querydsl query type for SParameter + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SParameter extends com.querydsl.sql.RelationalPathBase<SParameter> { + + private static final long serialVersionUID = 1712103815; + + public static final SParameter parameter_ = new SParameter("parameter_"); + + public final NumberPath<Long> id = createNumber("id", Long.class); + + public final com.querydsl.sql.PrimaryKey<SParameter> primary = createPrimaryKey(id); + + public final com.querydsl.sql.ForeignKey<SFormula> _fk1c4adbb924189298 = createInvForeignKey(id, "parameter_id"); + + public SParameter(String variable) { + super(SParameter.class, forVariable(variable), "", "parameter_"); + addMetadata(); + } + + public SParameter(String variable, String schema, String table) { + super(SParameter.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SParameter(Path<? extends SParameter> path) { + super(path.getType(), path.getMetadata(), "", "parameter_"); + addMetadata(); + } + + public SParameter(PathMetadata metadata) { + super(SParameter.class, metadata, "", "parameter_"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(-5).withSize(19).notNull()); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SParent.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SParent.java new file mode 100644 index 0000000000..5a438d8d2c --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SParent.java @@ -0,0 +1,59 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.StringPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SParent is a Querydsl query type for SParent + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SParent extends com.querydsl.sql.RelationalPathBase<SParent> { + + private static final long serialVersionUID = 1859105508; + + public static final SParent parent_ = new SParent("parent_"); + + public final StringPath childName = createString("childName"); + + public final NumberPath<Long> id = createNumber("id", Long.class); + + public final StringPath name = createString("name"); + + public final com.querydsl.sql.PrimaryKey<SParent> primary = createPrimaryKey(id); + + public SParent(String variable) { + super(SParent.class, forVariable(variable), "", "parent_"); + addMetadata(); + } + + public SParent(String variable, String schema, String table) { + super(SParent.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SParent(Path<? extends SParent> path) { + super(path.getType(), path.getMetadata(), "", "parent_"); + addMetadata(); + } + + public SParent(PathMetadata metadata) { + super(SParent.class, metadata, "", "parent_"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(childName, ColumnMetadata.named("childName").withIndex(2).ofType(12).withSize(255)); + addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(-5).withSize(19).notNull()); + addMetadata(name, ColumnMetadata.named("name").withIndex(3).ofType(12).withSize(255)); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SParent2.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SParent2.java new file mode 100644 index 0000000000..b1d6e4eec5 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SParent2.java @@ -0,0 +1,54 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SParent2 is a Querydsl query type for SParent2 + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SParent2 extends com.querydsl.sql.RelationalPathBase<SParent2> { + + private static final long serialVersionUID = 1859105463; + + public static final SParent2 Parent2 = new SParent2("Parent2"); + + public final NumberPath<Integer> id = createNumber("id", Integer.class); + + public final com.querydsl.sql.PrimaryKey<SParent2> primary = createPrimaryKey(id); + + public final com.querydsl.sql.ForeignKey<SChild2> _fk783f9ab6c2dbacbc = createInvForeignKey(id, "parent_id"); + + public SParent2(String variable) { + super(SParent2.class, forVariable(variable), "", "Parent2"); + addMetadata(); + } + + public SParent2(String variable, String schema, String table) { + super(SParent2.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SParent2(Path<? extends SParent2> path) { + super(path.getType(), path.getMetadata(), "", "Parent2"); + addMetadata(); + } + + public SParent2(PathMetadata metadata) { + super(SParent2.class, metadata, "", "Parent2"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(4).withSize(10).notNull()); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SPerson.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SPerson.java new file mode 100644 index 0000000000..2b7178aac7 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SPerson.java @@ -0,0 +1,72 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.DatePath; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.StringPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SPerson is a Querydsl query type for SPerson + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SPerson extends com.querydsl.sql.RelationalPathBase<SPerson> { + + private static final long serialVersionUID = 1974039961; + + public static final SPerson person_ = new SPerson("person_"); + + public final DatePath<java.sql.Date> birthDay = createDate("birthDay", java.sql.Date.class); + + public final NumberPath<Long> i = createNumber("i", Long.class); + + public final StringPath name = createString("name"); + + public final NumberPath<Long> nationalityId = createNumber("nationalityId", Long.class); + + public final NumberPath<Long> pidId = createNumber("pidId", Long.class); + + public final com.querydsl.sql.PrimaryKey<SPerson> primary = createPrimaryKey(i); + + public final com.querydsl.sql.ForeignKey<SPersonid> fkd78fcfaad7999e61 = createForeignKey(pidId, "id"); + + public final com.querydsl.sql.ForeignKey<SNationality> fkd78fcfaaf6578e38 = createForeignKey(nationalityId, "id"); + + public final com.querydsl.sql.ForeignKey<SAccount> _fk809dbbd28cfac74 = createInvForeignKey(i, "owner_i"); + + public SPerson(String variable) { + super(SPerson.class, forVariable(variable), "", "person_"); + addMetadata(); + } + + public SPerson(String variable, String schema, String table) { + super(SPerson.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SPerson(Path<? extends SPerson> path) { + super(path.getType(), path.getMetadata(), "", "person_"); + addMetadata(); + } + + public SPerson(PathMetadata metadata) { + super(SPerson.class, metadata, "", "person_"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(birthDay, ColumnMetadata.named("birthDay").withIndex(2).ofType(91).withSize(10)); + addMetadata(i, ColumnMetadata.named("i").withIndex(1).ofType(-5).withSize(19).notNull()); + addMetadata(name, ColumnMetadata.named("name").withIndex(3).ofType(12).withSize(255)); + addMetadata(nationalityId, ColumnMetadata.named("nationality_id").withIndex(4).ofType(-5).withSize(19)); + addMetadata(pidId, ColumnMetadata.named("pid_id").withIndex(5).ofType(-5).withSize(19)); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SPersonid.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SPersonid.java new file mode 100644 index 0000000000..e31d2c84ff --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SPersonid.java @@ -0,0 +1,61 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.StringPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SPersonid is a Querydsl query type for SPersonid + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SPersonid extends com.querydsl.sql.RelationalPathBase<SPersonid> { + + private static final long serialVersionUID = -1323129506; + + public static final SPersonid personid_ = new SPersonid("personid_"); + + public final StringPath country = createString("country"); + + public final NumberPath<Long> id = createNumber("id", Long.class); + + public final NumberPath<Integer> medicareNumber = createNumber("medicareNumber", Integer.class); + + public final com.querydsl.sql.PrimaryKey<SPersonid> primary = createPrimaryKey(id); + + public final com.querydsl.sql.ForeignKey<SPerson> _fkd78fcfaad7999e61 = createInvForeignKey(id, "pid_id"); + + public SPersonid(String variable) { + super(SPersonid.class, forVariable(variable), "", "personid_"); + addMetadata(); + } + + public SPersonid(String variable, String schema, String table) { + super(SPersonid.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SPersonid(Path<? extends SPersonid> path) { + super(path.getType(), path.getMetadata(), "", "personid_"); + addMetadata(); + } + + public SPersonid(PathMetadata metadata) { + super(SPersonid.class, metadata, "", "personid_"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(country, ColumnMetadata.named("country").withIndex(2).ofType(12).withSize(255)); + addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(-5).withSize(19).notNull()); + addMetadata(medicareNumber, ColumnMetadata.named("medicareNumber").withIndex(3).ofType(4).withSize(10).notNull()); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SPlayer.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SPlayer.java new file mode 100644 index 0000000000..9e830dd07e --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SPlayer.java @@ -0,0 +1,54 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SPlayer is a Querydsl query type for SPlayer + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SPlayer extends com.querydsl.sql.RelationalPathBase<SPlayer> { + + private static final long serialVersionUID = -2136053875; + + public static final SPlayer player_ = new SPlayer("player_"); + + public final NumberPath<Long> id = createNumber("id", Long.class); + + public final com.querydsl.sql.PrimaryKey<SPlayer> primary = createPrimaryKey(id); + + public final com.querydsl.sql.ForeignKey<SPlayerScores> _fkd5dc571fd8736d5c = createInvForeignKey(id, "Player_id"); + + public SPlayer(String variable) { + super(SPlayer.class, forVariable(variable), "", "player_"); + addMetadata(); + } + + public SPlayer(String variable, String schema, String table) { + super(SPlayer.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SPlayer(Path<? extends SPlayer> path) { + super(path.getType(), path.getMetadata(), "", "player_"); + addMetadata(); + } + + public SPlayer(PathMetadata metadata) { + super(SPlayer.class, metadata, "", "player_"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(-5).withSize(19).notNull()); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SPlayerScores.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SPlayerScores.java new file mode 100644 index 0000000000..2f9070e43b --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SPlayerScores.java @@ -0,0 +1,55 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SPlayerScores is a Querydsl query type for SPlayerScores + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SPlayerScores extends com.querydsl.sql.RelationalPathBase<SPlayerScores> { + + private static final long serialVersionUID = 1627547091; + + public static final SPlayerScores PlayerScores = new SPlayerScores("Player_scores"); + + public final NumberPath<Long> playerId = createNumber("playerId", Long.class); + + public final NumberPath<Integer> scores = createNumber("scores", Integer.class); + + public final com.querydsl.sql.ForeignKey<SPlayer> fkd5dc571fd8736d5c = createForeignKey(playerId, "id"); + + public SPlayerScores(String variable) { + super(SPlayerScores.class, forVariable(variable), "", "Player_scores"); + addMetadata(); + } + + public SPlayerScores(String variable, String schema, String table) { + super(SPlayerScores.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SPlayerScores(Path<? extends SPlayerScores> path) { + super(path.getType(), path.getMetadata(), "", "Player_scores"); + addMetadata(); + } + + public SPlayerScores(PathMetadata metadata) { + super(SPlayerScores.class, metadata, "", "Player_scores"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(playerId, ColumnMetadata.named("Player_id").withIndex(1).ofType(-5).withSize(19).notNull()); + addMetadata(scores, ColumnMetadata.named("scores").withIndex(2).ofType(4).withSize(10)); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SPrice.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SPrice.java new file mode 100644 index 0000000000..c5862a160c --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SPrice.java @@ -0,0 +1,62 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SPrice is a Querydsl query type for SPrice + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SPrice extends com.querydsl.sql.RelationalPathBase<SPrice> { + + private static final long serialVersionUID = 768137319; + + public static final SPrice price_ = new SPrice("price_"); + + public final NumberPath<Long> amount = createNumber("amount", Long.class); + + public final NumberPath<Long> id = createNumber("id", Long.class); + + public final NumberPath<Long> productId = createNumber("productId", Long.class); + + public final com.querydsl.sql.PrimaryKey<SPrice> primary = createPrimaryKey(id); + + public final com.querydsl.sql.ForeignKey<SItem> fkc59678362c7f0c58 = createForeignKey(productId, "id"); + + public final com.querydsl.sql.ForeignKey<SCatalog_price> _fkaa04532f5222eaf7 = createInvForeignKey(id, "prices_id"); + + public SPrice(String variable) { + super(SPrice.class, forVariable(variable), "", "price_"); + addMetadata(); + } + + public SPrice(String variable, String schema, String table) { + super(SPrice.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SPrice(Path<? extends SPrice> path) { + super(path.getType(), path.getMetadata(), "", "price_"); + addMetadata(); + } + + public SPrice(PathMetadata metadata) { + super(SPrice.class, metadata, "", "price_"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(amount, ColumnMetadata.named("amount").withIndex(2).ofType(-5).withSize(19).notNull()); + addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(-5).withSize(19).notNull()); + addMetadata(productId, ColumnMetadata.named("product_id").withIndex(3).ofType(-5).withSize(19)); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SShapes.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SShapes.java new file mode 100644 index 0000000000..d07778b3ef --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SShapes.java @@ -0,0 +1,56 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.SimplePath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SShapes is a Querydsl query type for SShapes + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SShapes extends com.querydsl.sql.RelationalPathBase<SShapes> { + + private static final long serialVersionUID = 844563747; + + public static final SShapes shapes = new SShapes("SHAPES"); + + public final SimplePath<byte[]> geometry = createSimple("geometry", byte[].class); + + public final NumberPath<Integer> id = createNumber("id", Integer.class); + + public final com.querydsl.sql.PrimaryKey<SShapes> primary = createPrimaryKey(id); + + public SShapes(String variable) { + super(SShapes.class, forVariable(variable), "", "SHAPES"); + addMetadata(); + } + + public SShapes(String variable, String schema, String table) { + super(SShapes.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SShapes(Path<? extends SShapes> path) { + super(path.getType(), path.getMetadata(), "", "SHAPES"); + addMetadata(); + } + + public SShapes(PathMetadata metadata) { + super(SShapes.class, metadata, "", "SHAPES"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(geometry, ColumnMetadata.named("GEOMETRY").withIndex(2).ofType(-2)); + addMetadata(id, ColumnMetadata.named("ID").withIndex(1).ofType(4).withSize(10).notNull()); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SShow.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SShow.java new file mode 100644 index 0000000000..273b14dffb --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SShow.java @@ -0,0 +1,54 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SShow is a Querydsl query type for SShow + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SShow extends com.querydsl.sql.RelationalPathBase<SShow> { + + private static final long serialVersionUID = -111289679; + + public static final SShow show_ = new SShow("show_"); + + public final NumberPath<Long> id = createNumber("id", Long.class); + + public final com.querydsl.sql.PrimaryKey<SShow> primary = createPrimaryKey(id); + + public final com.querydsl.sql.ForeignKey<SShowActs> _fk5f6ee03ab40105c = createInvForeignKey(id, "Show_id"); + + public SShow(String variable) { + super(SShow.class, forVariable(variable), "", "show_"); + addMetadata(); + } + + public SShow(String variable, String schema, String table) { + super(SShow.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SShow(Path<? extends SShow> path) { + super(path.getType(), path.getMetadata(), "", "show_"); + addMetadata(); + } + + public SShow(PathMetadata metadata) { + super(SShow.class, metadata, "", "show_"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(-5).withSize(19).notNull()); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SShowActs.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SShowActs.java new file mode 100644 index 0000000000..a8d470b8f2 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SShowActs.java @@ -0,0 +1,61 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.StringPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SShowActs is a Querydsl query type for SShowActs + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SShowActs extends com.querydsl.sql.RelationalPathBase<SShowActs> { + + private static final long serialVersionUID = 283130543; + + public static final SShowActs ShowActs = new SShowActs("Show_acts"); + + public final StringPath acts = createString("acts"); + + public final StringPath actsKEY = createString("actsKEY"); + + public final NumberPath<Long> showId = createNumber("showId", Long.class); + + public final com.querydsl.sql.PrimaryKey<SShowActs> primary = createPrimaryKey(showId, actsKEY); + + public final com.querydsl.sql.ForeignKey<SShow> fk5f6ee03ab40105c = createForeignKey(showId, "id"); + + public SShowActs(String variable) { + super(SShowActs.class, forVariable(variable), "", "Show_acts"); + addMetadata(); + } + + public SShowActs(String variable, String schema, String table) { + super(SShowActs.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SShowActs(Path<? extends SShowActs> path) { + super(path.getType(), path.getMetadata(), "", "Show_acts"); + addMetadata(); + } + + public SShowActs(PathMetadata metadata) { + super(SShowActs.class, metadata, "", "Show_acts"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(acts, ColumnMetadata.named("acts").withIndex(2).ofType(12).withSize(255)); + addMetadata(actsKEY, ColumnMetadata.named("acts_KEY").withIndex(3).ofType(12).withSize(255).notNull()); + addMetadata(showId, ColumnMetadata.named("Show_id").withIndex(1).ofType(-5).withSize(19).notNull()); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SSimpletypes.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SSimpletypes.java similarity index 77% rename from querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SSimpletypes.java rename to querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SSimpletypes.java index 0c9246a985..e5db358299 100644 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SSimpletypes.java +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SSimpletypes.java @@ -1,21 +1,24 @@ -package com.mysema.query.jpa.domain.sql; +package com.querydsl.jpa.domain.sql; -import static com.mysema.query.types.PathMetadataFactory.*; +import static com.querydsl.core.types.PathMetadataFactory.forVariable; -import com.mysema.query.types.path.*; +import java.sql.Date; +import java.sql.Time; +import java.sql.Timestamp; -import com.mysema.query.types.PathMetadata; import javax.annotation.Generated; -import com.mysema.query.types.Path; -import com.mysema.query.sql.ColumnMetadata; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.*; +import com.querydsl.sql.ColumnMetadata; /** * SSimpletypes is a Querydsl query type for SSimpletypes */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SSimpletypes extends com.mysema.query.sql.RelationalPathBase<SSimpletypes> { +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SSimpletypes extends com.querydsl.sql.RelationalPathBase<SSimpletypes> { private static final long serialVersionUID = 1466962601; @@ -31,7 +34,7 @@ public class SSimpletypes extends com.mysema.query.sql.RelationalPathBase<SSimpl public final StringPath cchar2 = createString("cchar2"); - public final DatePath<java.sql.Date> date = createDate("date", java.sql.Date.class); + public final DatePath<Date> date = createDate("date", java.sql.Date.class); public final NumberPath<Double> ddouble = createNumber("ddouble", Double.class); @@ -55,14 +58,14 @@ public class SSimpletypes extends com.mysema.query.sql.RelationalPathBase<SSimpl public final StringPath sstring = createString("sstring"); - public final TimePath<java.sql.Time> time = createTime("time", java.sql.Time.class); + public final TimePath<Time> time = createTime("time", java.sql.Time.class); - public final DateTimePath<java.sql.Timestamp> timestamp = createDateTime("timestamp", java.sql.Timestamp.class); + public final DateTimePath<Timestamp> timestamp = createDateTime("timestamp", java.sql.Timestamp.class); - public final com.mysema.query.sql.PrimaryKey<SSimpletypes> primary = createPrimaryKey(id); + public final com.querydsl.sql.PrimaryKey<SSimpletypes> primary = createPrimaryKey(id); public SSimpletypes(String variable) { - super(SSimpletypes.class, forVariable(variable), "null", "simpletypes_"); + super(SSimpletypes.class, forVariable(variable), "", "simpletypes_"); addMetadata(); } @@ -72,12 +75,12 @@ public SSimpletypes(String variable, String schema, String table) { } public SSimpletypes(Path<? extends SSimpletypes> path) { - super(path.getType(), path.getMetadata(), "null", "simpletypes_"); + super(path.getType(), path.getMetadata(), "", "simpletypes_"); addMetadata(); } - public SSimpletypes(PathMetadata<?> metadata) { - super(SSimpletypes.class, metadata, "null", "simpletypes_"); + public SSimpletypes(PathMetadata metadata) { + super(SSimpletypes.class, metadata, "", "simpletypes_"); addMetadata(); } diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SStatus.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SStatus.java new file mode 100644 index 0000000000..67cced11d1 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SStatus.java @@ -0,0 +1,60 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.StringPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SStatus is a Querydsl query type for SStatus + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SStatus extends com.querydsl.sql.RelationalPathBase<SStatus> { + + private static final long serialVersionUID = 755356828; + + public static final SStatus status_ = new SStatus("status_"); + + public final NumberPath<Long> id = createNumber("id", Long.class); + + public final StringPath name = createString("name"); + + public final com.querydsl.sql.PrimaryKey<SStatus> primary = createPrimaryKey(id); + + public final com.querydsl.sql.ForeignKey<SItem> _fk5fde7acd23307bc = createInvForeignKey(id, "status_id"); + + public final com.querydsl.sql.ForeignKey<SItem> _fk5fde7ac9ea26263 = createInvForeignKey(id, "currentStatus_id"); + + public SStatus(String variable) { + super(SStatus.class, forVariable(variable), "", "status_"); + addMetadata(); + } + + public SStatus(String variable, String schema, String table) { + super(SStatus.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SStatus(Path<? extends SStatus> path) { + super(path.getType(), path.getMetadata(), "", "status_"); + addMetadata(); + } + + public SStatus(PathMetadata metadata) { + super(SStatus.class, metadata, "", "status_"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(-5).withSize(19).notNull()); + addMetadata(name, ColumnMetadata.named("name").withIndex(2).ofType(12).withSize(255)); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SStatuschange.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SStatuschange.java new file mode 100644 index 0000000000..e33e86e55e --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SStatuschange.java @@ -0,0 +1,58 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.DateTimePath; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SStatuschange is a Querydsl query type for SStatuschange + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SStatuschange extends com.querydsl.sql.RelationalPathBase<SStatuschange> { + + private static final long serialVersionUID = 87971116; + + public static final SStatuschange statuschange_ = new SStatuschange("statuschange_"); + + public final NumberPath<Long> id = createNumber("id", Long.class); + + public final DateTimePath<java.sql.Timestamp> timeStamp = createDateTime("timeStamp", java.sql.Timestamp.class); + + public final com.querydsl.sql.PrimaryKey<SStatuschange> primary = createPrimaryKey(id); + + public final com.querydsl.sql.ForeignKey<SItem_statuschange> _fkcb99fb2ab2bd098d = createInvForeignKey(id, "statusChanges_id"); + + public SStatuschange(String variable) { + super(SStatuschange.class, forVariable(variable), "", "statuschange_"); + addMetadata(); + } + + public SStatuschange(String variable, String schema, String table) { + super(SStatuschange.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SStatuschange(Path<? extends SStatuschange> path) { + super(path.getType(), path.getMetadata(), "", "statuschange_"); + addMetadata(); + } + + public SStatuschange(PathMetadata metadata) { + super(SStatuschange.class, metadata, "", "statuschange_"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(-5).withSize(19).notNull()); + addMetadata(timeStamp, ColumnMetadata.named("timeStamp").withIndex(2).ofType(93).withSize(19)); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SStore.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SStore.java new file mode 100644 index 0000000000..f3d09d3007 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SStore.java @@ -0,0 +1,59 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SStore is a Querydsl query type for SStore + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SStore extends com.querydsl.sql.RelationalPathBase<SStore> { + + private static final long serialVersionUID = 856064975; + + public static final SStore store_ = new SStore("store_"); + + public final NumberPath<Long> id = createNumber("id", Long.class); + + public final NumberPath<Long> locationId = createNumber("locationId", Long.class); + + public final com.querydsl.sql.PrimaryKey<SStore> primary = createPrimaryKey(id); + + public final com.querydsl.sql.ForeignKey<SLocation> fkcad4239e8a55845c = createForeignKey(locationId, "id"); + + public final com.querydsl.sql.ForeignKey<SStore_customer> _fk82ba2ce035d2d6bb = createInvForeignKey(id, "store__id"); + + public SStore(String variable) { + super(SStore.class, forVariable(variable), "", "store_"); + addMetadata(); + } + + public SStore(String variable, String schema, String table) { + super(SStore.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SStore(Path<? extends SStore> path) { + super(path.getType(), path.getMetadata(), "", "store_"); + addMetadata(); + } + + public SStore(PathMetadata metadata) { + super(SStore.class, metadata, "", "store_"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(-5).withSize(19).notNull()); + addMetadata(locationId, ColumnMetadata.named("location_id").withIndex(2).ofType(-5).withSize(19)); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SStore_customer.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SStore_customer.java new file mode 100644 index 0000000000..0f2a63d530 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SStore_customer.java @@ -0,0 +1,57 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SStore_customer is a Querydsl query type for SStore_customer + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SStore_customer extends com.querydsl.sql.RelationalPathBase<SStore_customer> { + + private static final long serialVersionUID = 1343082834; + + public static final SStore_customer store_customer_ = new SStore_customer("store__customer_"); + + public final NumberPath<Integer> customersId = createNumber("customersId", Integer.class); + + public final NumberPath<Long> store_id = createNumber("store_id", Long.class); + + public final com.querydsl.sql.ForeignKey<SStore> fk82ba2ce035d2d6bb = createForeignKey(store_id, "id"); + + public final com.querydsl.sql.ForeignKey<SCustomer> fk82ba2ce051f3c3e5 = createForeignKey(customersId, "id"); + + public SStore_customer(String variable) { + super(SStore_customer.class, forVariable(variable), "", "store__customer_"); + addMetadata(); + } + + public SStore_customer(String variable, String schema, String table) { + super(SStore_customer.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SStore_customer(Path<? extends SStore_customer> path) { + super(path.getType(), path.getMetadata(), "", "store__customer_"); + addMetadata(); + } + + public SStore_customer(PathMetadata metadata) { + super(SStore_customer.class, metadata, "", "store__customer_"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(customersId, ColumnMetadata.named("customers_id").withIndex(2).ofType(4).withSize(10).notNull()); + addMetadata(store_id, ColumnMetadata.named("store__id").withIndex(1).ofType(-5).withSize(19).notNull()); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SSurvey.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SSurvey.java new file mode 100644 index 0000000000..1742264cc6 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SSurvey.java @@ -0,0 +1,59 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.StringPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SSurvey is a Querydsl query type for SSurvey + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SSurvey extends com.querydsl.sql.RelationalPathBase<SSurvey> { + + private static final long serialVersionUID = 857081739; + + public static final SSurvey survey = new SSurvey("SURVEY"); + + public final NumberPath<Integer> id = createNumber("id", Integer.class); + + public final StringPath name = createString("name"); + + public final StringPath name2 = createString("name2"); + + public final com.querydsl.sql.PrimaryKey<SSurvey> primary = createPrimaryKey(id); + + public SSurvey(String variable) { + super(SSurvey.class, forVariable(variable), "", "SURVEY"); + addMetadata(); + } + + public SSurvey(String variable, String schema, String table) { + super(SSurvey.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SSurvey(Path<? extends SSurvey> path) { + super(path.getType(), path.getMetadata(), "", "SURVEY"); + addMetadata(); + } + + public SSurvey(PathMetadata metadata) { + super(SSurvey.class, metadata, "", "SURVEY"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(id, ColumnMetadata.named("ID").withIndex(1).ofType(4).withSize(10).notNull()); + addMetadata(name, ColumnMetadata.named("NAME").withIndex(2).ofType(12).withSize(30)); + addMetadata(name2, ColumnMetadata.named("NAME2").withIndex(3).ofType(12).withSize(30)); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/STest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/STest.java new file mode 100644 index 0000000000..3819213b8e --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/STest.java @@ -0,0 +1,50 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.StringPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * STest is a Querydsl query type for STest + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class STest extends com.querydsl.sql.RelationalPathBase<STest> { + + private static final long serialVersionUID = -1389036285; + + public static final STest test = new STest("TEST"); + + public final StringPath name = createString("name"); + + public STest(String variable) { + super(STest.class, forVariable(variable), "", "TEST"); + addMetadata(); + } + + public STest(String variable, String schema, String table) { + super(STest.class, forVariable(variable), schema, table); + addMetadata(); + } + + public STest(Path<? extends STest> path) { + super(path.getType(), path.getMetadata(), "", "TEST"); + addMetadata(); + } + + public STest(PathMetadata metadata) { + super(STest.class, metadata, "", "TEST"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(name, ColumnMetadata.named("NAME").withIndex(1).ofType(12).withSize(255)); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/STimeTest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/STimeTest.java new file mode 100644 index 0000000000..ee14827c12 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/STimeTest.java @@ -0,0 +1,50 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.TimePath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * STimeTest is a Querydsl query type for STimeTest + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class STimeTest extends com.querydsl.sql.RelationalPathBase<STimeTest> { + + private static final long serialVersionUID = -1454836496; + + public static final STimeTest timeTest1 = new STimeTest("TIME_TEST"); + + public final TimePath<java.sql.Time> timeTest = createTime("timeTest", java.sql.Time.class); + + public STimeTest(String variable) { + super(STimeTest.class, forVariable(variable), "", "TIME_TEST"); + addMetadata(); + } + + public STimeTest(String variable, String schema, String table) { + super(STimeTest.class, forVariable(variable), schema, table); + addMetadata(); + } + + public STimeTest(Path<? extends STimeTest> path) { + super(path.getType(), path.getMetadata(), "", "TIME_TEST"); + addMetadata(); + } + + public STimeTest(PathMetadata metadata) { + super(STimeTest.class, metadata, "", "TIME_TEST"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(timeTest, ColumnMetadata.named("TIME_TEST").withIndex(1).ofType(92).withSize(8)); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SUser.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SUser.java new file mode 100644 index 0000000000..d1cceff6b7 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SUser.java @@ -0,0 +1,69 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.StringPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SUser is a Querydsl query type for SUser + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SUser extends com.querydsl.sql.RelationalPathBase<SUser> { + + private static final long serialVersionUID = -109124701; + + public static final SUser user_ = new SUser("user_"); + + public final NumberPath<Integer> companyId = createNumber("companyId", Integer.class); + + public final StringPath firstName = createString("firstName"); + + public final NumberPath<Long> id = createNumber("id", Long.class); + + public final StringPath lastName = createString("lastName"); + + public final StringPath userName = createString("userName"); + + public final com.querydsl.sql.PrimaryKey<SUser> primary = createPrimaryKey(id); + + public final com.querydsl.sql.ForeignKey<SCompany> fk6a68df4dc953998 = createForeignKey(companyId, "id"); + + public final com.querydsl.sql.ForeignKey<SEmployee> _fk9d39ef712743b59c = createInvForeignKey(id, "user_id"); + + public SUser(String variable) { + super(SUser.class, forVariable(variable), "", "user_"); + addMetadata(); + } + + public SUser(String variable, String schema, String table) { + super(SUser.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SUser(Path<? extends SUser> path) { + super(path.getType(), path.getMetadata(), "", "user_"); + addMetadata(); + } + + public SUser(PathMetadata metadata) { + super(SUser.class, metadata, "", "user_"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(companyId, ColumnMetadata.named("company_id").withIndex(5).ofType(4).withSize(10)); + addMetadata(firstName, ColumnMetadata.named("firstName").withIndex(2).ofType(12).withSize(255)); + addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(-5).withSize(19).notNull()); + addMetadata(lastName, ColumnMetadata.named("lastName").withIndex(3).ofType(12).withSize(255)); + addMetadata(userName, ColumnMetadata.named("userName").withIndex(4).ofType(12).withSize(255)); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SUser2.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SUser2.java similarity index 76% rename from querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SUser2.java rename to querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SUser2.java index 601d8ed1bd..bd811368c3 100644 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain/sql/SUser2.java +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SUser2.java @@ -1,21 +1,22 @@ -package com.mysema.query.jpa.domain.sql; +package com.querydsl.jpa.domain.sql; -import static com.mysema.query.types.PathMetadataFactory.*; +import static com.querydsl.core.types.PathMetadataFactory.forVariable; -import com.mysema.query.types.path.*; - -import com.mysema.query.types.PathMetadata; import javax.annotation.Generated; -import com.mysema.query.types.Path; -import com.mysema.query.sql.ColumnMetadata; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.DateTimePath; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.StringPath; +import com.querydsl.sql.ColumnMetadata; /** * SUser2 is a Querydsl query type for SUser2 */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class SUser2 extends com.mysema.query.sql.RelationalPathBase<SUser2> { +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SUser2 extends com.querydsl.sql.RelationalPathBase<SUser2> { private static final long serialVersionUID = 912100265; @@ -45,12 +46,12 @@ public class SUser2 extends com.mysema.query.sql.RelationalPathBase<SUser2> { public final StringPath userPassword = createString("userPassword"); - public final com.mysema.query.sql.PrimaryKey<SUser2> primary = createPrimaryKey(id); + public final com.querydsl.sql.PrimaryKey<SUser2> primary = createPrimaryKey(id); - public final com.mysema.query.sql.ForeignKey<SUser2_userprop> _fk4611b46af21971a1 = createInvForeignKey(id, "user2__id"); + public final com.querydsl.sql.ForeignKey<SUser2_userprop> _fk4611b46af21971a1 = createInvForeignKey(id, "user2__id"); public SUser2(String variable) { - super(SUser2.class, forVariable(variable), "null", "user2_"); + super(SUser2.class, forVariable(variable), "", "user2_"); addMetadata(); } @@ -60,12 +61,12 @@ public SUser2(String variable, String schema, String table) { } public SUser2(Path<? extends SUser2> path) { - super(path.getType(), path.getMetadata(), "null", "user2_"); + super(path.getType(), path.getMetadata(), "", "user2_"); addMetadata(); } - public SUser2(PathMetadata<?> metadata) { - super(SUser2.class, metadata, "null", "user2_"); + public SUser2(PathMetadata metadata) { + super(SUser2.class, metadata, "", "user2_"); addMetadata(); } diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SUser2_userprop.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SUser2_userprop.java new file mode 100644 index 0000000000..d76154eba1 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SUser2_userprop.java @@ -0,0 +1,59 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SUser2_userprop is a Querydsl query type for SUser2_userprop + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SUser2_userprop extends com.querydsl.sql.RelationalPathBase<SUser2_userprop> { + + private static final long serialVersionUID = -598341912; + + public static final SUser2_userprop user2_userprop_ = new SUser2_userprop("user2__userprop_"); + + public final NumberPath<Long> propertiesId = createNumber("propertiesId", Long.class); + + public final NumberPath<Long> user2_id = createNumber("user2_id", Long.class); + + public final com.querydsl.sql.PrimaryKey<SUser2_userprop> primary = createPrimaryKey(propertiesId, user2_id); + + public final com.querydsl.sql.ForeignKey<SUser2> fk4611b46af21971a1 = createForeignKey(user2_id, "id"); + + public final com.querydsl.sql.ForeignKey<SUserprop> fk4611b46aa56541dd = createForeignKey(propertiesId, "id"); + + public SUser2_userprop(String variable) { + super(SUser2_userprop.class, forVariable(variable), "", "user2__userprop_"); + addMetadata(); + } + + public SUser2_userprop(String variable, String schema, String table) { + super(SUser2_userprop.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SUser2_userprop(Path<? extends SUser2_userprop> path) { + super(path.getType(), path.getMetadata(), "", "user2__userprop_"); + addMetadata(); + } + + public SUser2_userprop(PathMetadata metadata) { + super(SUser2_userprop.class, metadata, "", "user2__userprop_"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(propertiesId, ColumnMetadata.named("properties_id").withIndex(2).ofType(-5).withSize(19).notNull()); + addMetadata(user2_id, ColumnMetadata.named("user2__id").withIndex(1).ofType(-5).withSize(19).notNull()); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SUserprop.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SUserprop.java new file mode 100644 index 0000000000..9d962a79ba --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SUserprop.java @@ -0,0 +1,84 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.DateTimePath; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.StringPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SUserprop is a Querydsl query type for SUserprop + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SUserprop extends com.querydsl.sql.RelationalPathBase<SUserprop> { + + private static final long serialVersionUID = -1821152608; + + public static final SUserprop userprop_ = new SUserprop("userprop_"); + + public final StringPath categoryDescription = createString("categoryDescription"); + + public final StringPath categoryName = createString("categoryName"); + + public final NumberPath<Double> createdBy = createNumber("createdBy", Double.class); + + public final DateTimePath<java.sql.Timestamp> creationDate = createDateTime("creationDate", java.sql.Timestamp.class); + + public final DateTimePath<java.sql.Timestamp> deleteDate = createDateTime("deleteDate", java.sql.Timestamp.class); + + public final NumberPath<Double> deletedBy = createNumber("deletedBy", Double.class); + + public final NumberPath<Long> id = createNumber("id", Long.class); + + public final DateTimePath<java.sql.Timestamp> modificationDate = createDateTime("modificationDate", java.sql.Timestamp.class); + + public final NumberPath<Double> modifiedBy = createNumber("modifiedBy", Double.class); + + public final com.querydsl.sql.PrimaryKey<SUserprop> primary = createPrimaryKey(id); + + public final com.querydsl.sql.ForeignKey<SUserprop_category> _fk851f48d3904c19df = createInvForeignKey(id, "userprop__id"); + + public final com.querydsl.sql.ForeignKey<SUserprop_categoryprop> _fke0fdb7d0904c19df = createInvForeignKey(id, "userprop__id"); + + public final com.querydsl.sql.ForeignKey<SUser2_userprop> _fk4611b46aa56541dd = createInvForeignKey(id, "properties_id"); + + public SUserprop(String variable) { + super(SUserprop.class, forVariable(variable), "", "userprop_"); + addMetadata(); + } + + public SUserprop(String variable, String schema, String table) { + super(SUserprop.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SUserprop(Path<? extends SUserprop> path) { + super(path.getType(), path.getMetadata(), "", "userprop_"); + addMetadata(); + } + + public SUserprop(PathMetadata metadata) { + super(SUserprop.class, metadata, "", "userprop_"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(categoryDescription, ColumnMetadata.named("categoryDescription").withIndex(2).ofType(12).withSize(255)); + addMetadata(categoryName, ColumnMetadata.named("categoryName").withIndex(3).ofType(12).withSize(255)); + addMetadata(createdBy, ColumnMetadata.named("createdBy").withIndex(4).ofType(8).withSize(22).notNull()); + addMetadata(creationDate, ColumnMetadata.named("creationDate").withIndex(5).ofType(93).withSize(19)); + addMetadata(deleteDate, ColumnMetadata.named("deleteDate").withIndex(6).ofType(93).withSize(19)); + addMetadata(deletedBy, ColumnMetadata.named("deletedBy").withIndex(7).ofType(8).withSize(22).notNull()); + addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(-5).withSize(19).notNull()); + addMetadata(modificationDate, ColumnMetadata.named("modificationDate").withIndex(8).ofType(93).withSize(19)); + addMetadata(modifiedBy, ColumnMetadata.named("modifiedBy").withIndex(9).ofType(8).withSize(22).notNull()); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SUserprop_category.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SUserprop_category.java new file mode 100644 index 0000000000..e2518d3c23 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SUserprop_category.java @@ -0,0 +1,59 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SUserprop_category is a Querydsl query type for SUserprop_category + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SUserprop_category extends com.querydsl.sql.RelationalPathBase<SUserprop_category> { + + private static final long serialVersionUID = 301952129; + + public static final SUserprop_category userprop_category_ = new SUserprop_category("userprop__category_"); + + public final NumberPath<Long> childCategoriesId = createNumber("childCategoriesId", Long.class); + + public final NumberPath<Long> userprop_id = createNumber("userprop_id", Long.class); + + public final com.querydsl.sql.PrimaryKey<SUserprop_category> primary = createPrimaryKey(childCategoriesId, userprop_id); + + public final com.querydsl.sql.ForeignKey<SUserprop> fk851f48d3904c19df = createForeignKey(userprop_id, "id"); + + public final com.querydsl.sql.ForeignKey<SCategory> fk851f48d37ab543e8 = createForeignKey(childCategoriesId, "id"); + + public SUserprop_category(String variable) { + super(SUserprop_category.class, forVariable(variable), "", "userprop__category_"); + addMetadata(); + } + + public SUserprop_category(String variable, String schema, String table) { + super(SUserprop_category.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SUserprop_category(Path<? extends SUserprop_category> path) { + super(path.getType(), path.getMetadata(), "", "userprop__category_"); + addMetadata(); + } + + public SUserprop_category(PathMetadata metadata) { + super(SUserprop_category.class, metadata, "", "userprop__category_"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(childCategoriesId, ColumnMetadata.named("childCategories_id").withIndex(2).ofType(-5).withSize(19).notNull()); + addMetadata(userprop_id, ColumnMetadata.named("userprop__id").withIndex(1).ofType(-5).withSize(19).notNull()); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SUserprop_categoryprop.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SUserprop_categoryprop.java new file mode 100644 index 0000000000..4a8f0c5450 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SUserprop_categoryprop.java @@ -0,0 +1,59 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SUserprop_categoryprop is a Querydsl query type for SUserprop_categoryprop + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SUserprop_categoryprop extends com.querydsl.sql.RelationalPathBase<SUserprop_categoryprop> { + + private static final long serialVersionUID = -190294914; + + public static final SUserprop_categoryprop userprop_categoryprop_ = new SUserprop_categoryprop("userprop__categoryprop_"); + + public final NumberPath<Long> propertiesId = createNumber("propertiesId", Long.class); + + public final NumberPath<Long> userprop_id = createNumber("userprop_id", Long.class); + + public final com.querydsl.sql.PrimaryKey<SUserprop_categoryprop> primary = createPrimaryKey(propertiesId, userprop_id); + + public final com.querydsl.sql.ForeignKey<SCategoryprop> fke0fdb7d0fd94cd90 = createForeignKey(propertiesId, "id"); + + public final com.querydsl.sql.ForeignKey<SUserprop> fke0fdb7d0904c19df = createForeignKey(userprop_id, "id"); + + public SUserprop_categoryprop(String variable) { + super(SUserprop_categoryprop.class, forVariable(variable), "", "userprop__categoryprop_"); + addMetadata(); + } + + public SUserprop_categoryprop(String variable, String schema, String table) { + super(SUserprop_categoryprop.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SUserprop_categoryprop(Path<? extends SUserprop_categoryprop> path) { + super(path.getType(), path.getMetadata(), "", "userprop__categoryprop_"); + addMetadata(); + } + + public SUserprop_categoryprop(PathMetadata metadata) { + super(SUserprop_categoryprop.class, metadata, "", "userprop__categoryprop_"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(propertiesId, ColumnMetadata.named("properties_id").withIndex(2).ofType(-5).withSize(19).notNull()); + addMetadata(userprop_id, ColumnMetadata.named("userprop__id").withIndex(1).ofType(-5).withSize(19).notNull()); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SWorld.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SWorld.java new file mode 100644 index 0000000000..f3d8dc8ed1 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SWorld.java @@ -0,0 +1,54 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SWorld is a Querydsl query type for SWorld + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SWorld extends com.querydsl.sql.RelationalPathBase<SWorld> { + + private static final long serialVersionUID = -107384511; + + public static final SWorld World = new SWorld("World"); + + public final NumberPath<Long> id = createNumber("id", Long.class); + + public final com.querydsl.sql.PrimaryKey<SWorld> primary = createPrimaryKey(id); + + public final com.querydsl.sql.ForeignKey<SWorldMammal> _fk4070aeecd3538cf8 = createInvForeignKey(id, "World_id"); + + public SWorld(String variable) { + super(SWorld.class, forVariable(variable), "", "World"); + addMetadata(); + } + + public SWorld(String variable, String schema, String table) { + super(SWorld.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SWorld(Path<? extends SWorld> path) { + super(path.getType(), path.getMetadata(), "", "World"); + addMetadata(); + } + + public SWorld(PathMetadata metadata) { + super(SWorld.class, metadata, "", "World"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(id, ColumnMetadata.named("id").withIndex(1).ofType(-5).withSize(19).notNull()); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SWorldMammal.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SWorldMammal.java new file mode 100644 index 0000000000..2da2164931 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain/sql/SWorldMammal.java @@ -0,0 +1,59 @@ +package com.querydsl.jpa.domain.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.sql.ColumnMetadata; + + +/** + * SWorldMammal is a Querydsl query type for SWorldMammal + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class SWorldMammal extends com.querydsl.sql.RelationalPathBase<SWorldMammal> { + + private static final long serialVersionUID = 979697152; + + public static final SWorldMammal WorldMammal = new SWorldMammal("World_Mammal"); + + public final NumberPath<Long> mammalsId = createNumber("mammalsId", Long.class); + + public final NumberPath<Long> worldId = createNumber("worldId", Long.class); + + public final com.querydsl.sql.PrimaryKey<SWorldMammal> primary = createPrimaryKey(worldId, mammalsId); + + public final com.querydsl.sql.ForeignKey<SMammal> fk4070aeece01c8ee7 = createForeignKey(mammalsId, "id"); + + public final com.querydsl.sql.ForeignKey<SWorld> fk4070aeecd3538cf8 = createForeignKey(worldId, "id"); + + public SWorldMammal(String variable) { + super(SWorldMammal.class, forVariable(variable), "", "World_Mammal"); + addMetadata(); + } + + public SWorldMammal(String variable, String schema, String table) { + super(SWorldMammal.class, forVariable(variable), schema, table); + addMetadata(); + } + + public SWorldMammal(Path<? extends SWorldMammal> path) { + super(path.getType(), path.getMetadata(), "", "World_Mammal"); + addMetadata(); + } + + public SWorldMammal(PathMetadata metadata) { + super(SWorldMammal.class, metadata, "", "World_Mammal"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(mammalsId, ColumnMetadata.named("mammals_id").withIndex(2).ofType(-5).withSize(19).notNull()); + addMetadata(worldId, ColumnMetadata.named("World_id").withIndex(1).ofType(-5).withSize(19).notNull()); + } + +} + diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain2/Category.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain2/Category.java similarity index 88% rename from querydsl-jpa/src/test/java/com/mysema/query/jpa/domain2/Category.java rename to querydsl-jpa/src/test/java/com/querydsl/jpa/domain2/Category.java index fe2bd47b06..da36a8b945 100644 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain2/Category.java +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain2/Category.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,50 +11,43 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.jpa.domain2; +package com.querydsl.jpa.domain2; import java.util.Date; import java.util.Set; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.JoinColumn; -import javax.persistence.JoinTable; -import javax.persistence.OneToMany; -import javax.persistence.Table; -import javax.persistence.Temporal; -import javax.persistence.TemporalType; +import javax.persistence.*; @Entity -@Table(name="category_") +@Table(name = "category_") public class Category { @Id private long id; - + private String categoryName; - + private String categoryDescription; - + private double createdBy; - + private double modifiedBy; - + @Temporal(TemporalType.TIMESTAMP) private Date creationDate; - + @Temporal(TemporalType.TIMESTAMP) private Date modificationDate; - + private double deletedBy; - + @Temporal(TemporalType.TIMESTAMP) private Date deleteDate; - + @OneToMany @JoinTable(joinColumns = @JoinColumn(name = "parentId"), inverseJoinColumns = @JoinColumn(name = "childId")) private Set<Category> childCategories; - + @OneToMany private Set<CategoryProp> properties; diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain2/CategoryProp.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain2/CategoryProp.java similarity index 90% rename from querydsl-jpa/src/test/java/com/mysema/query/jpa/domain2/CategoryProp.java rename to querydsl-jpa/src/test/java/com/querydsl/jpa/domain2/CategoryProp.java index cc3d6cbbcb..494a31046b 100644 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain2/CategoryProp.java +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain2/CategoryProp.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,23 +11,23 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.jpa.domain2; +package com.querydsl.jpa.domain2; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table; @Entity -@Table(name="categoryprop_") +@Table(name = "categoryprop_") public class CategoryProp { @Id private long id; - + private long categoryId; - + private String propName; - + private String propValue; public long getId() { @@ -61,5 +61,5 @@ public String getPropValue() { public void setPropValue(String propValue) { this.propValue = propValue; } - + } diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain2/Child.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain2/Child.java new file mode 100644 index 0000000000..de148c35b9 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain2/Child.java @@ -0,0 +1,32 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.domain2; + +import javax.persistence.Embeddable; + +@Embeddable +public class Child { + + private String childName; + + public String getChildName() { + return childName; + } + + public void setChildName(String childName) { + this.childName = childName; + } + + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain2/Contact.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain2/Contact.java new file mode 100644 index 0000000000..b58a868aae --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain2/Contact.java @@ -0,0 +1,54 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.domain2; + +public class Contact { + + private long id; + + private String firstName, lastName, email; + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + +} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain2/Document2.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain2/Document2.java similarity index 91% rename from querydsl-jpa/src/test/java/com/mysema/query/jpa/domain2/Document2.java rename to querydsl-jpa/src/test/java/com/querydsl/jpa/domain2/Document2.java index 07314f0737..6115e5679f 100644 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain2/Document2.java +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain2/Document2.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,50 +11,46 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.jpa.domain2; +package com.querydsl.jpa.domain2; import java.util.Date; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.Table; -import javax.persistence.Temporal; -import javax.persistence.TemporalType; +import javax.persistence.*; @Entity -@Table(name="document2_") +@Table(name = "document2_") public class Document2 { - + @Id private long id; - + private String documentTitle; - + private String documentBody; - + private String documentSummary; - + private double createdBy; - + @Temporal(TemporalType.TIMESTAMP) private Date creationDate; - + private double modifiedBy; - + @Temporal(TemporalType.TIMESTAMP) private Date modificationDate; - + private double deletedBy; - + @Temporal(TemporalType.TIMESTAMP) private Date deletedDate; - + private double documentVersion; private double documentStatus; - + private double entryId; - + public long getId() { return id; } diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain2/DocumentProp.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain2/DocumentProp.java similarity index 91% rename from querydsl-jpa/src/test/java/com/mysema/query/jpa/domain2/DocumentProp.java rename to querydsl-jpa/src/test/java/com/querydsl/jpa/domain2/DocumentProp.java index 0b63548d14..0746e96447 100644 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain2/DocumentProp.java +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain2/DocumentProp.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,23 +11,23 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.jpa.domain2; +package com.querydsl.jpa.domain2; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table; @Entity -@Table(name="documentprop_") +@Table(name = "documentprop_") public class DocumentProp { @Id private long id; - + private double documentId; - + private String propName, propValue, propValueDetails; - + public long getId() { return id; } @@ -67,5 +67,5 @@ public String getPropValueDetails() { public void setPropValueDetails(String propValueDetails) { this.propValueDetails = propValueDetails; } - + } diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain2/Domain2.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain2/Domain2.java similarity index 76% rename from querydsl-jpa/src/test/java/com/mysema/query/jpa/domain2/Domain2.java rename to querydsl-jpa/src/test/java/com/querydsl/jpa/domain2/Domain2.java index 00b4a655d4..541b3ba4ca 100644 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain2/Domain2.java +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain2/Domain2.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,22 +11,22 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.jpa.domain2; +package com.querydsl.jpa.domain2; import java.util.Arrays; import java.util.List; public final class Domain2 { - - private Domain2() {} + + private Domain2() { } public static final List<Class<?>> classes = Arrays.<Class<?>>asList( - Category.class, - CategoryProp.class, + Category.class, + CategoryProp.class, Contact.class, - Document2.class, + Document2.class, DocumentProp.class, - User2.class, + User2.class, UserProp.class); } diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain2/Parent.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain2/Parent.java new file mode 100644 index 0000000000..919c27d759 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain2/Parent.java @@ -0,0 +1,57 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.domain2; + +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "parent_") +public class Parent { + + @Id + private long id; + + private String name; + + @Embedded + private Child child; + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Child getChild() { + return child; + } + + public void setChild(Child child) { + this.child = child; + } + +} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain2/User2.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain2/User2.java similarity index 90% rename from querydsl-jpa/src/test/java/com/mysema/query/jpa/domain2/User2.java rename to querydsl-jpa/src/test/java/com/querydsl/jpa/domain2/User2.java index b7f5659830..6d3f99411a 100644 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain2/User2.java +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain2/User2.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,45 +11,40 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.jpa.domain2; +package com.querydsl.jpa.domain2; import java.util.Date; import java.util.Set; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.OneToMany; -import javax.persistence.Table; -import javax.persistence.Temporal; -import javax.persistence.TemporalType; +import javax.persistence.*; @Entity -@Table(name="user2_") +@Table(name = "user2_") public class User2 { @Id private long id; - + private String userName, userPassword, userFirstName, userEmail, userLastName; - + @Temporal(TemporalType.TIMESTAMP) private Date creationDate; - + private double createdBy; - + @Temporal(TemporalType.TIMESTAMP) private Date modificationDate; - + private double modifiedBy; - + @Temporal(TemporalType.TIMESTAMP) private Date deleteDate; - + private double deletedBy; - + @OneToMany private Set<UserProp> properties; - + public long getId() { return id; } @@ -154,5 +149,5 @@ public void setProperties(Set<UserProp> properties) { this.properties = properties; } - + } diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain2/UserProp.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain2/UserProp.java similarity index 89% rename from querydsl-jpa/src/test/java/com/mysema/query/jpa/domain2/UserProp.java rename to querydsl-jpa/src/test/java/com/querydsl/jpa/domain2/UserProp.java index f83aa5b42b..67e282ab83 100644 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain2/UserProp.java +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain2/UserProp.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,48 +11,43 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.jpa.domain2; +package com.querydsl.jpa.domain2; import java.util.Date; import java.util.Set; -import javax.persistence.Entity; -import javax.persistence.Id; -import javax.persistence.OneToMany; -import javax.persistence.Table; -import javax.persistence.Temporal; -import javax.persistence.TemporalType; +import javax.persistence.*; @Entity -@Table(name="userprop_") +@Table(name = "userprop_") public class UserProp { - + @Id private long id; private String categoryName, categoryDescription; - + private double createdBy; - + @Temporal(TemporalType.TIMESTAMP) private Date creationDate; - + private double modifiedBy; - + @Temporal(TemporalType.TIMESTAMP) private Date modificationDate; - + private double deletedBy; @Temporal(TemporalType.TIMESTAMP) private Date deleteDate; - + @OneToMany private Set<Category> childCategories; - + @OneToMany private Set<CategoryProp> properties; - + public long getId() { return id; } @@ -140,6 +135,6 @@ public Set<CategoryProp> getProperties() { public void setProperties(Set<CategoryProp> properties) { this.properties = properties; } - -} + +} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain3/HardwareStore.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain3/HardwareStore.java similarity index 84% rename from querydsl-jpa/src/test/java/com/mysema/query/jpa/domain3/HardwareStore.java rename to querydsl-jpa/src/test/java/com/querydsl/jpa/domain3/HardwareStore.java index 4c6f8e388e..74437b389d 100644 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/domain3/HardwareStore.java +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain3/HardwareStore.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,12 +11,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.jpa.domain3; +package com.querydsl.jpa.domain3; + +public class HardwareStore extends Store { -public class HardwareStore extends Store{ - private static final long serialVersionUID = 2725944536560445206L; - + private String storeCode; public String getStoreCode() { @@ -26,5 +26,5 @@ public String getStoreCode() { public void setStoreCode(String storeCode) { this.storeCode = storeCode; } - + } diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain3/Store.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain3/Store.java new file mode 100644 index 0000000000..f15e3d43c4 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain3/Store.java @@ -0,0 +1,102 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.domain3; + +import java.io.Serializable; + +public class Store implements Serializable { + + private static final long serialVersionUID = 7221730732392000227L; + + private String code; + + private String name; + + private String address; + + private String city; + + private String phoneDetails; + + private String faxDetails; + + private String zipCode; + + private String chainCode; + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public String getPhoneDetails() { + return phoneDetails; + } + + public void setPhoneDetails(String phoneDetails) { + this.phoneDetails = phoneDetails; + } + + public String getFaxDetails() { + return faxDetails; + } + + public void setFaxDetails(String faxDetails) { + this.faxDetails = faxDetails; + } + + public String getZipCode() { + return zipCode; + } + + public void setZipCode(String zipCode) { + this.zipCode = zipCode; + } + + public String getChainCode() { + return chainCode; + } + + public void setChainCode(String chainCode) { + this.chainCode = chainCode; + } + +} \ No newline at end of file diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain4/BookDefinition.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain4/BookDefinition.java new file mode 100644 index 0000000000..a4e25cd126 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain4/BookDefinition.java @@ -0,0 +1,62 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.domain4; + +import java.io.Serializable; +import java.util.List; + +import javax.persistence.*; + +@Embeddable +@Access(AccessType.PROPERTY) +public class BookDefinition implements Serializable { + + private static final long serialVersionUID = 3570098308959717614L; + + private String name; + + private String description; + + private List<BookMark> bookMarks; + + @Basic + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Basic + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + @ElementCollection() + @CollectionTable(name = "book_bookmarks") + @OrderColumn() + public List<BookMark> getBookMarks() { + return bookMarks; + } + + public void setBookMarks(List<BookMark> bookMarks) { + this.bookMarks = bookMarks; + } + +} \ No newline at end of file diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain4/BookID.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain4/BookID.java new file mode 100644 index 0000000000..2fb13f4dc7 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain4/BookID.java @@ -0,0 +1,39 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.domain4; + +import java.io.Serializable; + +import javax.persistence.*; + +@Entity +@Table(name = "bookid_") +@Access(AccessType.PROPERTY) +public class BookID implements Serializable { + + private static final long serialVersionUID = -3205025118656391776L; + + private Long identity; + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + public Long getIdentity() { + return identity; + } + + public void setIdentity(Long identity) { + this.identity = identity; + } + +} \ No newline at end of file diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain4/BookMark.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain4/BookMark.java new file mode 100644 index 0000000000..3dad83088a --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain4/BookMark.java @@ -0,0 +1,51 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.domain4; + +import java.io.Serializable; + +import javax.persistence.Access; +import javax.persistence.AccessType; +import javax.persistence.Basic; +import javax.persistence.Embeddable; + +@Embeddable +@Access(AccessType.PROPERTY) +public class BookMark implements Serializable { + + private static final long serialVersionUID = 8027009758015834551L; + + private Long page; + + private String comment; + + @Basic + public Long getPage() { + return page; + } + + public void setPage(Long page) { + this.page = page; + } + + @Basic + public String getComment() { + return comment; + } + + public void setComment(String comment) { + this.comment = comment; + } + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain4/BookVersion.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain4/BookVersion.java new file mode 100644 index 0000000000..5b69aa2d1c --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain4/BookVersion.java @@ -0,0 +1,73 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.domain4; + +import java.io.Serializable; + +import javax.persistence.*; + +@Entity +@Table(name = "bookversion_") +@Access(AccessType.PROPERTY) +public class BookVersion implements Serializable { + + private static final long serialVersionUID = -1697470794339057030L; + + private BookID bookID; + + private BookVersionPK pk = new BookVersionPK(); + + private Library library; + + private BookDefinition definition; + + @EmbeddedId + public BookVersionPK getPk() { + return pk; + } + + public void setPk(BookVersionPK pk) { + this.pk = pk; + } + + @MapsId("bookID") + @ManyToOne(cascade = CascadeType.ALL) + public BookID getBookID() { + return bookID; + } + + public void setBookID(BookID bookID) { + this.bookID = bookID; + } + + @MapsId("library") + @ManyToOne(cascade = CascadeType.ALL) + public Library getLibrary() { + return library; + } + + public void setLibrary(Library library) { + this.library = library; + } + + @Embedded + public BookDefinition getDefinition() { + return definition; + } + + public void setDefinition(BookDefinition definition) { + this.definition = definition; + } + +} \ No newline at end of file diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain4/BookVersionPK.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain4/BookVersionPK.java new file mode 100644 index 0000000000..3719a302c1 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain4/BookVersionPK.java @@ -0,0 +1,45 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.domain4; + +import java.io.Serializable; + +import javax.persistence.Embeddable; + +@Embeddable +public class BookVersionPK implements Serializable { + + private static final long serialVersionUID = 8483495681236266676L; + + private Long bookID; + + private Long library; + + public Long getBookID() { + return bookID; + } + + public void setBookID(Long bookID) { + this.bookID = bookID; + } + + public Long getLibrary() { + return library; + } + + public void setLibrary(Long library) { + this.library = library; + } + +} \ No newline at end of file diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain4/Library.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain4/Library.java new file mode 100644 index 0000000000..d583587998 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain4/Library.java @@ -0,0 +1,39 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.jpa.domain4; + +import java.io.Serializable; + +import javax.persistence.*; + +@Entity +@Table(name = "library_") +@Access(AccessType.PROPERTY) +public class Library implements Serializable { + + private static final long serialVersionUID = 6360420736014459567L; + + private Long identity; + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + public Long getIdentity() { + return identity; + } + + public void setIdentity(Long identity) { + this.identity = identity; + } + +} \ No newline at end of file diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain5/MyEmbeddedAttribute.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain5/MyEmbeddedAttribute.java new file mode 100644 index 0000000000..dd0215c46b --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain5/MyEmbeddedAttribute.java @@ -0,0 +1,9 @@ +package com.querydsl.jpa.domain5; + +import javax.persistence.*; + +@Embeddable +public class MyEmbeddedAttribute { + @ManyToOne + private MyOtherEntity attributeWithInitProblem; +} \ No newline at end of file diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain5/MyEntity.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain5/MyEntity.java new file mode 100644 index 0000000000..cb3e786d6d --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain5/MyEntity.java @@ -0,0 +1,18 @@ +package com.querydsl.jpa.domain5; + +import javax.persistence.Embedded; +import javax.persistence.Entity; +import javax.persistence.Id; + +import com.querydsl.core.annotations.QueryInit; + +@Entity +public class MyEntity extends MyMappedSuperclass { + + @Id + private int id; + + @Embedded + @QueryInit("*") + private MyEmbeddedAttribute embeddedAttribute; +} \ No newline at end of file diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain5/MyMappedSuperclass.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain5/MyMappedSuperclass.java new file mode 100644 index 0000000000..d23b284954 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain5/MyMappedSuperclass.java @@ -0,0 +1,8 @@ +package com.querydsl.jpa.domain5; + +import javax.persistence.MappedSuperclass; + +@MappedSuperclass +public class MyMappedSuperclass { + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/domain5/MyOtherEntity.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain5/MyOtherEntity.java new file mode 100644 index 0000000000..3b47b32ff3 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/domain5/MyOtherEntity.java @@ -0,0 +1,11 @@ +package com.querydsl.jpa.domain5; + +import javax.persistence.Entity; +import javax.persistence.Id; + +@Entity +public class MyOtherEntity { + + @Id + private int id; +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/suites/AbstractJPASuite.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/suites/AbstractJPASuite.java new file mode 100644 index 0000000000..efc617ee83 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/suites/AbstractJPASuite.java @@ -0,0 +1,18 @@ +package com.querydsl.jpa.suites; + +import org.junit.AfterClass; +import org.junit.experimental.runners.Enclosed; +import org.junit.runner.RunWith; + +import com.querydsl.jpa.Mode; + +@RunWith(Enclosed.class) +public abstract class AbstractJPASuite { + + @AfterClass + public static void tearDownClass() throws Exception { + Mode.mode.remove(); + Mode.target.remove(); + } + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/suites/AbstractSuite.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/suites/AbstractSuite.java new file mode 100644 index 0000000000..ab5b32e3e7 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/suites/AbstractSuite.java @@ -0,0 +1,18 @@ +package com.querydsl.jpa.suites; + +import org.junit.AfterClass; +import org.junit.experimental.runners.Enclosed; +import org.junit.runner.RunWith; + +import com.querydsl.jpa.Mode; + +@RunWith(Enclosed.class) +public abstract class AbstractSuite { + + @AfterClass + public static void tearDownClass() throws Exception { + Mode.mode.remove(); + Mode.target.remove(); + } + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/suites/DerbyEclipseLinkTest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/suites/DerbyEclipseLinkTest.java new file mode 100644 index 0000000000..be1db4bdc1 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/suites/DerbyEclipseLinkTest.java @@ -0,0 +1,40 @@ +package com.querydsl.jpa.suites; + +import org.junit.BeforeClass; +import org.junit.experimental.categories.Category; + +import com.querydsl.core.Target; +import com.querydsl.core.testutil.Derby; +import com.querydsl.jpa.*; + +@Category(Derby.class) +public class DerbyEclipseLinkTest extends AbstractJPASuite { + + public static class JPA extends JPABase { + @Override + public void order_stringValue() { + // not supported in MySQL/EclipseLink + } + @Override + public void order_stringValue_to_integer() { + // not supported in MySQL/EclipseLink + } + @Override + public void order_stringValue_toLong() { + // not supported in MySQL/EclipseLink + } + @Override + public void order_stringValue_toBigInteger() { + // not supported in MySQL/EclipseLink + } + } + public static class JPASQL extends JPASQLBase { } + public static class JPAIntegration extends JPAIntegrationBase { } + public static class Serialization extends SerializationBase { } + + @BeforeClass + public static void setUp() throws Exception { + Mode.mode.set("derby-eclipselink"); + Mode.target.set(Target.DERBY); + } +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/suites/DerbySuiteTest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/suites/DerbySuiteTest.java new file mode 100644 index 0000000000..17c9ccc244 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/suites/DerbySuiteTest.java @@ -0,0 +1,26 @@ +package com.querydsl.jpa.suites; + +import org.junit.BeforeClass; +import org.junit.experimental.categories.Category; + +import com.querydsl.core.Target; +import com.querydsl.core.testutil.Derby; +import com.querydsl.jpa.*; + +@Category(Derby.class) +public class DerbySuiteTest extends AbstractSuite { + + public static class JPA extends JPABase { } + public static class JPASQL extends JPASQLBase { } + public static class JPAIntegration extends JPAIntegrationBase { } + public static class Serialization extends SerializationBase { } + public static class Hibernate extends HibernateBase { } + public static class HibernateSQL extends HibernateSQLBase { } + + @BeforeClass + public static void setUp() throws Exception { + Mode.mode.set("derby"); + Mode.target.set(Target.DERBY); + } + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/suites/H2BatooTest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/suites/H2BatooTest.java new file mode 100644 index 0000000000..f66a20afab --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/suites/H2BatooTest.java @@ -0,0 +1,26 @@ +package com.querydsl.jpa.suites; + +import org.junit.BeforeClass; +import org.junit.Ignore; +import org.junit.experimental.categories.Category; + +import com.querydsl.core.Target; +import com.querydsl.core.testutil.H2; +import com.querydsl.jpa.*; + +@Ignore +@Category(H2.class) +public class H2BatooTest extends AbstractJPASuite { + + public static class JPA extends JPABase { } + public static class JPASQL extends JPASQLBase { } + public static class JPAIntegration extends JPAIntegrationBase { } + public static class Serialization extends SerializationBase { } + + @BeforeClass + public static void setUp() throws Exception { + Mode.mode.set("h2-batoo"); + Mode.target.set(Target.H2); + } + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/suites/H2EclipseLinkTest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/suites/H2EclipseLinkTest.java new file mode 100644 index 0000000000..d630a36866 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/suites/H2EclipseLinkTest.java @@ -0,0 +1,24 @@ +package com.querydsl.jpa.suites; + +import org.junit.BeforeClass; +import org.junit.experimental.categories.Category; + +import com.querydsl.core.Target; +import com.querydsl.core.testutil.H2; +import com.querydsl.jpa.*; + +@Category(H2.class) +public class H2EclipseLinkTest extends AbstractJPASuite { + + public static class JPA extends JPABase { } + public static class JPASQL extends JPASQLBase { } + public static class JPAIntegration extends JPAIntegrationBase { } + public static class Serialization extends SerializationBase { } + + @BeforeClass + public static void setUp() throws Exception { + Mode.mode.set("h2-eclipselink"); + Mode.target.set(Target.H2); + } + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/suites/H2OpenJPATest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/suites/H2OpenJPATest.java new file mode 100644 index 0000000000..13a7003375 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/suites/H2OpenJPATest.java @@ -0,0 +1,26 @@ +package com.querydsl.jpa.suites; + +import org.junit.BeforeClass; +import org.junit.Ignore; +import org.junit.experimental.categories.Category; + +import com.querydsl.core.Target; +import com.querydsl.core.testutil.H2; +import com.querydsl.jpa.*; + +@Ignore +@Category(H2.class) +public class H2OpenJPATest extends AbstractJPASuite { + + public static class JPA extends JPABase { } + public static class JPASQL extends JPASQLBase { } + public static class JPAIntegration extends JPAIntegrationBase { } + public static class Serialization extends SerializationBase { } + + @BeforeClass + public static void setUp() throws Exception { + Mode.mode.set("h2-openjpa"); + Mode.target.set(Target.H2); + } + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/suites/H2SuiteTest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/suites/H2SuiteTest.java new file mode 100644 index 0000000000..8e47b8951a --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/suites/H2SuiteTest.java @@ -0,0 +1,26 @@ +package com.querydsl.jpa.suites; + +import org.junit.BeforeClass; +import org.junit.experimental.categories.Category; + +import com.querydsl.core.Target; +import com.querydsl.core.testutil.H2; +import com.querydsl.jpa.*; + +@Category(H2.class) +public class H2SuiteTest extends AbstractSuite { + + public static class JPA extends JPABase { } + public static class JPASQL extends JPASQLBase { } + public static class JPAIntegration extends JPAIntegrationBase { } + public static class Serialization extends SerializationBase { } + public static class Hibernate extends HibernateBase { } + public static class HibernateSQL extends HibernateSQLBase { } + + @BeforeClass + public static void setUp() throws Exception { + Mode.mode.set("h2"); + Mode.target.set(Target.H2); + } + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/suites/HSQLDBEclipseLinkTest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/suites/HSQLDBEclipseLinkTest.java new file mode 100644 index 0000000000..3c90589825 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/suites/HSQLDBEclipseLinkTest.java @@ -0,0 +1,24 @@ +package com.querydsl.jpa.suites; + +import org.junit.BeforeClass; +import org.junit.experimental.categories.Category; + +import com.querydsl.core.Target; +import com.querydsl.core.testutil.HSQLDB; +import com.querydsl.jpa.*; + +@Category(HSQLDB.class) +public class HSQLDBEclipseLinkTest extends AbstractJPASuite { + + public static class JPA extends JPABase { } + public static class JPASQL extends JPASQLBase { } + public static class JPAIntegration extends JPAIntegrationBase { } + public static class Serialization extends SerializationBase { } + + @BeforeClass + public static void setUp() throws Exception { + Mode.mode.set("hsqldb-eclipselink"); + Mode.target.set(Target.HSQLDB); + } + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/suites/HSQLDBSuiteTest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/suites/HSQLDBSuiteTest.java new file mode 100644 index 0000000000..4158032174 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/suites/HSQLDBSuiteTest.java @@ -0,0 +1,26 @@ +package com.querydsl.jpa.suites; + +import org.junit.BeforeClass; +import org.junit.experimental.categories.Category; + +import com.querydsl.core.Target; +import com.querydsl.core.testutil.HSQLDB; +import com.querydsl.jpa.*; + +@Category(HSQLDB.class) +public class HSQLDBSuiteTest extends AbstractSuite { + + public static class JPA extends JPABase { } + public static class JPASQL extends JPASQLBase { } + public static class JPAIntegration extends JPAIntegrationBase { } + public static class Serialization extends SerializationBase { } + public static class Hibernate extends HibernateBase { } + public static class HibernateSQL extends HibernateSQLBase { } + + @BeforeClass + public static void setUp() throws Exception { + Mode.mode.set("hsqldb"); + Mode.target.set(Target.HSQLDB); + } + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/suites/MSSQLSuiteTest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/suites/MSSQLSuiteTest.java new file mode 100644 index 0000000000..efe1448c8e --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/suites/MSSQLSuiteTest.java @@ -0,0 +1,26 @@ +package com.querydsl.jpa.suites; + +import org.junit.BeforeClass; +import org.junit.experimental.categories.Category; + +import com.querydsl.core.Target; +import com.querydsl.core.testutil.SQLServer; +import com.querydsl.jpa.*; + +@Category(SQLServer.class) +public class MSSQLSuiteTest extends AbstractSuite { + + public static class JPA extends JPABase { } + public static class JPASQL extends JPASQLBase { } + public static class JPAIntegration extends JPAIntegrationBase { } + public static class Serialization extends SerializationBase { } + public static class Hibernate extends HibernateBase { } + public static class HibernateSQL extends HibernateSQLBase { } + + @BeforeClass + public static void setUp() throws Exception { + Mode.mode.set("mssql"); + Mode.target.set(Target.SQLSERVER); + } + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/suites/MySQLEclipseLinkTest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/suites/MySQLEclipseLinkTest.java new file mode 100644 index 0000000000..022fcfd905 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/suites/MySQLEclipseLinkTest.java @@ -0,0 +1,58 @@ +package com.querydsl.jpa.suites; + +import org.junit.BeforeClass; +import org.junit.experimental.categories.Category; + +import com.querydsl.core.Target; +import com.querydsl.core.testutil.MySQL; +import com.querydsl.jpa.*; + +@Category(MySQL.class) +public class MySQLEclipseLinkTest extends AbstractJPASuite { + + public static class JPA extends JPABase { + @Override + public void cast() { + // not supported in MySQL/EclipseLink + } + @Override + public void enum_startsWith() { + // not supported in MySQL/EclipseLink + } + @Override + public void order_stringValue() { + // not supported in MySQL/EclipseLink + } + @Override + public void order_stringValue_to_integer() { + // not supported in MySQL/EclipseLink + } + @Override + public void order_stringValue_toLong() { + // not supported in MySQL/EclipseLink + } + @Override + public void order_stringValue_toBigInteger() { + // not supported in MySQL/EclipseLink + } + @Override + public void order_nullsFirst() { + // not supported in MySQL/EclipseLink + } + @Override + public void order_nullsLast() { + // not supported in MySQL/EclipseLink + } + } + + public static class JPASQL extends JPASQLBase { } + public static class JPAIntegration extends JPAIntegrationBase { } + public static class Serialization extends SerializationBase { } + + @BeforeClass + public static void setUp() throws Exception { + Mode.mode.set("mysql-eclipselink"); + Mode.target.set(Target.MYSQL); + } + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/suites/MySQLSuiteTest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/suites/MySQLSuiteTest.java new file mode 100644 index 0000000000..ff980b8fa4 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/suites/MySQLSuiteTest.java @@ -0,0 +1,36 @@ +package com.querydsl.jpa.suites; + +import org.junit.BeforeClass; +import org.junit.experimental.categories.Category; + +import com.querydsl.core.Target; +import com.querydsl.core.testutil.MySQL; +import com.querydsl.jpa.*; + +@Category(MySQL.class) +public class MySQLSuiteTest extends AbstractSuite { + + public static class JPA extends JPABase { + @Override + public void order_stringValue_toLong() { + // not supported + } + } + public static class JPASQL extends JPASQLBase { } + public static class JPAIntegration extends JPAIntegrationBase { } + public static class Serialization extends SerializationBase { } + public static class Hibernate extends HibernateBase { + @Override + public void order_stringValue_toLong() { + // not supported + } + } + public static class HibernateSQL extends HibernateSQLBase { } + + @BeforeClass + public static void setUp() throws Exception { + Mode.mode.set("mysql"); + Mode.target.set(Target.MYSQL); + } + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/suites/OracleSuiteTest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/suites/OracleSuiteTest.java new file mode 100644 index 0000000000..1533578bb3 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/suites/OracleSuiteTest.java @@ -0,0 +1,42 @@ +package com.querydsl.jpa.suites; + +import java.util.TimeZone; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.experimental.categories.Category; + +import com.querydsl.core.Target; +import com.querydsl.core.testutil.Oracle; +import com.querydsl.jpa.*; + +@Category(Oracle.class) +public class OracleSuiteTest extends AbstractSuite { + + public static class JPA extends JPABase { } + public static class JPASQL extends JPASQLBase { } + public static class JPAIntegration extends JPAIntegrationBase { } + public static class Serialization extends SerializationBase { } + public static class Hibernate extends HibernateBase { } + public static class HibernateSQL extends HibernateSQLBase { } + + private static TimeZone defaultZone; + + @BeforeClass + public static void setUp() throws Exception { + Mode.mode.set("oracle"); + Mode.target.set(Target.ORACLE); + + // change time zone to work around ORA-01882 + // see https://gist.github.com/jarek-przygodzki/cbea3cedae3aef2bbbe0ff6b057e8321 + // the test may work fine on your machine without this, but it fails when the GitHub runner executes it + defaultZone = TimeZone.getDefault(); + TimeZone.setDefault(TimeZone.getTimeZone("UTC")); + } + + @AfterClass + public static void tearDown() { + TimeZone.setDefault(defaultZone); + } + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/suites/PostgreSQLEclipseLinkSuiteTest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/suites/PostgreSQLEclipseLinkSuiteTest.java new file mode 100644 index 0000000000..464c70d41b --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/suites/PostgreSQLEclipseLinkSuiteTest.java @@ -0,0 +1,24 @@ +package com.querydsl.jpa.suites; + +import org.junit.BeforeClass; +import org.junit.experimental.categories.Category; + +import com.querydsl.core.Target; +import com.querydsl.core.testutil.PostgreSQL; +import com.querydsl.jpa.*; + +@Category(PostgreSQL.class) +public class PostgreSQLEclipseLinkSuiteTest extends AbstractJPASuite { + + public static class JPA extends JPABase { } + public static class JPASQL extends JPASQLBase { } + public static class JPAIntegration extends JPAIntegrationBase { } + public static class Serialization extends SerializationBase { } + + @BeforeClass + public static void setUp() throws Exception { + Mode.mode.set("postgresql-eclipselink"); + Mode.target.set(Target.POSTGRESQL); + } + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/suites/PostgreSQLSuiteTest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/suites/PostgreSQLSuiteTest.java new file mode 100644 index 0000000000..00aea8148e --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/suites/PostgreSQLSuiteTest.java @@ -0,0 +1,26 @@ +package com.querydsl.jpa.suites; + +import org.junit.BeforeClass; +import org.junit.experimental.categories.Category; + +import com.querydsl.core.Target; +import com.querydsl.core.testutil.PostgreSQL; +import com.querydsl.jpa.*; + +@Category(PostgreSQL.class) +public class PostgreSQLSuiteTest extends AbstractSuite { + + public static class JPA extends JPABase { } + public static class JPASQL extends JPASQLBase { } + public static class JPAIntegration extends JPAIntegrationBase { } + public static class Serialization extends SerializationBase { } + public static class Hibernate extends HibernateBase { } + public static class HibernateSQL extends HibernateSQLBase { } + + @BeforeClass + public static void setUp() throws Exception { + Mode.mode.set("postgresql"); + Mode.target.set(Target.POSTGRESQL); + } + +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/support/DialectSupportTest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/support/DialectSupportTest.java new file mode 100644 index 0000000000..5391cbaa9c --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/support/DialectSupportTest.java @@ -0,0 +1,20 @@ +package com.querydsl.jpa.support; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import com.querydsl.core.types.Ops; +import com.querydsl.core.types.Template; +import com.querydsl.sql.HSQLDBTemplates; + +public class DialectSupportTest { + + @Test + public void convert() { + Template trim = HSQLDBTemplates.DEFAULT.getTemplate(Ops.TRIM); + assertEquals("trim(both from ?1)", DialectSupport.convert(trim)); + Template concat = HSQLDBTemplates.DEFAULT.getTemplate(Ops.CONCAT); + assertEquals("?1 || ?2", DialectSupport.convert(concat)); + } +} diff --git a/querydsl-jpa/src/test/java/com/querydsl/jpa/support/JPAPathBuilderValidatorTest.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/support/JPAPathBuilderValidatorTest.java new file mode 100644 index 0000000000..6387607dd3 --- /dev/null +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/support/JPAPathBuilderValidatorTest.java @@ -0,0 +1,40 @@ +package com.querydsl.jpa.support; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import java.util.Collection; + +import javax.persistence.EntityManagerFactory; +import javax.persistence.Persistence; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.querydsl.jpa.domain.Cat; + +public class JPAPathBuilderValidatorTest { + + private EntityManagerFactory entityManagerFactory; + + @Before + public void setUp() { + entityManagerFactory = Persistence.createEntityManagerFactory("h2"); + } + + @After + public void tearDown() { + entityManagerFactory.close(); + } + + @Test + public void validate() { + JPAPathBuilderValidator validator = new JPAPathBuilderValidator(entityManagerFactory.getMetamodel()); + assertEquals(String.class, validator.validate(Cat.class, "name", String.class)); + assertEquals(Cat.class, validator.validate(Cat.class, "kittens", Collection.class)); + assertEquals(Cat.class, validator.validate(Cat.class, "mate", Cat.class)); + assertNull(validator.validate(Cat.class, "xxx", String.class)); + assertNull(validator.validate(Object.class, "name", String.class)); + } +} diff --git a/querydsl-jpa/src/test/java/com/mysema/query/jpa/support/TeradataDialect.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/support/TeradataDialect.java similarity index 81% rename from querydsl-jpa/src/test/java/com/mysema/query/jpa/support/TeradataDialect.java rename to querydsl-jpa/src/test/java/com/querydsl/jpa/support/TeradataDialect.java index 75cac04001..78ad1544da 100644 --- a/querydsl-jpa/src/test/java/com/mysema/query/jpa/support/TeradataDialect.java +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/support/TeradataDialect.java @@ -1,424 +1,376 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as - * indicated by the @author tags or express copyright attribution - * statements applied by the authors. All third-party contributions are - * distributed under license by Red Hat Middleware LLC. - * - * This copyrighted material is made available to anyone wishing to use, modify, - * copy, or redistribute it subject to the terms and conditions of the GNU - * Lesser General Public License, as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this distribution; if not, write to: - * Free Software Foundation, Inc. - * 51 Franklin Street, Fifth Floor - * Boston, MA 02110-1301 USA - * - */ -package com.mysema.query.jpa.support; - -import java.sql.SQLException; -import java.sql.Statement; -import java.sql.Types; - -import org.hibernate.HibernateException; -import org.hibernate.cfg.Environment; -import org.hibernate.dialect.Dialect; -import org.hibernate.dialect.function.SQLFunctionTemplate; -import org.hibernate.dialect.function.VarArgsSQLFunction; -import org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtracter; -import org.hibernate.exception.spi.ViolatedConstraintNameExtracter; -import org.hibernate.type.StandardBasicTypes; - -/** - * A dialect for the Teradata database created by MCR as part of the dialect - * certification process. - * - * @author Jay Nance - */ -public class TeradataDialect extends Dialect { - - /** - * Constructor - */ - public TeradataDialect() { - super(); - // registerColumnType data types - registerColumnType(Types.NUMERIC, "NUMERIC($p,$s)"); - registerColumnType(Types.DOUBLE, "DOUBLE PRECISION"); - registerColumnType(Types.BIGINT, "NUMERIC(18,0)"); - registerColumnType(Types.BIT, "BYTEINT"); - registerColumnType(Types.TINYINT, "BYTEINT"); - registerColumnType(Types.VARBINARY, "VARBYTE($l)"); - registerColumnType(Types.BINARY, "BYTEINT"); - registerColumnType(Types.LONGVARCHAR, "LONG VARCHAR"); - registerColumnType(Types.CHAR, "CHAR(1)"); - registerColumnType(Types.DECIMAL, "DECIMAL"); - registerColumnType(Types.INTEGER, "INTEGER"); - registerColumnType(Types.SMALLINT, "SMALLINT"); - registerColumnType(Types.FLOAT, "FLOAT"); - registerColumnType(Types.VARCHAR, "VARCHAR($l)"); - registerColumnType(Types.DATE, "DATE"); - registerColumnType(Types.TIME, "TIME"); - registerColumnType(Types.TIMESTAMP, "TIMESTAMP"); - registerColumnType(Types.BOOLEAN, "BYTEINT"); // hibernate seems to - // ignore this type... - registerColumnType(Types.BLOB, "BLOB"); - registerColumnType(Types.CLOB, "CLOB"); - - registerFunction("year", new SQLFunctionTemplate(StandardBasicTypes.INTEGER, - "extract(year from ?1)")); - registerFunction("length", new SQLFunctionTemplate(StandardBasicTypes.INTEGER, - "character_length(?1)")); - registerFunction("concat", - new VarArgsSQLFunction(StandardBasicTypes.STRING, "(", "||", ")")); - registerFunction("substring", new SQLFunctionTemplate(StandardBasicTypes.STRING, - "substring(?1 from ?2 for ?3)")); - registerFunction("locate", new SQLFunctionTemplate(StandardBasicTypes.STRING, - "position(?1 in ?2)")); - registerFunction("mod", new SQLFunctionTemplate(StandardBasicTypes.STRING, "?1 mod ?2")); - registerFunction("str", new SQLFunctionTemplate(StandardBasicTypes.STRING, - "cast(?1 as varchar(255))")); - - // bit_length feels a bit broken to me. We have to cast to char in order - // to - // pass when a numeric value is supplied. But of course the answers - // given will - // be wildly different for these two datatypes. 1234.5678 will be 9 - // bytes as - // a char string but will be 8 or 16 bytes as a true numeric. - // Jay Nance 2006-09-22 - registerFunction("bit_length", new SQLFunctionTemplate(StandardBasicTypes.INTEGER, - "octet_length(cast(?1 as char))*4")); - - // The preference here would be - // SQLFunctionTemplate( Hibernate.TIMESTAMP, "current_timestamp(?1)", - // false) - // but this appears not to work. - // Jay Nance 2006-09-22 - registerFunction("current_timestamp", new SQLFunctionTemplate(StandardBasicTypes.TIMESTAMP, - "current_timestamp")); - registerFunction("current_time", new SQLFunctionTemplate(StandardBasicTypes.TIME, - "current_time")); - registerFunction("current_date", new SQLFunctionTemplate(StandardBasicTypes.DATE, - "current_date")); - // IBID for current_time and current_date - - registerKeyword("account"); - registerKeyword("alias"); - registerKeyword("class"); - registerKeyword("column"); - registerKeyword("first"); - registerKeyword("map"); - registerKeyword("month"); - registerKeyword("password"); - registerKeyword("role"); - registerKeyword("summary"); - registerKeyword("title"); - registerKeyword("type"); - registerKeyword("value"); - registerKeyword("year"); - - // Tell hibernate to use getBytes instead of getBinaryStream - getDefaultProperties().setProperty(Environment.USE_STREAMS_FOR_BINARY, "false"); - // No batch statements - getDefaultProperties().setProperty(Environment.STATEMENT_BATCH_SIZE, NO_BATCH); - } - - /** - * Does this dialect support the <tt>FOR UPDATE</tt> syntax? - * - * @return empty string ... Teradata does not support - * <tt>FOR UPDATE<tt> syntax - */ - @Override - public String getForUpdateString() { - return ""; - } - - @Override - public boolean supportsIdentityColumns() { - return false; - } - - @Override - public boolean supportsSequences() { - return false; - } - - @Override - public String getAddColumnString() { - return "Add"; - } - - @Override - public boolean supportsTemporaryTables() { - return true; - } - - @Override - public String getCreateTemporaryTableString() { - return "create global temporary table"; - } - - @Override - public String getCreateTemporaryTablePostfix() { - return " on commit preserve rows"; - } - - @Override - public Boolean performTemporaryTableDDLInIsolation() { - return Boolean.TRUE; - } - - @Override - public boolean dropTemporaryTableAfterUse() { - return false; - } - - /** - * Get the name of the database type associated with the given - * <tt>java.sql.Types</tt> typecode. - * - * @param code - * <tt>java.sql.Types</tt> typecode - * @param length - * the length or precision of the column - * @param precision - * the precision of the column - * @param scale - * the scale of the column - * - * @return the database type name - * - * @throws HibernateException - */ - public String getTypeName(int code, int length, int precision, int scale) - throws HibernateException { - /* - * We might want a special case for 19,2. This is very common for money - * types and here it is converted to 18,1 - */ - float f = precision > 0 ? (float) scale / (float) precision : 0; - int p = (precision > 18 ? 18 : precision); - int s = (precision > 18 ? (int) (18.0 * f) : (scale > 18 ? 18 : scale)); - - return super.getTypeName(code, length, p, s); - } - - @Override - public boolean supportsCascadeDelete() { - return false; - } - - @Override - public boolean supportsCircularCascadeDeleteConstraints() { - return false; - } - - @Override - public boolean areStringComparisonsCaseInsensitive() { - return true; - } - - @Override - public boolean supportsEmptyInList() { - return false; - } - - @Override - public String getSelectClauseNullString(int sqlType) { - String v = "null"; - - switch (sqlType) { - case Types.BIT: - case Types.TINYINT: - case Types.SMALLINT: - case Types.INTEGER: - case Types.BIGINT: - case Types.FLOAT: - case Types.REAL: - case Types.DOUBLE: - case Types.NUMERIC: - case Types.DECIMAL: - v = "cast(null as decimal)"; - break; - case Types.CHAR: - case Types.VARCHAR: - case Types.LONGVARCHAR: - v = "cast(null as varchar(255))"; - break; - case Types.DATE: - case Types.TIME: - case Types.TIMESTAMP: - v = "cast(null as timestamp)"; - break; - case Types.BINARY: - case Types.VARBINARY: - case Types.LONGVARBINARY: - case Types.NULL: - case Types.OTHER: - case Types.JAVA_OBJECT: - case Types.DISTINCT: - case Types.STRUCT: - case Types.ARRAY: - case Types.BLOB: - case Types.CLOB: - case Types.REF: - case Types.DATALINK: - case Types.BOOLEAN: - break; - } - return v; - } - - @Override - public String getCreateMultisetTableString() { - return "create multiset table "; - } - - @Override - public boolean supportsLobValueChangePropogation() { - return false; - } - - @Override - public boolean doesReadCommittedCauseWritersToBlockReaders() { - return true; - } - - @Override - public boolean doesRepeatableReadCauseReadersToBlockWriters() { - return true; - } - - @Override - public boolean supportsBindAsCallableArgument() { - return false; - } - - @Override - public ViolatedConstraintNameExtracter getViolatedConstraintNameExtracter() { - return EXTRACTER; - } - - private static ViolatedConstraintNameExtracter EXTRACTER = new TemplatedViolatedConstraintNameExtracter() { - - /** - * Extract the name of the violated constraint from the given - * SQLException. - * - * @param sqle - * The exception that was the result of the constraint - * violation. - * @return The extracted constraint name. - */ - @Override - public String extractConstraintName(SQLException sqle) { - String constraintName = null; - - int errorCode = sqle.getErrorCode(); - if (errorCode == 27003) { - constraintName = extractUsingTemplate("Unique constraint (", ") violated.", - sqle.getMessage()); - } - - if (constraintName != null) { - int i = constraintName.indexOf('.'); - if (i != -1) { - constraintName = constraintName.substring(i + 1); - } - } - return constraintName; - } - }; - - @Override - public boolean supportsNotNullUnique() { - return false; - } - - @Override - public boolean supportsExpectedLobUsagePattern() { - return true; - } - - @Override - public boolean supportsUnboundedLobLocatorMaterialization() { - return false; - } - - public boolean supportsDropPreProcess() { - return true; - } - - public String performDropPreProcess(Statement stmt, String dropSql) throws SQLException { - - String alterStr = "alter"; - String tableStr = "table"; - String dropStr = "drop"; - String constraintStr = "constraint"; - - java.util.StringTokenizer st = new java.util.StringTokenizer(dropSql); - if (alterStr.equalsIgnoreCase(st.nextToken()) && tableStr.equalsIgnoreCase(st.nextToken())) { - String tableName = st.nextToken(); - - if ((tableName.startsWith("\"")) && (!tableName.endsWith("\""))) { - String next = null; - while (true) { - next = st.nextToken(); - tableName += " " + next; - if (next.endsWith("\\\"")) { - continue; - } - if (next.endsWith("\"")) { - break; - } - } - - } - if (dropStr.equalsIgnoreCase(st.nextToken()) - && constraintStr.equalsIgnoreCase(st.nextToken())) { - String constraintName = st.nextToken(); - - // Table name might have whitespace characters within name so - // just take whatever lies between - // "alter table " and "drop constraint" - - int idx_start = dropSql.indexOf(tableStr, 0) + 5; - int idx_end = dropSql.lastIndexOf(dropStr); - tableName = dropSql.substring(idx_start, idx_end).trim(); - - if (tableName.startsWith("\"") && tableName.endsWith("\"")) { - tableName = tableName.substring(1, tableName.length() - 1); - } - - String arrStr = null; - String queryStr = "sel IndexId, ChildTable, IndexName from dbc.RI_Distinct_ChildrenV where IndexName = '" - + constraintName + "'"; - java.sql.ResultSet rs = stmt.executeQuery(queryStr); - - if (rs.next()) { - arrStr = "drop table \"" + tableName + "_" + rs.getString(1) + "\""; - rs.close(); - return arrStr; - } - } - } - return null; - } - - public void performDropPostProcess(Statement stmt, String dropSql) throws SQLException { - if (dropSql == null) { - return; - } - stmt.executeUpdate(dropSql); - } +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Middleware LLC. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + * + */ +package com.querydsl.jpa.support; + +import java.sql.SQLException; +import java.sql.Statement; +import java.sql.Types; + +import org.hibernate.HibernateException; +import org.hibernate.cfg.Environment; +import org.hibernate.dialect.Dialect; +import org.hibernate.dialect.function.SQLFunctionTemplate; +import org.hibernate.dialect.function.VarArgsSQLFunction; +import org.hibernate.type.StandardBasicTypes; + +/** + * A dialect for the Teradata database created by MCR as part of the dialect + * certification process. + * + * @author Jay Nance + */ +public class TeradataDialect extends Dialect { + + /** + * Constructor + */ + public TeradataDialect() { + super(); + // registerColumnType data types + registerColumnType(Types.NUMERIC, "NUMERIC($p,$s)"); + registerColumnType(Types.DOUBLE, "DOUBLE PRECISION"); + registerColumnType(Types.BIGINT, "NUMERIC(18,0)"); + registerColumnType(Types.BIT, "BYTEINT"); + registerColumnType(Types.TINYINT, "BYTEINT"); + registerColumnType(Types.VARBINARY, "VARBYTE($l)"); + registerColumnType(Types.BINARY, "BYTEINT"); + registerColumnType(Types.LONGVARCHAR, "LONG VARCHAR"); + registerColumnType(Types.CHAR, "CHAR(1)"); + registerColumnType(Types.DECIMAL, "DECIMAL"); + registerColumnType(Types.INTEGER, "INTEGER"); + registerColumnType(Types.SMALLINT, "SMALLINT"); + registerColumnType(Types.FLOAT, "FLOAT"); + registerColumnType(Types.VARCHAR, "VARCHAR($l)"); + registerColumnType(Types.DATE, "DATE"); + registerColumnType(Types.TIME, "TIME"); + registerColumnType(Types.TIMESTAMP, "TIMESTAMP"); + registerColumnType(Types.BOOLEAN, "BYTEINT"); // hibernate seems to + // ignore this type... + registerColumnType(Types.BLOB, "BLOB"); + registerColumnType(Types.CLOB, "CLOB"); + + registerFunction("year", new SQLFunctionTemplate(StandardBasicTypes.INTEGER, + "extract(year from ?1)")); + registerFunction("length", new SQLFunctionTemplate(StandardBasicTypes.INTEGER, + "character_length(?1)")); + registerFunction("concat", + new VarArgsSQLFunction(StandardBasicTypes.STRING, "(", "||", ")")); + registerFunction("substring", new SQLFunctionTemplate(StandardBasicTypes.STRING, + "substring(?1 from ?2 for ?3)")); + registerFunction("locate", new SQLFunctionTemplate(StandardBasicTypes.STRING, + "position(?1 in ?2)")); + registerFunction("mod", new SQLFunctionTemplate(StandardBasicTypes.STRING, "?1 mod ?2")); + registerFunction("str", new SQLFunctionTemplate(StandardBasicTypes.STRING, + "cast(?1 as varchar(255))")); + + // bit_length feels a bit broken to me. We have to cast to char in order + // to + // pass when a numeric value is supplied. But of course the answers + // given will + // be wildly different for these two datatypes. 1234.5678 will be 9 + // bytes as + // a char string but will be 8 or 16 bytes as a true numeric. + // Jay Nance 2006-09-22 + registerFunction("bit_length", new SQLFunctionTemplate(StandardBasicTypes.INTEGER, + "octet_length(cast(?1 as char))*4")); + + // The preference here would be + // SQLFunctionTemplate( Hibernate.TIMESTAMP, "current_timestamp(?1)", + // false) + // but this appears not to work. + // Jay Nance 2006-09-22 + registerFunction("current_timestamp", new SQLFunctionTemplate(StandardBasicTypes.TIMESTAMP, + "current_timestamp")); + registerFunction("current_time", new SQLFunctionTemplate(StandardBasicTypes.TIME, + "current_time")); + registerFunction("current_date", new SQLFunctionTemplate(StandardBasicTypes.DATE, + "current_date")); + // IBID for current_time and current_date + + registerKeyword("account"); + registerKeyword("alias"); + registerKeyword("class"); + registerKeyword("column"); + registerKeyword("first"); + registerKeyword("map"); + registerKeyword("month"); + registerKeyword("password"); + registerKeyword("role"); + registerKeyword("summary"); + registerKeyword("title"); + registerKeyword("type"); + registerKeyword("value"); + registerKeyword("year"); + + // Tell hibernate to use getBytes instead of getBinaryStream + getDefaultProperties().setProperty(Environment.USE_STREAMS_FOR_BINARY, "false"); + // No batch statements + getDefaultProperties().setProperty(Environment.STATEMENT_BATCH_SIZE, NO_BATCH); + } + + /** + * Does this dialect support the {@code FOR UPDATE} syntax? + * + * @return empty string ... Teradata does not support + * {@code FOR UPDATE} syntax + */ + @Override + public String getForUpdateString() { + return ""; + } + + @Override + public boolean supportsSequences() { + return false; + } + + @Override + public String getAddColumnString() { + return "Add"; + } + + public boolean supportsTemporaryTables() { + return true; + } + + public String getCreateTemporaryTableString() { + return "create global temporary table"; + } + + public String getCreateTemporaryTablePostfix() { + return " on commit preserve rows"; + } + + public Boolean performTemporaryTableDDLInIsolation() { + return Boolean.TRUE; + } + + public boolean dropTemporaryTableAfterUse() { + return false; + } + + /** + * Get the name of the database type associated with the given + * {@code java.sql.Types} typecode. + * + * @param code + * {@link java.sql.Types} typecode + * @param length + * the length or precision of the column + * @param precision + * the precision of the column + * @param scale + * the scale of the column + * + * @return the database type name + * + * @throws HibernateException + */ + public String getTypeName(int code, int length, int precision, int scale) + throws HibernateException { + /* + * We might want a special case for 19,2. This is very common for money + * types and here it is converted to 18,1 + */ + float f = precision > 0 ? (float) scale / (float) precision : 0; + int p = (precision > 18 ? 18 : precision); + int s = (precision > 18 ? (int) (18.0 * f) : (scale > 18 ? 18 : scale)); + + return super.getTypeName(code, length, p, s); + } + + @Override + public boolean supportsCascadeDelete() { + return false; + } + + @Override + public boolean supportsCircularCascadeDeleteConstraints() { + return false; + } + + @Override + public boolean areStringComparisonsCaseInsensitive() { + return true; + } + + @Override + public boolean supportsEmptyInList() { + return false; + } + + @Override + public String getSelectClauseNullString(int sqlType) { + String v = "null"; + + switch (sqlType) { + case Types.BIT: + case Types.TINYINT: + case Types.SMALLINT: + case Types.INTEGER: + case Types.BIGINT: + case Types.FLOAT: + case Types.REAL: + case Types.DOUBLE: + case Types.NUMERIC: + case Types.DECIMAL: + v = "cast(null as decimal)"; + break; + case Types.CHAR: + case Types.VARCHAR: + case Types.LONGVARCHAR: + v = "cast(null as varchar(255))"; + break; + case Types.DATE: + case Types.TIME: + case Types.TIMESTAMP: + v = "cast(null as timestamp)"; + break; + case Types.BINARY: + case Types.VARBINARY: + case Types.LONGVARBINARY: + case Types.NULL: + case Types.OTHER: + case Types.JAVA_OBJECT: + case Types.DISTINCT: + case Types.STRUCT: + case Types.ARRAY: + case Types.BLOB: + case Types.CLOB: + case Types.REF: + case Types.DATALINK: + case Types.BOOLEAN: + break; + } + return v; + } + + @Override + public String getCreateMultisetTableString() { + return "create multiset table "; + } + + @Override + public boolean supportsLobValueChangePropogation() { + return false; + } + + @Override + public boolean doesReadCommittedCauseWritersToBlockReaders() { + return true; + } + + @Override + public boolean doesRepeatableReadCauseReadersToBlockWriters() { + return true; + } + + @Override + public boolean supportsBindAsCallableArgument() { + return false; + } + + @Override + public boolean supportsNotNullUnique() { + return false; + } + + @Override + public boolean supportsExpectedLobUsagePattern() { + return true; + } + + @Override + public boolean supportsUnboundedLobLocatorMaterialization() { + return false; + } + + public boolean supportsDropPreProcess() { + return true; + } + + public String performDropPreProcess(Statement stmt, String dropSql) throws SQLException { + + String alterStr = "alter"; + String tableStr = "table"; + String dropStr = "drop"; + String constraintStr = "constraint"; + + java.util.StringTokenizer st = new java.util.StringTokenizer(dropSql); + if (alterStr.equalsIgnoreCase(st.nextToken()) && tableStr.equalsIgnoreCase(st.nextToken())) { + StringBuilder tableName = new StringBuilder(st.nextToken()); + + if ((tableName.toString().startsWith("\"")) && (!tableName.toString().endsWith("\""))) { + String next = null; + while (true) { + next = st.nextToken(); + tableName.append(" ").append(next); + if (next.endsWith("\\\"")) { + continue; + } + if (next.endsWith("\"")) { + break; + } + } + + } + if (dropStr.equalsIgnoreCase(st.nextToken()) + && constraintStr.equalsIgnoreCase(st.nextToken())) { + String constraintName = st.nextToken(); + + // Table name might have whitespace characters within name so + // just take whatever lies between + // "alter table " and "drop constraint" + + int idxStart = dropSql.indexOf(tableStr, 0) + 5; + int idxEnd = dropSql.lastIndexOf(dropStr); + tableName = new StringBuilder(dropSql.substring(idxStart, idxEnd).trim()); + + if (tableName.toString().startsWith("\"") && tableName.toString().endsWith("\"")) { + tableName = new StringBuilder(tableName.substring(1, tableName.length() - 1)); + } + + String arrStr = null; + String queryStr = "sel IndexId, ChildTable, IndexName from dbc.RI_Distinct_ChildrenV where IndexName = '" + + constraintName + "'"; + java.sql.ResultSet rs = stmt.executeQuery(queryStr); + + if (rs.next()) { + arrStr = "drop table \"" + tableName + "_" + rs.getString(1) + "\""; + rs.close(); + return arrStr; + } + } + } + return null; + } + + public void performDropPostProcess(Statement stmt, String dropSql) throws SQLException { + if (dropSql == null) { + return; + } + stmt.executeUpdate(dropSql); + } } \ No newline at end of file diff --git a/querydsl-jpa/src/test/java/com/mysema/testutil/HibernateTestRunner.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/testutil/HibernateTestRunner.java similarity index 84% rename from querydsl-jpa/src/test/java/com/mysema/testutil/HibernateTestRunner.java rename to querydsl-jpa/src/test/java/com/querydsl/jpa/testutil/HibernateTestRunner.java index 699941473e..6e541754fd 100644 --- a/querydsl-jpa/src/test/java/com/mysema/testutil/HibernateTestRunner.java +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/testutil/HibernateTestRunner.java @@ -1,5 +1,5 @@ /* - * Copyright 2011, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,15 +11,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.testutil; +package com.querydsl.jpa.testutil; + +import java.io.InputStream; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.util.List; +import java.util.Properties; -import com.mysema.query.Mode; -import com.mysema.query.jpa.domain.Domain; import org.hibernate.Session; import org.hibernate.SessionFactory; +import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.hibernate.cfg.Configuration; import org.hibernate.service.ServiceRegistry; -import org.hibernate.service.ServiceRegistryBuilder; import org.junit.rules.MethodRule; import org.junit.runner.Description; import org.junit.runner.notification.Failure; @@ -29,12 +33,11 @@ import org.junit.runners.model.InitializationError; import org.junit.runners.model.Statement; -import java.io.InputStream; -import java.lang.reflect.Method; -import java.sql.DriverManager; -import java.sql.SQLException; -import java.util.List; -import java.util.Properties; +import com.querydsl.jpa.HibernateTest; +import com.querydsl.jpa.Mode; +import com.querydsl.jpa.domain.Domain; + +import static org.junit.Assert.assertTrue; /** * @author tiwe @@ -46,8 +49,6 @@ public class HibernateTestRunner extends BlockJUnit4ClassRunner { private Session session; - private Method setter; - private boolean isDerby = false; public HibernateTestRunner(Class<?> klass) throws InitializationError { @@ -56,6 +57,9 @@ public HibernateTestRunner(Class<?> klass) throws InitializationError { @Override protected List<MethodRule> rules(Object test) { + assertTrue(String.format("In order to use the %s for %s, it should (directly or indirectly) implement %s", + HibernateTestRunner.class.getSimpleName(), test.getClass(), HibernateTest.class), test instanceof HibernateTest); + List<MethodRule> rules = super.rules(test); rules.add(new MethodRule() { @Override @@ -63,10 +67,7 @@ public Statement apply(final Statement base, FrameworkMethod method, final Objec return new Statement() { @Override public void evaluate() throws Throwable { - if (setter == null) { - setter = target.getClass().getMethod("setSession", Session.class); - } - setter.invoke(target, session); + ((HibernateTest) target).setSession(session); base.evaluate(); } }; @@ -106,7 +107,7 @@ private void start() throws Exception { throw new IllegalArgumentException("No configuration available at classpath:" + mode); } props.load(is); - ServiceRegistry serviceRegistry = new ServiceRegistryBuilder() + ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder() .applySettings(props) .build(); cfg.setProperties(props); @@ -118,9 +119,7 @@ private void start() throws Exception { private void shutdown() { if (session != null) { try { - if (session.getTransaction().isActive()) { - session.getTransaction().rollback(); - } + session.getTransaction().rollback(); } finally { session.close(); session = null; diff --git a/querydsl-jpa/src/test/java/com/mysema/testutil/JPATestRunner.java b/querydsl-jpa/src/test/java/com/querydsl/jpa/testutil/JPATestRunner.java similarity index 88% rename from querydsl-jpa/src/test/java/com/mysema/testutil/JPATestRunner.java rename to querydsl-jpa/src/test/java/com/querydsl/jpa/testutil/JPATestRunner.java index 18abb629a7..3b1a048f70 100644 --- a/querydsl-jpa/src/test/java/com/mysema/testutil/JPATestRunner.java +++ b/querydsl-jpa/src/test/java/com/querydsl/jpa/testutil/JPATestRunner.java @@ -1,5 +1,5 @@ /* - * Copyright 2011, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,9 +11,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.testutil; +package com.querydsl.jpa.testutil; -import java.lang.reflect.Method; import java.sql.DriverManager; import java.sql.SQLException; import java.util.List; @@ -22,6 +21,7 @@ import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence; +import org.junit.Assert; import org.junit.rules.MethodRule; import org.junit.runner.Description; import org.junit.runner.notification.Failure; @@ -31,7 +31,8 @@ import org.junit.runners.model.InitializationError; import org.junit.runners.model.Statement; -import com.mysema.query.Mode; +import com.querydsl.jpa.JPATest; +import com.querydsl.jpa.Mode; /** * @author tiwe @@ -43,16 +44,17 @@ public class JPATestRunner extends BlockJUnit4ClassRunner { private EntityManager entityManager; - private Method setter; - private boolean isDerby; - public JPATestRunner(Class<?> klass) throws InitializationError{ + public JPATestRunner(Class<?> klass) throws InitializationError { super(klass); } @Override protected List<MethodRule> rules(Object test) { + Assert.assertTrue(String.format("In order to use the %s for %s, it should (directly or indirectly) implement %s", + JPATestRunner.class.getSimpleName(), test.getClass(), JPATest.class), test instanceof JPATest); + List<MethodRule> rules = super.rules(test); rules.add(new MethodRule() { @Override @@ -60,10 +62,7 @@ public Statement apply(final Statement base, FrameworkMethod method, final Objec return new Statement() { @Override public void evaluate() throws Throwable { - if (setter == null) { - setter = target.getClass().getMethod("setEntityManager", EntityManager.class); - } - setter.invoke(target, entityManager); + ((JPATest) target).setEntityManager(entityManager); base.evaluate(); } }; diff --git a/querydsl-jpa/src/test/resources/META-INF/persistence.xml b/querydsl-jpa/src/test/resources/META-INF/persistence.xml index 522c545cc7..5ad7132c71 100644 --- a/querydsl-jpa/src/test/resources/META-INF/persistence.xml +++ b/querydsl-jpa/src/test/resources/META-INF/persistence.xml @@ -1,292 +1,314 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<persistence xmlns="http://java.sun.com/xml/ns/persistence" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://java.sun.com/xml/ns/persistence - http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" - version="1.0"> - - <!-- derby --> - - <persistence-unit name="derby"> - <provider>org.hibernate.ejb.HibernatePersistence</provider> - <properties> - <property name="hibernate.archive.autodetection" value="class" /> - <property name="hibernate.dialect" value="com.mysema.query.jpa.support.ExtendedDerbyDialect" /> - <property name="hibernate.connection.driver_class" value="org.apache.derby.jdbc.EmbeddedDriver" /> - <property name="hibernate.connection.url" value="jdbc:derby:target/derbydb-hibernate;create=true" /> - <!-- <property name="hibernate.show_sql" value="true"/> --> - <property name="hibernate.flushMode" value="FLUSH_AUTO" /> - <property name="hibernate.hbm2ddl.auto" value="update" /> - </properties> - </persistence-unit> - - <persistence-unit name="derby-eclipselink" transaction-type="RESOURCE_LOCAL"> - <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> - <exclude-unlisted-classes>false</exclude-unlisted-classes> - <properties> - <property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.EmbeddedDriver" /> - <property name="javax.persistence.jdbc.url" value="jdbc:derby:target/derbydb-eclipselink;create=true" /> - <property name="eclipselink.ddl-generation" value="drop-and-create-tables" /> - <property name="eclipselink.ddl-generation.output-mode" value="database" /> - </properties> - </persistence-unit> - - <persistence-unit name="derby-openjpa" transaction-type="RESOURCE_LOCAL"> - <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider> - <exclude-unlisted-classes>false</exclude-unlisted-classes> - <properties> - <property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.EmbeddedDriver" /> - <property name="javax.persistence.jdbc.url" value="jdbc:derby:target/derbydb-openjpa;create=true" /> - <property name="openjpa.RuntimeUnenhancedClasses" value="supported" /> - </properties> - </persistence-unit> - - <!-- hsqldb --> - - <persistence-unit name="hsqldb"> - <provider>org.hibernate.ejb.HibernatePersistence</provider> - <properties> - <property name="hibernate.archive.autodetection" value="class" /> - <property name="hibernate.dialect" value="com.mysema.query.jpa.support.ExtendedHSQLDialect" /> - <property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver" /> - <property name="hibernate.connection.url" value="jdbc:hsqldb:file:target/testdb-hibernate;shutdown=true" /> - <property name="hibernate.connection.user" value="sa" /> - <!-- <property name="hibernate.show_sql" value="true"/> --> - <property name="hibernate.flushMode" value="FLUSH_AUTO" /> - <property name="hibernate.hbm2ddl.auto" value="update" /> - </properties> - </persistence-unit> - - <persistence-unit name="hsqldb-eclipselink" transaction-type="RESOURCE_LOCAL"> - <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> - <exclude-unlisted-classes>false</exclude-unlisted-classes> - <properties> - <property name="javax.persistence.jdbc.driver" value="org.hsqldb.jdbcDriver" /> - <property name="javax.persistence.jdbc.url" value="jdbc:hsqldb:file:target/testdb-eclipselink;shutdown=true" /> - <property name="javax.persistence.jdbc.user" value="sa" /> - <property name="eclipselink.ddl-generation" value="drop-and-create-tables" /> - <property name="eclipselink.ddl-generation.output-mode" value="database" /> - </properties> - </persistence-unit> - - <!-- h2 --> - - <persistence-unit name="h2" transaction-type="RESOURCE_LOCAL"> - <provider>org.hibernate.ejb.HibernatePersistence</provider> - <properties> - <property name="hibernate.archive.autodetection" value="class" /> - <property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect" /> - <property name="hibernate.connection.driver_class" value="org.h2.Driver" /> - <property name="hibernate.connection.url" value="jdbc:h2:~/dbs/h2-hibernate" /> - <property name="hibernate.connection.user" value="sa" /> - <property name="hibernate.show_sql" value="false"/> - <property name="hibernate.flushMode" value="FLUSH_AUTO" /> - <property name="hibernate.hbm2ddl.auto" value="update" /> - </properties> - </persistence-unit> - - <persistence-unit name="h2perf" transaction-type="RESOURCE_LOCAL"> - <provider>org.hibernate.ejb.HibernatePersistence</provider> - <properties> - <property name="hibernate.archive.autodetection" value="class" /> - <property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect" /> - <property name="hibernate.connection.driver_class" value="org.h2.Driver" /> - <property name="hibernate.connection.url" value="jdbc:h2:~/dbs/h2-hibernate-perf" /> - <property name="hibernate.connection.user" value="sa" /> - <property name="hibernate.show_sql" value="false"/> - <property name="hibernate.flushMode" value="FLUSH_AUTO" /> - <property name="hibernate.hbm2ddl.auto" value="update" /> - </properties> - </persistence-unit> - - <persistence-unit name="h2-eclipselink" transaction-type="RESOURCE_LOCAL"> - <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> - <exclude-unlisted-classes>false</exclude-unlisted-classes> - <properties> - <property name="javax.persistence.jdbc.driver" value="org.h2.Driver" /> - <property name="javax.persistence.jdbc.url" value="jdbc:h2:~/dbs/h2-eclipselink" /> - <property name="javax.persistence.jdbc.user" value="sa" /> - <property name="eclipselink.ddl-generation" value="drop-and-create-tables" /> - <property name="eclipselink.ddl-generation.output-mode" value="database" /> - </properties> - </persistence-unit> - - <persistence-unit name="h2-batoo"> - <provider>org.batoo.jpa.core.BatooPersistenceProvider</provider> - <class>com.mysema.query.jpa.domain.Account</class> - <class>com.mysema.query.jpa.domain.Animal</class> - <class>com.mysema.query.jpa.domain.AuditLog</class> - <class>com.mysema.query.jpa.domain.Author</class> - <class>com.mysema.query.jpa.domain.Bar</class> - <class>com.mysema.query.jpa.domain.Book</class> - <class>com.mysema.query.jpa.domain.Calendar</class> - <class>com.mysema.query.jpa.domain.Cat</class> - <class>com.mysema.query.jpa.domain.Catalog</class> - <class>com.mysema.query.jpa.domain.Company</class> - <class>com.mysema.query.jpa.domain.Customer</class> - <class>com.mysema.query.jpa.domain.Department</class> - <class>com.mysema.query.jpa.domain.Document</class> - <class>com.mysema.query.jpa.domain.Dolphin</class> - <class>com.mysema.query.jpa.domain.DomesticCat</class> - <class>com.mysema.query.jpa.domain.EmbeddedType</class> - <class>com.mysema.query.jpa.domain.Employee</class> - <class>com.mysema.query.jpa.domain.Entity1</class> - <class>com.mysema.query.jpa.domain.Entity2</class> - <class>com.mysema.query.jpa.domain.EvilType</class> - <class>com.mysema.query.jpa.domain.Foo</class> - <class>com.mysema.query.jpa.domain.Formula</class> - <class>com.mysema.query.jpa.domain.Human</class> - <class>com.mysema.query.jpa.domain.InheritedProperties</class> - <class>com.mysema.query.jpa.domain.Item</class> - <class>com.mysema.query.jpa.domain.Location</class> - <class>com.mysema.query.jpa.domain.Mammal</class> - <class>com.mysema.query.jpa.domain.Name</class> - <class>com.mysema.query.jpa.domain.NameList</class> - <class>com.mysema.query.jpa.domain.Named</class> - <class>com.mysema.query.jpa.domain.Nationality</class> - <class>com.mysema.query.jpa.domain.Novel</class> - <class>com.mysema.query.jpa.domain.Numeric</class> - <class>com.mysema.query.jpa.domain.Order</class> - <class>com.mysema.query.jpa.domain.Parameter</class> - <class>com.mysema.query.jpa.domain.Payment</class> - <class>com.mysema.query.jpa.domain.Person</class> - <class>com.mysema.query.jpa.domain.PersonId</class> - <class>com.mysema.query.jpa.domain.Player</class> - <class>com.mysema.query.jpa.domain.Price</class> - <class>com.mysema.query.jpa.domain.Product</class> - <class>com.mysema.query.jpa.domain.Show</class> - <class>com.mysema.query.jpa.domain.SimpleTypes</class> - <class>com.mysema.query.jpa.domain.Status</class> - <class>com.mysema.query.jpa.domain.StatusChange</class> - <class>com.mysema.query.jpa.domain.Store</class> - <class>com.mysema.query.jpa.domain.Superclass</class> - <class>com.mysema.query.jpa.domain.User</class> - <class>com.mysema.query.jpa.domain.World</class> - <class>com.mysema.query.jpa.domain4.BookDefinition</class> - <class>com.mysema.query.jpa.domain4.BookID</class> - <class>com.mysema.query.jpa.domain4.BookMark</class> - <class>com.mysema.query.jpa.domain4.BookVersion</class> - <class>com.mysema.query.jpa.domain4.BookVersionPK</class> - <class>com.mysema.query.jpa.domain4.Library</class> - <properties> - <property name="javax.persistence.jdbc.driver" value="org.h2.Driver" /> - <property name="javax.persistence.jdbc.url" value="jdbc:h2:~/dbs/h2-batoo" /> - <property name="javax.persistence.jdbc.user" value="sa" /> - <property name="org.batoo.jpa.sql_logging" value="NONE"/> - <property name="org.batoo.jpa.ddl" value="DROP" /> - </properties> - </persistence-unit> - - <persistence-unit name="h2-openjpa" transaction-type="RESOURCE_LOCAL"> - <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider> - <properties> - <property name="javax.persistence.jdbc.driver" value="org.h2.Driver" /> - <property name="javax.persistence.jdbc.url" value="jdbc:h2:~/dbs/h2-openjpa" /> - <property name="javax.persistence.jdbc.user" value="sa" /> - <property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)"/> - <property name="openjpa.RuntimeUnenhancedClasses" value="supported" /> - <property name="openjpa.jdbc.Schemas" value="PUBLIC"/> - <property name="openjpa.jdbc.DBDictionary" value="h2(useSchemaName=true)"/> - <!-- - <property name="openjpa.Log" value="DefaultLevel=TRACE,Tool=TRACE"/> - --> - </properties> - </persistence-unit> - - <!-- mysql --> - - <persistence-unit name="mysql"> - <provider>org.hibernate.ejb.HibernatePersistence</provider> - <properties> - <property name="hibernate.archive.autodetection" value="class" /> - <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect" /> - <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" /> - <property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/querydsl" /> - <property name="hibernate.connection.username" value="querydsl" /> - <property name="hibernate.connection.password" value="querydsl" /> - <!-- <property name="hibernate.show_sql" value="true"/> --> - <property name="hibernate.flushMode" value="FLUSH_AUTO" /> - <property name="hibernate.hbm2ddl.auto" value="update" /> - </properties> - </persistence-unit> - - <persistence-unit name="mysql-eclipselink" transaction-type="RESOURCE_LOCAL"> - <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> - <exclude-unlisted-classes>false</exclude-unlisted-classes> - <properties> - <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" /> - <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/querydsl2" /> - <property name="javax.persistence.jdbc.user" value="querydsl" /> - <property name="javax.persistence.jdbc.password" value="querydsl" /> - <property name="eclipselink.ddl-generation" value="drop-and-create-tables" /> - <property name="eclipselink.ddl-generation.output-mode" value="database" /> - </properties> - </persistence-unit> - - <!-- postgres --> - - <persistence-unit name="postgres"> - <provider>org.hibernate.ejb.HibernatePersistence</provider> - <properties> - <property name="hibernate.archive.autodetection" value="class" /> - <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect" /> - <property name="hibernate.connection.driver_class" value="org.postgresql.Driver" /> - <property name="hibernate.connection.url" value="jdbc:postgresql://localhost:5432/querydsl" /> - <property name="hibernate.connection.username" value="querydsl" /> - <property name="hibernate.connection.password" value="querydsl" /> - <!-- <property name="hibernate.show_sql" value="true"/> --> - <property name="hibernate.flushMode" value="FLUSH_AUTO" /> - <property name="hibernate.hbm2ddl.auto" value="update" /> - </properties> - </persistence-unit> - - <persistence-unit name="postgres-eclipselink" transaction-type="RESOURCE_LOCAL"> - <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> - <exclude-unlisted-classes>false</exclude-unlisted-classes> - <properties> - <property name="javax.persistence.jdbc.driver" value="org.postgresql.Driver" /> - <property name="javax.persistence.jdbc.url" value="jdbc:postgresql://localhost:5432/querydsl2" /> - <property name="javax.persistence.jdbc.user" value="querydsl" /> - <property name="javax.persistence.jdbc.password" value="querydsl" /> - <property name="eclipselink.ddl-generation" value="drop-and-create-tables" /> - <property name="eclipselink.ddl-generation.output-mode" value="database" /> - </properties> - </persistence-unit> - - <!-- oracle --> - - <persistence-unit name="oracle"> - <provider>org.hibernate.ejb.HibernatePersistence</provider> - <properties> - <property name="hibernate.archive.autodetection" value="class" /> - <property name="hibernate.dialect" value="com.mysema.query.jpa.support.ExtendedOracleDialect" /> - <property name="hibernate.connection.driver_class" value="oracle.jdbc.driver.OracleDriver" /> - <property name="hibernate.connection.url" value="jdbc:oracle:thin:@localhost:1521:xe" /> - <property name="hibernate.connection.username" value="querydsl" /> - <property name="hibernate.connection.password" value="querydsl" /> - <property name="hibernate.show_sql" value="true"/> - <property name="hibernate.flushMode" value="FLUSH_AUTO" /> - <property name="hibernate.hbm2ddl.auto" value="update" /> - </properties> - </persistence-unit> - - <!-- teradata --> - - <persistence-unit name="teradata"> - <provider>org.hibernate.ejb.HibernatePersistence</provider> - <properties> - <property name="hibernate.archive.autodetection" value="class" /> - <property name="hibernate.dialect" value="com.mysema.query.jpa.support.TeradataDialect" /> - <property name="hibernate.connection.driver_class" value="com.teradata.jdbc.TeraDriver" /> - <property name="hibernate.connection.url" value="jdbc:teradata://teradata/dbc" /> - <property name="hibernate.connection.username" value="querydsl" /> - <property name="hibernate.connection.password" value="querydsl" /> - <!-- <property name="hibernate.show_sql" value="true"/> --> - <property name="hibernate.flushMode" value="FLUSH_AUTO" /> - <property name="hibernate.hbm2ddl.auto" value="update" /> - <property name="hibernate.globally_quoted_identifiers" value="true" /> - </properties> - </persistence-unit> - -</persistence> +<?xml version="1.0" encoding="UTF-8"?> + +<persistence xmlns="http://java.sun.com/xml/ns/persistence" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://java.sun.com/xml/ns/persistence + http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" + version="1.0"> + + <!-- derby --> + + <persistence-unit name="derby"> + <provider>org.hibernate.ejb.HibernatePersistence</provider> + <properties> + <property name="hibernate.archive.autodetection" value="class" /> + <property name="hibernate.dialect" value="com.querydsl.jpa.support.QDerbyDialect" /> + <property name="hibernate.connection.driver_class" value="org.apache.derby.jdbc.EmbeddedDriver" /> + <property name="hibernate.connection.url" value="jdbc:derby:target/derbydb-hibernate;create=true" /> + <!-- <property name="hibernate.show_sql" value="true"/> --> + <property name="hibernate.flushMode" value="FLUSH_AUTO" /> + <property name="hibernate.hbm2ddl.auto" value="create-drop" /> + </properties> + </persistence-unit> + + <persistence-unit name="derby-eclipselink" transaction-type="RESOURCE_LOCAL"> + <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> + <exclude-unlisted-classes>false</exclude-unlisted-classes> + <properties> + <property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.EmbeddedDriver" /> + <property name="javax.persistence.jdbc.url" value="jdbc:derby:target/derbydb-eclipselink;create=true" /> + <property name="eclipselink.ddl-generation" value="drop-and-create-tables" /> + <property name="eclipselink.ddl-generation.output-mode" value="database" /> + <property name="eclipselink.logging.level" value="SEVERE"/> + </properties> + </persistence-unit> + + <persistence-unit name="derby-openjpa" transaction-type="RESOURCE_LOCAL"> + <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider> + <exclude-unlisted-classes>false</exclude-unlisted-classes> + <properties> + <property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.EmbeddedDriver" /> + <property name="javax.persistence.jdbc.url" value="jdbc:derby:target/derbydb-openjpa;create=true" /> + <property name="openjpa.RuntimeUnenhancedClasses" value="supported" /> + </properties> + </persistence-unit> + + <!-- hsqldb --> + + <persistence-unit name="hsqldb"> + <provider>org.hibernate.ejb.HibernatePersistence</provider> + <properties> + <property name="hibernate.archive.autodetection" value="class" /> + <property name="hibernate.dialect" value="com.querydsl.jpa.support.QHSQLDialect" /> + <property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver" /> + <property name="hibernate.connection.url" value="jdbc:hsqldb:file:target/testdb-hibernate;shutdown=true" /> + <property name="hibernate.connection.user" value="sa" /> + <!-- <property name="hibernate.show_sql" value="true"/> --> + <property name="hibernate.flushMode" value="FLUSH_AUTO" /> + <property name="hibernate.hbm2ddl.auto" value="create-drop" /> + </properties> + </persistence-unit> + + <persistence-unit name="hsqldb-eclipselink" transaction-type="RESOURCE_LOCAL"> + <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> + <exclude-unlisted-classes>false</exclude-unlisted-classes> + <properties> + <property name="javax.persistence.jdbc.driver" value="org.hsqldb.jdbcDriver" /> + <property name="javax.persistence.jdbc.url" value="jdbc:hsqldb:file:target/testdb-eclipselink;shutdown=true" /> + <property name="javax.persistence.jdbc.user" value="sa" /> + <property name="eclipselink.ddl-generation" value="drop-and-create-tables" /> + <property name="eclipselink.ddl-generation.output-mode" value="database" /> + <property name="eclipselink.logging.level" value="SEVERE"/> + </properties> + </persistence-unit> + + <!-- h2 --> + + <persistence-unit name="h2" transaction-type="RESOURCE_LOCAL"> + <provider>org.hibernate.ejb.HibernatePersistence</provider> + <properties> + <property name="hibernate.archive.autodetection" value="class" /> + <property name="hibernate.dialect" value="com.querydsl.jpa.support.QH2Dialect" /> + <property name="hibernate.connection.driver_class" value="org.h2.Driver" /> + <property name="hibernate.connection.url" value="jdbc:h2:./target/h2-hibernate" /> + <property name="hibernate.connection.user" value="sa" /> + <property name="hibernate.show_sql" value="false"/> + <property name="hibernate.flushMode" value="FLUSH_AUTO" /> + <property name="hibernate.hbm2ddl.auto" value="create-drop" /> + </properties> + </persistence-unit> + + <persistence-unit name="h2perf" transaction-type="RESOURCE_LOCAL"> + <provider>org.hibernate.ejb.HibernatePersistence</provider> + <properties> + <property name="hibernate.archive.autodetection" value="class" /> + <property name="hibernate.dialect" value="com.querydsl.jpa.support.QH2Dialect" /> + <property name="hibernate.connection.driver_class" value="org.h2.Driver" /> + <property name="hibernate.connection.url" value="jdbc:h2:./target/h2-hibernate-perf" /> + <property name="hibernate.connection.user" value="sa" /> + <property name="hibernate.show_sql" value="false"/> + <property name="hibernate.flushMode" value="FLUSH_AUTO" /> + <property name="hibernate.hbm2ddl.auto" value="create-drop" /> + </properties> + </persistence-unit> + + <persistence-unit name="h2-eclipselink" transaction-type="RESOURCE_LOCAL"> + <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> + <exclude-unlisted-classes>false</exclude-unlisted-classes> + <properties> + <property name="javax.persistence.jdbc.driver" value="org.h2.Driver" /> + <property name="javax.persistence.jdbc.url" value="jdbc:h2:./target/h2-eclipselink" /> + <property name="javax.persistence.jdbc.user" value="sa" /> + <property name="eclipselink.ddl-generation" value="drop-and-create-tables" /> + <property name="eclipselink.ddl-generation.output-mode" value="database" /> + <property name="eclipselink.logging.level" value="SEVERE"/> + </properties> + </persistence-unit> + + <persistence-unit name="h2-batoo"> + <provider>org.batoo.jpa.core.BatooPersistenceProvider</provider> + <class>com.querydsl.jpa.domain.Account</class> + <class>com.querydsl.jpa.domain.Animal</class> + <class>com.querydsl.jpa.domain.AuditLog</class> + <class>com.querydsl.jpa.domain.Author</class> + <class>com.querydsl.jpa.domain.Bar</class> + <class>com.querydsl.jpa.domain.Book</class> + <class>com.querydsl.jpa.domain.Calendar</class> + <class>com.querydsl.jpa.domain.Cat</class> + <class>com.querydsl.jpa.domain.Catalog</class> + <class>com.querydsl.jpa.domain.Company</class> + <class>com.querydsl.jpa.domain.Customer</class> + <class>com.querydsl.jpa.domain.Department</class> + <class>com.querydsl.jpa.domain.Document</class> + <class>com.querydsl.jpa.domain.Dolphin</class> + <class>com.querydsl.jpa.domain.DomesticCat</class> + <class>com.querydsl.jpa.domain.EmbeddedType</class> + <class>com.querydsl.jpa.domain.Employee</class> + <class>com.querydsl.jpa.domain.Entity1</class> + <class>com.querydsl.jpa.domain.Entity2</class> + <class>com.querydsl.jpa.domain.EvilType</class> + <class>com.querydsl.jpa.domain.Foo</class> + <class>com.querydsl.jpa.domain.Formula</class> + <class>com.querydsl.jpa.domain.Human</class> + <class>com.querydsl.jpa.domain.InheritedProperties</class> + <class>com.querydsl.jpa.domain.Item</class> + <class>com.querydsl.jpa.domain.Location</class> + <class>com.querydsl.jpa.domain.Mammal</class> + <class>com.querydsl.jpa.domain.Name</class> + <class>com.querydsl.jpa.domain.NameList</class> + <class>com.querydsl.jpa.domain.Named</class> + <class>com.querydsl.jpa.domain.Nationality</class> + <class>com.querydsl.jpa.domain.Novel</class> + <class>com.querydsl.jpa.domain.Numeric</class> + <class>com.querydsl.jpa.domain.Order</class> + <class>com.querydsl.jpa.domain.Parameter</class> + <class>com.querydsl.jpa.domain.Payment</class> + <class>com.querydsl.jpa.domain.Person</class> + <class>com.querydsl.jpa.domain.PersonId</class> + <class>com.querydsl.jpa.domain.Player</class> + <class>com.querydsl.jpa.domain.Price</class> + <class>com.querydsl.jpa.domain.Product</class> + <class>com.querydsl.jpa.domain.Show</class> + <class>com.querydsl.jpa.domain.SimpleTypes</class> + <class>com.querydsl.jpa.domain.Status</class> + <class>com.querydsl.jpa.domain.StatusChange</class> + <class>com.querydsl.jpa.domain.Store</class> + <class>com.querydsl.jpa.domain.Superclass</class> + <class>com.querydsl.jpa.domain.User</class> + <class>com.querydsl.jpa.domain.World</class> + <class>com.querydsl.jpa.domain4.BookDefinition</class> + <class>com.querydsl.jpa.domain4.BookID</class> + <class>com.querydsl.jpa.domain4.BookMark</class> + <class>com.querydsl.jpa.domain4.BookVersion</class> + <class>com.querydsl.jpa.domain4.BookVersionPK</class> + <class>com.querydsl.jpa.domain4.Library</class> + <properties> + <property name="javax.persistence.jdbc.driver" value="org.h2.Driver" /> + <property name="javax.persistence.jdbc.url" value="jdbc:h2:./target/h2-batoo" /> + <property name="javax.persistence.jdbc.user" value="sa" /> + <property name="org.batoo.jpa.sql_logging" value="NONE"/> + <property name="org.batoo.jpa.ddl" value="DROP" /> + </properties> + </persistence-unit> + + <persistence-unit name="h2-openjpa" transaction-type="RESOURCE_LOCAL"> + <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider> + <properties> + <property name="javax.persistence.jdbc.driver" value="org.h2.Driver" /> + <property name="javax.persistence.jdbc.url" value="jdbc:h2:./target/h2-openjpa" /> + <property name="javax.persistence.jdbc.user" value="sa" /> + <property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)"/> + <property name="openjpa.RuntimeUnenhancedClasses" value="supported" /> + <property name="openjpa.jdbc.Schemas" value="PUBLIC"/> + <property name="openjpa.jdbc.DBDictionary" value="h2(useSchemaName=true)"/> + <!-- + <property name="openjpa.Log" value="DefaultLevel=TRACE,Tool=TRACE"/> + --> + </properties> + </persistence-unit> + + <!-- mysql --> + + <persistence-unit name="mysql"> + <provider>org.hibernate.ejb.HibernatePersistence</provider> + <properties> + <property name="hibernate.archive.autodetection" value="class" /> + <property name="hibernate.dialect" value="com.querydsl.jpa.support.QMySQL5InnoDBDialect" /> + <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" /> + <property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/querydsl" /> + <property name="hibernate.connection.username" value="querydsl" /> + <property name="hibernate.connection.password" value="querydsl" /> + <!-- <property name="hibernate.show_sql" value="true"/> --> + <property name="hibernate.flushMode" value="FLUSH_AUTO" /> + <property name="hibernate.hbm2ddl.auto" value="update" /> + </properties> + </persistence-unit> + + <persistence-unit name="mysql-eclipselink" transaction-type="RESOURCE_LOCAL"> + <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> + <exclude-unlisted-classes>false</exclude-unlisted-classes> + <properties> + <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" /> + <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/querydsl2" /> + <property name="javax.persistence.jdbc.user" value="querydsl" /> + <property name="javax.persistence.jdbc.password" value="querydsl" /> + <property name="eclipselink.ddl-generation" value="drop-and-create-tables" /> + <property name="eclipselink.ddl-generation.output-mode" value="database" /> + <property name="eclipselink.logging.level" value="SEVERE"/> + </properties> + </persistence-unit> + + <!--mssql --> + + <persistence-unit name="mssql"> + <provider>org.hibernate.ejb.HibernatePersistence</provider> + <properties> + <property name="hibernate.archive.autodetection" value="class" /> + <property name="hibernate.dialect" value="com.querydsl.jpa.support.QSQLServer2008Dialect" /> + <property name="hibernate.connection.driver_class" value="com.microsoft.sqlserver.jdbc.SQLServerDriver" /> + <property name="hibernate.connection.url" value="jdbc:sqlserver://localhost:1433;databaseName=tempdb;sendTimeAsDatetime=false;trustServerCertificate=true" /> + <property name="hibernate.connection.username" value="sa" /> + <property name="hibernate.connection.password" value="Password1!" /> + <!-- <property name="hibernate.show_sql" value="true"/> --> + <property name="hibernate.flushMode" value="FLUSH_AUTO" /> + <property name="hibernate.hbm2ddl.auto" value="update" /> + </properties> + </persistence-unit> + + <!-- postgresql --> + + <persistence-unit name="postgresql"> + <provider>org.hibernate.ejb.HibernatePersistence</provider> + <properties> + <property name="hibernate.archive.autodetection" value="class" /> + <property name="hibernate.dialect" value="com.querydsl.jpa.support.QPostgreSQL9Dialect" /> + <property name="hibernate.connection.driver_class" value="org.postgresql.Driver" /> + <property name="hibernate.connection.url" value="jdbc:postgresql://localhost:5433/querydsl" /> + <property name="hibernate.connection.username" value="querydsl" /> + <property name="hibernate.connection.password" value="querydsl" /> + <!-- <property name="hibernate.show_sql" value="true"/> --> + <property name="hibernate.flushMode" value="FLUSH_AUTO" /> + <property name="hibernate.hbm2ddl.auto" value="create-drop" /> + </properties> + </persistence-unit> + + <persistence-unit name="postgresql-eclipselink" transaction-type="RESOURCE_LOCAL"> + <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> + <exclude-unlisted-classes>false</exclude-unlisted-classes> + <properties> + <property name="javax.persistence.jdbc.driver" value="org.postgresql.Driver" /> + <property name="javax.persistence.jdbc.url" value="jdbc:postgresql://localhost:5433/querydsl2" /> + <property name="javax.persistence.jdbc.user" value="querydsl" /> + <property name="javax.persistence.jdbc.password" value="querydsl" /> + <property name="eclipselink.ddl-generation" value="drop-and-create-tables" /> + <property name="eclipselink.ddl-generation.output-mode" value="database" /> + <property name="eclipselink.logging.level" value="SEVERE"/> + </properties> + </persistence-unit> + + <!-- oracle --> + + <persistence-unit name="oracle"> + <provider>org.hibernate.ejb.HibernatePersistence</provider> + <properties> + <property name="hibernate.archive.autodetection" value="class" /> + <property name="hibernate.dialect" value="com.querydsl.jpa.support.QOracle10gDialect" /> + <property name="hibernate.connection.driver_class" value="oracle.jdbc.driver.OracleDriver" /> + <property name="hibernate.connection.url" value="jdbc:oracle:thin:@localhost:1521:xe" /> + <property name="hibernate.connection.username" value="querydsl" /> + <property name="hibernate.connection.password" value="querydsl" /> + <property name="hibernate.show_sql" value="true"/> + <property name="hibernate.flushMode" value="FLUSH_AUTO" /> + <property name="hibernate.hbm2ddl.auto" value="update" /> + </properties> + </persistence-unit> + + <!-- teradata --> + + <persistence-unit name="teradata"> + <provider>org.hibernate.ejb.HibernatePersistence</provider> + <properties> + <property name="hibernate.archive.autodetection" value="class" /> + <property name="hibernate.dialect" value="com.querydsl.jpa.support.TeradataDialect" /> + <property name="hibernate.connection.driver_class" value="com.teradata.jdbc.TeraDriver" /> + <property name="hibernate.connection.url" value="jdbc:teradata://teradata/dbc" /> + <property name="hibernate.connection.username" value="querydsl" /> + <property name="hibernate.connection.password" value="querydsl" /> + <!-- <property name="hibernate.show_sql" value="true"/> --> + <property name="hibernate.flushMode" value="FLUSH_AUTO" /> + <property name="hibernate.hbm2ddl.auto" value="update" /> + <property name="hibernate.globally_quoted_identifiers" value="true" /> + </properties> + </persistence-unit> + +</persistence> diff --git a/querydsl-jpa/src/test/resources/com/mysema/testutil/h2.properties b/querydsl-jpa/src/test/resources/com/mysema/testutil/h2.properties deleted file mode 100644 index 6aa4f0d5b9..0000000000 --- a/querydsl-jpa/src/test/resources/com/mysema/testutil/h2.properties +++ /dev/null @@ -1,9 +0,0 @@ -hibernate.dialect=org.hibernate.dialect.H2Dialect -hibernate.connection.driver_class=org.h2.Driver -hibernate.connection.url=jdbc:h2:~/dbs/h2-jpa1 -hibernate.connection.username=sa -hibernate.connection.password= - -#hibernate.show_sql=true -hibernate.flushMode=FLUSH_AUTO -hibernate.hbm2ddl.auto=create-drop \ No newline at end of file diff --git a/querydsl-jpa/src/test/resources/com/mysema/testutil/mssql.properties b/querydsl-jpa/src/test/resources/com/mysema/testutil/mssql.properties deleted file mode 100644 index 997752c0b1..0000000000 --- a/querydsl-jpa/src/test/resources/com/mysema/testutil/mssql.properties +++ /dev/null @@ -1,12 +0,0 @@ -## MSSQL -hibernate.dialect=org.hibernate.dialect.SQLServerDialect -hibernate.connection.driver_class=net.sourceforge.jtds.jdbc.Driver -hibernate.connection.url=jdbc:jtds:sqlserver://localhost:1433/querydsl -hibernate.connection.username=querydsl -hibernate.connection.password=querydsl - -## Common properties -#hibernate.show_sql=true -hibernate.flushMode=FLUSH_AUTO -hibernate.hbm2ddl.auto=update -#hibernate.use_sql_comments=true \ No newline at end of file diff --git a/querydsl-jpa/src/test/resources/com/mysema/testutil/oracle.properties b/querydsl-jpa/src/test/resources/com/mysema/testutil/oracle.properties deleted file mode 100644 index 26248b1a9d..0000000000 --- a/querydsl-jpa/src/test/resources/com/mysema/testutil/oracle.properties +++ /dev/null @@ -1,13 +0,0 @@ -## MySQL -#hibernate.dialect=org.hibernate.dialect.Oracle10gDialect -hibernate.dialect=com.mysema.query.jpa.support.ExtendedOracleDialect -hibernate.connection.driver_class=oracle.jdbc.driver.OracleDriver -hibernate.connection.url=jdbc:oracle:thin:@localhost:1521:xe -hibernate.connection.username=querydsl -hibernate.connection.password=querydsl - -## Common properties -#hibernate.show_sql=true -hibernate.flushMode=FLUSH_AUTO -hibernate.hbm2ddl.auto=update -#hibernate.use_sql_comments=true \ No newline at end of file diff --git a/querydsl-jpa/src/test/resources/com/mysema/testutil/postgres.properties b/querydsl-jpa/src/test/resources/com/mysema/testutil/postgres.properties deleted file mode 100644 index b78843c01e..0000000000 --- a/querydsl-jpa/src/test/resources/com/mysema/testutil/postgres.properties +++ /dev/null @@ -1,12 +0,0 @@ -## MySQL -hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect -hibernate.connection.driver_class=org.postgresql.Driver -hibernate.connection.url=jdbc:postgresql://localhost:5432/querydsl -hibernate.connection.username=querydsl -hibernate.connection.password=querydsl - -## Common properties -#hibernate.show_sql=true -hibernate.flushMode=FLUSH_AUTO -hibernate.hbm2ddl.auto=update -#hibernate.use_sql_comments=true \ No newline at end of file diff --git a/querydsl-jpa/src/test/resources/com/mysema/testutil/derby.properties b/querydsl-jpa/src/test/resources/com/querydsl/jpa/testutil/derby.properties similarity index 81% rename from querydsl-jpa/src/test/resources/com/mysema/testutil/derby.properties rename to querydsl-jpa/src/test/resources/com/querydsl/jpa/testutil/derby.properties index 209cbf0650..12588cba01 100644 --- a/querydsl-jpa/src/test/resources/com/mysema/testutil/derby.properties +++ b/querydsl-jpa/src/test/resources/com/querydsl/jpa/testutil/derby.properties @@ -1,11 +1,11 @@ -## Derby -#hibernate.dialect=org.hibernate.dialect.DerbyDialect -hibernate.dialect=com.mysema.query.jpa.support.ExtendedDerbyDialect -hibernate.connection.driver_class=org.apache.derby.jdbc.EmbeddedDriver -hibernate.connection.url=jdbc:derby:target/derbydb;create=true - -## Common properties -#hibernate.show_sql=true -hibernate.flushMode=FLUSH_AUTO -hibernate.hbm2ddl.auto=create-drop +## Derby +#hibernate.dialect=org.hibernate.dialect.DerbyDialect +hibernate.dialect=com.querydsl.jpa.support.QDerbyDialect +hibernate.connection.driver_class=org.apache.derby.jdbc.EmbeddedDriver +hibernate.connection.url=jdbc:derby:target/derbydb;create=true + +## Common properties +#hibernate.show_sql=true +hibernate.flushMode=FLUSH_AUTO +hibernate.hbm2ddl.auto=create-drop #hibernate.use_sql_comments=true \ No newline at end of file diff --git a/querydsl-jpa/src/test/resources/com/querydsl/jpa/testutil/h2.properties b/querydsl-jpa/src/test/resources/com/querydsl/jpa/testutil/h2.properties new file mode 100644 index 0000000000..0d714abb0c --- /dev/null +++ b/querydsl-jpa/src/test/resources/com/querydsl/jpa/testutil/h2.properties @@ -0,0 +1,9 @@ +hibernate.dialect=com.querydsl.jpa.support.QH2Dialect +hibernate.connection.driver_class=org.h2.Driver +hibernate.connection.url=jdbc:h2:./target/h2-jpa1 +hibernate.connection.username=sa +hibernate.connection.password= + +#hibernate.show_sql=true +hibernate.flushMode=FLUSH_AUTO +hibernate.hbm2ddl.auto=create-drop \ No newline at end of file diff --git a/querydsl-jpa/src/test/resources/com/mysema/testutil/hsqldb.properties b/querydsl-jpa/src/test/resources/com/querydsl/jpa/testutil/hsqldb.properties similarity index 83% rename from querydsl-jpa/src/test/resources/com/mysema/testutil/hsqldb.properties rename to querydsl-jpa/src/test/resources/com/querydsl/jpa/testutil/hsqldb.properties index 372403c439..b2dc0c0fec 100644 --- a/querydsl-jpa/src/test/resources/com/mysema/testutil/hsqldb.properties +++ b/querydsl-jpa/src/test/resources/com/querydsl/jpa/testutil/hsqldb.properties @@ -1,13 +1,13 @@ -## HSQL -#hibernate.dialect=org.hibernate.dialect.HSQLDialect -hibernate.dialect=com.mysema.query.jpa.support.ExtendedHSQLDialect -hibernate.connection.url=jdbc:hsqldb:file:target/testdb;shutdown=true -hibernate.connection.driver_class=org.hsqldb.jdbcDriver -hibernate.connection.username=sa -hibernate.connection.password= - -## Common properties -#hibernate.show_sql=true -hibernate.flushMode=FLUSH_AUTO -hibernate.hbm2ddl.auto=create-drop +## HSQL +#hibernate.dialect=org.hibernate.dialect.HSQLDialect +hibernate.dialect=com.querydsl.jpa.support.QHSQLDialect +hibernate.connection.url=jdbc:hsqldb:file:target/testdb;shutdown=true +hibernate.connection.driver_class=org.hsqldb.jdbcDriver +hibernate.connection.username=sa +hibernate.connection.password= + +## Common properties +#hibernate.show_sql=true +hibernate.flushMode=FLUSH_AUTO +hibernate.hbm2ddl.auto=create-drop #hibernate.use_sql_comments=true \ No newline at end of file diff --git a/querydsl-jpa/src/test/resources/com/querydsl/jpa/testutil/mssql.properties b/querydsl-jpa/src/test/resources/com/querydsl/jpa/testutil/mssql.properties new file mode 100644 index 0000000000..b7b0002044 --- /dev/null +++ b/querydsl-jpa/src/test/resources/com/querydsl/jpa/testutil/mssql.properties @@ -0,0 +1,12 @@ +## MSSQL +hibernate.dialect=com.querydsl.jpa.support.QSQLServer2008Dialect +hibernate.connection.driver_class=com.microsoft.sqlserver.jdbc.SQLServerDriver +hibernate.connection.url=jdbc:sqlserver://localhost:1433;databaseName=tempdb;sendTimeAsDatetime=false;trustServerCertificate=true +hibernate.connection.username=sa +hibernate.connection.password=Password1! + +## Common properties +#hibernate.show_sql=true +hibernate.flushMode=FLUSH_AUTO +hibernate.hbm2ddl.auto=update +#hibernate.use_sql_comments=true \ No newline at end of file diff --git a/querydsl-jpa/src/test/resources/com/mysema/testutil/mysql.properties b/querydsl-jpa/src/test/resources/com/querydsl/jpa/testutil/mysql.properties similarity index 75% rename from querydsl-jpa/src/test/resources/com/mysema/testutil/mysql.properties rename to querydsl-jpa/src/test/resources/com/querydsl/jpa/testutil/mysql.properties index d261199a55..619988c92f 100644 --- a/querydsl-jpa/src/test/resources/com/mysema/testutil/mysql.properties +++ b/querydsl-jpa/src/test/resources/com/querydsl/jpa/testutil/mysql.properties @@ -1,12 +1,12 @@ -## MySQL -hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect -hibernate.connection.driver_class=com.mysql.jdbc.Driver -hibernate.connection.url=jdbc:mysql://localhost:3306/querydsl -hibernate.connection.username=querydsl -hibernate.connection.password=querydsl - -## Common properties -#hibernate.show_sql=true -hibernate.flushMode=FLUSH_AUTO -hibernate.hbm2ddl.auto=update -#hibernate.use_sql_comments=true \ No newline at end of file +## MySQL +hibernate.dialect=com.querydsl.jpa.support.QMySQL5InnoDBDialect +hibernate.connection.driver_class=com.mysql.jdbc.Driver +hibernate.connection.url=jdbc:mysql://localhost:3306/querydsl +hibernate.connection.username=querydsl +hibernate.connection.password=querydsl + +## Common properties +#hibernate.show_sql=true +hibernate.flushMode=FLUSH_AUTO +hibernate.hbm2ddl.auto=update +#hibernate.use_sql_comments=true diff --git a/querydsl-jpa/src/test/resources/com/querydsl/jpa/testutil/oracle.properties b/querydsl-jpa/src/test/resources/com/querydsl/jpa/testutil/oracle.properties new file mode 100644 index 0000000000..389751334f --- /dev/null +++ b/querydsl-jpa/src/test/resources/com/querydsl/jpa/testutil/oracle.properties @@ -0,0 +1,13 @@ +## MySQL +#hibernate.dialect=org.hibernate.dialect.Oracle10gDialect +hibernate.dialect=com.querydsl.jpa.support.QOracle10gDialect +hibernate.connection.driver_class=oracle.jdbc.driver.OracleDriver +hibernate.connection.url=jdbc:oracle:thin:@localhost:1521:xe +hibernate.connection.username=system +hibernate.connection.password=oracle + +## Common properties +#hibernate.show_sql=true +hibernate.flushMode=FLUSH_AUTO +hibernate.hbm2ddl.auto=update +#hibernate.use_sql_comments=true diff --git a/querydsl-jpa/src/test/resources/com/querydsl/jpa/testutil/postgresql.properties b/querydsl-jpa/src/test/resources/com/querydsl/jpa/testutil/postgresql.properties new file mode 100644 index 0000000000..fb0dfa1336 --- /dev/null +++ b/querydsl-jpa/src/test/resources/com/querydsl/jpa/testutil/postgresql.properties @@ -0,0 +1,12 @@ +## MySQL +hibernate.dialect=com.querydsl.jpa.support.QPostgreSQL9Dialect +hibernate.connection.driver_class=org.postgresql.Driver +hibernate.connection.url=jdbc:postgresql://localhost:5433/querydsl +hibernate.connection.username=querydsl +hibernate.connection.password=querydsl + +## Common properties +#hibernate.show_sql=true +hibernate.flushMode=FLUSH_AUTO +hibernate.hbm2ddl.auto=update +#hibernate.use_sql_comments=true diff --git a/querydsl-jpa/src/test/resources/com/mysema/testutil/teradata.properties b/querydsl-jpa/src/test/resources/com/querydsl/jpa/testutil/teradata.properties similarity index 83% rename from querydsl-jpa/src/test/resources/com/mysema/testutil/teradata.properties rename to querydsl-jpa/src/test/resources/com/querydsl/jpa/testutil/teradata.properties index a621b98997..82e1bf205a 100644 --- a/querydsl-jpa/src/test/resources/com/mysema/testutil/teradata.properties +++ b/querydsl-jpa/src/test/resources/com/querydsl/jpa/testutil/teradata.properties @@ -1,4 +1,4 @@ -hibernate.dialect=com.mysema.query.jpa.support.TeradataDialect +hibernate.dialect=com.querydsl.jpa.support.TeradataDialect hibernate.connection.driver_class=com.teradata.jdbc.TeraDriver hibernate.connection.url=jdbc:teradata://teradata/dbc hibernate.connection.username=querydsl diff --git a/querydsl-jpa/src/test/resources/contact.hbm.xml b/querydsl-jpa/src/test/resources/contact.hbm.xml index bbe23fcf41..72265d314c 100644 --- a/querydsl-jpa/src/test/resources/contact.hbm.xml +++ b/querydsl-jpa/src/test/resources/contact.hbm.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> -<hibernate-mapping package="com.mysema.query.jpa.domain2"> +<hibernate-mapping package="com.querydsl.jpa.domain2"> <class name="Contact" table="CONTACT"> <id name="id" type="long" column="ID" > <generator class="assigned"/> diff --git a/querydsl-jpa/src/test/resources/contact2.hbm.xml b/querydsl-jpa/src/test/resources/contact2.hbm.xml index 5d84dc2f6d..49c99a45fe 100644 --- a/querydsl-jpa/src/test/resources/contact2.hbm.xml +++ b/querydsl-jpa/src/test/resources/contact2.hbm.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> - <class name="com.mysema.query.jpa.domain2.Contact" table="CONTACT"> + <class name="com.querydsl.jpa.domain2.Contact" table="CONTACT"> <id name="id" type="long" column="ID" > <generator class="assigned"/> </id> diff --git a/querydsl-jpa/src/test/resources/hibernate.cfg.xml b/querydsl-jpa/src/test/resources/hibernate.cfg.xml index eb1c3b8cf2..77f0d8b63b 100644 --- a/querydsl-jpa/src/test/resources/hibernate.cfg.xml +++ b/querydsl-jpa/src/test/resources/hibernate.cfg.xml @@ -1,12 +1,12 @@ <?xml version='1.0' encoding='utf-8'?> <!DOCTYPE hibernate-configuration PUBLIC -"-//Hibernate/Hibernate Configuration DTD//EN" -"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> + "-//Hibernate/Hibernate Configuration DTD//EN" + "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> -<session-factory> - <property name="hibernate.dialect">com.mysema.query.jpa.support.ExtendedDerbyDialect</property> - <property name="hibernate.connection.driver_class">org.apache.derby.jdbc.EmbeddedDriver</property> - <property name="hibernate.connection.url">jdbc:derby:target/derbydb;create=true</property> -</session-factory> + <session-factory> + <property name="hibernate.dialect">com.querydsl.jpa.support.ExtendedDerbyDialect</property> + <property name="hibernate.connection.driver_class">org.apache.derby.jdbc.EmbeddedDriver</property> + <property name="hibernate.connection.url">jdbc:derby:target/derbydb;create=true</property> + </session-factory> </hibernate-configuration> diff --git a/querydsl-jpa/src/test/resources/log4j.properties b/querydsl-jpa/src/test/resources/log4j.properties index 945b555e69..f32b17f209 100644 --- a/querydsl-jpa/src/test/resources/log4j.properties +++ b/querydsl-jpa/src/test/resources/log4j.properties @@ -2,7 +2,7 @@ log4j.appender.stdout=org.apache.log4j.ConsoleAppender #log4j.appender.stdout.Target=System.out log4j.appender.stdout.layout=org.apache.log4j.PatternLayout -log4j.appender.stdout.layout.ConversionPattern=%5p [%d{yyyy-MM-dd HH:mm:ss}] (%F:%L) - %m%n +log4j.appender.stdout.layout.ConversionPattern=%5p [%d{yyyy-MM-dd HH:mm:ss}] (%F:%L) - %m %X%n ### set log levels - for more verbose logging change 'info' to 'debug' ### @@ -11,6 +11,9 @@ log4j.rootLogger=WARN, stdout log4j.appender.querydsl=org.apache.log4j.ConsoleAppender log4j.appender.querydsl.layout=org.apache.log4j.PatternLayout log4j.appender.querydsl.layout.ConversionPattern=Querydsl : %C#%M - %m%n - -#log4j.logger.com.mysema.query.jpa.hibernate=DEBUG, querydsl -#log4j.logger.com.mysema.query.jpa.impl=DEBUG, querydsl \ No newline at end of file + +#log4j.logger.com.querydsl.jpa.hibernate=DEBUG, querydsl +#log4j.logger.com.querydsl.jpa.impl=DEBUG, querydsl + +log4j.logger.org.hibernate=ERROR +log4j.logger.org.hibernate.tool.hbm2ddl=FATAL \ No newline at end of file diff --git a/querydsl-jpa/src/test/resources/store.hbm.xml b/querydsl-jpa/src/test/resources/store.hbm.xml index 09cf3dfd0e..da0b6e537a 100644 --- a/querydsl-jpa/src/test/resources/store.hbm.xml +++ b/querydsl-jpa/src/test/resources/store.hbm.xml @@ -2,7 +2,7 @@ <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> - <class name="com.mysema.query.jpa.domain3.Store" table="STORE" discriminator-value="S"> + <class name="com.querydsl.jpa.domain3.Store" table="STORE" discriminator-value="S"> <!-- <discriminator column="subclass" type="character"/> @@ -39,11 +39,11 @@ <column name="CHAIN_CODE"/> </property> - <subclass name="com.mysema.query.jpa.domain3.HardwareStore" discriminator-value="D"> + <subclass name="com.querydsl.jpa.domain3.HardwareStore" discriminator-value="D"> - <property name="storeCode"> - <column name="STORE_CODE"/> - </property> + <property name="storeCode"> + <column name="STORE_CODE"/> + </property> </subclass> diff --git a/querydsl-jpa/template.mf b/querydsl-jpa/template.mf deleted file mode 100644 index a4eedfd08b..0000000000 --- a/querydsl-jpa/template.mf +++ /dev/null @@ -1,17 +0,0 @@ -Bundle-SymbolicName: com.mysema.querydsl.jpa -Bundle-Name: Querydsl JPA -Bundle-Vendor: Mysema -Bundle-ManifestVersion: 2 -Import-Template: - com.mysema.commons.lang.*;version="${mysema.lang.version}", - com.mysema.query.sql.*;version="${project.version}";resolution:=optional, - com.mysema.query.*;version="${project.version}", - com.mysema.util.*;version="${project.version}", - javax.annotation.*;version="0", - javax.inject.*;version="0", - javax.persistence.*;version="[1.1.0,2.1.0]", - javax.xml.stream.*;version="0", - org.hibernate.*;version="${hibernate.version}";resolution:=optional, - org.eclipse.persistence.*;version="2.4.0";resolution:=optional, - org.slf4j.*;version="${slf4j.version}", - com.google.common.*;version="${guava.version}" \ No newline at end of file diff --git a/querydsl-kotlin-codegen/pom.xml b/querydsl-kotlin-codegen/pom.xml new file mode 100644 index 0000000000..a884a29656 --- /dev/null +++ b/querydsl-kotlin-codegen/pom.xml @@ -0,0 +1,96 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" + xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <parent> + <artifactId>querydsl-root</artifactId> + <groupId>com.querydsl</groupId> + <version>5.1.0</version> + </parent> + <modelVersion>4.0.0</modelVersion> + + <artifactId>querydsl-kotlin-codegen</artifactId> + <name>Querydsl - Kotlin codegen support</name> + + <properties> + <surefire.useManifestOnlyJar>false</surefire.useManifestOnlyJar> + </properties> + + <dependencies> + <dependency> + <groupId>com.querydsl</groupId> + <artifactId>querydsl-core</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.jetbrains.kotlin</groupId> + <artifactId>kotlin-stdlib-jdk8</artifactId> + </dependency> + <dependency> + <groupId>org.jetbrains.kotlin</groupId> + <artifactId>kotlin-reflect</artifactId> + </dependency> + <dependency> + <groupId>com.squareup</groupId> + <artifactId>kotlinpoet</artifactId> + <version>1.12.0</version> + </dependency> + <dependency> + <groupId>com.querydsl</groupId> + <artifactId>querydsl-codegen</artifactId> + <version>5.1.0</version> + <scope>compile</scope> + </dependency> + <!-- test --> + <dependency> + <groupId>com.querydsl</groupId> + <artifactId>querydsl-core</artifactId> + <version>${project.version}</version> + <scope>test</scope> + <type>test-jar</type> + </dependency> + <dependency> + <groupId>org.jetbrains.kotlin</groupId> + <artifactId>kotlin-scripting-jsr223</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.jetbrains.kotlin</groupId> + <artifactId>kotlin-script-runtime</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.jetbrains.kotlin</groupId> + <artifactId>kotlin-test-junit</artifactId> + <scope>test</scope> + </dependency> + </dependencies> + <build> + <sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory> + <testSourceDirectory>${project.basedir}/src/test/kotlin</testSourceDirectory> + <plugins> + <plugin> + <groupId>org.jetbrains.kotlin</groupId> + <artifactId>kotlin-maven-plugin</artifactId> + <executions> + <execution> + <id>compile</id> + <goals> + <goal>compile</goal> + </goals> + </execution> + <execution> + <id>test-compile</id> + <goals> + <goal>test-compile</goal> + </goals> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.jetbrains.dokka</groupId> + <artifactId>dokka-maven-plugin</artifactId> + </plugin> + </plugins> + </build> +</project> \ No newline at end of file diff --git a/querydsl-kotlin-codegen/src/main/kotlin/com/querydsl/kotlin/codegen/Extensions.kt b/querydsl-kotlin-codegen/src/main/kotlin/com/querydsl/kotlin/codegen/Extensions.kt new file mode 100644 index 0000000000..0c3faacb26 --- /dev/null +++ b/querydsl-kotlin-codegen/src/main/kotlin/com/querydsl/kotlin/codegen/Extensions.kt @@ -0,0 +1,86 @@ +/* + * Copyright 2021, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.kotlin.codegen + +import com.querydsl.codegen.EntityType +import com.querydsl.codegen.TypeMappings +import com.querydsl.codegen.utils.model.Type +import com.squareup.kotlinpoet.ClassName +import com.squareup.kotlinpoet.CodeBlock +import com.squareup.kotlinpoet.ParameterSpec +import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy +import com.squareup.kotlinpoet.TypeName +import com.squareup.kotlinpoet.WildcardTypeName +import com.squareup.kotlinpoet.asClassName +import com.squareup.kotlinpoet.asTypeName +import com.squareup.kotlinpoet.joinToCode +import kotlin.reflect.KClass + +fun Type.asTypeName(): TypeName = asClassName().let { className -> + if (parameters.isNotEmpty()) + className.parameterizedBy(*parameters.map { it.asTypeName() }.toTypedArray()) else className +} + +fun Type.asClassName(): ClassName = when (this.fullName) { + "java.lang.Boolean", "boolean" -> Boolean::class.asClassName() + "java.lang.Byte", "byte" -> Byte::class.asClassName() + "java.lang.Character", "char" -> Char::class.asClassName() + "java.lang.Short", "short" -> Short::class.asClassName() + "java.lang.Integer", "int" -> Int::class.asClassName() + "java.lang.Long", "long" -> Long::class.asClassName() + "java.lang.Float", "float" -> Float::class.asClassName() + "java.lang.Double", "double" -> Double::class.asClassName() + "boolean[]" -> BooleanArray::class.asClassName() + "byte[]" -> ByteArray::class.asClassName() + "char[]" -> CharArray::class.asClassName() + "short[]" -> ShortArray::class.asClassName() + "int[]" -> IntArray::class.asClassName() + "long[]" -> LongArray::class.asClassName() + "float[]" -> FloatArray::class.asClassName() + "double[]" -> DoubleArray::class.asClassName() + "java.lang.String" -> String::class.asClassName() + "java.util.List" -> List::class.asClassName() + "java.util.Map" -> Map::class.asClassName() + "java.util.Set" -> Set::class.asClassName() + else -> ClassName(packageName, *enclosingTypeHierarchy().toTypedArray()) +} + +fun Type.asOutTypeName() = WildcardTypeName.producerOf(asTypeName()) + +private fun Type.enclosingTypeHierarchy(): List<String> { + var current: Type? = this + return generateSequence { current?.also { current = it.enclosingType }?.simpleName }.toList().asReversed() +} + +fun ClassName.asClassStatement() = CodeBlock.of("%T::class.java", this) + +fun Type.asClassNameStatement() = asClassName().asClassStatement() + +fun TypeMappings.getPathClassName(type: Type, model: EntityType) = getPathType(type, model, true).asClassName() + +fun TypeMappings.getPathTypeName(type: Type, model: EntityType) = getPathType(type, model, false).asTypeName() + +fun KClass<*>.parameterizedBy(vararg types: TypeName) = asTypeName().parameterizedBy(*types) + +fun KClass<*>.parameterizedBy(vararg types: Type) = asTypeName().parameterizedBy(types.map { it.asTypeName() }) + +fun Collection<String>.joinToCode( + format: String = "%S", + separator: CharSequence = ", ", + prefix: CharSequence = "", + suffix: CharSequence = "") = map { it.asCodeBlock(format) }.joinToCode(separator, prefix, suffix) + +fun Any.asCodeBlock(format: String = "%L") = CodeBlock.of(format, this) + +fun ParameterSpec.asCodeBlock(format: String = "%N") = (this as Any).asCodeBlock(format) diff --git a/querydsl-kotlin-codegen/src/main/kotlin/com/querydsl/kotlin/codegen/KotlinAptExtension.kt b/querydsl-kotlin-codegen/src/main/kotlin/com/querydsl/kotlin/codegen/KotlinAptExtension.kt new file mode 100644 index 0000000000..c8b733146f --- /dev/null +++ b/querydsl-kotlin-codegen/src/main/kotlin/com/querydsl/kotlin/codegen/KotlinAptExtension.kt @@ -0,0 +1,34 @@ +/* + * Copyright 2021, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.kotlin.codegen + +import com.querydsl.codegen.AbstractModule +import com.querydsl.codegen.EmbeddableSerializer +import com.querydsl.codegen.EntitySerializer +import com.querydsl.codegen.Extension +import com.querydsl.codegen.Filer +import com.querydsl.codegen.ProjectionSerializer +import com.querydsl.codegen.SupertypeSerializer +import com.querydsl.codegen.TypeMappings + +class KotlinAptExtension : Extension { + override fun addSupport(module: AbstractModule) { + module.bind(EntitySerializer::class.java, KotlinEntitySerializer::class.java) + module.bind(EmbeddableSerializer::class.java, KotlinEmbeddableSerializer::class.java) + module.bind(SupertypeSerializer::class.java, KotlinSuperSerializer::class.java) + module.bind(ProjectionSerializer::class.java, KotlinProjectionSerializer::class.java) + module.bind(TypeMappings::class.java, KotlinTypeMappings::class.java) + module.bind(Filer::class.java, KotlinFiler::class.java) + } +} \ No newline at end of file diff --git a/querydsl-kotlin-codegen/src/main/kotlin/com/querydsl/kotlin/codegen/KotlinEmbeddableSerializer.kt b/querydsl-kotlin-codegen/src/main/kotlin/com/querydsl/kotlin/codegen/KotlinEmbeddableSerializer.kt new file mode 100644 index 0000000000..4cfbaf50a7 --- /dev/null +++ b/querydsl-kotlin-codegen/src/main/kotlin/com/querydsl/kotlin/codegen/KotlinEmbeddableSerializer.kt @@ -0,0 +1,34 @@ +/* + * Copyright 2021, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.kotlin.codegen + +import com.querydsl.codegen.CodegenModule +import com.querydsl.codegen.EmbeddableSerializer +import com.querydsl.codegen.GeneratedAnnotationResolver +import com.querydsl.codegen.TypeMappings +import com.querydsl.core.types.Path +import com.querydsl.core.types.dsl.BeanPath +import javax.inject.Inject +import javax.inject.Named +import kotlin.reflect.KClass + +class KotlinEmbeddableSerializer @Inject constructor( + mappings: TypeMappings, + @Named(CodegenModule.KEYWORDS) + keywords: Collection<String>, + @Named(CodegenModule.GENERATED_ANNOTATION_CLASS) + generatedAnnotationClass: Class<out Annotation> = GeneratedAnnotationResolver.resolveDefault() +) : KotlinEntitySerializer(mappings, keywords, generatedAnnotationClass), EmbeddableSerializer { + override fun defaultSuperType(): KClass<out Path<*>> = BeanPath::class +} \ No newline at end of file diff --git a/querydsl-kotlin-codegen/src/main/kotlin/com/querydsl/kotlin/codegen/KotlinEntitySerializer.kt b/querydsl-kotlin-codegen/src/main/kotlin/com/querydsl/kotlin/codegen/KotlinEntitySerializer.kt new file mode 100644 index 0000000000..906e7b70cb --- /dev/null +++ b/querydsl-kotlin-codegen/src/main/kotlin/com/querydsl/kotlin/codegen/KotlinEntitySerializer.kt @@ -0,0 +1,318 @@ +/* + * Copyright 2021, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.kotlin.codegen + +import com.querydsl.codegen.CodegenModule +import com.querydsl.codegen.EntitySerializer +import com.querydsl.codegen.EntityType +import com.querydsl.codegen.GeneratedAnnotationResolver +import com.querydsl.codegen.Property +import com.querydsl.codegen.SerializerConfig +import com.querydsl.codegen.TypeMappings +import com.querydsl.codegen.utils.CodeWriter +import com.querydsl.codegen.utils.model.SimpleType +import com.querydsl.codegen.utils.model.Type +import com.querydsl.codegen.utils.model.TypeCategory +import com.querydsl.core.types.Path +import com.querydsl.core.types.PathMetadata +import com.querydsl.core.types.PathMetadataFactory +import com.querydsl.core.types.dsl.ArrayPath +import com.querydsl.core.types.dsl.BooleanPath +import com.querydsl.core.types.dsl.CollectionPath +import com.querydsl.core.types.dsl.CollectionPathBase +import com.querydsl.core.types.dsl.ComparablePath +import com.querydsl.core.types.dsl.DatePath +import com.querydsl.core.types.dsl.DateTimePath +import com.querydsl.core.types.dsl.EntityPathBase +import com.querydsl.core.types.dsl.EnumPath +import com.querydsl.core.types.dsl.ListPath +import com.querydsl.core.types.dsl.MapPath +import com.querydsl.core.types.dsl.NumberPath +import com.querydsl.core.types.dsl.SetPath +import com.querydsl.core.types.dsl.StringPath +import com.querydsl.core.types.dsl.TimePath +import com.squareup.kotlinpoet.AnnotationSpec +import com.squareup.kotlinpoet.CodeBlock +import com.squareup.kotlinpoet.FileSpec +import com.squareup.kotlinpoet.FunSpec +import com.squareup.kotlinpoet.KModifier +import com.squareup.kotlinpoet.ParameterSpec +import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy +import com.squareup.kotlinpoet.PropertySpec +import com.squareup.kotlinpoet.TypeName +import com.squareup.kotlinpoet.TypeSpec +import com.squareup.kotlinpoet.WildcardTypeName +import com.squareup.kotlinpoet.asTypeName +import com.squareup.kotlinpoet.buildCodeBlock +import java.util.* +import javax.inject.Inject +import javax.inject.Named +import kotlin.reflect.KClass + +open class KotlinEntitySerializer @Inject constructor( + private val mappings: TypeMappings, + @Named(CodegenModule.KEYWORDS) + protected val keywords: Collection<String>, + @Named(CodegenModule.GENERATED_ANNOTATION_CLASS) + private val generatedAnnotationClass: Class<out Annotation> = GeneratedAnnotationResolver.resolveDefault() +) : EntitySerializer { + + override fun serialize(model: EntityType, config: SerializerConfig, writer: CodeWriter) { + val queryType: Type = mappings.getPathType(model, model, false) + FileSpec.builder(queryType.packageName, queryType.simpleName) + .addImport(PathMetadataFactory::class, "forVariable", "forProperty") + .addType( + intro(model, config) + .serializeProperties(model, config) + .constructors(model, config) + .build() + ) + .build() + .writeTo(writer) + } + + protected open fun intro(model: EntityType, config: SerializerConfig): TypeSpec.Builder { + return introClassHeader(model, config) + .introJavadoc(model, config) + .introSuper(model) + } + + protected open fun introClassHeader(model: EntityType, config: SerializerConfig): TypeSpec.Builder { + val pathType = if (model.properties.isEmpty()) { + when (model.originalCategory) { + TypeCategory.COMPARABLE -> ComparablePath::class + TypeCategory.ENUM -> EnumPath::class + TypeCategory.DATE -> DatePath::class + TypeCategory.DATETIME -> DateTimePath::class + TypeCategory.TIME -> TimePath::class + TypeCategory.NUMERIC -> NumberPath::class + TypeCategory.STRING -> StringPath::class + TypeCategory.BOOLEAN -> BooleanPath::class + else -> defaultSuperType() + } + } else { + defaultSuperType() + } + val superType = when (model.originalCategory) { + TypeCategory.BOOLEAN, TypeCategory.STRING -> pathType.asTypeName() + else -> pathType.parameterizedBy(model) + } + return TypeSpec.classBuilder(mappings.getPathClassName(model, model)) + .addAnnotations(model.annotations.map { AnnotationSpec.get(it) }) + .addAnnotation(AnnotationSpec.builder(generatedAnnotationClass).addMember("%S", javaClass.name).build()) + .superclass(superType) + .addType(introCompanion(model, config)) + } + + protected open fun defaultSuperType(): KClass<out Path<*>> = EntityPathBase::class + + protected open fun introCompanion(model: EntityType, config: SerializerConfig): TypeSpec { + return TypeSpec.companionObjectBuilder() + .addProperty(PropertySpec.builder("serialVersionUID", Long::class, KModifier.CONST, KModifier.PRIVATE).initializer("%L", model.fullName.hashCode()).build()) + .let { if (config.createDefaultVariable()) it.introDefaultInstance(model, config.defaultVariableName()) else it } + .build() + } + + protected open fun TypeSpec.Builder.introJavadoc(model: EntityType, config: SerializerConfig): TypeSpec.Builder = apply { + addKdoc("%L is a Querydsl query type for %L", mappings.getPathType(model, model, true).simpleName, model.simpleName) + } + + protected open fun TypeSpec.Builder.introDefaultInstance(model: EntityType, defaultName: String): TypeSpec.Builder = apply { + val simpleName = defaultName.ifEmpty { model.modifiedSimpleName } + val queryType = mappings.getPathClassName(model, model) + val alias = if (keywords.contains(simpleName.uppercase(Locale.getDefault()))) "${simpleName}1" else simpleName + addProperty(PropertySpec.builder(simpleName, queryType, KModifier.PUBLIC).initializer("%T(%S)", queryType, alias).addAnnotation(JvmField::class).build()) + } + + protected open fun TypeSpec.Builder.introSuper(model: EntityType): TypeSpec.Builder = apply { + val superType = model.superType?.entityType + if (superType != null) { + val superQueryType = mappings.getPathTypeName(superType, model) + addProperty( + PropertySpec.builder("_super", superQueryType, KModifier.PUBLIC) + .delegate(buildCodeBlock { + beginControlFlow("lazy") + addStatement("%T(this)", superQueryType) + endControlFlow() + }).build() + ) + } + } + + protected open fun TypeSpec.Builder.serializeProperties(model: EntityType, config: SerializerConfig): TypeSpec.Builder = apply { + model.properties.forEach { property -> + // FIXME : the custom types should have the custom type category + if (mappings.isRegistered(property.type) && property.type.category != TypeCategory.CUSTOM && property.type.category != TypeCategory.ENTITY) { + customField(model, property, config) + } else { + // strips of "? extends " etc + val queryType = mappings.getPathTypeName(SimpleType(property.type, property.type.parameters), model) + val classStatement = property.type.asClassNameStatement() + + when (property.type.category ?: TypeCategory.ENTITY) { + TypeCategory.STRING -> serialize(model, property, queryType, "createString") + TypeCategory.BOOLEAN -> serialize(model, property, queryType, "createBoolean") + TypeCategory.SIMPLE -> serialize(model, property, queryType, "createSimple", classStatement) + TypeCategory.COMPARABLE -> serialize(model, property, queryType, "createComparable", classStatement) + TypeCategory.ENUM -> serialize(model, property, queryType, "createEnum", classStatement) + TypeCategory.DATE -> serialize(model, property, queryType, "createDate", classStatement) + TypeCategory.DATETIME -> serialize(model, property, queryType, "createDateTime", classStatement) + TypeCategory.TIME -> serialize(model, property, queryType, "createTime", classStatement) + TypeCategory.NUMERIC -> serialize(model, property, queryType, "createNumber", classStatement) + TypeCategory.CUSTOM -> customField(model, property, config) + TypeCategory.ARRAY -> serialize(model, property, ArrayPath::class.parameterizedBy(property.type, property.type.componentType), "createArray", classStatement) + TypeCategory.COLLECTION -> collectionField(model, property, "createCollection", CollectionPath::class) + TypeCategory.SET -> collectionField(model, property, "createSet", SetPath::class) + TypeCategory.LIST -> collectionField(model, property, "createList", ListPath::class) + TypeCategory.MAP -> { + val genericQueryType = mappings.getPathType(getRaw(property.getParameter(1)), model, false) + val qType = mappings.getPathClassName(property.getParameter(1), model) + serialize( + model, property, MapPath::class.parameterizedBy(getRaw(property.getParameter(0)), getRaw(property.getParameter(1)), genericQueryType), + CodeBlock.of("this.createMap<%T, %T, %T>", property.getParameter(0).asTypeName(), property.getParameter(1).asTypeName(), genericQueryType.asTypeName()), + property.getParameter(0).asClassNameStatement(), property.getParameter(1).asClassNameStatement(), qType.asClassStatement() + ) + } + TypeCategory.ENTITY -> entityField(model, property, config) + } + } + } + } + + private fun TypeSpec.Builder.collectionField(model: EntityType, property: Property, factoryMethod: String, pathClass: KClass<out CollectionPathBase<*, *, *>>) { + val genericQueryType = mappings.getPathType(getRaw(property.getParameter(0)), model, false) + val qType = mappings.getPathClassName(property.getParameter(0), model) + serialize( + model, property, pathClass.parameterizedBy(getRaw(property.getParameter(0)), genericQueryType), + CodeBlock.of("this.%L<%T, %T>", factoryMethod, property.getParameter(0).asTypeName(), genericQueryType.asTypeName()), + property.getParameter(0).asClassNameStatement(), qType.asClassStatement(), "null".asCodeBlock() + ) + } + + protected open fun TypeSpec.Builder.customField(model: EntityType, field: Property, config: SerializerConfig) { + val queryType = mappings.getPathTypeName(field.type, model) + val builder = PropertySpec.builder(field.escapedName, queryType, KModifier.PUBLIC).addKdoc("custom") + if (field.isInherited) { + builder.addKdoc("inherited") + builder.delegate(buildCodeBlock { + beginControlFlow("lazy") + addStatement("%T(_super.%L)", queryType, field.escapedName) + endControlFlow() + }) + } else { + builder.initializer("%T(forProperty(%S))", queryType, field.name) + } + addProperty(builder.build()) + } + + protected open fun TypeSpec.Builder.serialize(model: EntityType, field: Property, type: TypeName, factoryMethod: Any, vararg args: CodeBlock) { + val superType = model.superType + val builder = PropertySpec.builder(field.escapedName, type, KModifier.PUBLIC) + if (field.isInherited && superType != null) { + builder.delegate(buildCodeBlock { + beginControlFlow("lazy") + addStatement("_super.%L", field.escapedName) + endControlFlow() + }) + } else { + builder.initializer("%L(%S${", %L".repeat(args.size)})", factoryMethod, field.name, *args) + } + if (field.isInherited) { + builder.addKdoc("inherited") + } + addProperty(builder.build()) + } + + private fun getRaw(type: Type): Type { + return if (type is EntityType && type.getPackageName().startsWith("ext.java")) { + type + } else { + SimpleType(type, type.parameters) + } + } + + protected open fun TypeSpec.Builder.entityField(model: EntityType, field: Property, config: SerializerConfig) { + val fieldType = mappings.getPathTypeName(field.type, model) + val builder = PropertySpec.builder(field.escapedName, fieldType) + if (field.isInherited) { + builder.addKdoc("inherited") + } + builder.addModifiers(if (config.useEntityAccessors()) KModifier.PROTECTED else KModifier.PUBLIC) + builder.delegate(buildCodeBlock { + beginControlFlow("lazy") + addStatement("%T(forProperty(%S))", fieldType, field.name) + endControlFlow() + }) + addProperty(builder.build()) + } + + protected open fun TypeSpec.Builder.constructors(model: EntityType, config: SerializerConfig): TypeSpec.Builder { + val stringOrBoolean = (model.originalCategory == TypeCategory.STRING || model.originalCategory == TypeCategory.BOOLEAN) + + // String + constructorsForVariables(model) + + // Path + val path = ParameterSpec.builder("path", if (model.isFinal) Path::class.parameterizedBy(model) else Path::class.parameterizedBy(model.asOutTypeName())).build() + val pathConstructor = FunSpec.constructorBuilder().addParameter(path) + if (stringOrBoolean) { + pathConstructor.callSuperConstructor(CodeBlock.of("%N.metadata", path)) + } else { + pathConstructor.callSuperConstructor(CodeBlock.of("%N.type", path), CodeBlock.of("%N.metadata", path)) + } + pathConstructor.addCode(constructorContent(model)) + addFunction(pathConstructor.build()) + + // PathMetadata + val metadata = ParameterSpec.builder("metadata", PathMetadata::class).build() + val pathMetadataConstructor = FunSpec.constructorBuilder().addParameter(metadata) + if (stringOrBoolean) { + pathMetadataConstructor.callSuperConstructor(metadata.asCodeBlock()) + } else { + pathMetadataConstructor.callSuperConstructor(model.asClassNameStatement(), metadata.asCodeBlock()) + } + pathConstructor.addCode(constructorContent(model)) + addFunction(pathMetadataConstructor.build()) + + // Class, PathMetadata + val type = ParameterSpec.builder("type", Class::class.asTypeName().parameterizedBy(WildcardTypeName.producerOf(model.asTypeName()))).build() + addFunction( + FunSpec.constructorBuilder() + .addParameter(type) + .addParameter(metadata) + .callSuperConstructor(type.asCodeBlock(), metadata.asCodeBlock()) + .addCode(constructorContent(model)).build() + ) + return this + } + + protected open fun constructorContent(model: EntityType): CodeBlock { + // override in subclasses + return CodeBlock.builder().build() + } + + protected open fun TypeSpec.Builder.constructorsForVariables(model: EntityType) { + val stringOrBoolean = (model.originalCategory == TypeCategory.STRING || model.originalCategory == TypeCategory.BOOLEAN) + + val variable = ParameterSpec.builder("variable", String::class).build() + val builder = FunSpec.constructorBuilder().addParameter(variable) + if (stringOrBoolean) { + builder.callSuperConstructor(CodeBlock.of("forVariable(%N)", variable)) + } else { + builder.callSuperConstructor(model.asClassNameStatement(), CodeBlock.of("forVariable(%N)", variable)) + } + builder.addCode(constructorContent(model)) + addFunction(builder.build()) + } +} diff --git a/querydsl-kotlin-codegen/src/main/kotlin/com/querydsl/kotlin/codegen/KotlinFiler.kt b/querydsl-kotlin-codegen/src/main/kotlin/com/querydsl/kotlin/codegen/KotlinFiler.kt new file mode 100644 index 0000000000..8d85d923cd --- /dev/null +++ b/querydsl-kotlin-codegen/src/main/kotlin/com/querydsl/kotlin/codegen/KotlinFiler.kt @@ -0,0 +1,29 @@ +/* + * Copyright 2021, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.kotlin.codegen + +import com.querydsl.codegen.Filer +import java.io.File +import java.io.Writer +import java.lang.Appendable +import javax.annotation.processing.ProcessingEnvironment +import javax.lang.model.element.Element + +class KotlinFiler : Filer { + override fun createFile(processingEnvironment: ProcessingEnvironment, classname: String, elements: MutableCollection<out Element>): Writer { + val file = File("${processingEnvironment.options["kapt.kotlin.generated"]}/${classname.replace(".", "/")}.kt") + file.parentFile.mkdirs() + return file.writer() + } +} \ No newline at end of file diff --git a/querydsl-kotlin-codegen/src/main/kotlin/com/querydsl/kotlin/codegen/KotlinProjectionSerializer.kt b/querydsl-kotlin-codegen/src/main/kotlin/com/querydsl/kotlin/codegen/KotlinProjectionSerializer.kt new file mode 100644 index 0000000000..c3d8bb810d --- /dev/null +++ b/querydsl-kotlin-codegen/src/main/kotlin/com/querydsl/kotlin/codegen/KotlinProjectionSerializer.kt @@ -0,0 +1,96 @@ +/* + * Copyright 2021, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.kotlin.codegen + +import com.querydsl.codegen.CodegenModule +import com.querydsl.codegen.EntityType +import com.querydsl.codegen.GeneratedAnnotationResolver +import com.querydsl.codegen.ProjectionSerializer +import com.querydsl.codegen.SerializerConfig +import com.querydsl.codegen.TypeMappings +import com.querydsl.codegen.utils.CodeWriter +import com.querydsl.codegen.utils.model.Type +import com.querydsl.core.types.ConstructorExpression +import com.querydsl.core.types.Expression +import com.squareup.kotlinpoet.AnnotationSpec +import com.squareup.kotlinpoet.CodeBlock +import com.squareup.kotlinpoet.FileSpec +import com.squareup.kotlinpoet.FunSpec +import com.squareup.kotlinpoet.KModifier +import com.squareup.kotlinpoet.ParameterSpec +import com.squareup.kotlinpoet.ParameterizedTypeName.Companion.parameterizedBy +import com.squareup.kotlinpoet.PropertySpec +import com.squareup.kotlinpoet.TypeSpec +import com.squareup.kotlinpoet.WildcardTypeName +import com.squareup.kotlinpoet.asClassName +import com.squareup.kotlinpoet.joinToCode +import javax.inject.Inject +import javax.inject.Named + +open class KotlinProjectionSerializer @Inject constructor( + private val mappings: TypeMappings, + @Named(CodegenModule.GENERATED_ANNOTATION_CLASS) + private val generatedAnnotationClass: Class<out Annotation> = GeneratedAnnotationResolver.resolveDefault() +) : ProjectionSerializer { + + protected open fun intro(model: EntityType): TypeSpec.Builder { + val queryType = mappings.getPathClassName(model, model) + return TypeSpec.classBuilder(queryType) + .superclass(ConstructorExpression::class.parameterizedBy(model)) + .addKdoc("${queryType.canonicalName} is a Querydsl Projection type for ${model.simpleName}") + .addAnnotation(AnnotationSpec.builder(generatedAnnotationClass).addMember("%S", javaClass.name).build()) + .addType(introCompanion(model)) + } + + protected open fun introCompanion(model: EntityType): TypeSpec { + return TypeSpec.companionObjectBuilder() + .addProperty(PropertySpec.builder("serialVersionUID", Long::class, KModifier.CONST, KModifier.PRIVATE).initializer("%L", model.hashCode()).build()) + .build() + } + + protected open fun TypeSpec.Builder.outro(type: EntityType, writer: CodeWriter) { + val queryType: Type = mappings.getPathType(type, type, false) + FileSpec.builder(queryType.packageName, queryType.simpleName) + .addType(build()) + .build() + .writeTo(writer) + } + + override fun serialize(model: EntityType, serializerConfig: SerializerConfig, writer: CodeWriter) { + val builder = intro(model) + val sizes: MutableSet<Int> = mutableSetOf() + for (c in model.constructors) { + val asExpr = sizes.add(c.parameters.size) + builder.addFunction( + FunSpec.constructorBuilder() + .addParameters(c.parameters.map { + ParameterSpec.builder( + it.name, when { + !asExpr -> mappings.getExprType(it.type, model, false, false, true).asTypeName() + it.type.isFinal -> Expression::class.parameterizedBy(it.type.asTypeName()) + else -> Expression::class.asClassName().parameterizedBy(WildcardTypeName.producerOf(it.type.asTypeName())) + } + ).build() + }) + .callSuperConstructor(model.asClassNameStatement(), + c.parameters.map { it.type.asClassNameStatement() }.joinToCode(", ", "arrayOf(", ")"), + *c.parameters.map { CodeBlock.of("%L", it.name) }.toTypedArray() + ) + .build() + ) + } + builder.outro(model, writer) + } + +} \ No newline at end of file diff --git a/querydsl-kotlin-codegen/src/main/kotlin/com/querydsl/kotlin/codegen/KotlinSuperSerializer.kt b/querydsl-kotlin-codegen/src/main/kotlin/com/querydsl/kotlin/codegen/KotlinSuperSerializer.kt new file mode 100644 index 0000000000..a430acd307 --- /dev/null +++ b/querydsl-kotlin-codegen/src/main/kotlin/com/querydsl/kotlin/codegen/KotlinSuperSerializer.kt @@ -0,0 +1,23 @@ +/* + * Copyright 2021, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.kotlin.codegen + +import com.querydsl.codegen.SupertypeSerializer +import com.querydsl.codegen.TypeMappings +import javax.inject.Inject +import javax.inject.Named + +class KotlinSuperSerializer @Inject constructor(mappings: TypeMappings, @Named("keywords") keyword: Collection<String>) : KotlinEntitySerializer(mappings, keyword), + SupertypeSerializer { +} \ No newline at end of file diff --git a/querydsl-kotlin-codegen/src/main/kotlin/com/querydsl/kotlin/codegen/KotlinTypeMappings.kt b/querydsl-kotlin-codegen/src/main/kotlin/com/querydsl/kotlin/codegen/KotlinTypeMappings.kt new file mode 100644 index 0000000000..a4237f3f05 --- /dev/null +++ b/querydsl-kotlin-codegen/src/main/kotlin/com/querydsl/kotlin/codegen/KotlinTypeMappings.kt @@ -0,0 +1,18 @@ +/* + * Copyright 2021, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.kotlin.codegen + +import com.querydsl.codegen.JavaTypeMappings + +class KotlinTypeMappings : JavaTypeMappings() \ No newline at end of file diff --git a/querydsl-kotlin-codegen/src/main/resources/META-INF/services/com.querydsl.codegen.Extension b/querydsl-kotlin-codegen/src/main/resources/META-INF/services/com.querydsl.codegen.Extension new file mode 100644 index 0000000000..7cad3ee661 --- /dev/null +++ b/querydsl-kotlin-codegen/src/main/resources/META-INF/services/com.querydsl.codegen.Extension @@ -0,0 +1 @@ +com.querydsl.kotlin.codegen.KotlinAptExtension \ No newline at end of file diff --git a/querydsl-kotlin-codegen/src/test/kotlin/Entity.kt b/querydsl-kotlin-codegen/src/test/kotlin/Entity.kt new file mode 100644 index 0000000000..d56c52d853 --- /dev/null +++ b/querydsl-kotlin-codegen/src/test/kotlin/Entity.kt @@ -0,0 +1,22 @@ +/* + * Copyright 2021, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +class Entity { + var name: String? = null + + companion object { + fun test(o: Any?): String? { + return null + } + } +} \ No newline at end of file diff --git a/querydsl-kotlin-codegen/src/test/kotlin/Entity2.kt b/querydsl-kotlin-codegen/src/test/kotlin/Entity2.kt new file mode 100644 index 0000000000..029946eb63 --- /dev/null +++ b/querydsl-kotlin-codegen/src/test/kotlin/Entity2.kt @@ -0,0 +1,16 @@ +/* + * Copyright 2021, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +class Entity2 { + var name: String? = null +} \ No newline at end of file diff --git a/querydsl-kotlin-codegen/src/test/kotlin/com/querydsl/kotlin/codegen/CompileUtils.kt b/querydsl-kotlin-codegen/src/test/kotlin/com/querydsl/kotlin/codegen/CompileUtils.kt new file mode 100644 index 0000000000..542b03bc3f --- /dev/null +++ b/querydsl-kotlin-codegen/src/test/kotlin/com/querydsl/kotlin/codegen/CompileUtils.kt @@ -0,0 +1,23 @@ +/* + * Copyright 2021, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.kotlin.codegen + +import javax.script.ScriptEngineManager + +object CompileUtils { + fun assertCompiles(name: String, code: String) { + val engine = ScriptEngineManager().getEngineByExtension("kts")!! + engine.eval(code) + } +} \ No newline at end of file diff --git a/querydsl-kotlin-codegen/src/test/kotlin/com/querydsl/kotlin/codegen/EmbeddableSerializerTest.kt b/querydsl-kotlin-codegen/src/test/kotlin/com/querydsl/kotlin/codegen/EmbeddableSerializerTest.kt new file mode 100644 index 0000000000..88589e52e7 --- /dev/null +++ b/querydsl-kotlin-codegen/src/test/kotlin/com/querydsl/kotlin/codegen/EmbeddableSerializerTest.kt @@ -0,0 +1,195 @@ +/* + * Copyright 2021, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.kotlin.codegen + +import com.querydsl.codegen.Delegate +import com.querydsl.codegen.EntitySerializer +import com.querydsl.codegen.EntityType +import com.querydsl.codegen.GeneratedAnnotationResolver +import com.querydsl.codegen.Property +import com.querydsl.codegen.QueryTypeFactory +import com.querydsl.codegen.QueryTypeFactoryImpl +import com.querydsl.codegen.SimpleSerializerConfig +import com.querydsl.codegen.Supertype +import com.querydsl.codegen.TypeMappings +import com.querydsl.codegen.utils.JavaWriter +import com.querydsl.codegen.utils.model.ClassType +import com.querydsl.codegen.utils.model.SimpleType +import com.querydsl.codegen.utils.model.TypeCategory +import com.querydsl.codegen.utils.model.Types +import com.querydsl.core.annotations.Generated +import com.querydsl.core.annotations.PropertyType +import com.querydsl.kotlin.codegen.CompileUtils.assertCompiles +import org.hamcrest.Matchers +import org.junit.Assert +import org.junit.Ignore +import org.junit.Test +import java.io.StringWriter +import java.sql.Time +import java.util.* + +class EmbeddableSerializerTest { + private val queryTypeFactory: QueryTypeFactory = QueryTypeFactoryImpl("Q", "", "") + private val typeMappings: TypeMappings = KotlinTypeMappings() + private val serializer: EntitySerializer = KotlinEmbeddableSerializer(typeMappings, emptySet()) + private val writer = StringWriter() + + @Test + fun properties() { + val type = SimpleType(TypeCategory.ENTITY, "Entity", "", "Entity", false, false) + val entityType = EntityType(type) + entityType.addProperty(Property(entityType, "b", ClassType(TypeCategory.BOOLEAN, Boolean::class.java))) + entityType.addProperty(Property(entityType, "c", ClassType(TypeCategory.COMPARABLE, String::class.java))) + //entityType.addProperty(new Property(entityType, "cu", new ClassType(TypeCategory.CUSTOM, PropertyType.class))); + entityType.addProperty(Property(entityType, "d", ClassType(TypeCategory.DATE, Date::class.java))) + entityType.addProperty(Property(entityType, "e", ClassType(TypeCategory.ENUM, PropertyType::class.java))) + entityType.addProperty(Property(entityType, "dt", ClassType(TypeCategory.DATETIME, Date::class.java))) + entityType.addProperty(Property(entityType, "i", ClassType(TypeCategory.NUMERIC, Int::class.java))) + entityType.addProperty(Property(entityType, "s", ClassType(TypeCategory.STRING, String::class.java))) + entityType.addProperty(Property(entityType, "t", ClassType(TypeCategory.TIME, Time::class.java))) + typeMappings.register(entityType, queryTypeFactory.create(entityType)) + serializer.serialize(entityType, SimpleSerializerConfig.DEFAULT, JavaWriter(writer)) + assertCompiles("QEntity", writer.toString()) + } + + @Test + fun originalCategory() { + val categoryToSuperClass: MutableMap<TypeCategory, String> = EnumMap(TypeCategory::class.java) + categoryToSuperClass[TypeCategory.COMPARABLE] = "ComparablePath<Entity>" + categoryToSuperClass[TypeCategory.ENUM] = "EnumPath<Entity>" + categoryToSuperClass[TypeCategory.DATE] = "DatePath<Entity>" + categoryToSuperClass[TypeCategory.DATETIME] = "DateTimePath<Entity>" + categoryToSuperClass[TypeCategory.TIME] = "TimePath<Entity>" + categoryToSuperClass[TypeCategory.NUMERIC] = "NumberPath<Entity>" + categoryToSuperClass[TypeCategory.STRING] = "StringPath" + categoryToSuperClass[TypeCategory.BOOLEAN] = "BooleanPath" + for ((key, value) in categoryToSuperClass) { + val w = StringWriter() + val type = SimpleType(key, "Entity", "", "Entity", false, false) + val entityType = EntityType(type) + typeMappings.register(entityType, queryTypeFactory.create(entityType)) + serializer.serialize(entityType, SimpleSerializerConfig.DEFAULT, JavaWriter(w)) + Assert.assertTrue("$value is missing from $w", w.toString().contains("class QEntity : $value {")) + } + } + + @Test + fun empty() { + val type = SimpleType(TypeCategory.ENTITY, "Entity", "", "Entity", false, false) + val entityType = EntityType(type) + typeMappings.register(entityType, queryTypeFactory.create(entityType)) + serializer.serialize(entityType, SimpleSerializerConfig.DEFAULT, JavaWriter(writer)) + assertCompiles("QEntity", writer.toString()) + } + + @Test + fun no_package() { + val type = SimpleType(TypeCategory.ENTITY, "Entity", "", "Entity", false, false) + val entityType = EntityType(type) + typeMappings.register(entityType, queryTypeFactory.create(entityType)) + serializer.serialize(entityType, SimpleSerializerConfig.DEFAULT, JavaWriter(writer)) + Assert.assertTrue(writer.toString().contains("class QEntity : BeanPath<Entity> {")) + assertCompiles("QEntity", writer.toString()) + } + + @Test + fun correct_superclass() { + val type = SimpleType(TypeCategory.ENTITY, "java.util.Locale", "java.util", "Locale", false, false) + val entityType = EntityType(type) + typeMappings.register(entityType, queryTypeFactory.create(entityType)) + serializer.serialize(entityType, SimpleSerializerConfig.DEFAULT, JavaWriter(writer)) + Assert.assertTrue(writer.toString().contains("class QLocale : BeanPath<Locale> {")) + assertCompiles("QLocale", writer.toString()) + } + + @Test + fun primitive_array() { + val type = SimpleType(TypeCategory.ENTITY, "Entity", "", "Entity", false, false) + val entityType = EntityType(type) + entityType.addProperty(Property(entityType, "bytes", ClassType(ByteArray::class.java))) + typeMappings.register(entityType, queryTypeFactory.create(entityType)) + serializer.serialize(entityType, SimpleSerializerConfig.DEFAULT, JavaWriter(writer)) + Assert.assertTrue(writer.toString().contains("val bytes: SimplePath<ByteArray>")) + assertCompiles("QEntity", writer.toString()) + } + + @Test + fun include() { + val type = SimpleType(TypeCategory.ENTITY, "Entity", "", "Entity", false, false) + val entityType = EntityType(type) + entityType.addProperty(Property(entityType, "b", ClassType(TypeCategory.BOOLEAN, Boolean::class.java))) + entityType.addProperty(Property(entityType, "c", ClassType(TypeCategory.COMPARABLE, String::class.java))) + //entityType.addProperty(new Property(entityType, "cu", new ClassType(TypeCategory.CUSTOM, PropertyType.class))); + entityType.addProperty(Property(entityType, "d", ClassType(TypeCategory.DATE, Date::class.java))) + entityType.addProperty(Property(entityType, "e", ClassType(TypeCategory.ENUM, PropertyType::class.java))) + entityType.addProperty(Property(entityType, "dt", ClassType(TypeCategory.DATETIME, Date::class.java))) + entityType.addProperty(Property(entityType, "i", ClassType(TypeCategory.NUMERIC, Int::class.java))) + entityType.addProperty(Property(entityType, "s", ClassType(TypeCategory.STRING, String::class.java))) + entityType.addProperty(Property(entityType, "t", ClassType(TypeCategory.TIME, Time::class.java))) + val subType = EntityType(SimpleType(TypeCategory.ENTITY, "Entity2", "", "Entity2", false, false)) + subType.include(Supertype(type, entityType)) + typeMappings.register(entityType, queryTypeFactory.create(entityType)) + typeMappings.register(subType, queryTypeFactory.create(subType)) + serializer.serialize(subType, SimpleSerializerConfig.DEFAULT, JavaWriter(writer)) + assertCompiles("QEntity2", writer.toString()) + } + + @Test + fun superType() { + val superType = EntityType(SimpleType(TypeCategory.ENTITY, "Entity2", "", "Entity2", false, false)) + val type = SimpleType(TypeCategory.ENTITY, "Entity", "", "Entity", false, false) + val entityType = EntityType(type, setOf(Supertype(superType, superType))) + typeMappings.register(superType, queryTypeFactory.create(superType)) + typeMappings.register(entityType, queryTypeFactory.create(entityType)) + serializer.serialize(entityType, SimpleSerializerConfig.DEFAULT, JavaWriter(writer)) + Assert.assertTrue(writer.toString().contains("val _super: QEntity2 by lazy {\n QEntity2(this)\n }")) + //CompileUtils.assertCompiles("QEntity", writer.toString()); + } + + @Test + @Ignore + fun delegates() { + val type = SimpleType(TypeCategory.ENTITY, "Entity", "", "Entity", false, false) + val entityType = EntityType(type) + val delegate = Delegate(type, type, "test", emptyList(), Types.STRING) + entityType.addDelegate(delegate) + typeMappings.register(entityType, queryTypeFactory.create(entityType)) + serializer.serialize(entityType, SimpleSerializerConfig.DEFAULT, JavaWriter(writer)) + Assert.assertTrue(writer.toString().contains("return Entity.test(this);")) + assertCompiles("QEntity", writer.toString()) + } + + @Test + fun defaultGeneratedAnnotation() { + val type = SimpleType(TypeCategory.ENTITY, "Entity", "", "Entity", false, false) + val entityType = EntityType(type) + typeMappings.register(entityType, queryTypeFactory.create(entityType)) + serializer.serialize(entityType, SimpleSerializerConfig.DEFAULT, JavaWriter(writer)) + val generatedSource = writer.toString() + Assert.assertThat(generatedSource, Matchers.containsString("import $generatedAnnotationImport")) + Assert.assertThat(generatedSource, Matchers.containsString("@Generated(\"com.querydsl.kotlin.codegen.KotlinEmbeddableSerializer\")\npublic class")) + assertCompiles("QEntity", generatedSource) + } + + @Test + fun customGeneratedAnnotation() { + val type = SimpleType(TypeCategory.ENTITY, "Entity", "", "Entity", false, false) + val entityType = EntityType(type) + typeMappings.register(entityType, queryTypeFactory.create(entityType)) + KotlinEmbeddableSerializer(typeMappings, emptySet(), Generated::class.java).serialize(entityType, SimpleSerializerConfig.DEFAULT, JavaWriter(writer)) + val generatedSourceCode = writer.toString() + Assert.assertThat(generatedSourceCode, Matchers.containsString("@Generated(\"com.querydsl.kotlin.codegen.KotlinEmbeddableSerializer\")\npublic class")) + assertCompiles("QEntity", generatedSourceCode) + } +} \ No newline at end of file diff --git a/querydsl-kotlin-codegen/src/test/kotlin/com/querydsl/kotlin/codegen/EntitySerializerTest.kt b/querydsl-kotlin-codegen/src/test/kotlin/com/querydsl/kotlin/codegen/EntitySerializerTest.kt new file mode 100644 index 0000000000..127096799d --- /dev/null +++ b/querydsl-kotlin-codegen/src/test/kotlin/com/querydsl/kotlin/codegen/EntitySerializerTest.kt @@ -0,0 +1,204 @@ +/* + * Copyright 2021, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.kotlin.codegen + +import com.querydsl.codegen.Delegate +import com.querydsl.codegen.EntitySerializer +import com.querydsl.codegen.EntityType +import com.querydsl.codegen.GeneratedAnnotationResolver +import com.querydsl.codegen.Property +import com.querydsl.codegen.QueryTypeFactory +import com.querydsl.codegen.QueryTypeFactoryImpl +import com.querydsl.codegen.SimpleSerializerConfig +import com.querydsl.codegen.Supertype +import com.querydsl.codegen.TypeMappings +import com.querydsl.codegen.utils.JavaWriter +import com.querydsl.codegen.utils.model.ClassType +import com.querydsl.codegen.utils.model.SimpleType +import com.querydsl.codegen.utils.model.TypeCategory +import com.querydsl.codegen.utils.model.Types +import com.querydsl.core.annotations.Generated +import com.querydsl.core.annotations.PropertyType +import com.querydsl.kotlin.codegen.CompileUtils.assertCompiles +import org.junit.Assert +import org.junit.Ignore +import org.junit.Test +import java.io.StringWriter +import java.sql.Time +import java.util.* + +class EntitySerializerTest { + private var queryTypeFactory: QueryTypeFactory = QueryTypeFactoryImpl("Q", "", "") + private val typeMappings: TypeMappings = KotlinTypeMappings() + private val serializer: EntitySerializer = KotlinEntitySerializer(typeMappings, emptySet()) + private val writer = StringWriter() + + class Entity + + @Test + fun javadocs_for_innerClass() { + val entityType = EntityType(ClassType(Entity::class.java)) + typeMappings.register(entityType, queryTypeFactory.create(entityType)) + serializer.serialize(entityType, SimpleSerializerConfig.DEFAULT, JavaWriter(writer)) + Assert.assertTrue(writer.toString().contains("QEntitySerializerTest_Entity is a Querydsl query type for Entity")) + assertCompiles("QEntitySerializerTest_Entity", writer.toString()) + } + + @Test + fun different_package() { + queryTypeFactory = QueryTypeFactoryImpl("Q", "", ".gen") + val entityType = EntityType(ClassType(Entity::class.java)) + typeMappings.register(entityType, queryTypeFactory.create(entityType)) + serializer.serialize(entityType, SimpleSerializerConfig.DEFAULT, JavaWriter(writer)) + Assert.assertTrue(writer.toString().contains("class QEntitySerializerTest_Entity : EntityPathBase<EntitySerializerTest.Entity>")) + assertCompiles("QEntitySerializerTest_Entity", writer.toString()) + } + + @Test + fun no_package() { + val type = SimpleType(TypeCategory.ENTITY, "Entity", "", "Entity", false, false) + val entityType = EntityType(type) + typeMappings.register(entityType, queryTypeFactory.create(entityType)) + serializer.serialize(entityType, SimpleSerializerConfig.DEFAULT, JavaWriter(writer)) + Assert.assertTrue(writer.toString().contains("class QEntity : EntityPathBase<Entity> {")) + assertCompiles("QEntity", writer.toString()) + } + + @Test + fun original_category() { + val categoryToSuperClass: MutableMap<TypeCategory, String> = EnumMap(TypeCategory::class.java) + categoryToSuperClass[TypeCategory.COMPARABLE] = "ComparablePath<Entity>" + categoryToSuperClass[TypeCategory.ENUM] = "EnumPath<Entity>" + categoryToSuperClass[TypeCategory.DATE] = "DatePath<Entity>" + categoryToSuperClass[TypeCategory.DATETIME] = "DateTimePath<Entity>" + categoryToSuperClass[TypeCategory.TIME] = "TimePath<Entity>" + categoryToSuperClass[TypeCategory.NUMERIC] = "NumberPath<Entity>" + categoryToSuperClass[TypeCategory.STRING] = "StringPath" + categoryToSuperClass[TypeCategory.BOOLEAN] = "BooleanPath" + for (entry in categoryToSuperClass.entries) { + val type = SimpleType(entry.key, "Entity", "", "Entity", false, false) + val entityType = EntityType(type) + typeMappings.register(entityType, queryTypeFactory.create(entityType)) + serializer.serialize(entityType, SimpleSerializerConfig.DEFAULT, JavaWriter(writer)) + Assert.assertTrue(entry.toString(), writer.toString().contains("class QEntity : " + entry.value + " {")) + } + } + + @Test + fun correct_superclass() { + val type = SimpleType(TypeCategory.ENTITY, "java.util.Locale", "java.util", "Locale", false, false) + val entityType = EntityType(type) + typeMappings.register(entityType, queryTypeFactory.create(entityType)) + serializer.serialize(entityType, SimpleSerializerConfig.DEFAULT, JavaWriter(writer)) + Assert.assertTrue(writer.toString().contains("class QLocale : EntityPathBase<Locale> {")) + assertCompiles("QLocale", writer.toString()) + } + + @Test + fun primitive_array() { + val type = SimpleType(TypeCategory.ENTITY, "Entity", "", "Entity", false, false) + val entityType = EntityType(type) + entityType.addProperty(Property(entityType, "bytes", ClassType(ByteArray::class.java))) + typeMappings.register(entityType, queryTypeFactory.create(entityType)) + serializer.serialize(entityType, SimpleSerializerConfig.DEFAULT, JavaWriter(writer)) + Assert.assertTrue(writer.toString().contains("val bytes: SimplePath<ByteArray>")) + assertCompiles("QEntity", writer.toString()) + } + + @Test + fun include() { + val type = SimpleType(TypeCategory.ENTITY, "Entity", "", "Entity", false, false) + val entityType = EntityType(type) + entityType.addProperty(Property(entityType, "b", ClassType(TypeCategory.BOOLEAN, Boolean::class.java))) + entityType.addProperty(Property(entityType, "c", ClassType(TypeCategory.COMPARABLE, String::class.java))) + //entityType.addProperty(new Property(entityType, "cu", new ClassType(TypeCategory.CUSTOM, PropertyType.class))); + entityType.addProperty(Property(entityType, "d", ClassType(TypeCategory.DATE, Date::class.java))) + entityType.addProperty(Property(entityType, "e", ClassType(TypeCategory.ENUM, PropertyType::class.java))) + entityType.addProperty(Property(entityType, "dt", ClassType(TypeCategory.DATETIME, Date::class.java))) + entityType.addProperty(Property(entityType, "i", ClassType(TypeCategory.NUMERIC, Int::class.java))) + entityType.addProperty(Property(entityType, "s", ClassType(TypeCategory.STRING, String::class.java))) + entityType.addProperty(Property(entityType, "t", ClassType(TypeCategory.TIME, Time::class.java))) + val subType = EntityType(SimpleType(TypeCategory.ENTITY, "Entity2", "", "Entity2", false, false)) + subType.include(Supertype(type, entityType)) + typeMappings.register(subType, queryTypeFactory.create(subType)) + serializer.serialize(subType, SimpleSerializerConfig.DEFAULT, JavaWriter(writer)) + assertCompiles("QEntity2", writer.toString()) + } + + @Test + fun properties() { + val type = SimpleType(TypeCategory.ENTITY, "Entity", "", "Entity", false, false) + val entityType = EntityType(type) + entityType.addProperty(Property(entityType, "b", ClassType(TypeCategory.BOOLEAN, Boolean::class.java))) + entityType.addProperty(Property(entityType, "c", ClassType(TypeCategory.COMPARABLE, String::class.java))) + //entityType.addProperty(new Property(entityType, "cu", new ClassType(TypeCategory.CUSTOM, PropertyType.class))); + entityType.addProperty(Property(entityType, "d", ClassType(TypeCategory.DATE, Date::class.java))) + entityType.addProperty(Property(entityType, "e", ClassType(TypeCategory.ENUM, PropertyType::class.java))) + entityType.addProperty(Property(entityType, "dt", ClassType(TypeCategory.DATETIME, Date::class.java))) + entityType.addProperty(Property(entityType, "i", ClassType(TypeCategory.NUMERIC, Int::class.java))) + entityType.addProperty(Property(entityType, "s", ClassType(TypeCategory.STRING, String::class.java))) + entityType.addProperty(Property(entityType, "t", ClassType(TypeCategory.TIME, Time::class.java))) + typeMappings.register(entityType, queryTypeFactory.create(entityType)) + serializer.serialize(entityType, SimpleSerializerConfig.DEFAULT, JavaWriter(writer)) + assertCompiles("QEntity", writer.toString()) + } + + @Test + fun superType() { + val superType = EntityType(SimpleType(TypeCategory.ENTITY, "Entity2", "", "Entity2", false, false)) + val type = SimpleType(TypeCategory.ENTITY, "Entity", "", "Entity", false, false) + val entityType = EntityType(type, setOf(Supertype(superType, superType))) + typeMappings.register(superType, queryTypeFactory.create(superType)) + typeMappings.register(entityType, queryTypeFactory.create(entityType)) + serializer.serialize(entityType, SimpleSerializerConfig.DEFAULT, JavaWriter(writer)) + Assert.assertTrue(writer.toString().contains("val _super: QEntity2 by lazy {\n QEntity2(this)\n }")) + //CompileUtils.assertCompiles("QEntity", writer.toString()); + } + + + @Test + @Ignore //TODO: Implement delegates. Or document that extensions need to be used instead? + fun delegates() { + val type = SimpleType(TypeCategory.ENTITY, "Entity", "", "Entity", false, false) + val entityType = EntityType(type) + val delegate = Delegate(type, type, "test", emptyList(), Types.STRING) + entityType.addDelegate(delegate) + typeMappings.register(entityType, queryTypeFactory.create(entityType)) + serializer.serialize(entityType, SimpleSerializerConfig.DEFAULT, JavaWriter(writer)) + Assert.assertTrue(writer.toString().contains("return Entity.test(this)")) + assertCompiles("QEntity", writer.toString()) + } + + @Test + fun defaultGeneratedAnnotation() { + val entityType = EntityType(ClassType(Entity::class.java)) + typeMappings.register(entityType, queryTypeFactory.create(entityType)) + serializer.serialize(entityType, SimpleSerializerConfig.DEFAULT, JavaWriter(writer)) + val generatedSourceCode = writer.toString() + Assert.assertTrue(generatedSourceCode.contains("import $generatedAnnotationImport")) + Assert.assertTrue(generatedSourceCode.contains("@Generated(\"com.querydsl.kotlin.codegen.KotlinEntitySerializer\")\npublic class")) + assertCompiles("QEntitySerializerTest_Entity", generatedSourceCode) + } + + @Test + fun customGeneratedAnnotation() { + val entityType = EntityType(ClassType(Entity::class.java)) + typeMappings.register(entityType, queryTypeFactory.create(entityType)) + KotlinEntitySerializer(typeMappings, emptySet(), Generated::class.java).serialize(entityType, SimpleSerializerConfig.DEFAULT, JavaWriter(writer)) + val generatedSourceCode = writer.toString() + Assert.assertTrue(generatedSourceCode.contains("import " + Generated::class.java.name)) + Assert.assertTrue(generatedSourceCode.contains("@${Generated::class.java.simpleName}(\"com.querydsl.kotlin.codegen.KotlinEntitySerializer\")\npublic class")) + assertCompiles("QEntitySerializerTest_Entity", generatedSourceCode) + } +} \ No newline at end of file diff --git a/querydsl-kotlin-codegen/src/test/kotlin/com/querydsl/kotlin/codegen/ProjectionSerializerTest.kt b/querydsl-kotlin-codegen/src/test/kotlin/com/querydsl/kotlin/codegen/ProjectionSerializerTest.kt new file mode 100644 index 0000000000..6f313189f6 --- /dev/null +++ b/querydsl-kotlin-codegen/src/test/kotlin/com/querydsl/kotlin/codegen/ProjectionSerializerTest.kt @@ -0,0 +1,77 @@ +/* + * Copyright 2021, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.kotlin.codegen + +import com.querydsl.codegen.EntityType +import com.querydsl.codegen.GeneratedAnnotationResolver +import com.querydsl.codegen.ProjectionSerializer +import com.querydsl.codegen.SimpleSerializerConfig +import com.querydsl.codegen.utils.JavaWriter +import com.querydsl.codegen.utils.model.Constructor +import com.querydsl.codegen.utils.model.Parameter +import com.querydsl.codegen.utils.model.SimpleType +import com.querydsl.codegen.utils.model.Type +import com.querydsl.codegen.utils.model.TypeCategory +import com.querydsl.codegen.utils.model.Types +import com.querydsl.core.annotations.Generated +import org.hamcrest.Matchers +import org.junit.Assert +import org.junit.Test +import java.io.StringWriter +import java.io.Writer +import java.util.* + +class ProjectionSerializerTest { + @Test + fun constructors() { + val typeModel: Type = SimpleType(TypeCategory.ENTITY, "com.querydsl.DomainClass", "com.querydsl", "DomainClass", false, false) + val type = EntityType(typeModel) + + // constructor + val firstName = Parameter("firstName", Types.STRING) + val lastName = Parameter("lastName", Types.STRING) + val age = Parameter("age", Types.INTEGER) + type.addConstructor(Constructor(Arrays.asList(firstName, lastName, age))) + val writer: Writer = StringWriter() + val serializer: ProjectionSerializer = KotlinProjectionSerializer(KotlinTypeMappings()) + serializer.serialize(type, SimpleSerializerConfig.DEFAULT, JavaWriter(writer)) + Assert.assertTrue(writer.toString().contains("firstName: Expression<String>")) + Assert.assertTrue(writer.toString().contains("lastName: Expression<String>")) + Assert.assertTrue(writer.toString().contains("age: Expression<Int>")) + } + + @Test + fun defaultGeneratedAnnotation() { + val typeModel: Type = SimpleType(TypeCategory.ENTITY, "com.querydsl.DomainClass", "com.querydsl", "DomainClass", false, false) + val type = EntityType(typeModel) + val writer: Writer = StringWriter() + val serializer: ProjectionSerializer = KotlinProjectionSerializer(KotlinTypeMappings()) + serializer.serialize(type, SimpleSerializerConfig.DEFAULT, JavaWriter(writer)) + val generatedSource = writer.toString() + Assert.assertThat(generatedSource, Matchers.containsString("import $generatedAnnotationImport")) + Assert.assertThat(generatedSource, Matchers.containsString("@Generated(\"com.querydsl.kotlin.codegen.KotlinProjectionSerializer\")\npublic class")) + } + + @Test + fun customGeneratedAnnotation() { + val typeModel: Type = SimpleType(TypeCategory.ENTITY, "com.querydsl.DomainClass", "com.querydsl", "DomainClass", false, false) + val type = EntityType(typeModel) + val writer: Writer = StringWriter() + val serializer: ProjectionSerializer = KotlinProjectionSerializer(KotlinTypeMappings(), Generated::class.java) + serializer.serialize(type, SimpleSerializerConfig.DEFAULT, JavaWriter(writer)) + val generatedSource = writer.toString() + Assert.assertThat(generatedSource, Matchers.containsString("import com.querydsl.core.annotations.Generated")) + Assert.assertThat(generatedSource, Matchers.containsString("@Generated(\"com.querydsl.kotlin.codegen.KotlinProjectionSerializer\")\npublic class")) + } +} \ No newline at end of file diff --git a/querydsl-kotlin-codegen/src/test/kotlin/com/querydsl/kotlin/codegen/utils.kt b/querydsl-kotlin-codegen/src/test/kotlin/com/querydsl/kotlin/codegen/utils.kt new file mode 100644 index 0000000000..4bf71bb64d --- /dev/null +++ b/querydsl-kotlin-codegen/src/test/kotlin/com/querydsl/kotlin/codegen/utils.kt @@ -0,0 +1,5 @@ +package com.querydsl.kotlin.codegen + +import com.querydsl.codegen.GeneratedAnnotationResolver + +val generatedAnnotationImport = GeneratedAnnotationResolver.resolveDefault().name.replace("annotation", "`annotation`") \ No newline at end of file diff --git a/querydsl-kotlin/pom.xml b/querydsl-kotlin/pom.xml new file mode 100644 index 0000000000..55fc0090ea --- /dev/null +++ b/querydsl-kotlin/pom.xml @@ -0,0 +1,133 @@ +<?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"> + <parent> + <artifactId>querydsl-root</artifactId> + <groupId>com.querydsl</groupId> + <version>5.1.0</version> + </parent> + <modelVersion>4.0.0</modelVersion> + + <artifactId>querydsl-kotlin</artifactId> + <name>Querydsl - Kotlin extensions</name> + + <dependencies> + <dependency> + <groupId>com.querydsl</groupId> + <artifactId>querydsl-core</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>com.querydsl</groupId> + <artifactId>querydsl-core</artifactId> + <version>${project.version}</version> + <scope>test</scope> + <type>test-jar</type> + </dependency> + <dependency> + <groupId>org.jetbrains.kotlin</groupId> + <artifactId>kotlin-stdlib-jdk8</artifactId> + </dependency> + <dependency> + <groupId>org.jetbrains.kotlin</groupId> + <artifactId>kotlin-test-junit</artifactId> + <scope>test</scope> + </dependency> + </dependencies> + + + <build> + <sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory> + <testSourceDirectory>${project.basedir}/src/test/kotlin</testSourceDirectory> + <plugins> + <plugin> + <groupId>org.jetbrains.kotlin</groupId> + <artifactId>kotlin-maven-plugin</artifactId> + <version>${kotlin.version}</version> + <configuration> + <compilerPlugins> + <plugin>jpa</plugin> + </compilerPlugins> + <annotationProcessorPaths> + <annotationProcessorPath> + <groupId>com.querydsl</groupId> + <artifactId>querydsl-apt</artifactId> + <version>${project.version}</version> + <classifier>general</classifier> + </annotationProcessorPath> + </annotationProcessorPaths> + </configuration> + <dependencies> + <dependency> + <groupId>org.jetbrains.kotlin</groupId> + <artifactId>kotlin-maven-allopen</artifactId> + <version>${kotlin.version}</version> + </dependency> + <dependency> + <groupId>org.jetbrains.kotlin</groupId> + <artifactId>kotlin-maven-noarg</artifactId> + <version>${kotlin.version}</version> + </dependency> + </dependencies> + <executions> + <execution> + <id>kapt</id> + <goals> + <goal>kapt</goal> + </goals> + <configuration> + <sourceDirs> + <sourceDir>src/main/kotlin</sourceDir> + <sourceDir>src/main/java</sourceDir> + </sourceDirs> + </configuration> + </execution> + <execution> + <id>compile</id> + <phase>process-sources</phase> + <goals> + <goal>compile</goal> + </goals> + <configuration> + <sourceDirs> + <sourceDir>src/main/java</sourceDir> + <sourceDir>src/main/kotlin</sourceDir> + </sourceDirs> + </configuration> + </execution> + <execution> + <id>test-kapt</id> + <goals> + <goal>test-kapt</goal> + </goals> + <configuration> + <sourceDirs> + <sourceDir>src/test/kotlin</sourceDir> + <sourceDir>src/test/java</sourceDir> + </sourceDirs> + </configuration> + </execution> + <execution> + <id>test-compile</id> + <phase>process-test-sources</phase> + <goals> + <goal>test-compile</goal> + </goals> + <configuration> + <sourceDirs> + <sourceDir>src/test/java</sourceDir> + <sourceDir>src/test/kotlin</sourceDir> + <sourceDir>target/generated-sources/kapt/test</sourceDir> + </sourceDirs> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.jetbrains.dokka</groupId> + <artifactId>dokka-maven-plugin</artifactId> + </plugin> + </plugins> + </build> +</project> \ No newline at end of file diff --git a/querydsl-kotlin/src/main/kotlin/com/querydsl/kotlin/ExpressionExtensions.kt b/querydsl-kotlin/src/main/kotlin/com/querydsl/kotlin/ExpressionExtensions.kt new file mode 100644 index 0000000000..f54daa0a73 --- /dev/null +++ b/querydsl-kotlin/src/main/kotlin/com/querydsl/kotlin/ExpressionExtensions.kt @@ -0,0 +1,227 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ + +package com.querydsl.kotlin + +import com.querydsl.core.types.Expression +import com.querydsl.core.types.Ops +import com.querydsl.core.types.dsl.* +import com.querydsl.core.types.dsl.Expressions.constant + +/** + * Get a negation of this boolean expression + * + * @return !this + */ +operator fun Expression<Boolean>.not() : BooleanExpression { + return Expressions.booleanOperation(Ops.NOT, this) +} + +/** + * Get an intersection of this and the given expression + * + * @param predicate right hand side of the union + * @return this and right + */ +infix fun Expression<Boolean>.and(predicate: Expression<Boolean>) : BooleanExpression { + return Expressions.booleanOperation(Ops.AND, this, predicate); +} + +/** + * Get a union of this and the given expression + * + * @param predicate right hand side of the union + * @return this || right + */ +infix fun Expression<Boolean>.or(predicate: Expression<Boolean>) : BooleanExpression { + return Expressions.booleanOperation(Ops.OR, this, predicate); +} + +/** + * Get a union of this and the given expression + * + * @param predicate right hand side of the union + * @return this || right + */ +infix fun Expression<Boolean>.xor(predicate: Expression<Boolean>) : BooleanExpression { + return Expressions.booleanOperation(Ops.XOR, this, predicate); +} + +/** + * Get a union of this and the given expression + * + * @param predicate right hand side of the union + * @return this || right + */ +infix fun Expression<Boolean>.xnor(predicate: Expression<Boolean>) : BooleanExpression { + return Expressions.booleanOperation(Ops.XNOR, this, predicate); +} + +/** + * Get the negation of this expression + * + * @return this * -1 + */ +operator fun <T> Expression<T>.unaryMinus() : NumberExpression<T> where T : Comparable<*>, T : Number { + return Expressions.numberOperation(type, Ops.NEGATE, this); +} + +/** + * Get the sum of this and right + * + * @return this + right + */ +operator fun <T, V> Expression<T>.plus(other : Expression<V>) : NumberExpression<T> where T : Comparable<*>, T : Number, V : Number { + return Expressions.numberOperation(type, Ops.ADD, this, other); +} + +/** + * Get the difference of this and right + * + * @return this - right + */ +operator fun <T, V> Expression<T>.minus(other : Expression<V>) : NumberExpression<T> where T : Comparable<*>, T : Number, V : Number { + return Expressions.numberOperation(type, Ops.SUB, this, other); +} + +/** + * Get the result of the operation this * right + * + * @return this * right + */ +operator fun <T, V> Expression<T>.times(other : Expression<V>) : NumberExpression<T> where T : Comparable<*>, T : Number, V : Number { + return Expressions.numberOperation(type, Ops.MULT, this, other); +} + +/** + * Get the result of the operation this / right + * + * @return this / right + */ +operator fun <T, V> Expression<T>.div(other : Expression<V>) : NumberExpression<T> where T : Comparable<*>, T : Number, V : Number { + return Expressions.numberOperation(type, Ops.DIV, this, other); +} + + +/** + * Get the result of the operation this / right + * + * @return this / right + */ +operator fun <T, V> NumberExpression<T>.div(other : Expression<V>) : NumberExpression<T> where T : Comparable<*>, T : Number, V : Number, V : Comparable<*> { + return this.divide(other); +} + +/** + * Get the result of the operation this % right + * + * @return this % right + */ +operator fun <T, V> Expression<T>.rem(other : Expression<V>) : NumberExpression<T> where T : Comparable<*>, T : Number, V : Number { + return Expressions.numberOperation(type, Ops.MOD, this, other); +} + +/** + * Get the sum of this and right + * + * @return this + right + */ +operator fun <T, V> Expression<T>.plus(other : V) : NumberExpression<T> where T : Comparable<*>, T : Number, V : Number { + return Expressions.numberOperation(type, Ops.ADD, this, constant(other)); +} + +/** + * Get the difference of this and right + * + * @return this - right + */ +operator fun <T, V> Expression<T>.minus(other : V) : NumberExpression<T> where T : Comparable<*>, T : Number, V : Number { + return Expressions.numberOperation(type, Ops.SUB, this, constant(other)); +} + +/** + * Get the result of the operation this * right + * + * @return this * right + */ +operator fun <T, V> Expression<T>.times(other : V) : NumberExpression<T> where T : Comparable<*>, T : Number, V : Number { + return Expressions.numberOperation(type, Ops.MULT, this, constant(other)); +} + +/** + * Get the result of the operation this / right + * + * @return this / right + */ +operator fun <T, V> Expression<T>.div(other : V) : NumberExpression<T> where T : Comparable<*>, T : Number, V : Number { + return Expressions.numberOperation(type, Ops.DIV, this, constant(other)); +} + +/** + * Get the result of the operation this / right + * + * @return this / right + */ +operator fun <T, V> NumberExpression<T>.div(other : V) : NumberExpression<T> where T : Comparable<*>, T : Number, V : Number, V : Comparable<*> { + return this.divide(other); +} + +/** + * Get the result of the operation this % right + * + * @return this % right + */ +operator fun <T, V> Expression<T>.rem(other : V) : NumberExpression<T> where T : Comparable<*>, T : Number, V : Number { + return Expressions.numberOperation(type, Ops.MOD, this, constant(other)); +} + +/** + * Get the concatenation of this and str + * + * @return this + str + */ +operator fun Expression<String>.plus(x : Expression<String>) : StringExpression { + return Expressions.stringOperation(Ops.CONCAT, this, x); +} + +/** + * Get the concatenation of this and str + * + * @return this + str + */ +operator fun Expression<String>.plus(x : String) : StringExpression { + return Expressions.stringOperation(Ops.CONCAT, this, constant(x)); +} + +/** + * Get the character at the given index + * + * @param x + * @return this.charAt(x) + * @see java.lang.String#charAt(int) + */ +operator fun Expression<String>.get(x : Expression<Int>) : SimpleExpression<Character> { + return Expressions.simpleOperation(Character::class.java, Ops.CHAR_AT, this, x) +} + +/** + * Get the character at the given index + * + * @param x + * @return this.charAt(x) + * @see java.lang.String#charAt(int) + */ +operator fun Expression<String>.get(x : Int) : SimpleExpression<Character> { + return Expressions.simpleOperation(Character::class.java, Ops.CHAR_AT, this, constant(x)) +} diff --git a/querydsl-kotlin/src/test/kotlin/com/querydsl/kotlin/CollectionTest.kt b/querydsl-kotlin/src/test/kotlin/com/querydsl/kotlin/CollectionTest.kt new file mode 100644 index 0000000000..ece4ab4de5 --- /dev/null +++ b/querydsl-kotlin/src/test/kotlin/com/querydsl/kotlin/CollectionTest.kt @@ -0,0 +1,107 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ + +package com.querydsl.kotlin + +import com.querydsl.core.types.dsl.* +import org.junit.Test +import java.math.BigDecimal +import kotlin.test.assertEquals + +class CollectionTest { + + @Test + fun basicArithmetic() { + val someBigDecimal = Expressions.numberPath(BigDecimal::class.java, "a") + val someDouble = Expressions.numberPath(Double::class.java, "b"); + val someInteger = Expressions.numberPath(Int::class.java, "c") + val someOtherInteger = Expressions.numberPath(Int::class.java, "d") + + val multiplyResult: NumberExpression<BigDecimal> = someBigDecimal * someDouble / someInteger + val expected: NumberExpression<BigDecimal> = someBigDecimal.multiply(someDouble).divide(someInteger) + assertEquals(expected, multiplyResult) + + val sumResult : NumberExpression<BigDecimal> = someBigDecimal + someDouble - someInteger; + assertEquals(someBigDecimal.add(someDouble).subtract(someInteger), sumResult) + + val moduloResult = someInteger % someOtherInteger + assertEquals(someInteger.mod(someOtherInteger), moduloResult) + } + + + @Test + fun basicArithmeticWithConstants() { + val someBigDecimal = Expressions.numberPath(BigDecimal::class.java, "a") + val someInteger = Expressions.numberPath(Int::class.java, "c") + + val constantArithmeticResult = (((someBigDecimal * 2) - 1) / 4) + 1 + val expectedConstantArithmeticResult = someBigDecimal.multiply(2).subtract(1).divide(4).add(1) + assertEquals(expectedConstantArithmeticResult, constantArithmeticResult) + + val moduloResult = someInteger % 5 + assertEquals(someInteger.mod(5), moduloResult) + } + + @Test + fun booleanOperators() { + val someBoolean = Expressions.booleanPath("a"); + val someOtherBoolean = Expressions.booleanPath("b"); + + val booleanResult = (!someBoolean) or (someBoolean and someOtherBoolean) + assertEquals(someBoolean.not().or(someBoolean.and(someOtherBoolean)), booleanResult) + } + + @Test + fun stringOperators() { + val someString = Expressions.stringPath("a"); + val someOtherString = Expressions.stringPath("b"); + val someIndex = Expressions.numberPath(Int::class.java, "idx") + + val firstChar = someString[0] + assertEquals<SimpleExpression<out Any>?>(someString.charAt(0), firstChar) + + val firstCharExpr = someString[someIndex]; + assertEquals<SimpleExpression<out Any>?>(someString.charAt(someIndex), firstCharExpr) + + val stringConcat = someString + someOtherString + "c" + assertEquals(someString.concat(someOtherString).concat("c"), stringConcat) + } + + @Test + fun listPathOperators() { + val listPath = Expressions.listPath(String::class.java, StringPath::class.java, Expressions.stringPath("a").metadata); + + val someIndex = Expressions.numberPath(Int::class.java, "idx") + + val firstValue = listPath[someIndex] + assertEquals(listPath.get(someIndex), firstValue) + + val secondValue = listPath[1] + assertEquals(listPath.get(1), secondValue) + } + + @Test + fun mapPathOperators() { + val mapPath = Expressions.mapPath(String::class.java, String::class.java, StringPath::class.java, Expressions.stringPath("a").metadata); + + val someKey = Expressions.stringPath("idx") + + val firstValue = mapPath[someKey] + assertEquals(mapPath.get(someKey), firstValue) + + val secondValue = mapPath["second"] + assertEquals(mapPath.get("second"), secondValue) + } + +} \ No newline at end of file diff --git a/querydsl-lucene3/README.md b/querydsl-lucene3/README.md index 1aca60249b..cbc694c4d6 100644 --- a/querydsl-lucene3/README.md +++ b/querydsl-lucene3/README.md @@ -5,36 +5,33 @@ The Lucene module provides integration with the Lucene 3 indexing library. **Maven integration** Add the following dependencies to your Maven project : - - <dependency> - <groupId>com.mysema.querydsl</groupId> - <artifactId>querydsl-lucene3</artifactId> - <version>${querydsl.version}</version> - </dependency> - - <dependency> - <groupId>org.slf4j</groupId> - <artifactId>slf4j-log4j12</artifactId> - <version>1.6.1</version> - </dependency> +```XML +<dependency> + <groupId>com.querydsl</groupId> + <artifactId>querydsl-lucene3</artifactId> + <version>${querydsl.version}</version> +</dependency> +``` **Creating the query types** With fields year and title a manually created query type could look something like this: - - public class QDocument extends EntityPathBase<Document>{ - private static final long serialVersionUID = -4872833626508344081L; - - public QDocument(String var) { - super(Document.class, PathMetadataFactory.forVariable(var)); - } - - public final StringPath year = createString("year"); - - public final StringPath title = createString("title"); + +```JAVA +public class QDocument extends EntityPathBase<Document>{ + private static final long serialVersionUID = -4872833626508344081L; + + public QDocument(String var) { + super(Document.class, PathMetadataFactory.forVariable(var)); } + public final StringPath year = createString("year"); + + public final StringPath title = createString("title"); +} +``` + QDocument represents a Lucene document with the fields year and title. Code generation is not available for Lucene, since no schema data is available. @@ -42,17 +39,21 @@ Code generation is not available for Lucene, since no schema data is available. **Querying** Querying with Querydsl Lucene is as simple as this: - - QDocument doc = new QDocument("doc"); - - IndexSearcher searcher = new IndexSearher(index); - LuceneQuery query = new LuceneQuery(true, searcher); - List<Document> documents = query - .where(doc.year.between("1800", "2000").and(doc.title.startsWith("Huckle")) - .list(); + +```JAVA +QDocument doc = new QDocument("doc"); + +IndexSearcher searcher = new IndexSearcher(index); +LuceneQuery query = new LuceneQuery(true, searcher); +List<Document> documents = query + .where(doc.year.between("1800", "2000").and(doc.title.startsWith("Huckle")) + .fetch(); + ``` which is transformed into the following Lucene query : - - +year:[1800 TO 2000] +title:huckle* -For more information on the Querydsl Lucene module visit the reference documentation http://www.querydsl.com/static/querydsl/latest/reference/html/ch02s04.html +``` ++year:[1800 TO 2000] +title:huckle* +``` + +For more information on the Querydsl Lucene module visit the reference documentation http://www.querydsl.com/static/querydsl/latest/reference/html/ch02s05.html diff --git a/querydsl-lucene3/pom.xml b/querydsl-lucene3/pom.xml index 491b21e846..735dca673e 100644 --- a/querydsl-lucene3/pom.xml +++ b/querydsl-lucene3/pom.xml @@ -1,15 +1,15 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0" encoding="UTF-8"?> <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <modelVersion>4.0.0</modelVersion> <parent> - <groupId>com.mysema.querydsl</groupId> + <groupId>com.querydsl</groupId> <artifactId>querydsl-root</artifactId> - <version>3.4.1.BUILD-SNAPSHOT</version> - <relativePath>../querydsl-root/pom.xml</relativePath> + <version>5.1.0</version> + <relativePath>../pom.xml</relativePath> </parent> - <groupId>com.mysema.querydsl</groupId> + <groupId>com.querydsl</groupId> <artifactId>querydsl-lucene3</artifactId> <name>Querydsl - Lucene 3 support</name> <description>Lucene support for Querydsl</description> @@ -24,9 +24,18 @@ <properties> <lucene.version>3.6.2</lucene.version> + <osgi.import.package> + org.apache.lucene.*;version="[3.6,4)", + ${osgi.import.package.root} + </osgi.import.package> </properties> - <dependencies> + <dependencies> + <dependency> + <groupId>org.jetbrains</groupId> + <artifactId>annotations</artifactId> + <scope>provided</scope> + </dependency> <dependency> <groupId>org.apache.lucene</groupId> <artifactId>lucene-core</artifactId> @@ -40,23 +49,20 @@ <scope>provided</scope> </dependency> <dependency> - <groupId>com.mysema.querydsl</groupId> + <groupId>com.querydsl</groupId> <artifactId>querydsl-core</artifactId> <version>${project.version}</version> </dependency> + <!-- test --> <dependency> - <groupId>org.slf4j</groupId> - <artifactId>slf4j-api</artifactId> + <groupId>cglib</groupId> + <artifactId>cglib</artifactId> + <version>${cglib.version}</version> + <scope>test</scope> </dependency> <dependency> - <groupId>org.slf4j</groupId> - <artifactId>slf4j-log4j12</artifactId> - </dependency> - - <!-- test --> - <dependency> - <groupId>com.mysema.querydsl</groupId> + <groupId>com.querydsl</groupId> <artifactId>querydsl-core</artifactId> <version>${project.version}</version> <scope>test</scope> @@ -66,12 +72,12 @@ <dependency> <groupId>joda-time</groupId> <artifactId>joda-time</artifactId> - <version>1.6</version> + <version>${jodatime.version}</version> <scope>test</scope> </dependency> <dependency> - <groupId>com.mysema.querydsl</groupId> + <groupId>com.querydsl</groupId> <artifactId>querydsl-apt</artifactId> <version>${project.version}</version> </dependency> @@ -80,8 +86,20 @@ <build> <plugins> <plugin> - <groupId>com.springsource.bundlor</groupId> - <artifactId>com.springsource.bundlor.maven</artifactId> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-jar-plugin</artifactId> + <configuration> + <archive> + <manifestEntries> + <Automatic-Module-Name>com.querydsl.lucene3</Automatic-Module-Name> + </manifestEntries> + </archive> + </configuration> + </plugin> + + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> </plugin> <plugin> @@ -95,7 +113,7 @@ </goals> <configuration> <outputDirectory>target/generated-test-sources/java</outputDirectory> - <processor>com.mysema.query.apt.QuerydslAnnotationProcessor</processor> + <processor>com.querydsl.apt.QuerydslAnnotationProcessor</processor> <showWarnings>true</showWarnings> </configuration> </execution> @@ -103,4 +121,43 @@ </plugin> </plugins> </build> -</project> + + <profiles> + <profile> + <id>java-21</id> + <activation> + <jdk>[21,)</jdk> + </activation> + <dependencies> + <dependency> + <groupId>cglib</groupId> + <artifactId>cglib</artifactId> + <version>${cglib.version}</version> + <scope>test</scope> + <exclusions> + <exclusion> + <groupId>org.ow2.asm</groupId> + <artifactId>asm</artifactId> + </exclusion> + <exclusion> + <groupId>org.ow2.asm</groupId> + <artifactId>asm-commons</artifactId> + </exclusion> + </exclusions> + </dependency> + <dependency> + <groupId>org.ow2.asm</groupId> + <artifactId>asm</artifactId> + <version>${asm.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.ow2.asm</groupId> + <artifactId>asm-commons</artifactId> + <version>${asm.version}</version> + <scope>test</scope> + </dependency> + </dependencies> + </profile> + </profiles> +</project> diff --git a/querydsl-lucene3/src/main/java/com/mysema/query/lucene/AbstractLuceneQuery.java b/querydsl-lucene3/src/main/java/com/mysema/query/lucene/AbstractLuceneQuery.java deleted file mode 100644 index 2817874324..0000000000 --- a/querydsl-lucene3/src/main/java/com/mysema/query/lucene/AbstractLuceneQuery.java +++ /dev/null @@ -1,376 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.lucene; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import javax.annotation.Nullable; - -import org.apache.lucene.document.Document; -import org.apache.lucene.document.FieldSelector; -import org.apache.lucene.document.MapFieldSelector; -import org.apache.lucene.search.ChainedFilter; -import org.apache.lucene.search.DuplicateFilter; -import org.apache.lucene.search.Filter; -import org.apache.lucene.search.IndexSearcher; -import org.apache.lucene.search.MatchAllDocsQuery; -import org.apache.lucene.search.Query; -import org.apache.lucene.search.QueryWrapperFilter; -import org.apache.lucene.search.ScoreDoc; -import org.apache.lucene.search.Sort; - -import com.google.common.base.Function; -import com.google.common.collect.ImmutableList; -import com.mysema.commons.lang.CloseableIterator; -import com.mysema.commons.lang.EmptyCloseableIterator; -import com.mysema.commons.lang.IteratorAdapter; -import com.mysema.query.DefaultQueryMetadata; -import com.mysema.query.NonUniqueResultException; -import com.mysema.query.QueryException; -import com.mysema.query.QueryMetadata; -import com.mysema.query.QueryModifiers; -import com.mysema.query.SearchResults; -import com.mysema.query.SimpleProjectable; -import com.mysema.query.SimpleQuery; -import com.mysema.query.support.QueryMixin; -import com.mysema.query.types.OrderSpecifier; -import com.mysema.query.types.ParamExpression; -import com.mysema.query.types.Path; -import com.mysema.query.types.Predicate; - -/** - * AbstractLuceneQuery is an abstract super class for Lucene query implementations - * - * @author tiwe - * - * @param <T> projection type - * @param <Q> concrete subtype of query - */ -public abstract class AbstractLuceneQuery<T,Q extends AbstractLuceneQuery<T,Q>> implements SimpleQuery<Q>, -SimpleProjectable<T> { - - private final QueryMixin<Q> queryMixin; - - private final IndexSearcher searcher; - - private final LuceneSerializer serializer; - - private final Function<Document, T> transformer; - - @Nullable - private FieldSelector fieldSelector; - - private List<Filter> filters = ImmutableList.of(); - - @Nullable - private Filter _filter; - - @Nullable - private Sort querySort; - - @SuppressWarnings("unchecked") - public AbstractLuceneQuery(LuceneSerializer serializer, IndexSearcher searcher, - Function<Document, T> transformer) { - queryMixin = new QueryMixin<Q>((Q) this, new DefaultQueryMetadata().noValidate()); - this.serializer = serializer; - this.searcher = searcher; - this.transformer = transformer; - } - - public AbstractLuceneQuery(IndexSearcher searcher, Function<Document, T> transformer) { - this(LuceneSerializer.DEFAULT, searcher, transformer); - } - - @Override - public boolean exists() { - return innerCount() > 0; - } - - @Override - public boolean notExists() { - return innerCount() == 0; - } - - private long innerCount() { - try { - final int maxDoc = searcher.maxDoc(); - if (maxDoc == 0) { - return 0; - } - return searcher.search(createQuery(), getFilter(), maxDoc).totalHits; - } catch (IOException e) { - throw new QueryException(e); - } catch (IllegalArgumentException e) { - throw new QueryException(e); - } - } - - @Override - public long count() { - return innerCount(); - } - - protected Query createQuery() { - if (queryMixin.getMetadata().getWhere() == null) { - return new MatchAllDocsQuery(); - } - return serializer.toQuery(queryMixin.getMetadata().getWhere(), queryMixin.getMetadata()); - } - - /** - * Create a filter for constraints defined in this query - * - * @return - */ - public Filter asFilter() { - return new QueryWrapperFilter(createQuery()); - } - - @Override - public Q distinct() { - throw new UnsupportedOperationException("use distinct(path) instead"); - } - - /** - * Add a DuplicateFilter for the field of the given property path - * - * @param property - * @return - */ - public Q distinct(Path<?> property) { - return filter(new DuplicateFilter(serializer.toField(property))); - } - - /** - * Apply the given Lucene filter to the search results - * - * @param filter - * @return - */ - @SuppressWarnings("unchecked") - public Q filter(Filter filter) { - if (filters.isEmpty()) { - this._filter = filter; - filters = ImmutableList.of(filter); - } else { - this._filter = null; - if (filters.size() == 1) { - filters = new ArrayList<Filter>(); - } - filters.add(filter); - } - return (Q)this; - } - - private Filter getFilter() { - if (_filter == null && !filters.isEmpty()) { - _filter = new ChainedFilter(filters.toArray(new Filter[filters.size()])); - } - return _filter; - } - - @Override - public Q limit(long limit) { - return queryMixin.limit(limit); - } - - @Override - public CloseableIterator<T> iterate() { - final QueryMetadata metadata = queryMixin.getMetadata(); - final List<OrderSpecifier<?>> orderBys = metadata.getOrderBy(); - final Integer queryLimit = metadata.getModifiers().getLimitAsInteger(); - final Integer queryOffset = metadata.getModifiers().getOffsetAsInteger(); - Sort sort = querySort; - int limit; - final int offset = queryOffset != null ? queryOffset.intValue() : 0; - try { - limit = maxDoc(); - if (limit == 0) { - return new EmptyCloseableIterator<T>(); - } - } catch (IOException e) { - throw new QueryException(e); - } catch (IllegalArgumentException e) { - throw new QueryException(e); - } - if (queryLimit != null && queryLimit.intValue() < limit) { - limit = queryLimit.intValue(); - } - if (sort == null && !orderBys.isEmpty()) { - sort = serializer.toSort(orderBys); - } - - try { - ScoreDoc[] scoreDocs; - int sumOfLimitAndOffset = limit + offset; - if (sumOfLimitAndOffset < 1) { - throw new QueryException("The given limit (" + limit + ") and offset (" + offset + ") cause an integer overflow."); - } - if (sort != null) { - scoreDocs = searcher.search(createQuery(), getFilter(), sumOfLimitAndOffset, sort).scoreDocs; - } else { - scoreDocs = searcher.search(createQuery(), getFilter(), sumOfLimitAndOffset).scoreDocs; - } - if (offset < scoreDocs.length) { - return new ResultIterator<T>(scoreDocs, offset, searcher, fieldSelector, transformer); - } - return new EmptyCloseableIterator<T>(); - } catch (final IOException e) { - throw new QueryException(e); - } - } - - private List<T> innerList() { - return new IteratorAdapter<T>(iterate()).asList(); - } - - @Override - public List<T> list() { - return innerList(); - } - - /** - * Set the given FieldSelector to the query - * - * @param fieldSelector - * @return - */ - @SuppressWarnings("unchecked") - public Q load(FieldSelector fieldSelector) { - this.fieldSelector = fieldSelector; - return (Q)this; - } - - /** - * Load only the fields of the given paths - * - * @param paths - * @return - */ - @SuppressWarnings("unchecked") - public Q load(Path<?>... paths) { - List<String> fields = new ArrayList<String>(paths.length); - for (Path<?> path : paths) { - fields.add(serializer.toField(path)); - } - this.fieldSelector = new MapFieldSelector(fields); - return (Q)this; - } - - @Override - public SearchResults<T> listResults() { - List<T> documents = innerList(); - /* - * TODO Get rid of count(). It could be implemented by iterating the - * list results in list* from n to m. - */ - return new SearchResults<T>(documents, queryMixin.getMetadata().getModifiers(), innerCount()); - } - - @Override - public Q offset(long offset) { - return queryMixin.offset(offset); - } - - public Q orderBy(OrderSpecifier<?> o) { - return queryMixin.orderBy(o); - } - - @Override - public Q orderBy(OrderSpecifier<?>... o) { - return queryMixin.orderBy(o); - } - - @Override - public Q restrict(QueryModifiers modifiers) { - return queryMixin.restrict(modifiers); - } - - @Override - public <P> Q set(ParamExpression<P> param, P value) { - return queryMixin.set(param, value); - } - - @SuppressWarnings("unchecked") - public Q sort(Sort sort) { - this.querySort = sort; - return (Q)this; - } - - @Nullable - private T oneResult(boolean unique) { - try { - int maxDoc = maxDoc(); - if (maxDoc == 0) { - return null; - } - final ScoreDoc[] scoreDocs = searcher.search(createQuery(), getFilter(), maxDoc).scoreDocs; - int index = 0; - QueryModifiers modifiers = queryMixin.getMetadata().getModifiers(); - Long offset = modifiers.getOffset(); - if (offset != null) { - index = offset.intValue(); - } - Long limit = modifiers.getLimit(); - if (unique && (limit == null ? scoreDocs.length - index > 1 : - limit > 1 && scoreDocs.length > 1)) { - throw new NonUniqueResultException("Unique result requested, but " + scoreDocs.length + " found."); - } else if (scoreDocs.length > index) { - Document document; - if (fieldSelector != null) { - document = searcher.doc(scoreDocs[index].doc, fieldSelector); - } else { - document = searcher.doc(scoreDocs[index].doc); - } - return transformer.apply(document); - } else { - return null; - } - } catch (IOException e) { - throw new QueryException(e); - } catch (IllegalArgumentException e) { - throw new QueryException(e); - } - } - - @Override - public T singleResult() { - return oneResult(false); - } - - @Override - public T uniqueResult() { - return oneResult(true); - } - - public Q where(Predicate e) { - return queryMixin.where(e); - } - - @Override - public Q where(Predicate... e) { - return queryMixin.where(e); - } - - @Override - public String toString() { - return createQuery().toString(); - } - - private int maxDoc() throws IOException { - return searcher.maxDoc(); - } -} diff --git a/querydsl-lucene3/src/main/java/com/mysema/query/lucene/IgnoreCaseUnsupportedException.java b/querydsl-lucene3/src/main/java/com/mysema/query/lucene/IgnoreCaseUnsupportedException.java deleted file mode 100644 index 987f80d1b4..0000000000 --- a/querydsl-lucene3/src/main/java/com/mysema/query/lucene/IgnoreCaseUnsupportedException.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.lucene; - -/** - * @author tiwe - * - */ -public class IgnoreCaseUnsupportedException extends UnsupportedOperationException{ - - private static final long serialVersionUID = 412913389929530788L; - - public IgnoreCaseUnsupportedException() { - super("Ignore case queries are not supported with Lucene"); - } - -} diff --git a/querydsl-lucene3/src/main/java/com/mysema/query/lucene/LuceneExpressions.java b/querydsl-lucene3/src/main/java/com/mysema/query/lucene/LuceneExpressions.java deleted file mode 100644 index ba4e134d5f..0000000000 --- a/querydsl-lucene3/src/main/java/com/mysema/query/lucene/LuceneExpressions.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.lucene; - -import org.apache.lucene.index.Term; -import org.apache.lucene.search.FuzzyQuery; - -import com.mysema.query.types.Path; -import com.mysema.query.types.expr.BooleanExpression; - -/** - * Utility methods to create filter expressions for Lucene queries that are not covered by the - * Querydsl standard expression model - * - * @author tiwe - * - */ -public final class LuceneExpressions { - - /** - * Create a fuzzy query - * - * @param path - * @param value - * @return - */ - public static BooleanExpression fuzzyLike(Path<String> path, String value) { - Term term = new Term(path.getMetadata().getName(), value); - return new QueryElement(new FuzzyQuery(term)); - } - - /** - * Create a fuzzy query - * - * @param path - * @param value - * @param minimumSimilarity - * @return - */ - public static BooleanExpression fuzzyLike(Path<String> path, String value, float minimumSimilarity) { - Term term = new Term(path.getMetadata().getName(), value); - return new QueryElement(new FuzzyQuery(term, minimumSimilarity)); - } - - /** - * Create a fuzzy query - * - * @param path - * @param value - * @param minimumSimilarity - * @param prefixLength - * @return - */ - public static BooleanExpression fuzzyLike(Path<String> path, String value, - float minimumSimilarity, int prefixLength) { - Term term = new Term(path.getMetadata().getName(), value); - return new QueryElement(new FuzzyQuery(term, minimumSimilarity, prefixLength)); - } - - private LuceneExpressions() {} - -} diff --git a/querydsl-lucene3/src/main/java/com/mysema/query/lucene/LuceneOps.java b/querydsl-lucene3/src/main/java/com/mysema/query/lucene/LuceneOps.java deleted file mode 100644 index 7b8f1b7160..0000000000 --- a/querydsl-lucene3/src/main/java/com/mysema/query/lucene/LuceneOps.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2013, Mysema Ltd - * - * 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. - */ -package com.mysema.query.lucene; - -import com.mysema.query.types.Operator; -import com.mysema.query.types.OperatorImpl; - -/** - * @author tiwe - * - */ -public final class LuceneOps { - - private static final String NS = LuceneOps.class.getName(); - - static final Operator<Object> LUCENE_QUERY = new OperatorImpl<Object>(NS, "QUERY"); - - static final Operator<String> PHRASE = new OperatorImpl<String>(NS, "PHRASE"); - - static final Operator<String> TERM = new OperatorImpl<String>(NS, "TERM"); - - private LuceneOps() {} - -} diff --git a/querydsl-lucene3/src/main/java/com/mysema/query/lucene/LuceneQuery.java b/querydsl-lucene3/src/main/java/com/mysema/query/lucene/LuceneQuery.java deleted file mode 100644 index 96a6b74646..0000000000 --- a/querydsl-lucene3/src/main/java/com/mysema/query/lucene/LuceneQuery.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.lucene; - -import org.apache.lucene.document.Document; -import org.apache.lucene.search.IndexSearcher; - -import com.google.common.base.Function; - -/** - * LuceneQuery is a Querydsl query implementation for Lucene queries. - * - * @author vema - */ -public class LuceneQuery extends AbstractLuceneQuery<Document, LuceneQuery> { - - private static final Function<Document,Document> TRANSFORMER = new Function<Document,Document>() { - @Override - public Document apply(Document input) { - return input; - } - }; - - public LuceneQuery(IndexSearcher searcher) { - super(searcher, TRANSFORMER); - } - - public LuceneQuery(LuceneSerializer luceneSerializer, IndexSearcher searcher) { - super(luceneSerializer, searcher, TRANSFORMER); - } - -} diff --git a/querydsl-lucene3/src/main/java/com/mysema/query/lucene/LuceneSerializer.java b/querydsl-lucene3/src/main/java/com/mysema/query/lucene/LuceneSerializer.java deleted file mode 100644 index 64c5c8e17e..0000000000 --- a/querydsl-lucene3/src/main/java/com/mysema/query/lucene/LuceneSerializer.java +++ /dev/null @@ -1,567 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.lucene; - -import java.math.BigDecimal; -import java.math.BigInteger; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.regex.Pattern; - -import javax.annotation.Nullable; - -import org.apache.lucene.index.Term; -import org.apache.lucene.queryParser.QueryParser; -import org.apache.lucene.search.BooleanClause; -import org.apache.lucene.search.BooleanClause.Occur; -import org.apache.lucene.search.BooleanQuery; -import org.apache.lucene.search.MatchAllDocsQuery; -import org.apache.lucene.search.NumericRangeQuery; -import org.apache.lucene.search.PhraseQuery; -import org.apache.lucene.search.PrefixQuery; -import org.apache.lucene.search.Query; -import org.apache.lucene.search.Sort; -import org.apache.lucene.search.SortField; -import org.apache.lucene.search.TermQuery; -import org.apache.lucene.search.TermRangeQuery; -import org.apache.lucene.search.WildcardQuery; -import org.apache.lucene.util.NumericUtils; - -import com.google.common.base.Splitter; -import com.google.common.collect.Iterables; -import com.mysema.query.QueryMetadata; -import com.mysema.query.types.Constant; -import com.mysema.query.types.Expression; -import com.mysema.query.types.ExpressionUtils; -import com.mysema.query.types.Operation; -import com.mysema.query.types.Operator; -import com.mysema.query.types.Ops; -import com.mysema.query.types.OrderSpecifier; -import com.mysema.query.types.ParamExpression; -import com.mysema.query.types.ParamNotSetException; -import com.mysema.query.types.Path; -import com.mysema.query.types.PathType; - -/** - * Serializes Querydsl queries to Lucene queries. - * - * @author vema - * - */ -public class LuceneSerializer { - private static final Map<Class<?>, Integer> sortFields = new HashMap<Class<?>, Integer>(); - - static { - sortFields.put(Integer.class, SortField.INT); - sortFields.put(Float.class, SortField.FLOAT); - sortFields.put(Long.class, SortField.LONG); - sortFields.put(Double.class, SortField.DOUBLE); - sortFields.put(Short.class, SortField.SHORT); - sortFields.put(Byte.class, SortField.BYTE); - sortFields.put(BigDecimal.class, SortField.DOUBLE); - sortFields.put(BigInteger.class, SortField.LONG); - } - - private static final Splitter WS_SPLITTER = Splitter.on(Pattern.compile("\\s+")); - - public static final LuceneSerializer DEFAULT = new LuceneSerializer(false, true); - - private final boolean lowerCase; - - private final boolean splitTerms; - - private final Locale sortLocale; - - public LuceneSerializer(boolean lowerCase, boolean splitTerms) { - this(lowerCase, splitTerms, Locale.getDefault()); - } - - public LuceneSerializer(boolean lowerCase, boolean splitTerms, Locale sortLocale) { - this.lowerCase = lowerCase; - this.splitTerms = splitTerms; - this.sortLocale = sortLocale; - } - - private Query toQuery(Operation<?> operation, QueryMetadata metadata) { - Operator<?> op = operation.getOperator(); - if (op == Ops.OR) { - return toTwoHandSidedQuery(operation, Occur.SHOULD, metadata); - } else if (op == Ops.AND) { - return toTwoHandSidedQuery(operation, Occur.MUST, metadata); - } else if (op == Ops.NOT) { - BooleanQuery bq = new BooleanQuery(); - bq.add(new BooleanClause(toQuery(operation.getArg(0), metadata), Occur.MUST_NOT)); - bq.add(new BooleanClause(new MatchAllDocsQuery(), Occur.MUST)); - return bq; - } else if (op == Ops.LIKE) { - return like(operation, metadata); - } else if (op == Ops.EQ) { - return eq(operation, metadata, false); - } else if (op == Ops.EQ_IGNORE_CASE) { - throw new IgnoreCaseUnsupportedException(); - } else if (op == Ops.NE) { - return ne(operation, metadata, false); - } else if (op == Ops.STARTS_WITH) { - return startsWith(metadata, operation, false); - } else if (op == Ops.STARTS_WITH_IC) { - throw new IgnoreCaseUnsupportedException(); - } else if (op == Ops.ENDS_WITH) { - return endsWith(operation, metadata, false); - } else if (op == Ops.ENDS_WITH_IC) { - throw new IgnoreCaseUnsupportedException(); - } else if (op == Ops.STRING_CONTAINS) { - return stringContains(operation, metadata, false); - } else if (op == Ops.STRING_CONTAINS_IC) { - throw new IgnoreCaseUnsupportedException(); - } else if (op == Ops.BETWEEN) { - return between(operation, metadata); - } else if (op == Ops.IN) { - return in(operation, metadata, false); - } else if (op == Ops.NOT_IN) { - return notIn(operation, metadata, false); - } else if (op == Ops.LT) { - return lt(operation, metadata); - } else if (op == Ops.GT) { - return gt(operation, metadata); - } else if (op == Ops.LOE) { - return le(operation, metadata); - } else if (op == Ops.GOE) { - return ge(operation, metadata); - } else if (op == LuceneOps.LUCENE_QUERY) { - return ((Constant<Query>)operation.getArg(0)).getConstant(); - } - throw new UnsupportedOperationException("Illegal operation " + operation); - } - - private Query toTwoHandSidedQuery(Operation<?> operation, Occur occur, QueryMetadata metadata) { - Query lhs = toQuery(operation.getArg(0), metadata); - Query rhs = toQuery(operation.getArg(1), metadata); - BooleanQuery bq = new BooleanQuery(); - bq.add(createBooleanClause(lhs, occur)); - bq.add(createBooleanClause(rhs, occur)); - return bq; - } - - /** - * If the query is a BooleanQuery and it contains a single Occur.MUST_NOT - * clause it will be returned as is. Otherwise it will be wrapped in a - * BooleanClause with the given Occur. - */ - private BooleanClause createBooleanClause(Query query, Occur occur) { - if (query instanceof BooleanQuery) { - BooleanClause[] clauses = ((BooleanQuery) query).getClauses(); - if (clauses.length == 1 && clauses[0].getOccur().equals(Occur.MUST_NOT)) { - return clauses[0]; - } - } - return new BooleanClause(query, occur); - } - - protected Query like(Operation<?> operation, QueryMetadata metadata) { - verifyArguments(operation); - Path<?> path = getPath(operation.getArg(0)); - String field = toField(path); - String[] terms = convert(path, operation.getArg(1)); - if (terms.length > 1) { - BooleanQuery bq = new BooleanQuery(); - for (String s : terms) { - bq.add(new WildcardQuery(new Term(field, "*" + s + "*")), Occur.MUST); - } - return bq; - } - return new WildcardQuery(new Term(field, terms[0])); - } - - @SuppressWarnings("unchecked") - protected Query eq(Operation<?> operation, QueryMetadata metadata, boolean ignoreCase) { - verifyArguments(operation); - Path<?> path = getPath(operation.getArg(0)); - String field = toField(path); - - if (Number.class.isAssignableFrom(operation.getArg(1).getType())) { - return new TermQuery(new Term(field, convertNumber(((Constant<Number>) operation - .getArg(1)).getConstant()))); - } - - return eq(field, convert(path, operation.getArg(1), metadata), ignoreCase); - } - - - private String convertNumber(Number number) { - if (Integer.class.isInstance(number)) { - return NumericUtils.intToPrefixCoded(number.intValue()); - } else if (Double.class.isInstance(number)) { - return NumericUtils.doubleToPrefixCoded(number.doubleValue()); - } else if (Long.class.isInstance(number)) { - return NumericUtils.longToPrefixCoded(number.longValue()); - } else if (Float.class.isInstance(number)) { - return NumericUtils.floatToPrefixCoded(number.floatValue()); - } else if (Byte.class.isInstance(number)) { - return NumericUtils.intToPrefixCoded(number.intValue()); - } else if (Short.class.isInstance(number)) { - return NumericUtils.intToPrefixCoded(number.intValue()); - } else if (BigDecimal.class.isInstance(number)) { - return NumericUtils.doubleToPrefixCoded(number.doubleValue()); - } else if (BigInteger.class.isInstance(number)) { - return NumericUtils.longToPrefixCoded(number.longValue()); - } else { - throw new IllegalArgumentException("Unsupported numeric type " - + number.getClass().getName()); - } - } - - protected Query eq(String field, String[] terms, boolean ignoreCase) { - if (terms.length > 1) { - PhraseQuery pq = new PhraseQuery(); - for (String s : terms) { - pq.add(new Term(field, s)); - } - return pq; - } - return new TermQuery(new Term(field, terms[0])); - } - - protected Query in(Operation<?> operation, QueryMetadata metadata, boolean ignoreCase) { - Path<?> path = getPath(operation.getArg(0)); - String field = toField(path); - Collection<?> values = (Collection<?>) ((Constant<?>) operation.getArg(1)).getConstant(); - BooleanQuery bq = new BooleanQuery(); - for (Object value : values) { - String[] str = convert(path, value); - bq.add(eq(field, str, ignoreCase), Occur.SHOULD); - } - return bq; - } - - protected Query notIn(Operation<?> operation, QueryMetadata metadata, boolean ignoreCase) { - BooleanQuery bq = new BooleanQuery(); - bq.add(new BooleanClause(in(operation, metadata, false), Occur.MUST_NOT)); - bq.add(new BooleanClause(new MatchAllDocsQuery(), Occur.MUST)); - return bq; - } - - protected Query ne(Operation<?> operation, QueryMetadata metadata, boolean ignoreCase) { - BooleanQuery bq = new BooleanQuery(); - bq.add(new BooleanClause(eq(operation, metadata, ignoreCase), Occur.MUST_NOT)); - bq.add(new BooleanClause(new MatchAllDocsQuery(), Occur.MUST)); - return bq; - } - - protected Query startsWith(QueryMetadata metadata, Operation<?> operation, boolean ignoreCase) { - verifyArguments(operation); - Path<?> path = getPath(operation.getArg(0)); - String field = toField(path); - String[] terms = convertEscaped(path, operation.getArg(1), metadata); - if (terms.length > 1) { - BooleanQuery bq = new BooleanQuery(); - for (int i = 0; i < terms.length; ++i) { - String s = i == 0 ? terms[i] + "*" : "*" + terms[i] + "*"; - bq.add(new WildcardQuery(new Term(field, s)), Occur.MUST); - } - return bq; - } - return new PrefixQuery(new Term(field, terms[0])); - } - - - - protected Query stringContains(Operation<?> operation, QueryMetadata metadata, boolean ignoreCase) { - verifyArguments(operation); - Path<?> path = getPath(operation.getArg(0)); - String field = toField(path); - String[] terms = convertEscaped(path, operation.getArg(1), metadata); - if (terms.length > 1) { - BooleanQuery bq = new BooleanQuery(); - for (String s : terms) { - bq.add(new WildcardQuery(new Term(field, "*" + s + "*")), Occur.MUST); - } - return bq; - } - return new WildcardQuery(new Term(field, "*" + terms[0] + "*")); - } - - protected Query endsWith(Operation<?> operation, QueryMetadata metadata, boolean ignoreCase) { - verifyArguments(operation); - Path<?> path = getPath(operation.getArg(0)); - String field = toField(path); - String[] terms = convertEscaped(path, operation.getArg(1), metadata); - if (terms.length > 1) { - BooleanQuery bq = new BooleanQuery(); - for (int i = 0; i < terms.length; ++i) { - String s = i == terms.length - 1 ? "*" + terms[i] : "*" + terms[i] + "*"; - bq.add(new WildcardQuery(new Term(field, s)), Occur.MUST); - } - return bq; - } - return new WildcardQuery(new Term(field, "*" + terms[0])); - } - - protected Query between(Operation<?> operation, QueryMetadata metadata) { - verifyArguments(operation); - Path<?> path = getPath(operation.getArg(0)); - // TODO Phrase not properly supported - return range( - path, - toField(path), - operation.getArg(1), - operation.getArg(2), - true, - true, - metadata); - } - - protected Query lt(Operation<?> operation, QueryMetadata metadata) { - verifyArguments(operation); - Path<?> path = getPath(operation.getArg(0)); - return range( - path, - toField(path), - null, - operation.getArg(1), - false, - false, - metadata); - } - - protected Query gt(Operation<?> operation, QueryMetadata metadata) { - verifyArguments(operation); - Path<?> path = getPath(operation.getArg(0)); - return range( - path, - toField(path), - operation.getArg(1), - null, - false, - false, - metadata); - } - - protected Query le(Operation<?> operation, QueryMetadata metadata) { - verifyArguments(operation); - Path<?> path = getPath(operation.getArg(0)); - return range( - path, - toField(path), - null, - operation.getArg(1), - true, - true, - metadata); - } - - protected Query ge(Operation<?> operation, QueryMetadata metadata) { - verifyArguments(operation); - Path<?> path = getPath(operation.getArg(0)); - return range( - path, - toField(path), - operation.getArg(1), - null, - true, - true, - metadata); - } - - @SuppressWarnings({"unchecked"}) - protected Query range(Path<?> leftHandSide, String field, @Nullable Expression<?> min, - @Nullable Expression<?> max, boolean minInc, boolean maxInc, QueryMetadata metadata) { - if (min != null && Number.class.isAssignableFrom(min.getType()) || max != null - && Number.class.isAssignableFrom(max.getType())) { - Class<? extends Number> numType = (Class) (min != null ? min.getType() : max.getType()); - return numericRange((Class) numType, field, (Number) (min == null ? null - : ((Constant) min).getConstant()), (Number) (max == null ? null - : ((Constant) max).getConstant()), minInc, maxInc); - } - return stringRange(leftHandSide, field, min, max, minInc, maxInc, metadata); - } - - protected <N extends Number> NumericRangeQuery<?> numericRange(Class<N> clazz, String field, - @Nullable N min, @Nullable N max, boolean minInc, boolean maxInc) { - if (clazz.equals(Integer.class)) { - return NumericRangeQuery.newIntRange(field, (Integer) min, (Integer) max, minInc, maxInc); - } else if (clazz.equals(Double.class)) { - return NumericRangeQuery.newDoubleRange(field, (Double) min, (Double) max, minInc, minInc); - } else if (clazz.equals(Float.class)) { - return NumericRangeQuery.newFloatRange(field, (Float) min, (Float) max, minInc, minInc); - } else if (clazz.equals(Long.class)) { - return NumericRangeQuery.newLongRange(field, (Long) min, (Long) max, minInc, minInc); - } else if (clazz.equals(Byte.class) || clazz.equals(Short.class)) { - return NumericRangeQuery.newIntRange(field, min != null ? min.intValue() : null, - max != null ? max.intValue() : null, minInc, maxInc); - } else { - throw new IllegalArgumentException("Unsupported numeric type " + clazz.getName()); - } - } - - protected Query stringRange( - Path<?> leftHandSide, - String field, - @Nullable Expression<?> min, - @Nullable Expression<?> max, - boolean minInc, - boolean maxInc, - QueryMetadata metadata) { - - if (min == null) { - return new TermRangeQuery( - field, null, convert(leftHandSide, max, metadata)[0], minInc, maxInc); - } else if (max == null) { - return new TermRangeQuery( - field, convert(leftHandSide, min, metadata)[0], - null, minInc, maxInc); - } else { - return new TermRangeQuery( - field, convert(leftHandSide, min, metadata)[0], - convert(leftHandSide, max, metadata)[0], - minInc, maxInc); - } - } - - private Path<?> getPath(Expression<?> leftHandSide) { - if (leftHandSide instanceof Path<?>) { - return (Path<?>)leftHandSide; - } else if (leftHandSide instanceof Operation<?>) { - Operation<?> operation = (Operation<?>) leftHandSide; - if (operation.getOperator() == Ops.LOWER || operation.getOperator() == Ops.UPPER) { - return (Path<?>)operation.getArg(0); - } - } - throw new IllegalArgumentException("Unable to transform " + leftHandSide + " to path"); - } - - /** - * template method, override to customize - * - * @param path - * @return - */ - protected String toField(Path<?> path) { - String rv = path.getMetadata().getName(); - if (path.getMetadata().getParent() != null) { - Path<?> parent = path.getMetadata().getParent(); - if (parent.getMetadata().getPathType() != PathType.VARIABLE) { - rv = toField(parent) + "." + rv; - } - } - return rv; - } - - private void verifyArguments(Operation<?> operation) { - List<Expression<?>> arguments = operation.getArgs(); - for (int i = 1; i < arguments.size(); ++i) { - if (!(arguments.get(i) instanceof Constant<?>) - && !(arguments.get(i) instanceof ParamExpression<?>) - && !(arguments.get(i) instanceof PhraseElement) - && !(arguments.get(i) instanceof TermElement)) { - throw new IllegalArgumentException("operand was of unsupported type " - + arguments.get(i).getClass().getName()); - } - } - } - - /** - * template method - * - * @param leftHandSide - * @param rightHandSide - * @return - */ - protected String[] convert(Path<?> leftHandSide, Expression<?> rightHandSide, QueryMetadata metadata) { - if (rightHandSide instanceof Operation) { - Operation<?> operation = (Operation<?>)rightHandSide; - if (operation.getOperator() == LuceneOps.PHRASE) { - return Iterables.toArray(WS_SPLITTER.split(operation.getArg(0).toString()), String.class); - } else if (operation.getOperator() == LuceneOps.TERM) { - return new String[] { operation.getArg(0).toString() }; - } else { - throw new IllegalArgumentException(rightHandSide.toString()); - } - } else if (rightHandSide instanceof ParamExpression<?>) { - Object value = metadata.getParams().get(rightHandSide); - if (value == null) { - throw new ParamNotSetException((ParamExpression<?>) rightHandSide); - } - return convert(leftHandSide, value); - - } else if (rightHandSide instanceof Constant<?>) { - return convert(leftHandSide, ((Constant<?>)rightHandSide).getConstant()); - } else { - throw new IllegalArgumentException(rightHandSide.toString()); - } - } - - /** - * template method - * - * @param leftHandSide - * @param rightHandSide - * @return - */ - protected String[] convert(Path<?> leftHandSide, Object rightHandSide) { - String str = rightHandSide.toString(); - if (lowerCase) { - str = str.toLowerCase(); - } - if (splitTerms) { - if (str.equals("")) { - return new String[] { str }; - } else { -// return StringUtils.split(str); - return Iterables.toArray(WS_SPLITTER.split(str), String.class); - } - } else { - return new String[] { str }; - } - } - - private String[] convertEscaped(Path<?> leftHandSide, Expression<?> rightHandSide, QueryMetadata metadata) { - String[] str = convert(leftHandSide, rightHandSide, metadata); - for (int i = 0; i < str.length; i++) { - str[i] = QueryParser.escape(str[i]); - } - return str; - } - - public Query toQuery(Expression<?> expr, QueryMetadata metadata) { - if (expr instanceof Operation<?>) { - return toQuery((Operation<?>) expr, metadata); - } else { - return toQuery(ExpressionUtils.extract(expr), metadata); - } - } - - public Sort toSort(List<? extends OrderSpecifier<?>> orderBys) { - List<SortField> sorts = new ArrayList<SortField>(orderBys.size()); - for (OrderSpecifier<?> order : orderBys) { - if (!(order.getTarget() instanceof Path<?>)) { - throw new IllegalArgumentException("argument was not of type Path."); - } - Class<?> type = order.getTarget().getType(); - boolean reverse = !order.isAscending(); - Path<?> path = getPath(order.getTarget()); - if (Number.class.isAssignableFrom(type)) { - sorts.add(new SortField(toField(path), sortFields.get(type), reverse)); - } else { - sorts.add(new SortField(toField(path), sortLocale, reverse)); - } - } - Sort sort = new Sort(); - sort.setSort(sorts.toArray(new SortField[sorts.size()])); - return sort; - } -} diff --git a/querydsl-lucene3/src/main/java/com/mysema/query/lucene/PhraseElement.java b/querydsl-lucene3/src/main/java/com/mysema/query/lucene/PhraseElement.java deleted file mode 100644 index 6cf5f4d638..0000000000 --- a/querydsl-lucene3/src/main/java/com/mysema/query/lucene/PhraseElement.java +++ /dev/null @@ -1,33 +0,0 @@ - /* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.lucene; - -import com.mysema.query.types.ConstantImpl; -import com.mysema.query.types.expr.StringOperation; - -/** - * PhraseElement represents the embedded String as a phrase - * - * @author tiwe - * - */ -public class PhraseElement extends StringOperation { - - private static final long serialVersionUID = 2350215644019186076L; - - public PhraseElement(String str) { - super(LuceneOps.PHRASE, ConstantImpl.create(str)); - } - -} diff --git a/querydsl-lucene3/src/main/java/com/mysema/query/lucene/QueryElement.java b/querydsl-lucene3/src/main/java/com/mysema/query/lucene/QueryElement.java deleted file mode 100644 index 6e81e3531e..0000000000 --- a/querydsl-lucene3/src/main/java/com/mysema/query/lucene/QueryElement.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.lucene; - -import org.apache.lucene.search.Query; - -import com.mysema.query.types.ConstantImpl; -import com.mysema.query.types.expr.BooleanOperation; - -/** - * QueryElement wraps a Lucene Query - * - * @author tiwe - * - */ -public class QueryElement extends BooleanOperation { - - private static final long serialVersionUID = 470868107363840155L; - - public QueryElement(Query query) { - super(LuceneOps.LUCENE_QUERY, ConstantImpl.create(query)); - } - -} diff --git a/querydsl-lucene3/src/main/java/com/mysema/query/lucene/ResultIterator.java b/querydsl-lucene3/src/main/java/com/mysema/query/lucene/ResultIterator.java deleted file mode 100644 index a22046cfc2..0000000000 --- a/querydsl-lucene3/src/main/java/com/mysema/query/lucene/ResultIterator.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.lucene; - -import java.io.IOException; - -import javax.annotation.Nullable; - -import org.apache.lucene.document.Document; -import org.apache.lucene.document.FieldSelector; -import org.apache.lucene.search.IndexSearcher; -import org.apache.lucene.search.ScoreDoc; - -import com.google.common.base.Function; -import com.mysema.commons.lang.CloseableIterator; -import com.mysema.query.QueryException; - -/** - * ResultIterator is a {@link CloseableIterator} implementation for Lucene query results - * - * @author tiwe - * - * @param <T> - */ -public final class ResultIterator<T> implements CloseableIterator<T> { - - private final ScoreDoc[] scoreDocs; - - private int cursor; - - private final IndexSearcher searcher; - - @Nullable - private final FieldSelector fieldSelector; - - private final Function<Document,T> transformer; - - public ResultIterator(ScoreDoc[] scoreDocs, int offset, IndexSearcher searcher, - @Nullable FieldSelector fieldSelector, Function<Document, T> transformer) { - this.scoreDocs = scoreDocs.clone(); - this.cursor = offset; - this.searcher = searcher; - this.fieldSelector = fieldSelector; - this.transformer = transformer; - } - - @Override - public boolean hasNext() { - return cursor != scoreDocs.length; - } - - @Override - public T next() { - try { - Document document; - if (fieldSelector != null) { - document = searcher.doc(scoreDocs[cursor++].doc, fieldSelector); - } else { - document = searcher.doc(scoreDocs[cursor++].doc); - } - return transformer.apply(document); - } catch (IOException e) { - throw new QueryException(e); - } - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - - @Override - public void close() { - - } - -} \ No newline at end of file diff --git a/querydsl-lucene3/src/main/java/com/mysema/query/lucene/TermElement.java b/querydsl-lucene3/src/main/java/com/mysema/query/lucene/TermElement.java deleted file mode 100644 index 0309847683..0000000000 --- a/querydsl-lucene3/src/main/java/com/mysema/query/lucene/TermElement.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.lucene; - -import com.mysema.query.types.ConstantImpl; -import com.mysema.query.types.expr.StringOperation; - -/** - * TermElement represents the embedded String as a term - * - * @author tiwe - * - */ -public class TermElement extends StringOperation { - - private static final long serialVersionUID = 2350215644019186076L; - - public TermElement(String str) { - super(LuceneOps.TERM, ConstantImpl.create(str)); - } - -} diff --git a/querydsl-lucene3/src/main/java/com/mysema/query/lucene/TypedQuery.java b/querydsl-lucene3/src/main/java/com/mysema/query/lucene/TypedQuery.java deleted file mode 100644 index b6fa4b9884..0000000000 --- a/querydsl-lucene3/src/main/java/com/mysema/query/lucene/TypedQuery.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.lucene; - -import org.apache.lucene.document.Document; -import org.apache.lucene.search.IndexSearcher; - -import com.google.common.base.Function; - -/** - * TypedQuery is a typed query implementation for Lucene queries. - * - * @author laim - * @author tiwe - */ -public class TypedQuery<T> extends AbstractLuceneQuery<T, TypedQuery<T>> { - - public TypedQuery(IndexSearcher searcher, Function<Document, T> transformer) { - super(searcher, transformer); - } - - public TypedQuery(LuceneSerializer serializer, IndexSearcher searcher, Function<Document, T> transformer) { - super(serializer, searcher, transformer); - } - -} diff --git a/querydsl-lucene3/src/main/java/com/mysema/query/lucene/package-info.java b/querydsl-lucene3/src/main/java/com/mysema/query/lucene/package-info.java deleted file mode 100644 index 0f6c4a03a6..0000000000 --- a/querydsl-lucene3/src/main/java/com/mysema/query/lucene/package-info.java +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ - -package com.mysema.query.lucene; diff --git a/querydsl-lucene3/src/main/java/com/querydsl/lucene3/AbstractLuceneQuery.java b/querydsl-lucene3/src/main/java/com/querydsl/lucene3/AbstractLuceneQuery.java new file mode 100644 index 0000000000..5fab24265e --- /dev/null +++ b/querydsl-lucene3/src/main/java/com/querydsl/lucene3/AbstractLuceneQuery.java @@ -0,0 +1,362 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.lucene3; + +import com.mysema.commons.lang.CloseableIterator; +import com.mysema.commons.lang.EmptyCloseableIterator; +import com.mysema.commons.lang.IteratorAdapter; +import com.querydsl.core.DefaultQueryMetadata; +import com.querydsl.core.Fetchable; +import com.querydsl.core.NonUniqueResultException; +import com.querydsl.core.QueryException; +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.QueryModifiers; +import com.querydsl.core.QueryResults; +import com.querydsl.core.SimpleQuery; +import com.querydsl.core.support.QueryMixin; +import com.querydsl.core.types.OrderSpecifier; +import com.querydsl.core.types.ParamExpression; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.Predicate; +import org.apache.lucene.document.Document; +import org.apache.lucene.document.FieldSelector; +import org.apache.lucene.document.MapFieldSelector; +import org.apache.lucene.search.ChainedFilter; +import org.apache.lucene.search.DuplicateFilter; +import org.apache.lucene.search.Filter; +import org.apache.lucene.search.IndexSearcher; +import org.apache.lucene.search.MatchAllDocsQuery; +import org.apache.lucene.search.Query; +import org.apache.lucene.search.QueryWrapperFilter; +import org.apache.lucene.search.ScoreDoc; +import org.apache.lucene.search.Sort; +import org.apache.lucene.search.TotalHitCountCollector; +import org.jetbrains.annotations.Nullable; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.function.Function; + +/** + * AbstractLuceneQuery is an abstract super class for Lucene query implementations + * + * @author tiwe + * + * @param <T> projection type + * @param <Q> concrete subtype of query + */ +public abstract class AbstractLuceneQuery<T,Q extends AbstractLuceneQuery<T,Q>> implements SimpleQuery<Q>, Fetchable<T> { + + private static final String JAVA_ISO_CONTROL = "[\\p{Cntrl}&&[^\r\n\t]]"; + + private final QueryMixin<Q> queryMixin; + + private final IndexSearcher searcher; + + private final LuceneSerializer serializer; + + private final Function<Document, T> transformer; + + @Nullable + private FieldSelector fieldSelector; + + private List<Filter> filters = Collections.emptyList(); + + @Nullable + private Filter filter; + + @Nullable + private Sort querySort; + + @SuppressWarnings("unchecked") + public AbstractLuceneQuery(LuceneSerializer serializer, IndexSearcher searcher, + Function<Document, T> transformer) { + queryMixin = new QueryMixin<Q>((Q) this, new DefaultQueryMetadata()); + this.serializer = serializer; + this.searcher = searcher; + this.transformer = transformer; + } + + public AbstractLuceneQuery(IndexSearcher searcher, Function<Document, T> transformer) { + this(LuceneSerializer.DEFAULT, searcher, transformer); + } + + private long innerCount() { + try { + final int maxDoc = searcher.maxDoc(); + if (maxDoc == 0) { + return 0; + } + TotalHitCountCollector collector = new TotalHitCountCollector(); + searcher.search(createQuery(), getFilter(), collector); + return collector.getTotalHits(); + } catch (IOException | IllegalArgumentException e) { + throw new QueryException(e); + } + } + + @Override + public long fetchCount() { + return innerCount(); + } + + protected Query createQuery() { + if (queryMixin.getMetadata().getWhere() == null) { + return new MatchAllDocsQuery(); + } + return serializer.toQuery(queryMixin.getMetadata().getWhere(), queryMixin.getMetadata()); + } + + /** + * Create a filter for constraints defined in this query + * + * @return filter + */ + public Filter asFilter() { + return new QueryWrapperFilter(createQuery()); + } + + @Override + public Q distinct() { + throw new UnsupportedOperationException("use distinct(path) instead"); + } + + /** + * Add a DuplicateFilter for the field of the given property path + * + * @param property distinct property + * @return the current object + */ + public Q distinct(Path<?> property) { + return filter(new DuplicateFilter(serializer.toField(property))); + } + + /** + * Apply the given Lucene filter to the search results + * + * @param filter filter + * @return the current object + */ + @SuppressWarnings("unchecked") + public Q filter(Filter filter) { + if (filters.isEmpty()) { + this.filter = filter; + filters = Collections.singletonList(filter); + } else { + this.filter = null; + if (filters.size() == 1) { + filters = new ArrayList<Filter>(); + } + filters.add(filter); + } + return (Q) this; + } + + private Filter getFilter() { + if (filter == null && !filters.isEmpty()) { + filter = new ChainedFilter(filters.toArray(new Filter[0])); + } + return filter; + } + + @Override + public Q limit(long limit) { + return queryMixin.limit(limit); + } + + @Override + public CloseableIterator<T> iterate() { + final QueryMetadata metadata = queryMixin.getMetadata(); + final List<OrderSpecifier<?>> orderBys = metadata.getOrderBy(); + final Integer queryLimit = metadata.getModifiers().getLimitAsInteger(); + final Integer queryOffset = metadata.getModifiers().getOffsetAsInteger(); + Sort sort = querySort; + int limit; + final int offset = queryOffset != null ? queryOffset : 0; + try { + limit = maxDoc(); + if (limit == 0) { + return new EmptyCloseableIterator<T>(); + } + } catch (IOException | IllegalArgumentException e) { + throw new QueryException(e); + } + if (queryLimit != null && queryLimit < limit) { + limit = queryLimit; + } + if (sort == null && !orderBys.isEmpty()) { + sort = serializer.toSort(orderBys); + } + + try { + ScoreDoc[] scoreDocs; + int sumOfLimitAndOffset = limit + offset; + if (sumOfLimitAndOffset < 1) { + throw new QueryException("The given limit (" + limit + ") and offset (" + offset + ") cause an integer overflow."); + } + if (sort != null) { + scoreDocs = searcher.search(createQuery(), getFilter(), sumOfLimitAndOffset, sort).scoreDocs; + } else { + scoreDocs = searcher.search(createQuery(), getFilter(), sumOfLimitAndOffset).scoreDocs; + } + if (offset < scoreDocs.length) { + return new ResultIterator<T>(scoreDocs, offset, searcher, fieldSelector, transformer); + } + return new EmptyCloseableIterator<T>(); + } catch (final IOException e) { + throw new QueryException(e); + } + } + + private List<T> innerList() { + return new IteratorAdapter<T>(iterate()).asList(); + } + + @Override + public List<T> fetch() { + return innerList(); + } + + /** + * Set the given FieldSelector to the query + * + * @param fieldSelector field selector + * @return the current object + */ + @SuppressWarnings("unchecked") + public Q load(FieldSelector fieldSelector) { + this.fieldSelector = fieldSelector; + return (Q) this; + } + + /** + * Load only the fields of the given paths + * + * @param paths fields to load + * @return the current object + */ + @SuppressWarnings("unchecked") + public Q load(Path<?>... paths) { + List<String> fields = new ArrayList<String>(paths.length); + for (Path<?> path : paths) { + fields.add(serializer.toField(path)); + } + this.fieldSelector = new MapFieldSelector(fields); + return (Q) this; + } + + @Override + public QueryResults<T> fetchResults() { + List<T> documents = innerList(); + /* + * TODO Get rid of fetchCount(). It could be implemented by iterating the + * fetch results in fetch* from n to m. + */ + return new QueryResults<T>(documents, queryMixin.getMetadata().getModifiers(), innerCount()); + } + + @Override + public Q offset(long offset) { + return queryMixin.offset(offset); + } + + public Q orderBy(OrderSpecifier<?> o) { + return queryMixin.orderBy(o); + } + + @Override + public Q orderBy(OrderSpecifier<?>... o) { + return queryMixin.orderBy(o); + } + + @Override + public Q restrict(QueryModifiers modifiers) { + return queryMixin.restrict(modifiers); + } + + @Override + public <P> Q set(ParamExpression<P> param, P value) { + return queryMixin.set(param, value); + } + + @SuppressWarnings("unchecked") + public Q sort(Sort sort) { + this.querySort = sort; + return (Q) this; + } + + @Nullable + private T oneResult(boolean unique) { + try { + int maxDoc = maxDoc(); + if (maxDoc == 0) { + return null; + } + final ScoreDoc[] scoreDocs = searcher.search(createQuery(), getFilter(), maxDoc).scoreDocs; + int index = 0; + QueryModifiers modifiers = queryMixin.getMetadata().getModifiers(); + Long offset = modifiers.getOffset(); + if (offset != null) { + index = offset.intValue(); + } + Long limit = modifiers.getLimit(); + if (unique && (limit == null ? scoreDocs.length - index > 1 : + limit > 1 && scoreDocs.length > 1)) { + throw new NonUniqueResultException("Unique result requested, but " + scoreDocs.length + " found."); + } else if (scoreDocs.length > index) { + Document document; + if (fieldSelector != null) { + document = searcher.doc(scoreDocs[index].doc, fieldSelector); + } else { + document = searcher.doc(scoreDocs[index].doc); + } + return transformer.apply(document); + } else { + return null; + } + } catch (IOException | IllegalArgumentException e) { + throw new QueryException(e); + } + } + + @Override + public T fetchFirst() { + return oneResult(false); + } + + @Override + public T fetchOne() throws NonUniqueResultException { + return oneResult(true); + } + + public Q where(Predicate e) { + return queryMixin.where(e); + } + + @Override + public Q where(Predicate... e) { + return queryMixin.where(e); + } + + @Override + public String toString() { + return createQuery().toString().replaceAll(JAVA_ISO_CONTROL, "_"); + } + + private int maxDoc() throws IOException { + return searcher.maxDoc(); + } +} diff --git a/querydsl-lucene3/src/main/java/com/querydsl/lucene3/IgnoreCaseUnsupportedException.java b/querydsl-lucene3/src/main/java/com/querydsl/lucene3/IgnoreCaseUnsupportedException.java new file mode 100644 index 0000000000..bd2dc7df46 --- /dev/null +++ b/querydsl-lucene3/src/main/java/com/querydsl/lucene3/IgnoreCaseUnsupportedException.java @@ -0,0 +1,30 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.lucene3; + +/** + * Thrown for case ignore usage + * + * @author tiwe + * + */ +public class IgnoreCaseUnsupportedException extends UnsupportedOperationException { + + private static final long serialVersionUID = 412913389929530788L; + + public IgnoreCaseUnsupportedException() { + super("Ignore case queries are not supported with Lucene"); + } + +} diff --git a/querydsl-lucene3/src/main/java/com/querydsl/lucene3/LuceneExpressions.java b/querydsl-lucene3/src/main/java/com/querydsl/lucene3/LuceneExpressions.java new file mode 100644 index 0000000000..433921fe66 --- /dev/null +++ b/querydsl-lucene3/src/main/java/com/querydsl/lucene3/LuceneExpressions.java @@ -0,0 +1,73 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.lucene3; + +import org.apache.lucene.index.Term; +import org.apache.lucene.search.FuzzyQuery; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.dsl.BooleanExpression; + +/** + * Utility methods to create filter expressions for Lucene queries that are not covered by the + * Querydsl standard expression model + * + * @author tiwe + * + */ +public final class LuceneExpressions { + + /** + * Create a fuzzy query + * + * @param path path + * @param value value to match + * @return condition + */ + public static BooleanExpression fuzzyLike(Path<String> path, String value) { + Term term = new Term(path.getMetadata().getName(), value); + return new QueryElement(new FuzzyQuery(term)); + } + + /** + * Create a fuzzy query + * + * @param path path + * @param value value to match + * @param minimumSimilarity a value between 0 and 1 to set the required similarity + * @return condition + */ + public static BooleanExpression fuzzyLike(Path<String> path, String value, float minimumSimilarity) { + Term term = new Term(path.getMetadata().getName(), value); + return new QueryElement(new FuzzyQuery(term, minimumSimilarity)); + } + + /** + * Create a fuzzy query + * + * @param path path + * @param value value to match + * @param minimumSimilarity a value between 0 and 1 to set the required similarity + * @param prefixLength length of common (non-fuzzy) prefix + * @return condition + */ + public static BooleanExpression fuzzyLike(Path<String> path, String value, + float minimumSimilarity, int prefixLength) { + Term term = new Term(path.getMetadata().getName(), value); + return new QueryElement(new FuzzyQuery(term, minimumSimilarity, prefixLength)); + } + + private LuceneExpressions() { } + +} diff --git a/querydsl-lucene3/src/main/java/com/querydsl/lucene3/LuceneOps.java b/querydsl-lucene3/src/main/java/com/querydsl/lucene3/LuceneOps.java new file mode 100644 index 0000000000..2a18da4eb6 --- /dev/null +++ b/querydsl-lucene3/src/main/java/com/querydsl/lucene3/LuceneOps.java @@ -0,0 +1,39 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.lucene3; + +import com.querydsl.core.types.Operator; + +/** + * Lucene specific operators + * + * @author tiwe + * + */ +public enum LuceneOps implements Operator { + LUCENE_QUERY(Object.class), + PHRASE(String.class), + TERM(String.class); + + private final Class<?> type; + + LuceneOps(Class<?> type) { + this.type = type; + } + + @Override + public Class<?> getType() { + return type; + } +} diff --git a/querydsl-lucene3/src/main/java/com/querydsl/lucene3/LuceneQuery.java b/querydsl-lucene3/src/main/java/com/querydsl/lucene3/LuceneQuery.java new file mode 100644 index 0000000000..31cca76a5e --- /dev/null +++ b/querydsl-lucene3/src/main/java/com/querydsl/lucene3/LuceneQuery.java @@ -0,0 +1,55 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.lucene3; + +import org.apache.lucene.document.Document; +import org.apache.lucene.search.IndexSearcher; + +import java.util.function.Function; + +/** + * {@code LuceneQuery} is a Querydsl query implementation for Lucene queries. + * + * <p>Example:</p> + * + * <pre>{@code + * QDocument doc = new QDocument("doc"); + * + * IndexSearcher searcher = new IndexSearcher(index); + * LuceneQuery query = new LuceneQuery(true, searcher); + * List<Document> documents = query + * .where(doc.year.between("1800", "2000").and(doc.title.startsWith("Huckle")) + * .fetch(); + * }</pre> + * + * @author vema + */ +public class LuceneQuery extends AbstractLuceneQuery<Document, LuceneQuery> { + + private static final Function<Document,Document> TRANSFORMER = new Function<Document,Document>() { + @Override + public Document apply(Document input) { + return input; + } + }; + + public LuceneQuery(IndexSearcher searcher) { + super(searcher, TRANSFORMER); + } + + public LuceneQuery(LuceneSerializer luceneSerializer, IndexSearcher searcher) { + super(luceneSerializer, searcher, TRANSFORMER); + } + +} diff --git a/querydsl-lucene3/src/main/java/com/querydsl/lucene3/LuceneSerializer.java b/querydsl-lucene3/src/main/java/com/querydsl/lucene3/LuceneSerializer.java new file mode 100644 index 0000000000..430fe7fa54 --- /dev/null +++ b/querydsl-lucene3/src/main/java/com/querydsl/lucene3/LuceneSerializer.java @@ -0,0 +1,561 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.lucene3; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.*; + +import org.jetbrains.annotations.Nullable; + +import org.apache.lucene.index.Term; +import org.apache.lucene.queryParser.QueryParser; +import org.apache.lucene.search.*; +import org.apache.lucene.search.BooleanClause.Occur; +import org.apache.lucene.util.NumericUtils; + +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.types.*; + +/** + * Serializes Querydsl queries to Lucene queries. + * + * @author vema + * + */ +public class LuceneSerializer { + private static final Map<Class<?>, Integer> sortFields = new HashMap<Class<?>, Integer>(); + + static { + sortFields.put(Integer.class, SortField.INT); + sortFields.put(Float.class, SortField.FLOAT); + sortFields.put(Long.class, SortField.LONG); + sortFields.put(Double.class, SortField.DOUBLE); + sortFields.put(Short.class, SortField.SHORT); + sortFields.put(Byte.class, SortField.BYTE); + sortFields.put(BigDecimal.class, SortField.DOUBLE); + sortFields.put(BigInteger.class, SortField.LONG); + } + + public static final LuceneSerializer DEFAULT = new LuceneSerializer(false, true); + + private final boolean lowerCase; + + private final boolean splitTerms; + + private final Locale sortLocale; + + public LuceneSerializer(boolean lowerCase, boolean splitTerms) { + this(lowerCase, splitTerms, Locale.getDefault()); + } + + public LuceneSerializer(boolean lowerCase, boolean splitTerms, Locale sortLocale) { + this.lowerCase = lowerCase; + this.splitTerms = splitTerms; + this.sortLocale = sortLocale; + } + + private Query toQuery(Operation<?> operation, QueryMetadata metadata) { + Operator op = operation.getOperator(); + if (op == Ops.OR) { + return toTwoHandSidedQuery(operation, Occur.SHOULD, metadata); + } else if (op == Ops.AND) { + return toTwoHandSidedQuery(operation, Occur.MUST, metadata); + } else if (op == Ops.NOT) { + BooleanQuery bq = new BooleanQuery(); + bq.add(new BooleanClause(toQuery(operation.getArg(0), metadata), Occur.MUST_NOT)); + bq.add(new BooleanClause(new MatchAllDocsQuery(), Occur.MUST)); + return bq; + } else if (op == Ops.LIKE) { + return like(operation, metadata); + } else if (op == Ops.LIKE_IC) { + throw new IgnoreCaseUnsupportedException(); + } else if (op == Ops.EQ) { + return eq(operation, metadata, false); + } else if (op == Ops.EQ_IGNORE_CASE) { + throw new IgnoreCaseUnsupportedException(); + } else if (op == Ops.NE) { + return ne(operation, metadata, false); + } else if (op == Ops.STARTS_WITH) { + return startsWith(metadata, operation, false); + } else if (op == Ops.STARTS_WITH_IC) { + throw new IgnoreCaseUnsupportedException(); + } else if (op == Ops.ENDS_WITH) { + return endsWith(operation, metadata, false); + } else if (op == Ops.ENDS_WITH_IC) { + throw new IgnoreCaseUnsupportedException(); + } else if (op == Ops.STRING_CONTAINS) { + return stringContains(operation, metadata, false); + } else if (op == Ops.STRING_CONTAINS_IC) { + throw new IgnoreCaseUnsupportedException(); + } else if (op == Ops.BETWEEN) { + return between(operation, metadata); + } else if (op == Ops.IN) { + return in(operation, metadata, false); + } else if (op == Ops.NOT_IN) { + return notIn(operation, metadata, false); + } else if (op == Ops.LT) { + return lt(operation, metadata); + } else if (op == Ops.GT) { + return gt(operation, metadata); + } else if (op == Ops.LOE) { + return le(operation, metadata); + } else if (op == Ops.GOE) { + return ge(operation, metadata); + } else if (op == LuceneOps.LUCENE_QUERY) { + @SuppressWarnings("unchecked") //This is the expected type + Query rv = ((Constant<Query>) operation.getArg(0)).getConstant(); + return rv; + } + throw new UnsupportedOperationException("Illegal operation " + operation); + } + + private Query toTwoHandSidedQuery(Operation<?> operation, Occur occur, QueryMetadata metadata) { + Query lhs = toQuery(operation.getArg(0), metadata); + Query rhs = toQuery(operation.getArg(1), metadata); + BooleanQuery bq = new BooleanQuery(); + bq.add(createBooleanClause(lhs, occur)); + bq.add(createBooleanClause(rhs, occur)); + return bq; + } + + /** + * If the query is a BooleanQuery and it contains a single Occur.MUST_NOT + * clause it will be returned as is. Otherwise it will be wrapped in a + * BooleanClause with the given Occur. + */ + private BooleanClause createBooleanClause(Query query, Occur occur) { + if (query instanceof BooleanQuery) { + BooleanClause[] clauses = ((BooleanQuery) query).getClauses(); + if (clauses.length == 1 && clauses[0].getOccur().equals(Occur.MUST_NOT)) { + return clauses[0]; + } + } + return new BooleanClause(query, occur); + } + + protected Query like(Operation<?> operation, QueryMetadata metadata) { + verifyArguments(operation); + Path<?> path = getPath(operation.getArg(0)); + String field = toField(path); + String[] terms = convert(path, operation.getArg(1)); + if (terms.length > 1) { + BooleanQuery bq = new BooleanQuery(); + for (String s : terms) { + bq.add(new WildcardQuery(new Term(field, "*" + s + "*")), Occur.MUST); + } + return bq; + } + return new WildcardQuery(new Term(field, terms[0])); + } + + protected Query eq(Operation<?> operation, QueryMetadata metadata, boolean ignoreCase) { + verifyArguments(operation); + Path<?> path = getPath(operation.getArg(0)); + String field = toField(path); + + if (Number.class.isAssignableFrom(operation.getArg(1).getType())) { + @SuppressWarnings("unchecked") //guarded by previous check + Constant<? extends Number> rightArg = (Constant<? extends Number>) operation.getArg(1); + return new TermQuery(new Term(field, convertNumber(rightArg.getConstant()))); + } + + return eq(field, convert(path, operation.getArg(1), metadata), ignoreCase); + } + + + private String convertNumber(Number number) { + if (Integer.class.isInstance(number)) { + return NumericUtils.intToPrefixCoded(number.intValue()); + } else if (Double.class.isInstance(number)) { + return NumericUtils.doubleToPrefixCoded(number.doubleValue()); + } else if (Long.class.isInstance(number)) { + return NumericUtils.longToPrefixCoded(number.longValue()); + } else if (Float.class.isInstance(number)) { + return NumericUtils.floatToPrefixCoded(number.floatValue()); + } else if (Byte.class.isInstance(number)) { + return NumericUtils.intToPrefixCoded(number.intValue()); + } else if (Short.class.isInstance(number)) { + return NumericUtils.intToPrefixCoded(number.intValue()); + } else if (BigDecimal.class.isInstance(number)) { + return NumericUtils.doubleToPrefixCoded(number.doubleValue()); + } else if (BigInteger.class.isInstance(number)) { + return NumericUtils.longToPrefixCoded(number.longValue()); + } else { + throw new IllegalArgumentException("Unsupported numeric type " + + number.getClass().getName()); + } + } + + protected Query eq(String field, String[] terms, boolean ignoreCase) { + if (terms.length > 1) { + PhraseQuery pq = new PhraseQuery(); + for (String s : terms) { + pq.add(new Term(field, s)); + } + return pq; + } + return new TermQuery(new Term(field, terms[0])); + } + + protected Query in(Operation<?> operation, QueryMetadata metadata, boolean ignoreCase) { + Path<?> path = getPath(operation.getArg(0)); + String field = toField(path); + @SuppressWarnings("unchecked") //This is the second argument type + Constant<Collection<?>> collConstant = (Constant<Collection<?>>) operation.getArg(1); + Collection<?> values = collConstant.getConstant(); + BooleanQuery bq = new BooleanQuery(); + if (Number.class.isAssignableFrom(path.getType())) { + for (Object value : values) { + TermQuery eq = new TermQuery(new Term(field, convertNumber((Number) value))); + bq.add(eq, Occur.SHOULD); + } + } else { + for (Object value : values) { + String[] str = convert(path, value); + bq.add(eq(field, str, ignoreCase), Occur.SHOULD); + } + } + return bq; + } + + protected Query notIn(Operation<?> operation, QueryMetadata metadata, boolean ignoreCase) { + BooleanQuery bq = new BooleanQuery(); + bq.add(new BooleanClause(in(operation, metadata, false), Occur.MUST_NOT)); + bq.add(new BooleanClause(new MatchAllDocsQuery(), Occur.MUST)); + return bq; + } + + protected Query ne(Operation<?> operation, QueryMetadata metadata, boolean ignoreCase) { + BooleanQuery bq = new BooleanQuery(); + bq.add(new BooleanClause(eq(operation, metadata, ignoreCase), Occur.MUST_NOT)); + bq.add(new BooleanClause(new MatchAllDocsQuery(), Occur.MUST)); + return bq; + } + + protected Query startsWith(QueryMetadata metadata, Operation<?> operation, boolean ignoreCase) { + verifyArguments(operation); + Path<?> path = getPath(operation.getArg(0)); + String field = toField(path); + String[] terms = convertEscaped(path, operation.getArg(1), metadata); + if (terms.length > 1) { + BooleanQuery bq = new BooleanQuery(); + for (int i = 0; i < terms.length; ++i) { + String s = i == 0 ? terms[i] + "*" : "*" + terms[i] + "*"; + bq.add(new WildcardQuery(new Term(field, s)), Occur.MUST); + } + return bq; + } + return new PrefixQuery(new Term(field, terms[0])); + } + + + + protected Query stringContains(Operation<?> operation, QueryMetadata metadata, boolean ignoreCase) { + verifyArguments(operation); + Path<?> path = getPath(operation.getArg(0)); + String field = toField(path); + String[] terms = convertEscaped(path, operation.getArg(1), metadata); + if (terms.length > 1) { + BooleanQuery bq = new BooleanQuery(); + for (String s : terms) { + bq.add(new WildcardQuery(new Term(field, "*" + s + "*")), Occur.MUST); + } + return bq; + } + return new WildcardQuery(new Term(field, "*" + terms[0] + "*")); + } + + protected Query endsWith(Operation<?> operation, QueryMetadata metadata, boolean ignoreCase) { + verifyArguments(operation); + Path<?> path = getPath(operation.getArg(0)); + String field = toField(path); + String[] terms = convertEscaped(path, operation.getArg(1), metadata); + if (terms.length > 1) { + BooleanQuery bq = new BooleanQuery(); + for (int i = 0; i < terms.length; ++i) { + String s = i == terms.length - 1 ? "*" + terms[i] : "*" + terms[i] + "*"; + bq.add(new WildcardQuery(new Term(field, s)), Occur.MUST); + } + return bq; + } + return new WildcardQuery(new Term(field, "*" + terms[0])); + } + + protected Query between(Operation<?> operation, QueryMetadata metadata) { + verifyArguments(operation); + Path<?> path = getPath(operation.getArg(0)); + // TODO Phrase not properly supported + return range( + path, + toField(path), + operation.getArg(1), + operation.getArg(2), + true, + true, + metadata); + } + + protected Query lt(Operation<?> operation, QueryMetadata metadata) { + verifyArguments(operation); + Path<?> path = getPath(operation.getArg(0)); + return range( + path, + toField(path), + null, + operation.getArg(1), + false, + false, + metadata); + } + + protected Query gt(Operation<?> operation, QueryMetadata metadata) { + verifyArguments(operation); + Path<?> path = getPath(operation.getArg(0)); + return range( + path, + toField(path), + operation.getArg(1), + null, + false, + false, + metadata); + } + + protected Query le(Operation<?> operation, QueryMetadata metadata) { + verifyArguments(operation); + Path<?> path = getPath(operation.getArg(0)); + return range( + path, + toField(path), + null, + operation.getArg(1), + true, + true, + metadata); + } + + protected Query ge(Operation<?> operation, QueryMetadata metadata) { + verifyArguments(operation); + Path<?> path = getPath(operation.getArg(0)); + return range( + path, + toField(path), + operation.getArg(1), + null, + true, + true, + metadata); + } + + protected Query range(Path<?> leftHandSide, String field, @Nullable Expression<?> min, + @Nullable Expression<?> max, boolean minInc, boolean maxInc, QueryMetadata metadata) { + if (min != null && Number.class.isAssignableFrom(min.getType()) || max != null + && Number.class.isAssignableFrom(max.getType())) { + @SuppressWarnings("unchecked") //guarded by previous check + Constant<? extends Number> minConstant = (Constant<? extends Number>) min; + @SuppressWarnings("unchecked") //guarded by previous check + Constant<? extends Number> maxConstant = (Constant<? extends Number>) max; + + Class<? extends Number> numType = minConstant != null ? minConstant.getType() : maxConstant.getType(); + //this is not necessarily safe, but compile time checking + //on the user side mandates these types to be interchangeable + @SuppressWarnings("unchecked") + Class<Number> unboundedNumType = (Class<Number>) numType; + return numericRange(unboundedNumType, field, minConstant == null ? null + : minConstant.getConstant(), maxConstant == null ? null + : maxConstant.getConstant(), minInc, maxInc); + } + return stringRange(leftHandSide, field, min, max, minInc, maxInc, metadata); + } + + protected <N extends Number> NumericRangeQuery<?> numericRange(Class<N> clazz, String field, + @Nullable N min, @Nullable N max, boolean minInc, boolean maxInc) { + if (clazz.equals(Integer.class)) { + return NumericRangeQuery.newIntRange(field, (Integer) min, (Integer) max, minInc, maxInc); + } else if (clazz.equals(Double.class)) { + return NumericRangeQuery.newDoubleRange(field, (Double) min, (Double) max, minInc, minInc); + } else if (clazz.equals(Float.class)) { + return NumericRangeQuery.newFloatRange(field, (Float) min, (Float) max, minInc, minInc); + } else if (clazz.equals(Long.class)) { + return NumericRangeQuery.newLongRange(field, (Long) min, (Long) max, minInc, minInc); + } else if (clazz.equals(Byte.class) || clazz.equals(Short.class)) { + return NumericRangeQuery.newIntRange(field, min != null ? min.intValue() : null, + max != null ? max.intValue() : null, minInc, maxInc); + } else { + throw new IllegalArgumentException("Unsupported numeric type " + clazz.getName()); + } + } + + protected Query stringRange( + Path<?> leftHandSide, + String field, + @Nullable Expression<?> min, + @Nullable Expression<?> max, + boolean minInc, + boolean maxInc, + QueryMetadata metadata) { + + if (min == null) { + return new TermRangeQuery( + field, null, convert(leftHandSide, max, metadata)[0], minInc, maxInc); + } else if (max == null) { + return new TermRangeQuery( + field, convert(leftHandSide, min, metadata)[0], + null, minInc, maxInc); + } else { + return new TermRangeQuery( + field, convert(leftHandSide, min, metadata)[0], + convert(leftHandSide, max, metadata)[0], + minInc, maxInc); + } + } + + private Path<?> getPath(Expression<?> leftHandSide) { + if (leftHandSide instanceof Path<?>) { + return (Path<?>) leftHandSide; + } else if (leftHandSide instanceof Operation<?>) { + Operation<?> operation = (Operation<?>) leftHandSide; + if (operation.getOperator() == Ops.LOWER || operation.getOperator() == Ops.UPPER) { + return (Path<?>) operation.getArg(0); + } + } + throw new IllegalArgumentException("Unable to transform " + leftHandSide + " to path"); + } + + /** + * template method, override to customize + * + * @param path path + * @return field name + */ + protected String toField(Path<?> path) { + PathMetadata md = path.getMetadata(); + if (md.getPathType() == PathType.COLLECTION_ANY) { + return toField(md.getParent()); + } else { + String rv = md.getName(); + if (md.getParent() != null) { + Path<?> parent = md.getParent(); + if (parent.getMetadata().getPathType() != PathType.VARIABLE) { + rv = toField(parent) + "." + rv; + } + } + return rv; + } + } + + private void verifyArguments(Operation<?> operation) { + List<Expression<?>> arguments = operation.getArgs(); + for (int i = 1; i < arguments.size(); ++i) { + if (!(arguments.get(i) instanceof Constant<?>) + && !(arguments.get(i) instanceof ParamExpression<?>) + && !(arguments.get(i) instanceof PhraseElement) + && !(arguments.get(i) instanceof TermElement)) { + throw new IllegalArgumentException("operand was of unsupported type " + + arguments.get(i).getClass().getName()); + } + } + } + + /** + * template method + * + * @param leftHandSide left hand side + * @param rightHandSide right hand side + * @return results + */ + protected String[] convert(Path<?> leftHandSide, Expression<?> rightHandSide, QueryMetadata metadata) { + if (rightHandSide instanceof Operation) { + Operation<?> operation = (Operation<?>) rightHandSide; + if (operation.getOperator() == LuceneOps.PHRASE) { + return operation.getArg(0).toString().split("\\s+"); + } else if (operation.getOperator() == LuceneOps.TERM) { + return new String[] {operation.getArg(0).toString()}; + } else { + throw new IllegalArgumentException(rightHandSide.toString()); + } + } else if (rightHandSide instanceof ParamExpression<?>) { + Object value = metadata.getParams().get(rightHandSide); + if (value == null) { + throw new ParamNotSetException((ParamExpression<?>) rightHandSide); + } + return convert(leftHandSide, value); + + } else if (rightHandSide instanceof Constant<?>) { + return convert(leftHandSide, ((Constant<?>) rightHandSide).getConstant()); + } else { + throw new IllegalArgumentException(rightHandSide.toString()); + } + } + + /** + * template method + * + * @param leftHandSide left hand side + * @param rightHandSide right hand side + * @return results + */ + protected String[] convert(Path<?> leftHandSide, Object rightHandSide) { + String str = rightHandSide.toString(); + if (lowerCase) { + str = str.toLowerCase(); + } + if (splitTerms) { + if (str.equals("")) { + return new String[] {str}; + } else { + return str.split("\\s+"); + } + } else { + return new String[] {str}; + } + } + + private String[] convertEscaped(Path<?> leftHandSide, Expression<?> rightHandSide, QueryMetadata metadata) { + String[] str = convert(leftHandSide, rightHandSide, metadata); + for (int i = 0; i < str.length; i++) { + str[i] = QueryParser.escape(str[i]); + } + return str; + } + + public Query toQuery(Expression<?> expr, QueryMetadata metadata) { + if (expr instanceof Operation<?>) { + return toQuery((Operation<?>) expr, metadata); + } else { + return toQuery(ExpressionUtils.extract(expr), metadata); + } + } + + public Sort toSort(List<? extends OrderSpecifier<?>> orderBys) { + List<SortField> sorts = new ArrayList<SortField>(orderBys.size()); + for (OrderSpecifier<?> order : orderBys) { + if (!(order.getTarget() instanceof Path<?>)) { + throw new IllegalArgumentException("argument was not of type Path."); + } + Class<?> type = order.getTarget().getType(); + boolean reverse = !order.isAscending(); + Path<?> path = getPath(order.getTarget()); + if (Number.class.isAssignableFrom(type)) { + sorts.add(new SortField(toField(path), sortFields.get(type), reverse)); + } else { + sorts.add(new SortField(toField(path), sortLocale, reverse)); + } + } + Sort sort = new Sort(); + sort.setSort(sorts.toArray(new SortField[0])); + return sort; + } +} diff --git a/querydsl-lucene3/src/main/java/com/querydsl/lucene3/PhraseElement.java b/querydsl-lucene3/src/main/java/com/querydsl/lucene3/PhraseElement.java new file mode 100644 index 0000000000..d3f5822997 --- /dev/null +++ b/querydsl-lucene3/src/main/java/com/querydsl/lucene3/PhraseElement.java @@ -0,0 +1,33 @@ + /* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.lucene3; + +import com.querydsl.core.types.ConstantImpl; +import com.querydsl.core.types.dsl.StringOperation; + +/** + * {@code PhraseElement} represents the embedded String as a phrase + * + * @author tiwe + * + */ +public class PhraseElement extends StringOperation { + + private static final long serialVersionUID = 2350215644019186076L; + + public PhraseElement(String str) { + super(LuceneOps.PHRASE, ConstantImpl.create(str)); + } + +} diff --git a/querydsl-lucene3/src/main/java/com/querydsl/lucene3/QueryElement.java b/querydsl-lucene3/src/main/java/com/querydsl/lucene3/QueryElement.java new file mode 100644 index 0000000000..2ab4d07fdb --- /dev/null +++ b/querydsl-lucene3/src/main/java/com/querydsl/lucene3/QueryElement.java @@ -0,0 +1,35 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.lucene3; + +import org.apache.lucene.search.Query; + +import com.querydsl.core.types.ConstantImpl; +import com.querydsl.core.types.dsl.BooleanOperation; + +/** + * {@code QueryElement} wraps a Lucene Query + * + * @author tiwe + * + */ +public class QueryElement extends BooleanOperation { + + private static final long serialVersionUID = 470868107363840155L; + + public QueryElement(Query query) { + super(LuceneOps.LUCENE_QUERY, ConstantImpl.create(query)); + } + +} diff --git a/querydsl-lucene3/src/main/java/com/querydsl/lucene3/ResultIterator.java b/querydsl-lucene3/src/main/java/com/querydsl/lucene3/ResultIterator.java new file mode 100644 index 0000000000..1d66d985a9 --- /dev/null +++ b/querydsl-lucene3/src/main/java/com/querydsl/lucene3/ResultIterator.java @@ -0,0 +1,86 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.lucene3; + +import com.mysema.commons.lang.CloseableIterator; +import com.querydsl.core.QueryException; +import org.apache.lucene.document.Document; +import org.apache.lucene.document.FieldSelector; +import org.apache.lucene.search.IndexSearcher; +import org.apache.lucene.search.ScoreDoc; +import org.jetbrains.annotations.Nullable; + +import java.io.IOException; +import java.util.function.Function; + +/** + * {@code ResultIterator} is a {@link CloseableIterator} implementation for Lucene query results + * + * @author tiwe + * + * @param <T> + */ +public final class ResultIterator<T> implements CloseableIterator<T> { + + private final ScoreDoc[] scoreDocs; + + private int cursor; + + private final IndexSearcher searcher; + + @Nullable + private final FieldSelector fieldSelector; + + private final Function<Document,T> transformer; + + public ResultIterator(ScoreDoc[] scoreDocs, int offset, IndexSearcher searcher, + @Nullable FieldSelector fieldSelector, Function<Document, T> transformer) { + this.scoreDocs = scoreDocs.clone(); + this.cursor = offset; + this.searcher = searcher; + this.fieldSelector = fieldSelector; + this.transformer = transformer; + } + + @Override + public boolean hasNext() { + return cursor != scoreDocs.length; + } + + @Override + public T next() { + try { + Document document; + if (fieldSelector != null) { + document = searcher.doc(scoreDocs[cursor++].doc, fieldSelector); + } else { + document = searcher.doc(scoreDocs[cursor++].doc); + } + return transformer.apply(document); + } catch (IOException e) { + throw new QueryException(e); + } + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + + @Override + public void close() { + + } + +} \ No newline at end of file diff --git a/querydsl-lucene3/src/main/java/com/querydsl/lucene3/TermElement.java b/querydsl-lucene3/src/main/java/com/querydsl/lucene3/TermElement.java new file mode 100644 index 0000000000..9c54e4936c --- /dev/null +++ b/querydsl-lucene3/src/main/java/com/querydsl/lucene3/TermElement.java @@ -0,0 +1,33 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.lucene3; + +import com.querydsl.core.types.ConstantImpl; +import com.querydsl.core.types.dsl.StringOperation; + +/** + * {@code TermElement} represents the embedded String as a term + * + * @author tiwe + * + */ +public class TermElement extends StringOperation { + + private static final long serialVersionUID = 2350215644019186076L; + + public TermElement(String str) { + super(LuceneOps.TERM, ConstantImpl.create(str)); + } + +} diff --git a/querydsl-lucene3/src/main/java/com/querydsl/lucene3/TypedQuery.java b/querydsl-lucene3/src/main/java/com/querydsl/lucene3/TypedQuery.java new file mode 100644 index 0000000000..0242be9a3e --- /dev/null +++ b/querydsl-lucene3/src/main/java/com/querydsl/lucene3/TypedQuery.java @@ -0,0 +1,54 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.lucene3; + +import org.apache.lucene.document.Document; +import org.apache.lucene.search.IndexSearcher; + +import java.util.function.Function; + +/** + * {@code TypedQuery} is a typed query implementation for Lucene queries. + * + * <p>Converts Lucene documents to typed results via a constructor supplied transformer</p> + * + * @param <T> result type + * + * @author laim + * @author tiwe + */ +public class TypedQuery<T> extends AbstractLuceneQuery<T, TypedQuery<T>> { + + /** + * Create a new TypedQuery instance + * + * @param searcher index searcher + * @param transformer transformer to transform Lucene documents to result objects + */ + public TypedQuery(IndexSearcher searcher, Function<Document, T> transformer) { + super(searcher, transformer); + } + + /** + * Create a new TypedQuery instance + * + * @param serializer serializer + * @param searcher index search + * @param transformer transformer to transform documents to result objects + */ + public TypedQuery(LuceneSerializer serializer, IndexSearcher searcher, Function<Document, T> transformer) { + super(serializer, searcher, transformer); + } + +} diff --git a/querydsl-lucene3/src/main/java/com/querydsl/lucene3/package-info.java b/querydsl-lucene3/src/main/java/com/querydsl/lucene3/package-info.java new file mode 100644 index 0000000000..a91ba33d33 --- /dev/null +++ b/querydsl-lucene3/src/main/java/com/querydsl/lucene3/package-info.java @@ -0,0 +1,18 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ + +/** + * Lucene 3 support + */ +package com.querydsl.lucene3; diff --git a/querydsl-lucene3/src/test/java/com/mysema/query/LuceneSerializerNotTokenizedTest.java b/querydsl-lucene3/src/test/java/com/mysema/query/LuceneSerializerNotTokenizedTest.java deleted file mode 100644 index f1bce88607..0000000000 --- a/querydsl-lucene3/src/test/java/com/mysema/query/LuceneSerializerNotTokenizedTest.java +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query; -import static com.mysema.query.QPerson.person; -import static org.junit.Assert.assertEquals; - -import java.util.Arrays; - -import org.apache.lucene.analysis.standard.StandardAnalyzer; -import org.apache.lucene.document.Document; -import org.apache.lucene.document.Field; -import org.apache.lucene.document.Field.Index; -import org.apache.lucene.document.Field.Store; -import org.apache.lucene.index.IndexReader; -import org.apache.lucene.index.IndexWriter; -import org.apache.lucene.index.IndexWriterConfig; -import org.apache.lucene.search.IndexSearcher; -import org.apache.lucene.search.Query; -import org.apache.lucene.search.TopDocs; -import org.apache.lucene.store.RAMDirectory; -import org.apache.lucene.util.Version; -import org.joda.time.LocalDate; -import org.junit.Before; -import org.junit.Test; - -import com.mysema.query.lucene.LuceneSerializer; -import com.mysema.query.types.Expression; -import com.mysema.query.types.path.StringPath; - -public class LuceneSerializerNotTokenizedTest { - private RAMDirectory idx; - private IndexWriter writer; - private IndexSearcher searcher; - private LuceneSerializer serializer; - - private final QueryMetadata metadata = new DefaultQueryMetadata(); - - private final Person clooney = new Person("actor_1", "George Clooney", new LocalDate(1961, 4, 6)); - private final Person pitt = new Person("actor_2", "Brad Pitt", new LocalDate(1963, 12, 18)); - - private void testQuery(Expression<?> expr, String expectedQuery, int expectedHits) throws Exception { - Query query = serializer.toQuery(expr, metadata); - TopDocs docs = searcher.search(query, 100); - assertEquals(expectedHits, docs.totalHits); - assertEquals(expectedQuery, query.toString()); - } - - private Document createDocument(Person person) { - Document doc = new Document(); - doc.add(new Field("id", person.getId(), Store.YES, Index.NOT_ANALYZED)); - doc.add(new Field("name", person.getName(), Store.YES, Index.NOT_ANALYZED)); - doc.add(new Field("birthDate", person.getBirthDate().toString(), Store.YES, Index.NOT_ANALYZED)); - return doc; - } - - @Before - public void Before() throws Exception { - serializer = new LuceneSerializer(false, false); - idx = new RAMDirectory(); - IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_31, - new StandardAnalyzer(Version.LUCENE_30)) - .setOpenMode(IndexWriterConfig.OpenMode.CREATE); - writer = new IndexWriter(idx, config); - - writer.addDocument(createDocument(clooney)); - writer.addDocument(createDocument(pitt)); - - Document document = new Document(); - for (String movie : Arrays.asList("Interview with the Vampire", - "Up in the Air")) { - document.add(new Field("movie", movie, Store.YES, Index.NOT_ANALYZED)); - } - writer.addDocument(document); - - writer.close(); - - IndexReader reader = IndexReader.open(idx); - searcher = new IndexSearcher(reader); - } - - @Test - public void Equals_By_Id_Matches() throws Exception { - testQuery(person.id.eq("actor_1"), "id:actor_1", 1); - } - - @Test - public void Equals_By_Id_Does_Not_Match() throws Exception { - testQuery(person.id.eq("actor_8"), "id:actor_8", 0); - } - - @Test - public void Equals_By_Name_Matches() throws Exception { - testQuery(person.name.eq("George Clooney"), "name:George Clooney", 1); - } - - @Test(expected=UnsupportedOperationException.class) - public void Equals_By_Name_Ignoring_Case_Does_Not_Match() throws Exception { - testQuery(person.name.equalsIgnoreCase("george clooney"), "name:george clooney", 0); - } - - @Test - public void Equals_By_Name_Does_Not_Match() throws Exception { - testQuery(person.name.eq("George Looney"), "name:George Looney", 0); - } - - @Test - public void Starts_With_Name_Should_Match() throws Exception { - testQuery(person.name.startsWith("George C"), "name:George C*", 1); - } - - @Test - public void Starts_With_Name_Should_Not_Match() throws Exception { - testQuery(person.name.startsWith("George L"), "name:George L*", 0); - } - - @Test - public void Ends_With_Name_Should_Match() throws Exception { - testQuery(person.name.endsWith("e Clooney"), "name:*e Clooney", 1); - } - - @Test - public void Ends_With_Name_Should_Not_Match() throws Exception { - testQuery(person.name.endsWith("e Looney"), "name:*e Looney", 0); - } - - @Test - public void Contains_Name_Should_Match() throws Exception { - testQuery(person.name.contains("oney"), "name:*oney*", 1); - } - - @Test - public void Contains_Name_Should_Not_Match() throws Exception { - testQuery(person.name.contains("bloney"), "name:*bloney*", 0); - } - - @Test - public void In_Names_Should_Match_2() throws Exception { - testQuery(person.name.in("Brad Pitt", "George Clooney"), "name:Brad Pitt name:George Clooney", 2); - } - - @Test - public void Or_By_Name_Should_Match_2() throws Exception { - testQuery( person.name.eq("Brad Pitt") - .or(person.name.eq("George Clooney")), "name:Brad Pitt name:George Clooney", 2); - } - - @Test - public void Equals_By_Birth_Date() throws Exception { - testQuery(person.birthDate.eq(clooney.getBirthDate()), "birthDate:1961-04-06", 1); - } - - @Test - public void Between_Phrase() throws Exception { - testQuery(person.name.between("Brad Pitt","George Clooney"), "name:[Brad Pitt TO George Clooney]", 2); - } - - @Test - public void Not_Equals_Finds_The_Actors_And_Movies() throws Exception { - testQuery(person.name.ne("Michael Douglas"), "-name:Michael Douglas +*:*", 3); - } - - @Test - public void Not_Equals_Finds_Only_Clooney_And_Movies() throws Exception { - testQuery(person.name.ne("Brad Pitt"), "-name:Brad Pitt +*:*", 2); - } - - @Test - public void And_With_Two_Not_Equals_Doesnt_Find_The_Actors() throws Exception { - testQuery( person.name.ne("Brad Pitt") - .and(person.name.ne("George Clooney")), "+(-name:Brad Pitt +*:*) +(-name:George Clooney +*:*)", 1); - } - - @Test - public void Or_With_Two_Not_Equals_Finds_Movies_And_Actors() throws Exception { - testQuery( person.name.ne("Brad Pitt") - .or(person.name.ne("George Clooney")), "(-name:Brad Pitt +*:*) (-name:George Clooney +*:*)", 3); - } - - @Test - public void Negation_Of_Equals_Finds_Movies_And_Actors() throws Exception { - testQuery(person.name.eq("Michael Douglas").not(), "-name:Michael Douglas +*:*", 3); - } - - @Test - public void Negation_Of_Equals_Finds_Pitt_And_Movies() throws Exception { - testQuery(person.name.eq("Brad Pitt").not(), "-name:Brad Pitt +*:*", 2); - } - - @Test - public void Multiple_Field_Search_From_Movies() throws Exception { - StringPath movie = new StringPath("movie"); - testQuery(movie.in("Interview with the Vampire"), "movie:Interview with the Vampire", 1); - testQuery(movie.eq("Up in the Air"), "movie:Up in the Air", 1); - } -} diff --git a/querydsl-lucene3/src/test/java/com/mysema/query/LuceneSerializerTest.java b/querydsl-lucene3/src/test/java/com/mysema/query/LuceneSerializerTest.java deleted file mode 100644 index e2c382825f..0000000000 --- a/querydsl-lucene3/src/test/java/com/mysema/query/LuceneSerializerTest.java +++ /dev/null @@ -1,669 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query; - -import java.io.StringReader; -import java.util.Arrays; - -import com.mysema.query.lucene.LuceneExpressions; -import com.mysema.query.lucene.LuceneSerializer; -import com.mysema.query.lucene.QueryElement; -import com.mysema.query.types.*; -import com.mysema.query.types.expr.BooleanExpression; -import com.mysema.query.types.path.NumberPath; -import com.mysema.query.types.path.PathBuilder; -import com.mysema.query.types.path.StringPath; -import org.apache.lucene.analysis.standard.StandardAnalyzer; -import org.apache.lucene.document.Document; -import org.apache.lucene.document.Field; -import org.apache.lucene.document.Field.Index; -import org.apache.lucene.document.Field.Store; -import org.apache.lucene.document.NumericField; -import org.apache.lucene.index.IndexReader; -import org.apache.lucene.index.IndexWriter; -import org.apache.lucene.index.IndexWriterConfig; -import org.apache.lucene.search.IndexSearcher; -import org.apache.lucene.search.Query; -import org.apache.lucene.search.TopDocs; -import org.apache.lucene.store.RAMDirectory; -import org.apache.lucene.util.NumericUtils; -import org.apache.lucene.util.Version; -import org.junit.After; -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; - -/** - * Tests for LuceneSerializer - * - * @author vema - * - */ -public class LuceneSerializerTest { - private LuceneSerializer serializer; - private PathBuilder<Object> entityPath; - private StringPath title; - private StringPath author; - private StringPath text; - private StringPath rating; - private StringPath publisher; - private NumberPath<Integer> year; - private NumberPath<Double> gross; - - private NumberPath<Long> longField; - private NumberPath<Short> shortField; - private NumberPath<Byte> byteField; - private NumberPath<Float> floatField; - - private static final String YEAR_PREFIX_CODED = NumericUtils.intToPrefixCoded(1990); - private static final String GROSS_PREFIX_CODED = NumericUtils.doubleToPrefixCoded(900.00); - private static final String LONG_PREFIX_CODED = NumericUtils.longToPrefixCoded(1); - private static final String SHORT_PREFIX_CODED = NumericUtils.intToPrefixCoded(1); - private static final String BYTE_PREFIX_CODED = NumericUtils.intToPrefixCoded(1); - private static final String FLOAT_PREFIX_CODED = NumericUtils.floatToPrefixCoded((float)1.0); - - private IndexWriterConfig config; - private RAMDirectory idx; - private IndexWriter writer; - private IndexSearcher searcher; - - private final QueryMetadata metadata = new DefaultQueryMetadata(); - - private Document createDocument() { - Document doc = new Document(); - - doc.add(new Field("title", new StringReader("Jurassic Park"))); - doc.add(new Field("author", new StringReader("Michael Crichton"))); - doc.add(new Field("text", new StringReader("It's a UNIX system! I know this!"))); - doc.add(new Field("rating", new StringReader("Good"))); - doc.add(new Field("publisher", "", Store.YES, Index.ANALYZED)); - doc.add(new NumericField("year", Store.YES, true).setIntValue(1990)); - doc.add(new NumericField("gross", Store.YES, true).setDoubleValue(900.00)); - - doc.add(new NumericField("longField", Store.YES, true).setLongValue(1)); - doc.add(new NumericField("shortField", Store.YES, true).setIntValue(1)); - doc.add(new NumericField("byteField", Store.YES, true).setIntValue(1)); - doc.add(new NumericField("floatField", Store.YES, true).setFloatValue(1)); - - return doc; - } - - @Before - public void setUp() throws Exception { - serializer = new LuceneSerializer(true,true); - entityPath = new PathBuilder<Object>(Object.class, "obj"); - title = entityPath.getString("title"); - author = entityPath.getString("author"); - text = entityPath.getString("text"); - publisher = entityPath.getString("publisher"); - year = entityPath.getNumber("year", Integer.class); - rating = entityPath.getString("rating"); - gross = entityPath.getNumber("gross", Double.class); - - longField = entityPath.getNumber("longField", Long.class); - shortField = entityPath.getNumber("shortField", Short.class); - byteField = entityPath.getNumber("byteField", Byte.class); - floatField = entityPath.getNumber("floatField", Float.class); - - idx = new RAMDirectory(); - config = new IndexWriterConfig(Version.LUCENE_31, - new StandardAnalyzer(Version.LUCENE_30)) - .setOpenMode(IndexWriterConfig.OpenMode.CREATE); - writer = new IndexWriter(idx, config); - - writer.addDocument(createDocument()); - - writer.close(); - - IndexReader reader = IndexReader.open(idx); - searcher = new IndexSearcher(reader); - } - - @After - public void tearDown() throws Exception { - searcher.close(); - } - - private void testQuery(Expression<?> expr, int expectedHits) throws Exception { - Query query = serializer.toQuery(expr, metadata); - TopDocs docs = searcher.search(query, 100); - assertEquals(expectedHits, docs.totalHits); - } - - private void testQuery(Expression<?> expr, String expectedQuery, int expectedHits) throws Exception { - Query query = serializer.toQuery(expr, metadata); - TopDocs docs = searcher.search(query, 100); - assertEquals(expectedHits, docs.totalHits); - assertEquals(expectedQuery, query.toString()); - } - - @Test - public void QueryElement() throws Exception{ - Query query1 = serializer.toQuery(author.like("Michael"), metadata); - Query query2 = serializer.toQuery(text.like("Text"), metadata); - - BooleanExpression query = BooleanExpression.anyOf( - new QueryElement(query1), - new QueryElement(query2) - ); - testQuery(query, "author:michael text:text", 1); - } - - @Test - public void Like() throws Exception { - testQuery(author.like("*ichael*"), "author:*ichael*", 1); - } - - @Test - public void Like_Custom_Wildcard_Single_Character() throws Exception { - testQuery(author.like("Mi?hael"), "author:mi?hael", 1); - } - - @Test - public void Like_Custom_Wildcard_Multiple_Character() throws Exception { - testQuery(text.like("*U*X*"), "text:*u*x*", 1); - } - - @Test - public void Like_Phrase() throws Exception { - testQuery(title.like("*rassic Par*"), "+title:**rassic* +title:*par**", 1); - } - - @Test - public void Like_or_like() throws Exception { - testQuery(title.like("House").or(author.like("*ichae*")), "title:house author:*ichae*", 1); - } - - @Test - public void Like_and_like() throws Exception { - testQuery(title.like("*assic*").and(rating.like("G?od")), "+title:*assic* +rating:g?od", 1); - } - - @Test - public void Eq() throws Exception { - testQuery(rating.eq("good"), "rating:good", 1); - } - - @Test - public void Eq_with_deep_path() throws Exception{ - StringPath deepPath = entityPath.get("property1", Object.class).getString("property2"); - testQuery(deepPath.eq("good"), "property1.property2:good", 0); - } - - @Test - public void FuzzyLike() throws Exception{ - testQuery(LuceneExpressions.fuzzyLike(rating, "Good"), "rating:Good~0.5", 1); - } - - @Test - public void FuzzyLike_with_Similarity() throws Exception{ - testQuery(LuceneExpressions.fuzzyLike(rating, "Good", 0.6f), "rating:Good~0.6", 1); - } - - @Test - public void FuzzyLike_with_Similarity_and_prefix() throws Exception{ - testQuery(LuceneExpressions.fuzzyLike(rating, "Good", 0.6f, 0), "rating:Good~0.6", 1); - } - - @Test - public void Eq_Numeric_Integer() throws Exception { - testQuery(year.eq(1990), "year:" + YEAR_PREFIX_CODED, 1); - } - - @Test - public void Eq_Numeric_Double() throws Exception { - testQuery(gross.eq(900.00), "gross:" + GROSS_PREFIX_CODED, 1); - } - - @Test - public void Eq_Numeric() throws Exception{ - testQuery(longField.eq(1l), "longField:" + LONG_PREFIX_CODED, 1); - testQuery(shortField.eq((short)1), "shortField:" + SHORT_PREFIX_CODED, 1); - testQuery(byteField.eq((byte)1), "byteField:" + BYTE_PREFIX_CODED, 1); - testQuery(floatField.eq((float)1.0), "floatField:" + FLOAT_PREFIX_CODED, 1); - } - - @Test - public void Equals_Ignores_Case() throws Exception { - testQuery(title.eq("Jurassic"), "title:jurassic", 1); - } - - @Test(expected=UnsupportedOperationException.class) - public void Title_Equals_Ignore_Case_Or_Year_Equals() throws Exception { - testQuery(title.equalsIgnoreCase("House").or(year.eq(1990)), "title:house year:" + YEAR_PREFIX_CODED, 1); - } - - @Test - public void Eq_and_eq() throws Exception { - testQuery(title.eq("Jurassic Park").and(year.eq(1990)), "+title:\"jurassic park\" +year:" + YEAR_PREFIX_CODED, 1); - } - - @Test - public void Eq_and_Eq_and_eq() throws Exception { - testQuery(title.eq("Jurassic Park").and(year.eq(1990)).and(author.eq("Michael Crichton")), "+(+title:\"jurassic park\" +year:" + YEAR_PREFIX_CODED + ") +author:\"michael crichton\"", 1); - } - - @Test(expected=UnsupportedOperationException.class) - public void Equals_Ignore_Case_And_Or() throws Exception { - testQuery(title.equalsIgnoreCase("Jurassic Park").and(rating.equalsIgnoreCase("Bad")).or(author.equalsIgnoreCase("Michael Crichton")), "(+title:\"jurassic park\" +rating:bad) author:\"michael crichton\"", 1); - } - - @Test - public void Eq_or_Eq_and_Eq_Does_Not_Find_Results() throws Exception { - testQuery(title.eq("jeeves").or(rating.eq("superb")).and(author.eq("michael crichton")), "+(title:jeeves rating:superb) +author:\"michael crichton\"", 0); - } - - @Test - public void Eq_Phrase() throws Exception { - testQuery(title.eq("Jurassic Park"), "title:\"jurassic park\"", 1); - } - - @Test - @Ignore("Not easily done in Lucene!") - public void Publisher_Equals_Empty_String() throws Exception { - testQuery(publisher.eq(""), "publisher:", 1); - } - - @Test - public void Eq_Phrase_Should_Not_Find_Results_But_LuceNe_Semantics_Differs_From_Querydsls() throws Exception { - testQuery(text.eq("UNIX System"), "text:\"unix system\"", 1); - } - - @Test - public void Eq_Phrase_Does_Not_Find_Results_Because_Word_In_Middle() throws Exception { - testQuery(title.eq("Jurassic Amusement Park"), "title:\"jurassic amusement park\"", 0); - } - - @Test - public void Like_not_Does_Not_Find_Results() throws Exception { - testQuery(title.like("*H*e*").not(), "-title:*h*e* +*:*", 1); - } - - @Test(expected=UnsupportedOperationException.class) - public void Title_Equals_Ignore_Case_Negation_Or_Rating_Equals_Ignore_Case() throws Exception { - testQuery(title.equalsIgnoreCase("House").not().or(rating.equalsIgnoreCase("Good")), "-title:house rating:good", 1); - } - - @Test - public void Eq_not_Does_Not_Find_Results() throws Exception { - testQuery(title.eq("Jurassic Park").not(), "-title:\"jurassic park\" +*:*", 0); - } - - @Test - public void Title_Equals_Not_House() throws Exception { - testQuery(title.eq("house").not(), "-title:house +*:*", 1); - } - - @Test - public void Eq_and_Eq_not_Does_Not_Find_Results_Because_Second_Expression_Finds_Nothing() throws Exception { - testQuery(rating.eq("superb").and(title.eq("house").not()), "+rating:superb +(-title:house +*:*)", 0); - } - - @Test - public void Not_Equals_Finds_One() throws Exception { - testQuery(title.ne("house"), "-title:house +*:*", 1); - } - - @Test - public void Not_Equals_Finds_None() throws Exception { - testQuery(title.ne("Jurassic Park"), "-title:\"jurassic park\" +*:*", 0); - } - - @Test - public void Nothing_Found_With_Not_Equals_Or_Equals() throws Exception { - testQuery(title.ne("jurassic park").or(rating.eq("lousy")), "(-title:\"jurassic park\" +*:*) rating:lousy", 0); - } - - @Test - public void Ne_and_eq() throws Exception { - testQuery(title.ne("house").and(rating.eq("good")), "+(-title:house +*:*) +rating:good", 1); - } - - @Test - public void StartsWith() throws Exception { - testQuery(title.startsWith("Jurassi"), "title:jurassi*", 1); - } - - @Test - public void StartsWith_Phrase() throws Exception { - testQuery(title.startsWith("jurassic par"), "+title:jurassic* +title:*par*", 1); - } - - @Test(expected=UnsupportedOperationException.class) - public void Starts_With_Ignore_Case_Phrase_Does_Not_Find_Results() throws Exception { - testQuery(title.startsWithIgnoreCase("urassic Par"), "+title:urassic* +title:*par*", 0); - } - - @Test - public void EndsWith() throws Exception { - testQuery(title.endsWith("ark"), "title:*ark", 1); - } - - @Test(expected=UnsupportedOperationException.class) - public void Ends_With_Ignore_Case_Phrase() throws Exception { - testQuery(title.endsWithIgnoreCase("sic Park"), "+title:*sic* +title:*park", 1); - } - - @Test(expected=UnsupportedOperationException.class) - public void Ends_With_Ignore_Case_Phrase_Does_Not_Find_Results() throws Exception { - testQuery(title.endsWithIgnoreCase("sic Par"), "+title:*sic* +title:*par", 0); - } - - @Test - public void Contains() throws Exception { - testQuery(title.contains("rassi"), "title:*rassi*", 1); - } - - @Test(expected=UnsupportedOperationException.class) - public void Contains_Ignore_Case_Phrase() throws Exception { - testQuery(title.containsIgnoreCase("rassi Pa"), "+title:*rassi* +title:*pa*", 1); - } - - @Test - public void Contains_User_Inputted_Wildcards_Dont_Work() throws Exception { - testQuery(title.contains("r*i"), "title:*r\\*i*", 0); - } - - @Test - public void Between() throws Exception { - testQuery(title.between("Indiana", "Kundun"), "title:[indiana TO kundun]", 1); - } - - @Test - public void Between_Numeric_Integer() throws Exception { - testQuery(year.between(1980, 2000), "year:[1980 TO 2000]", 1); - } - - @Test - public void Between_Numeric_Double() throws Exception { - testQuery(gross.between(10.00, 19030.00), "gross:[10.0 TO 19030.0]", 1); - } - - @Test - public void Between_Numeric() throws Exception{ - testQuery(longField.between(0l,2l), "longField:[0 TO 2]", 1); - testQuery(shortField.between((short)0,(short)2), "shortField:[0 TO 2]", 1); - testQuery(byteField.between((byte)0,(byte)2), "byteField:[0 TO 2]", 1); - testQuery(floatField.between((float)0.0,(float)2.0), "floatField:[0.0 TO 2.0]", 1); - } - - @Test - public void Between_Is_Inclusive_From_Start() throws Exception { - testQuery(title.between("Jurassic", "Kundun"), "title:[jurassic TO kundun]", 1); - } - - @Test - public void Between_Is_Inclusive_To_End() throws Exception { - testQuery(title.between("Indiana", "Jurassic"), "title:[indiana TO jurassic]", 1); - } - - @Test - public void Between_Does_Not_Find_Results() throws Exception { - testQuery(title.between("Indiana", "Jurassib"), "title:[indiana TO jurassib]", 0); - } - - @Test - public void In() throws Exception { - testQuery(title.in(Arrays.asList("jurassic", "park")), "title:jurassic title:park", 1); - testQuery(title.in("jurassic","park"), "title:jurassic title:park", 1); - testQuery(title.eq("jurassic").or(title.eq("park")), "title:jurassic title:park", 1); - } - - @Test - public void Lt() throws Exception { - testQuery(rating.lt("Superb"), "rating:{* TO superb}", 1); - } - - @Test - public void Lt_Numeric_Integer() throws Exception { - testQuery(year.lt(1991), "year:{* TO 1991}", 1); - } - - @Test - public void Lt_Numeric_Double() throws Exception { - testQuery(gross.lt(10000.0), "gross:{* TO 10000.0}", 1); - } - - @Test - public void Lt_Not_In_Range_Because_Equal() throws Exception { - testQuery(rating.lt("Good"), "rating:{* TO good}", 0); - } - - @Test - public void Lt_Numeric_Integer_Not_In_Range_Because_Equal() throws Exception { - testQuery(year.lt(1990), "year:{* TO 1990}", 0); - } - - @Test - public void Lt_Numeric_Double_Not_In_Range_Because_Equal() throws Exception { - testQuery(gross.lt(900.0), "gross:{* TO 900.0}", 0); - } - - @Test - public void Loe() throws Exception { - testQuery(rating.loe("Superb"), "rating:[* TO superb]", 1); - } - - @Test - public void Loe_Numeric_Integer() throws Exception { - testQuery(year.loe(1991), "year:[* TO 1991]", 1); - } - - @Test - public void Loe_Numeric_Double() throws Exception { - testQuery(gross.loe(903.0), "gross:[* TO 903.0]", 1); - } - - @Test - public void Loe_Equal() throws Exception { - testQuery(rating.loe("Good"), "rating:[* TO good]", 1); - } - - @Test - public void Loe_Numeric_Integer_Equal() throws Exception { - testQuery(year.loe(1990), "year:[* TO 1990]", 1); - } - - @Test - public void Loe_Numeric_Double_Equal() throws Exception { - testQuery(gross.loe(900.0), "gross:[* TO 900.0]", 1); - } - - @Test - public void Loe_Not_Found() throws Exception { - testQuery(rating.loe("Bad"), "rating:[* TO bad]", 0); - } - - @Test - public void Loe_Numeric_Integer_Not_Found() throws Exception { - testQuery(year.loe(1989), "year:[* TO 1989]", 0); - } - - @Test - public void Loe_Numeric_Double_Not_Found() throws Exception { - testQuery(gross.loe(899.9), "gross:[* TO 899.9]", 0); - } - - @Test - public void Gt() throws Exception { - testQuery(rating.gt("Bad"), "rating:{bad TO *}", 1); - } - - @Test - public void Gt_Numeric_Integer() throws Exception { - testQuery(year.gt(1989), "year:{1989 TO *}", 1); - } - - @Test - public void Gt_Numeric_Double() throws Exception { - testQuery(gross.gt(100.00), "gross:{100.0 TO *}", 1); - } - - @Test - public void Gt_Not_In_Range_Because_Equal() throws Exception { - testQuery(rating.gt("Good"), "rating:{good TO *}", 0); - } - - @Test - public void Gt_Numeric_Integer_Not_In_Range_Because_Equal() throws Exception { - testQuery(year.gt(1990), "year:{1990 TO *}", 0); - } - - @Test - public void Gt_Numeric_Double_Not_In_Range_Because_Equal() throws Exception { - testQuery(gross.gt(900.00), "gross:{900.0 TO *}", 0); - } - - @Test - public void Goe() throws Exception { - testQuery(rating.goe("Bad"), "rating:[bad TO *]", 1); - } - - @Test - public void Goe_Numeric_Integer() throws Exception { - testQuery(year.goe(1989), "year:[1989 TO *]", 1); - } - - @Test - public void Goe_Numeric_Double() throws Exception { - testQuery(gross.goe(320.50), "gross:[320.5 TO *]", 1); - } - - @Test - public void Goe_Equal() throws Exception { - testQuery(rating.goe("Good"), "rating:[good TO *]", 1); - } - - @Test - public void Goe_Numeric_Integer_Equal() throws Exception { - testQuery(year.goe(1990), "year:[1990 TO *]", 1); - } - - @Test - public void Goe_Numeric_Double_Equal() throws Exception { - testQuery(gross.goe(900.00), "gross:[900.0 TO *]", 1); - } - - @Test - public void Goe_Not_Found() throws Exception { - testQuery(rating.goe("Hood"), "rating:[hood TO *]", 0); - } - - @Test - public void Goe_Numeric_Integer_Not_Found() throws Exception { - testQuery(year.goe(1991), "year:[1991 TO *]", 0); - } - - @Test - public void Goe_Numeric_Double_Not_Found() throws Exception { - testQuery(gross.goe(900.10), "gross:[900.1 TO *]", 0); - } - - @Test - public void Equals_Empty_String() throws Exception { - testQuery(title.eq(""), "title:", 0); - } - - @Test - public void Not_Equals_Empty_String() throws Exception { - testQuery(title.ne(""), "-title: +*:*", 1); - } - - @Test - public void Contains_Empty_String() throws Exception { - testQuery(title.contains(""), "title:**", 1); - } - - @Test - public void Like_Empty_String() throws Exception { - testQuery(title.like(""), "title:", 0); - } - - @Test - public void Starts_With_Empty_String() throws Exception { - testQuery(title.startsWith(""), "title:*", 1); - } - - @Test - public void Ends_With_Empty_String() throws Exception { - testQuery(title.endsWith(""), "title:*", 1); - } - - @Test - public void Between_Empty_Strings() throws Exception { - testQuery(title.between("", ""), "title:[ TO ]", 0); - } - - @Test - public void BooleanBuilder() throws Exception{ - testQuery(new BooleanBuilder(gross.goe(900.10)), "gross:[900.1 TO *]", 0); - } - - @Test - @Ignore - public void Fuzzy() throws Exception { - fail("Not yet implemented!"); - } - - @Test - @Ignore - public void Proximity() throws Exception { - fail("Not yet implemented!"); - } - - @Test - @Ignore - public void Boost() throws Exception { - fail("Not yet implemented!"); - } - - private boolean unsupportedOperation(Predicate filter) { - if (filter instanceof Operation<?>) { - Operator<?> op = ((Operation<?>) filter).getOperator(); - if (op == Ops.STARTS_WITH_IC || op == Ops.EQ_IGNORE_CASE || op == Ops.STARTS_WITH_IC - || op == Ops.ENDS_WITH_IC || op == Ops.STRING_CONTAINS_IC) { - return true; - } - } - return false; - } - - @Test - public void various() throws Exception{ - MatchingFiltersFactory filters = new MatchingFiltersFactory(Module.LUCENE, Target.LUCENE); - for (Predicate filter : filters.string(title, StringConstant.create("jurassic park"))) { - if (unsupportedOperation(filter)) { - continue; - } - testQuery(filter, 1); - } - - for (Predicate filter : filters.string(author, StringConstant.create("michael crichton"))) { - if (unsupportedOperation(filter)) { - continue; - } - testQuery(filter, 1); - } - - for (Predicate filter : filters.string(title, StringConstant.create("1990"))) { - if (unsupportedOperation(filter)) { - continue; - } - testQuery(filter, 0); - } - } - -} diff --git a/querydsl-lucene3/src/test/java/com/mysema/query/Person.java b/querydsl-lucene3/src/test/java/com/mysema/query/Person.java deleted file mode 100644 index 32a1ad42e9..0000000000 --- a/querydsl-lucene3/src/test/java/com/mysema/query/Person.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query; - -import org.joda.time.LocalDate; - -import com.mysema.query.annotations.QueryEntity; - -@QueryEntity -public class Person { - private final String id; - private final String name; - private final LocalDate birthDate; - - public Person(String id, String name, LocalDate birthDate) { - this.id = id; - this.name = name; - this.birthDate = birthDate; - } - - public String getId() { - return id; - } - - public LocalDate getBirthDate() { - return birthDate; - } - - public String getName() { - return name; - } -} - - diff --git a/querydsl-lucene3/src/test/java/com/mysema/query/lucene/LuceneQueryTest.java b/querydsl-lucene3/src/test/java/com/mysema/query/lucene/LuceneQueryTest.java deleted file mode 100644 index 7df9ba7802..0000000000 --- a/querydsl-lucene3/src/test/java/com/mysema/query/lucene/LuceneQueryTest.java +++ /dev/null @@ -1,743 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.lucene; - -import static org.easymock.EasyMock.createMockBuilder; -import static org.easymock.EasyMock.expect; -import static org.easymock.EasyMock.replay; -import static org.easymock.EasyMock.verify; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -import java.io.IOException; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.Locale; - -import org.apache.lucene.analysis.standard.StandardAnalyzer; -import org.apache.lucene.document.Document; -import org.apache.lucene.document.Field; -import org.apache.lucene.document.Field.Index; -import org.apache.lucene.document.Field.Store; -import org.apache.lucene.document.MapFieldSelector; -import org.apache.lucene.document.NumericField; -import org.apache.lucene.index.IndexReader; -import org.apache.lucene.index.IndexWriter; -import org.apache.lucene.index.IndexWriterConfig; -import org.apache.lucene.search.DuplicateFilter; -import org.apache.lucene.search.Filter; -import org.apache.lucene.search.IndexSearcher; -import org.apache.lucene.search.Sort; -import org.apache.lucene.store.RAMDirectory; -import org.apache.lucene.util.Version; -import org.junit.After; -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; - -import com.mysema.query.NonUniqueResultException; -import com.mysema.query.QueryException; -import com.mysema.query.QueryModifiers; -import com.mysema.query.SearchResults; -import com.mysema.query.types.ParamNotSetException; -import com.mysema.query.types.expr.Param; -import com.mysema.query.types.path.NumberPath; -import com.mysema.query.types.path.StringPath; - -/** - * Tests for LuceneQuery - * - * @author vema - * - */ -public class LuceneQueryTest { - - private LuceneQuery query; - private StringPath title; - private NumberPath<Integer> year; - private NumberPath<Double> gross; - - private final StringPath sort = new StringPath("sort"); - - private RAMDirectory idx; - private IndexWriter writer; - private IndexSearcher searcher; - - private Document createDocument(final String docTitle, - final String docAuthor, final String docText, final int docYear, - final double docGross) { - final Document doc = new Document(); - - doc.add(new Field("title", docTitle, Store.YES, Index.ANALYZED)); - doc.add(new Field("author", docAuthor, Store.YES, Index.ANALYZED)); - doc.add(new Field("text", docText, Store.YES, Index.ANALYZED)); - doc.add(new NumericField("year", Store.YES, true).setIntValue(docYear)); - doc.add(new NumericField("gross", Store.YES, true) - .setDoubleValue(docGross)); - - return doc; - } - - @Before - public void setUp() throws Exception { - final QDocument entityPath = new QDocument("doc"); - title = entityPath.title; - year = entityPath.year; - gross = entityPath.gross; - - - idx = new RAMDirectory(); - writer = createWriter(idx); - - writer.addDocument(createDocument("Jurassic Park", "Michael Crichton", - "It's a UNIX system! I know this!", 1990, 90.00)); - writer.addDocument(createDocument("Nummisuutarit", "Aleksis Kivi", - "ESKO. Ja iloitset ja riemuitset?", 1864, 10.00)); - writer - .addDocument(createDocument( - "The Lord of the Rings", - "John R. R. Tolkien", - "One Ring to rule them all, One Ring to find them, One Ring to bring them all and in the darkness bind them", - 1954, 89.00)); - writer - .addDocument(createDocument( - "Introduction to Algorithms", - "Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein", - "Bubble sort", 1990, 30.50)); - - writer.close(); - - IndexReader reader = IndexReader.open(idx); - searcher = new IndexSearcher(reader); - query = new LuceneQuery(new LuceneSerializer(true, true), searcher); - } - - private IndexWriter createWriter(RAMDirectory idx) throws Exception { - IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_31, - new StandardAnalyzer(Version.LUCENE_30)) - .setOpenMode(IndexWriterConfig.OpenMode.CREATE); - return new IndexWriter(idx, config); - } - - @After - public void tearDown() throws Exception { - searcher.close(); - } - - @Test - public void Count_Empty_Where_Clause() { - assertEquals(4, query.count()); - } - - @Test - public void Exists() { - assertTrue(query.where(title.eq("Jurassic Park")).exists()); - assertFalse(query.where(title.eq("Jurassic Park X")).exists()); - } - - @Test - public void NotExists() { - assertFalse(query.where(title.eq("Jurassic Park")).notExists()); - assertTrue(query.where(title.eq("Jurassic Park X")).notExists()); - } - - @Test - public void Count() { - query.where(title.eq("Jurassic Park")); - assertEquals(1, query.count()); - } - - @Test(expected = QueryException.class) - public void Count_Index_Problem() throws IOException { - searcher = createMockBuilder(IndexSearcher.class).addMockedMethod( - "maxDoc").createMock(); - query = new LuceneQuery(new LuceneSerializer(true, true), searcher); - expect(searcher.maxDoc()).andThrow(new IllegalArgumentException()); - replay(searcher); - query.where(title.eq("Jurassic Park")); - query.count(); - verify(searcher); - } - - @Test(expected=UnsupportedOperationException.class) - public void CountDistinct() { - query.where(year.between(1900, 3000)); - assertEquals(3, query.distinct().count()); - } - - @Test - public void List_Sorted_By_Year_Ascending() { - query.where(year.between(1800, 2000)); - query.orderBy(year.asc()); - final List<Document> documents = query.list(); - assertFalse(documents.isEmpty()); - assertEquals(4, documents.size()); - } - - @Test - public void List_Not_Sorted() { - query.where(year.between(1800, 2000)); - final List<Document> documents = query.list(); - assertFalse(documents.isEmpty()); - assertEquals(4, documents.size()); - } - - @Test - public void Sorted_By_Different_Locales() throws Exception { - Document d1 = new Document(); - Document d2 = new Document(); - Document d3 = new Document(); - d1.add(new Field("sort", "a\u00c4",Store.YES, Index.NOT_ANALYZED)); - d2.add(new Field("sort", "ab",Store.YES, Index.NOT_ANALYZED)); - d3.add(new Field("sort", "aa",Store.YES, Index.NOT_ANALYZED)); - writer = createWriter(idx); - writer.addDocument(d1); - writer.addDocument(d2); - writer.addDocument(d3); - writer.close(); - - IndexReader reader = IndexReader.open(idx); - searcher = new IndexSearcher(reader); - query = new LuceneQuery(new LuceneSerializer(true, true, Locale.ENGLISH), searcher); - assertEquals(3, query.list().size()); - List<Document> results = query.where(sort.startsWith("a")).orderBy(sort.asc()).list(); - assertEquals(3, results.size()); - assertEquals("aa", results.get(0).getFieldable("sort").stringValue()); - assertEquals("a\u00c4", results.get(1).getFieldable("sort").stringValue()); - assertEquals("ab", results.get(2).getFieldable("sort").stringValue()); - - query = new LuceneQuery(new LuceneSerializer(true, true, new Locale("fi", "FI")), searcher); - results = query.where(sort.startsWith("a")).orderBy(sort.asc()).list(); - assertEquals("aa", results.get(0).getFieldable("sort").stringValue()); - assertEquals("ab", results.get(1).getFieldable("sort").stringValue()); - assertEquals("a\u00c4", results.get(2).getFieldable("sort").stringValue()); - - - } - - @Test - public void List_Not_Sorted_Limit_2() { - query.where(year.between(1800, 2000)); - query.limit(2); - final List<Document> documents = query.list(); - assertFalse(documents.isEmpty()); - assertEquals(2, documents.size()); - } - - @Test - public void List_Sorted_By_Year_Limit_1() { - query.where(year.between(1800, 2000)); - query.limit(1); - query.orderBy(year.asc()); - final List<Document> documents = query.list(); - assertFalse(documents.isEmpty()); - assertEquals(1, documents.size()); - } - - @Test - public void List_Not_Sorted_Offset_2() { - query.where(year.between(1800, 2000)); - query.offset(2); - final List<Document> documents = query.list(); - assertFalse(documents.isEmpty()); - assertEquals(2, documents.size()); - } - - @Test - public void List_Sorted_Ascending_By_Year_Offset_2() { - query.where(year.between(1800, 2000)); - query.offset(2); - query.orderBy(year.asc()); - final List<Document> documents = query.list(); - assertFalse(documents.isEmpty()); - assertEquals(2, documents.size()); - assertEquals("1990", documents.get(0).get("year")); - assertEquals("1990", documents.get(1).get("year")); - } - - @Test - public void List_Sorted_Ascending_By_Year_Restrict_Limit_2_Offset_1() { - query.where(year.between(1800, 2000)); - query.restrict(new QueryModifiers(2l, 1l)); - query.orderBy(year.asc()); - final List<Document> documents = query.list(); - assertFalse(documents.isEmpty()); - assertEquals(2, documents.size()); - assertEquals("1954", documents.get(0).get("year")); - assertEquals("1990", documents.get(1).get("year")); - } - - @Test - public void List_Sorted_Ascending_By_Year() { - query.where(year.between(1800, 2000)); - query.orderBy(year.asc()); - final List<Document> documents = query.list(); - assertFalse(documents.isEmpty()); - assertEquals(4, documents.size()); - assertEquals("1864", documents.get(0).get("year")); - assertEquals("1954", documents.get(1).get("year")); - assertEquals("1990", documents.get(2).get("year")); - assertEquals("1990", documents.get(3).get("year")); - } - - - @Test - public void List_Sort() { - Sort sort = LuceneSerializer.DEFAULT.toSort(Collections.singletonList(year.asc())); - - query.where(year.between(1800, 2000)); - //query.orderBy(year.asc()); - query.sort(sort); - final List<Document> documents = query.list(); - assertFalse(documents.isEmpty()); - assertEquals(4, documents.size()); - assertEquals("1864", documents.get(0).get("year")); - assertEquals("1954", documents.get(1).get("year")); - assertEquals("1990", documents.get(2).get("year")); - assertEquals("1990", documents.get(3).get("year")); - } - - @Test - public void List_Distinct_Property() { - assertEquals(4, query.list().size()); - assertEquals(3, query.distinct(year).list().size()); - } - - @Test - public void List_With_Filter() { - Filter filter = new DuplicateFilter("year"); - assertEquals(4, query.list().size()); - assertEquals(3, query.filter(filter).list().size()); - } - - @Test - public void Count_Distinct_Property() { - assertEquals(4l, query.count()); - assertEquals(3l, query.distinct(year).count()); - } - - @Test - public void List_Sorted_Descending_By_Year() { - query.where(year.between(1800, 2000)); - query.orderBy(year.desc()); - final List<Document> documents = query.list(); - assertFalse(documents.isEmpty()); - assertEquals(4, documents.size()); - assertEquals("1990", documents.get(0).get("year")); - assertEquals("1990", documents.get(1).get("year")); - assertEquals("1954", documents.get(2).get("year")); - assertEquals("1864", documents.get(3).get("year")); - } - - - @Test - public void List_Sorted_Descending_By_Gross() { - query.where(gross.between(0.0, 1000.00)); - query.orderBy(gross.desc()); - final List<Document> documents = query.list(); - assertFalse(documents.isEmpty()); - assertEquals(4, documents.size()); - assertEquals("90.0", documents.get(0).get("gross")); - assertEquals("89.0", documents.get(1).get("gross")); - assertEquals("30.5", documents.get(2).get("gross")); - assertEquals("10.0", documents.get(3).get("gross")); - } - - @Test - public void List_Sorted_Descending_By_Year_And_Ascending_By_Title() { - query.where(year.between(1800, 2000)); - query.orderBy(year.desc()); - query.orderBy(title.asc()); - final List<Document> documents = query.list(); - assertFalse(documents.isEmpty()); - assertEquals(4, documents.size()); - assertEquals("1990", documents.get(0).get("year")); - assertEquals("1990", documents.get(1).get("year")); - assertEquals("Introduction to Algorithms", documents.get(0) - .get("title")); - assertEquals("Jurassic Park", documents.get(1).get("title")); - } - - @Test - public void List_Sorted_Descending_By_Year_And_Descending_By_Title() { - query.where(year.between(1800, 2000)); - query.orderBy(year.desc()); - query.orderBy(title.desc()); - final List<Document> documents = query.list(); - assertFalse(documents.isEmpty()); - assertEquals(4, documents.size()); - assertEquals("1990", documents.get(0).get("year")); - assertEquals("1990", documents.get(1).get("year")); - assertEquals("Jurassic Park", documents.get(0).get("title")); - assertEquals("Introduction to Algorithms", documents.get(1) - .get("title")); - } - - @Ignore - @Test(expected = QueryException.class) - public void List_Index_Problem_In_Max_Doc() throws IOException { - searcher = createMockBuilder(IndexSearcher.class).addMockedMethod( - "maxDoc").createMock(); - query = new LuceneQuery(new LuceneSerializer(true, true), searcher); - expect(searcher.maxDoc()).andThrow(new IOException()); - replay(searcher); - query.where(title.eq("Jurassic Park")); - query.list(); - verify(searcher); - } - - @Ignore - @Test(expected = QueryException.class) - public void List_Sorted_Index_Problem_In_Max_Doc() throws IOException { - searcher = createMockBuilder(IndexSearcher.class).addMockedMethod( - "maxDoc").createMock(); - query = new LuceneQuery(new LuceneSerializer(true, true), searcher); - expect(searcher.maxDoc()).andThrow(new IOException()); - replay(searcher); - query.where(title.eq("Jurassic Park")); - query.orderBy(title.asc()); - query.list(); - verify(searcher); - } - - @Test - public void Offset() { - assertTrue(query.where(title.eq("Jurassic Park")).offset(30).list() - .isEmpty()); - } - - - @Test - public void Load_List() { - Document document = query.where(title.ne("")).load(title).list().get(0); - assertNotNull(document.get("title")); - assertNull(document.get("year")); - } - - @Test - public void Load_List_FieldSelector() { - Document document = query.where(title.ne("")).load(new MapFieldSelector("title")).list().get(0); - assertNotNull(document.get("title")); - assertNull(document.get("year")); - } - - @Test - public void Load_SingleResult() { - Document document = query.where(title.ne("")).load(title).singleResult(); - assertNotNull(document.get("title")); - assertNull(document.get("year")); - } - - @Test - public void Load_SingleResult_FieldSelector() { - Document document = query.where(title.ne("")).load(new MapFieldSelector("title")).singleResult(); - assertNotNull(document.get("title")); - assertNull(document.get("year")); - } - - @Test - public void SingleResult() { - assertNotNull(query.where(title.ne("")).singleResult()); - } - - @Test - public void Single_Result_Takes_Limit() { - assertEquals("Jurassic Park", query - .where(title.ne("")) - .limit(1) - .singleResult().get("title")); - } - - @Test - public void Single_Result_Considers_Limit_And_Actual_Result_Size() { - query.where(title.startsWith("Nummi")); - final Document document = query.limit(3).singleResult(); - assertEquals("Nummisuutarit", document.get("title")); - } - - @Test - public void Single_Result_Returns_Null_If_Nothing_Is_In_Range() { - query.where(title.startsWith("Nummi")); - assertNull(query.offset(10).singleResult()); - } - - @Test - public void Single_Result_Considers_Offset() { - assertEquals("Introduction to Algorithms", query.where(title.ne("")).offset(3).singleResult().get("title")); - } - - @Test - public void Single_Result_Considers_Limit_And_Offset() { - assertEquals("The Lord of the Rings", query.where(title.ne("")).limit(1).offset(2).singleResult().get("title")); - } - - @Test(expected=NonUniqueResultException.class) - public void UniqueResult_Contract() { - query.where(title.ne("")).uniqueResult(); - } - - @Test - public void Unique_Result_Takes_Limit() { - assertEquals("Jurassic Park", query - .where(title.ne("")) - .limit(1) - .uniqueResult().get("title")); - } - - @Test - public void Unique_Result_Considers_Limit_And_Actual_Result_Size() { - query.where(title.startsWith("Nummi")); - final Document document = query.limit(3).uniqueResult(); - assertEquals("Nummisuutarit", document.get("title")); - } - - @Test - public void Unique_Result_Returns_Null_If_Nothing_Is_In_Range() { - query.where(title.startsWith("Nummi")); - assertNull(query.offset(10).uniqueResult()); - } - - @Test - public void Unique_Result_Considers_Offset() { - assertEquals("Introduction to Algorithms", query.where(title.ne("")).offset(3).uniqueResult().get("title")); - } - - @Test - public void Unique_Result_Considers_Limit_And_Offset() { - assertEquals("The Lord of the Rings", query.where(title.ne("")).limit(1).offset(2).uniqueResult().get("title")); - } - - @Test - public void UniqueResult() { - query.where(title.startsWith("Nummi")); - final Document document = query.uniqueResult(); - assertEquals("Nummisuutarit", document.get("title")); - } - - @Test - public void UniqueResult_With_Param() { - final Param<String> param = new Param<String>(String.class, "title"); - query.set(param, "Nummi"); - query.where(title.startsWith(param)); - final Document document = query.uniqueResult(); - assertEquals("Nummisuutarit", document.get("title")); - } - - @Test(expected = ParamNotSetException.class) - public void UniqueResult_Param_Not_Set() { - final Param<String> param = new Param<String>(String.class, "title"); - query.where(title.startsWith(param)); - query.uniqueResult(); - } - - @Test(expected = QueryException.class) - public void UniqueResult_Finds_More_Than_One_Result() { - query.where(year.eq(1990)); - query.uniqueResult(); - } - - @Test - public void UniqueResult_Finds_No_Results() { - query.where(year.eq(2200)); - assertNull(query.uniqueResult()); - } - - @Test - public void UniqueResult_Finds_No_Results_Because_No_Documents_In_Index() - throws IOException { - searcher = createMockBuilder(IndexSearcher.class).addMockedMethod( - "maxDoc").createMock(); - query = new LuceneQuery(new LuceneSerializer(true, true), searcher); - expect(searcher.maxDoc()).andReturn(0); - replay(searcher); - assertNull(query.where(year.eq(3000)).uniqueResult()); - verify(searcher); - } - - @Test(expected = QueryException.class) - public void UniqueResult_Sorted_Index_Problem_In_Max_Doc() - throws IOException { - searcher = createMockBuilder(IndexSearcher.class).addMockedMethod( - "maxDoc").createMock(); - query = new LuceneQuery(new LuceneSerializer(true, true), searcher); - expect(searcher.maxDoc()).andThrow(new IllegalArgumentException()); - replay(searcher); - query.where(title.eq("Jurassic Park")); - query.uniqueResult(); - verify(searcher); - } - - @Test - public void Count_Returns_0_Because_No_Documents_In_Index() - throws IOException { - searcher = createMockBuilder(IndexSearcher.class).addMockedMethod( - "maxDoc").createMock(); - query = new LuceneQuery(new LuceneSerializer(true, true), searcher); - expect(searcher.maxDoc()).andReturn(0); - replay(searcher); - assertEquals(0, query.where(year.eq(3000)).count()); - verify(searcher); - } - - @Test(expected=UnsupportedOperationException.class) - public void ListDistinct() { - query.where(year.between(1900, 2000).or(title.startsWith("Jura"))); - query.orderBy(year.asc()); - final List<Document> documents = query.distinct().list(); - assertFalse(documents.isEmpty()); - assertEquals(3, documents.size()); - } - - @Test - public void ListResults() { - query.where(year.between(1800, 2000)); - query.restrict(new QueryModifiers(2l, 1l)); - query.orderBy(year.asc()); - final SearchResults<Document> results = query.listResults(); - assertFalse(results.isEmpty()); - assertEquals("1954", results.getResults().get(0).get("year")); - assertEquals("1990", results.getResults().get(1).get("year")); - assertEquals(2, results.getLimit()); - assertEquals(1, results.getOffset()); - assertEquals(4, results.getTotal()); - } - - @Test(expected=UnsupportedOperationException.class) - public void ListDistinctResults() { - query.where(year.between(1800, 2000).or( - title.eq("The Lord of the Rings"))); - query.restrict(new QueryModifiers(1l, 1l)); - query.orderBy(year.asc()); - final SearchResults<Document> results = query.distinct().listResults(); - assertFalse(results.isEmpty()); - assertEquals("1954", results.getResults().get(0).get("year")); - assertEquals(1, results.getLimit()); - assertEquals(1, results.getOffset()); - assertEquals(4, results.getTotal()); - } - - @Test - public void List_All() { - final List<Document> results = query.where(title.like("*")).orderBy( - title.asc(), year.desc()).list(); - assertEquals(4, results.size()); - } - - @Test(expected = IllegalArgumentException.class) - public void List_Sorted_Ascending_Limit_Negative() { - query.where(year.between(1800, 2000)); - query.limit(-1); - query.orderBy(year.asc()); - query.list(); - } - - @Test(expected = IllegalArgumentException.class) - public void List_Not_Sorted_Limit_Negative() { - query.where(year.between(1800, 2000)); - query.limit(-1); - query.list(); - } - - @Test(expected = IllegalArgumentException.class) - public void List_Sorted_Ascending_Limit_0() { - query.where(year.between(1800, 2000)); - query.limit(0); - query.orderBy(year.asc()); - query.list(); - } - - @Test(expected = IllegalArgumentException.class) - public void List_Not_Sorted_Limit_0() { - query.where(year.between(1800, 2000)); - query.limit(0); - query.list(); - } - - @Test(expected = IllegalArgumentException.class) - public void List_Sorted_Ascending_Offset_Negative() { - query.where(year.between(1800, 2000)); - query.offset(-1); - query.orderBy(year.asc()); - query.list(); - } - - @Test(expected = IllegalArgumentException.class) - public void List_Not_Sorted_Offset_Negative() { - query.where(year.between(1800, 2000)); - query.offset(-1); - query.list(); - } - - @Test - public void List_Sorted_Ascending_Offset_0() { - query.where(year.between(1800, 2000)); - query.offset(0); - query.orderBy(year.asc()); - final List<Document> documents = query.list(); - assertFalse(documents.isEmpty()); - assertEquals(4, documents.size()); - } - - @Test - public void List_Not_Sorted_Offset_0() { - query.where(year.between(1800, 2000)); - query.offset(0); - final List<Document> documents = query.list(); - assertFalse(documents.isEmpty()); - assertEquals(4, documents.size()); - } - - @Test - public void Iterate() { - query.where(year.between(1800, 2000)); - final Iterator<Document> iterator = query.iterate(); - int count = 0; - while (iterator.hasNext()) { - iterator.next(); - ++count; - } - assertEquals(4, count); - } - - @Test - public void All_By_Excluding_Where() { - assertEquals(4, query.list().size()); - } - - @Test - public void Empty_Index_Should_Return_Empty_List() throws Exception { - idx = new RAMDirectory(); - - writer = createWriter(idx); - writer.close(); - IndexReader reader = IndexReader.open(idx); - searcher = new IndexSearcher(reader); - query = new LuceneQuery(new LuceneSerializer(true, true), searcher); - assertTrue(query.list().isEmpty()); - } - - @Test(expected = QueryException.class) - public void List_Results_Throws_An_Illegal_Argument_Exception_When_Sum_Of_Limit_And_Offset_Is_Negative() { - query.limit(1).offset(Integer.MAX_VALUE).listResults(); - } - - @Test - public void Limit_Max_Value() { - assertEquals(4, query.limit(Long.MAX_VALUE).list().size()); - } -} diff --git a/querydsl-lucene3/src/test/java/com/mysema/query/lucene/PhraseElementTest.java b/querydsl-lucene3/src/test/java/com/mysema/query/lucene/PhraseElementTest.java deleted file mode 100644 index 2cad5c07f8..0000000000 --- a/querydsl-lucene3/src/test/java/com/mysema/query/lucene/PhraseElementTest.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.lucene; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; - -import org.junit.Test; - -import com.mysema.query.DefaultQueryMetadata; -import com.mysema.query.QueryMetadata; -import com.mysema.query.types.path.StringPath; - -public class PhraseElementTest { - - @Test - public void test() { - StringPath title = new StringPath("title"); - LuceneSerializer serializer = new LuceneSerializer(false,false); - QueryMetadata metadata = new DefaultQueryMetadata(); - assertEquals("title:Hello World", serializer.toQuery(title.eq("Hello World"), metadata).toString()); - assertEquals("title:\"Hello World\"", serializer.toQuery(title.eq(new PhraseElement("Hello World")), metadata).toString()); - } - - @Test - public void Equals() { - PhraseElement el1 = new PhraseElement("x"), el2 = new PhraseElement("x"), el3 = new PhraseElement("y"); - assertEquals(el1, el2); - assertFalse(el1.equals(el3)); - } - - @Test - public void HashCode() { - PhraseElement el1 = new PhraseElement("x"), el2 = new PhraseElement("x"); - assertEquals(el1.hashCode(), el2.hashCode()); - } - -} diff --git a/querydsl-lucene3/src/test/java/com/mysema/query/lucene/QDocument.java b/querydsl-lucene3/src/test/java/com/mysema/query/lucene/QDocument.java deleted file mode 100644 index f8583ca853..0000000000 --- a/querydsl-lucene3/src/test/java/com/mysema/query/lucene/QDocument.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.lucene; - -import org.apache.lucene.document.Document; - -import com.mysema.query.types.PathMetadataFactory; -import com.mysema.query.types.path.EntityPathBase; -import com.mysema.query.types.path.NumberPath; -import com.mysema.query.types.path.StringPath; - -public class QDocument extends EntityPathBase<Document> { - - private static final long serialVersionUID = -4872833626508344081L; - - public QDocument(final String var) { - super(Document.class, PathMetadataFactory.forVariable(var)); - } - - public final NumberPath<Integer> year = createNumber("year", Integer.class); - - public final StringPath title = createString("title"); - - public final NumberPath<Double> gross = createNumber("gross", Double.class); - -} \ No newline at end of file diff --git a/querydsl-lucene3/src/test/java/com/mysema/query/lucene/QueryElementTest.java b/querydsl-lucene3/src/test/java/com/mysema/query/lucene/QueryElementTest.java deleted file mode 100644 index c28949bd0f..0000000000 --- a/querydsl-lucene3/src/test/java/com/mysema/query/lucene/QueryElementTest.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.lucene; - -import static org.junit.Assert.assertEquals; - -import org.apache.lucene.index.Term; -import org.apache.lucene.search.TermQuery; -import org.junit.Ignore; -import org.junit.Test; - -public class QueryElementTest { - - @Test - @Ignore - public void test() { - QueryElement element = new QueryElement(new TermQuery(new Term("str","text"))); - assertEquals("str:text",element.toString()); - //assertEquals(element.getQuery().hashCode(), element.hashCode()); - - QueryElement element2 = new QueryElement(new TermQuery(new Term("str","text"))); - assertEquals(element2, element); - } -} diff --git a/querydsl-lucene3/src/test/java/com/mysema/query/lucene/TermElementTest.java b/querydsl-lucene3/src/test/java/com/mysema/query/lucene/TermElementTest.java deleted file mode 100644 index 2020cfad62..0000000000 --- a/querydsl-lucene3/src/test/java/com/mysema/query/lucene/TermElementTest.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.lucene; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; - -import org.junit.Test; - -import com.mysema.query.DefaultQueryMetadata; -import com.mysema.query.QueryMetadata; -import com.mysema.query.types.path.StringPath; - -public class TermElementTest { - - @Test - public void test() { - StringPath title = new StringPath("title"); - LuceneSerializer serializer = new LuceneSerializer(false,true); - QueryMetadata metadata = new DefaultQueryMetadata(); - assertEquals("title:\"Hello World\"", serializer.toQuery(title.eq("Hello World"), metadata).toString()); - assertEquals("title:Hello World", serializer.toQuery(title.eq(new TermElement("Hello World")), metadata).toString()); - } - - @Test - public void testEqualsAndHashCode() { - TermElement el1 = new TermElement("x"), el2 = new TermElement("x"), el3 = new TermElement("y"); - assertEquals(el1, el2); - assertFalse(el1.equals(el3)); - assertEquals(el1.hashCode(), el2.hashCode()); - } - -} diff --git a/querydsl-lucene3/src/test/java/com/querydsl/lucene3/LuceneQueryTest.java b/querydsl-lucene3/src/test/java/com/querydsl/lucene3/LuceneQueryTest.java new file mode 100644 index 0000000000..b5c356342d --- /dev/null +++ b/querydsl-lucene3/src/test/java/com/querydsl/lucene3/LuceneQueryTest.java @@ -0,0 +1,757 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.lucene3; + +import static org.easymock.EasyMock.*; +import static org.junit.Assert.*; + +import java.io.IOException; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; + +import org.apache.lucene.analysis.standard.StandardAnalyzer; +import org.apache.lucene.document.Document; +import org.apache.lucene.document.Field; +import org.apache.lucene.document.Field.Index; +import org.apache.lucene.document.Field.Store; +import org.apache.lucene.document.MapFieldSelector; +import org.apache.lucene.document.NumericField; +import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexWriter; +import org.apache.lucene.index.IndexWriterConfig; +import org.apache.lucene.search.DuplicateFilter; +import org.apache.lucene.search.Filter; +import org.apache.lucene.search.IndexSearcher; +import org.apache.lucene.search.Sort; +import org.apache.lucene.store.RAMDirectory; +import org.apache.lucene.util.Version; +import org.junit.After; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; + +import com.querydsl.core.NonUniqueResultException; +import com.querydsl.core.QueryException; +import com.querydsl.core.QueryModifiers; +import com.querydsl.core.QueryResults; +import com.querydsl.core.types.ParamNotSetException; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.Param; +import com.querydsl.core.types.dsl.StringPath; + +/** + * Tests for LuceneQuery + * + * @author vema + * + */ +public class LuceneQueryTest { + + private LuceneQuery query; + private StringPath title; + private NumberPath<Integer> year; + private NumberPath<Double> gross; + + private final StringPath sort = Expressions.stringPath("sort"); + + private RAMDirectory idx; + private IndexWriter writer; + private IndexSearcher searcher; + + private Document createDocument(final String docTitle, + final String docAuthor, final String docText, final int docYear, + final double docGross) { + final Document doc = new Document(); + + doc.add(new Field("title", docTitle, Store.YES, Index.ANALYZED)); + doc.add(new Field("author", docAuthor, Store.YES, Index.ANALYZED)); + doc.add(new Field("text", docText, Store.YES, Index.ANALYZED)); + doc.add(new NumericField("year", Store.YES, true).setIntValue(docYear)); + doc.add(new NumericField("gross", Store.YES, true) + .setDoubleValue(docGross)); + + return doc; + } + + @Before + public void setUp() throws Exception { + final QDocument entityPath = new QDocument("doc"); + title = entityPath.title; + year = entityPath.year; + gross = entityPath.gross; + + + idx = new RAMDirectory(); + writer = createWriter(idx); + + writer.addDocument(createDocument("Jurassic Park", "Michael Crichton", + "It's a UNIX system! I know this!", 1990, 90.00)); + writer.addDocument(createDocument("Nummisuutarit", "Aleksis Kivi", + "ESKO. Ja iloitset ja riemuitset?", 1864, 10.00)); + writer + .addDocument(createDocument( + "The Lord of the Rings", + "John R. R. Tolkien", + "One Ring to rule them all, One Ring to find them, One Ring to bring them all and in the darkness bind them", + 1954, 89.00)); + writer + .addDocument(createDocument( + "Introduction to Algorithms", + "Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein", + "Bubble sort", 1990, 30.50)); + + writer.close(); + + IndexReader reader = IndexReader.open(idx); + searcher = new IndexSearcher(reader); + query = new LuceneQuery(new LuceneSerializer(true, true), searcher); + } + + private IndexWriter createWriter(RAMDirectory idx) throws Exception { + IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_31, + new StandardAnalyzer(Version.LUCENE_30)) + .setOpenMode(IndexWriterConfig.OpenMode.CREATE); + return new IndexWriter(idx, config); + } + + @After + public void tearDown() throws Exception { + searcher.close(); + } + + @Test + public void between() { + assertEquals(3, query.where(year.between(1950, 1990)).fetchCount()); + } + + @Test + public void count_empty_where_clause() { + assertEquals(4, query.fetchCount()); + } + + @Test + public void exists() { + assertTrue(query.where(title.eq("Jurassic Park")).fetchCount() > 0); + assertFalse(query.where(title.eq("Jurassic Park X")).fetchCount() > 0); + } + + @Test + public void notExists() { + assertFalse(query.where(title.eq("Jurassic Park")).fetchCount() == 0); + assertTrue(query.where(title.eq("Jurassic Park X")).fetchCount() == 0); + } + + @Test + public void count() { + query.where(title.eq("Jurassic Park")); + assertEquals(1, query.fetchCount()); + } + + @Test(expected = QueryException.class) + public void count_index_problem() throws IOException { + searcher = createMockBuilder(IndexSearcher.class).addMockedMethod( + "maxDoc").createMock(); + query = new LuceneQuery(new LuceneSerializer(true, true), searcher); + expect(searcher.maxDoc()).andThrow(new IllegalArgumentException()); + replay(searcher); + query.where(title.eq("Jurassic Park")); + query.fetchCount(); + verify(searcher); + } + + @Test(expected = UnsupportedOperationException.class) + public void countDistinct() { + query.where(year.between(1900, 3000)); + assertEquals(3, query.distinct().fetchCount()); + } + + @Test + public void in() { + assertEquals(2, query.where(title.in("Jurassic Park", "Nummisuutarit")).fetchCount()); + } + + @Test + public void in2() { + assertEquals(3, query.where(year.in(1990, 1864)).fetchCount()); + } + + @Test + public void in_toString() { + assertEquals("year:`____F year:`____H", query.where(year.in(1990, 1864)).toString()); + } + + @Test + public void list_sorted_by_year_ascending() { + query.where(year.between(1800, 2000)); + query.orderBy(year.asc()); + final List<Document> documents = query.fetch(); + assertFalse(documents.isEmpty()); + assertEquals(4, documents.size()); + } + + @Test + public void list_not_sorted() { + query.where(year.between(1800, 2000)); + final List<Document> documents = query.fetch(); + assertFalse(documents.isEmpty()); + assertEquals(4, documents.size()); + } + + @Test + public void sorted_by_different_locales() throws Exception { + Document d1 = new Document(); + Document d2 = new Document(); + Document d3 = new Document(); + d1.add(new Field("sort", "a\u00c4",Store.YES, Index.NOT_ANALYZED)); + d2.add(new Field("sort", "ab",Store.YES, Index.NOT_ANALYZED)); + d3.add(new Field("sort", "aa",Store.YES, Index.NOT_ANALYZED)); + writer = createWriter(idx); + writer.addDocument(d1); + writer.addDocument(d2); + writer.addDocument(d3); + writer.close(); + + IndexReader reader = IndexReader.open(idx); + searcher = new IndexSearcher(reader); + query = new LuceneQuery(new LuceneSerializer(true, true, Locale.ENGLISH), searcher); + assertEquals(3, query.fetch().size()); + List<Document> results = query.where(sort.startsWith("a")).orderBy(sort.asc()).fetch(); + assertEquals(3, results.size()); + assertEquals("aa", results.get(0).getFieldable("sort").stringValue()); + assertEquals("a\u00c4", results.get(1).getFieldable("sort").stringValue()); + assertEquals("ab", results.get(2).getFieldable("sort").stringValue()); + + query = new LuceneQuery(new LuceneSerializer(true, true, new Locale("fi", "FI")), searcher); + results = query.where(sort.startsWith("a")).orderBy(sort.asc()).fetch(); + assertEquals("aa", results.get(0).getFieldable("sort").stringValue()); + assertEquals("ab", results.get(1).getFieldable("sort").stringValue()); + assertEquals("a\u00c4", results.get(2).getFieldable("sort").stringValue()); + + + } + + @Test + public void list_not_sorted_limit_2() { + query.where(year.between(1800, 2000)); + query.limit(2); + final List<Document> documents = query.fetch(); + assertFalse(documents.isEmpty()); + assertEquals(2, documents.size()); + } + + @Test + public void list_sorted_by_year_limit_1() { + query.where(year.between(1800, 2000)); + query.limit(1); + query.orderBy(year.asc()); + final List<Document> documents = query.fetch(); + assertFalse(documents.isEmpty()); + assertEquals(1, documents.size()); + } + + @Test + public void list_not_sorted_offset_2() { + query.where(year.between(1800, 2000)); + query.offset(2); + final List<Document> documents = query.fetch(); + assertFalse(documents.isEmpty()); + assertEquals(2, documents.size()); + } + + @Test + public void list_sorted_ascending_by_year_offset_2() { + query.where(year.between(1800, 2000)); + query.offset(2); + query.orderBy(year.asc()); + final List<Document> documents = query.fetch(); + assertFalse(documents.isEmpty()); + assertEquals(2, documents.size()); + assertEquals("1990", documents.get(0).get("year")); + assertEquals("1990", documents.get(1).get("year")); + } + + @Test + public void list_sorted_ascending_by_year_restrict_limit_2_offset_1() { + query.where(year.between(1800, 2000)); + query.restrict(new QueryModifiers(2L, 1L)); + query.orderBy(year.asc()); + final List<Document> documents = query.fetch(); + assertFalse(documents.isEmpty()); + assertEquals(2, documents.size()); + assertEquals("1954", documents.get(0).get("year")); + assertEquals("1990", documents.get(1).get("year")); + } + + @Test + public void list_sorted_ascending_by_year() { + query.where(year.between(1800, 2000)); + query.orderBy(year.asc()); + final List<Document> documents = query.fetch(); + assertFalse(documents.isEmpty()); + assertEquals(4, documents.size()); + assertEquals("1864", documents.get(0).get("year")); + assertEquals("1954", documents.get(1).get("year")); + assertEquals("1990", documents.get(2).get("year")); + assertEquals("1990", documents.get(3).get("year")); + } + + + @Test + public void list_sort() { + Sort sort = LuceneSerializer.DEFAULT.toSort(Collections.singletonList(year.asc())); + + query.where(year.between(1800, 2000)); + //query.orderBy(year.asc()); + query.sort(sort); + final List<Document> documents = query.fetch(); + assertFalse(documents.isEmpty()); + assertEquals(4, documents.size()); + assertEquals("1864", documents.get(0).get("year")); + assertEquals("1954", documents.get(1).get("year")); + assertEquals("1990", documents.get(2).get("year")); + assertEquals("1990", documents.get(3).get("year")); + } + + @Test + public void list_distinct_property() { + assertEquals(4, query.fetch().size()); + assertEquals(3, query.distinct(year).fetch().size()); + } + + @Test + public void list_with_filter() { + Filter filter = new DuplicateFilter("year"); + assertEquals(4, query.fetch().size()); + assertEquals(3, query.filter(filter).fetch().size()); + } + + @Test + public void count_distinct_property() { + assertEquals(4L, query.fetchCount()); + assertEquals(3L, query.distinct(year).fetchCount()); + } + + @Test + public void list_sorted_descending_by_year() { + query.where(year.between(1800, 2000)); + query.orderBy(year.desc()); + final List<Document> documents = query.fetch(); + assertFalse(documents.isEmpty()); + assertEquals(4, documents.size()); + assertEquals("1990", documents.get(0).get("year")); + assertEquals("1990", documents.get(1).get("year")); + assertEquals("1954", documents.get(2).get("year")); + assertEquals("1864", documents.get(3).get("year")); + } + + + @Test + public void list_sorted_descending_by_gross() { + query.where(gross.between(0.0, 1000.00)); + query.orderBy(gross.desc()); + final List<Document> documents = query.fetch(); + assertFalse(documents.isEmpty()); + assertEquals(4, documents.size()); + assertEquals("90.0", documents.get(0).get("gross")); + assertEquals("89.0", documents.get(1).get("gross")); + assertEquals("30.5", documents.get(2).get("gross")); + assertEquals("10.0", documents.get(3).get("gross")); + } + + @Test + public void list_sorted_descending_by_year_and_ascending_by_title() { + query.where(year.between(1800, 2000)); + query.orderBy(year.desc()); + query.orderBy(title.asc()); + final List<Document> documents = query.fetch(); + assertFalse(documents.isEmpty()); + assertEquals(4, documents.size()); + assertEquals("1990", documents.get(0).get("year")); + assertEquals("1990", documents.get(1).get("year")); + assertEquals("Introduction to Algorithms", documents.get(0) + .get("title")); + assertEquals("Jurassic Park", documents.get(1).get("title")); + } + + @Test + public void list_sorted_descending_by_year_and_descending_by_title() { + query.where(year.between(1800, 2000)); + query.orderBy(year.desc()); + query.orderBy(title.desc()); + final List<Document> documents = query.fetch(); + assertFalse(documents.isEmpty()); + assertEquals(4, documents.size()); + assertEquals("1990", documents.get(0).get("year")); + assertEquals("1990", documents.get(1).get("year")); + assertEquals("Jurassic Park", documents.get(0).get("title")); + assertEquals("Introduction to Algorithms", documents.get(1) + .get("title")); + } + + @Ignore + @Test(expected = QueryException.class) + public void list_index_problem_in_max_doc() throws IOException { + searcher = createMockBuilder(IndexSearcher.class).addMockedMethod( + "maxDoc").createMock(); + query = new LuceneQuery(new LuceneSerializer(true, true), searcher); + expect(searcher.maxDoc()).andThrow(new IOException()); + replay(searcher); + query.where(title.eq("Jurassic Park")); + query.fetch(); + verify(searcher); + } + + @Ignore + @Test(expected = QueryException.class) + public void list_sorted_index_problem_in_max_doc() throws IOException { + searcher = createMockBuilder(IndexSearcher.class).addMockedMethod( + "maxDoc").createMock(); + query = new LuceneQuery(new LuceneSerializer(true, true), searcher); + expect(searcher.maxDoc()).andThrow(new IOException()); + replay(searcher); + query.where(title.eq("Jurassic Park")); + query.orderBy(title.asc()); + query.fetch(); + verify(searcher); + } + + @Test + public void offset() { + assertTrue(query.where(title.eq("Jurassic Park")).offset(30).fetch() + .isEmpty()); + } + + + @Test + public void load_list() { + Document document = query.where(title.ne("")).load(title).fetch().get(0); + assertNotNull(document.get("title")); + assertNull(document.get("year")); + } + + @Test + public void load_list_fieldSelector() { + Document document = query.where(title.ne("")).load(new MapFieldSelector("title")).fetch().get(0); + assertNotNull(document.get("title")); + assertNull(document.get("year")); + } + + @Test + public void load_singleResult() { + Document document = query.where(title.ne("")).load(title).fetchFirst(); + assertNotNull(document.get("title")); + assertNull(document.get("year")); + } + + @Test + public void load_singleResult_fieldSelector() { + Document document = query.where(title.ne("")).load(new MapFieldSelector("title")).fetchFirst(); + assertNotNull(document.get("title")); + assertNull(document.get("year")); + } + + @Test + public void singleResult() { + assertNotNull(query.where(title.ne("")).fetchFirst()); + } + + @Test + public void single_result_takes_limit() { + assertEquals("Jurassic Park", query + .where(title.ne("")) + .limit(1) + .fetchFirst().get("title")); + } + + @Test + public void single_result_considers_limit_and_actual_result_size() { + query.where(title.startsWith("Nummi")); + final Document document = query.limit(3).fetchFirst(); + assertEquals("Nummisuutarit", document.get("title")); + } + + @Test + public void single_result_returns_null_if_nothing_is_in_range() { + query.where(title.startsWith("Nummi")); + assertNull(query.offset(10).fetchFirst()); + } + + @Test + public void single_result_considers_offset() { + assertEquals("Introduction to Algorithms", query.where(title.ne("")).offset(3).fetchFirst().get("title")); + } + + @Test + public void single_result_considers_limit_and_offset() { + assertEquals("The Lord of the Rings", query.where(title.ne("")).limit(1).offset(2).fetchFirst().get("title")); + } + + @Test(expected = NonUniqueResultException.class) + public void uniqueResult_contract() { + query.where(title.ne("")).fetchOne(); + } + + @Test + public void unique_result_takes_limit() { + assertEquals("Jurassic Park", query + .where(title.ne("")) + .limit(1) + .fetchOne().get("title")); + } + + @Test + public void unique_result_considers_limit_and_actual_result_size() { + query.where(title.startsWith("Nummi")); + final Document document = query.limit(3).fetchOne(); + assertEquals("Nummisuutarit", document.get("title")); + } + + @Test + public void unique_result_returns_null_if_nothing_is_in_range() { + query.where(title.startsWith("Nummi")); + assertNull(query.offset(10).fetchOne()); + } + + @Test + public void unique_result_considers_offset() { + assertEquals("Introduction to Algorithms", query.where(title.ne("")).offset(3).fetchOne().get("title")); + } + + @Test + public void unique_result_considers_limit_and_offset() { + assertEquals("The Lord of the Rings", query.where(title.ne("")).limit(1).offset(2).fetchOne().get("title")); + } + + @Test + public void uniqueResult() { + query.where(title.startsWith("Nummi")); + final Document document = query.fetchOne(); + assertEquals("Nummisuutarit", document.get("title")); + } + + @Test + public void uniqueResult_with_param() { + final Param<String> param = new Param<String>(String.class, "title"); + query.set(param, "Nummi"); + query.where(title.startsWith(param)); + final Document document = query.fetchOne(); + assertEquals("Nummisuutarit", document.get("title")); + } + + @Test(expected = ParamNotSetException.class) + public void uniqueResult_param_not_set() { + final Param<String> param = new Param<String>(String.class, "title"); + query.where(title.startsWith(param)); + query.fetchOne(); + } + + @Test(expected = QueryException.class) + public void uniqueResult_finds_more_than_one_result() { + query.where(year.eq(1990)); + query.fetchOne(); + } + + @Test + public void uniqueResult_finds_no_results() { + query.where(year.eq(2200)); + assertNull(query.fetchOne()); + } + + @Test + public void uniqueResult_finds_no_results_because_no_documents_in_index() + throws IOException { + searcher = createMockBuilder(IndexSearcher.class).addMockedMethod( + "maxDoc").createMock(); + query = new LuceneQuery(new LuceneSerializer(true, true), searcher); + expect(searcher.maxDoc()).andReturn(0); + replay(searcher); + assertNull(query.where(year.eq(3000)).fetchOne()); + verify(searcher); + } + + @Test(expected = QueryException.class) + public void uniqueResult_sorted_index_problem_in_max_doc() + throws IOException { + searcher = createMockBuilder(IndexSearcher.class).addMockedMethod( + "maxDoc").createMock(); + query = new LuceneQuery(new LuceneSerializer(true, true), searcher); + expect(searcher.maxDoc()).andThrow(new IllegalArgumentException()); + replay(searcher); + query.where(title.eq("Jurassic Park")); + query.fetchOne(); + verify(searcher); + } + + @Test + public void count_returns_0_because_no_documents_in_index() + throws IOException { + searcher = createMockBuilder(IndexSearcher.class).addMockedMethod( + "maxDoc").createMock(); + query = new LuceneQuery(new LuceneSerializer(true, true), searcher); + expect(searcher.maxDoc()).andReturn(0); + replay(searcher); + assertEquals(0, query.where(year.eq(3000)).fetchCount()); + verify(searcher); + } + + @Test(expected = UnsupportedOperationException.class) + public void listDistinct() { + query.where(year.between(1900, 2000).or(title.startsWith("Jura"))); + query.orderBy(year.asc()); + final List<Document> documents = query.distinct().fetch(); + assertFalse(documents.isEmpty()); + assertEquals(3, documents.size()); + } + + @Test + public void listResults() { + query.where(year.between(1800, 2000)); + query.restrict(new QueryModifiers(2L, 1L)); + query.orderBy(year.asc()); + final QueryResults<Document> results = query.fetchResults(); + assertFalse(results.isEmpty()); + assertEquals("1954", results.getResults().get(0).get("year")); + assertEquals("1990", results.getResults().get(1).get("year")); + assertEquals(2, results.getLimit()); + assertEquals(1, results.getOffset()); + assertEquals(4, results.getTotal()); + } + + @Test(expected = UnsupportedOperationException.class) + public void listDistinctResults() { + query.where(year.between(1800, 2000).or( + title.eq("The Lord of the Rings"))); + query.restrict(new QueryModifiers(1L, 1L)); + query.orderBy(year.asc()); + final QueryResults<Document> results = query.distinct().fetchResults(); + assertFalse(results.isEmpty()); + assertEquals("1954", results.getResults().get(0).get("year")); + assertEquals(1, results.getLimit()); + assertEquals(1, results.getOffset()); + assertEquals(4, results.getTotal()); + } + + @Test + public void list_all() { + final List<Document> results = query.where(title.like("*")).orderBy( + title.asc(), year.desc()).fetch(); + assertEquals(4, results.size()); + } + + @Test(expected = IllegalArgumentException.class) + public void list_sorted_ascending_limit_negative() { + query.where(year.between(1800, 2000)); + query.limit(-1); + query.orderBy(year.asc()); + query.fetch(); + } + + @Test(expected = IllegalArgumentException.class) + public void list_not_sorted_limit_negative() { + query.where(year.between(1800, 2000)); + query.limit(-1); + query.fetch(); + } + + @Test(expected = IllegalArgumentException.class) + public void list_sorted_ascending_limit_0() { + query.where(year.between(1800, 2000)); + query.limit(0); + query.orderBy(year.asc()); + query.fetch(); + } + + @Test(expected = IllegalArgumentException.class) + public void list_not_sorted_limit_0() { + query.where(year.between(1800, 2000)); + query.limit(0); + query.fetch(); + } + + @Test(expected = IllegalArgumentException.class) + public void list_sorted_ascending_offset_negative() { + query.where(year.between(1800, 2000)); + query.offset(-1); + query.orderBy(year.asc()); + query.fetch(); + } + + @Test(expected = IllegalArgumentException.class) + public void list_not_sorted_offset_negative() { + query.where(year.between(1800, 2000)); + query.offset(-1); + query.fetch(); + } + + @Test + public void list_sorted_ascending_offset_0() { + query.where(year.between(1800, 2000)); + query.offset(0); + query.orderBy(year.asc()); + final List<Document> documents = query.fetch(); + assertFalse(documents.isEmpty()); + assertEquals(4, documents.size()); + } + + @Test + public void list_not_sorted_offset_0() { + query.where(year.between(1800, 2000)); + query.offset(0); + final List<Document> documents = query.fetch(); + assertFalse(documents.isEmpty()); + assertEquals(4, documents.size()); + } + + @Test + public void iterate() { + query.where(year.between(1800, 2000)); + final Iterator<Document> iterator = query.iterate(); + int count = 0; + while (iterator.hasNext()) { + iterator.next(); + ++count; + } + assertEquals(4, count); + } + + @Test + public void all_by_excluding_where() { + assertEquals(4, query.fetch().size()); + } + + @Test + public void empty_index_should_return_empty_list() throws Exception { + idx = new RAMDirectory(); + + writer = createWriter(idx); + writer.close(); + IndexReader reader = IndexReader.open(idx); + searcher = new IndexSearcher(reader); + query = new LuceneQuery(new LuceneSerializer(true, true), searcher); + assertTrue(query.fetch().isEmpty()); + } + + @Test(expected = QueryException.class) + public void list_results_throws_an_illegal_argument_exception_when_sum_of_limit_and_offset_is_negative() { + query.limit(1).offset(Integer.MAX_VALUE).fetchResults(); + } + + @Test + public void limit_max_value() { + assertEquals(4, query.limit(Long.MAX_VALUE).fetch().size()); + } +} diff --git a/querydsl-lucene3/src/test/java/com/querydsl/lucene3/LuceneSerializerNotTokenizedTest.java b/querydsl-lucene3/src/test/java/com/querydsl/lucene3/LuceneSerializerNotTokenizedTest.java new file mode 100644 index 0000000000..cc7f94bb12 --- /dev/null +++ b/querydsl-lucene3/src/test/java/com/querydsl/lucene3/LuceneSerializerNotTokenizedTest.java @@ -0,0 +1,209 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.lucene3; + +import static com.querydsl.lucene3.QPerson.person; +import static org.junit.Assert.assertEquals; + +import java.util.Arrays; + +import org.apache.lucene.analysis.standard.StandardAnalyzer; +import org.apache.lucene.document.Document; +import org.apache.lucene.document.Field; +import org.apache.lucene.document.Field.Index; +import org.apache.lucene.document.Field.Store; +import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexWriter; +import org.apache.lucene.index.IndexWriterConfig; +import org.apache.lucene.search.IndexSearcher; +import org.apache.lucene.search.Query; +import org.apache.lucene.search.TopDocs; +import org.apache.lucene.store.RAMDirectory; +import org.apache.lucene.util.Version; +import org.joda.time.LocalDate; +import org.junit.Before; +import org.junit.Test; + +import com.querydsl.core.DefaultQueryMetadata; +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.StringPath; + +public class LuceneSerializerNotTokenizedTest { + private RAMDirectory idx; + private IndexWriter writer; + private IndexSearcher searcher; + private LuceneSerializer serializer; + + private final QueryMetadata metadata = new DefaultQueryMetadata(); + + private final Person clooney = new Person("actor_1", "George Clooney", new LocalDate(1961, 4, 6)); + private final Person pitt = new Person("actor_2", "Brad Pitt", new LocalDate(1963, 12, 18)); + + private void testQuery(Expression<?> expr, String expectedQuery, int expectedHits) throws Exception { + Query query = serializer.toQuery(expr, metadata); + TopDocs docs = searcher.search(query, 100); + assertEquals(expectedHits, docs.totalHits); + assertEquals(expectedQuery, query.toString()); + } + + private Document createDocument(Person person) { + Document doc = new Document(); + doc.add(new Field("id", person.getId(), Store.YES, Index.NOT_ANALYZED)); + doc.add(new Field("name", person.getName(), Store.YES, Index.NOT_ANALYZED)); + doc.add(new Field("birthDate", person.getBirthDate().toString(), Store.YES, Index.NOT_ANALYZED)); + return doc; + } + + @Before + public void before() throws Exception { + serializer = new LuceneSerializer(false, false); + idx = new RAMDirectory(); + IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_31, + new StandardAnalyzer(Version.LUCENE_30)) + .setOpenMode(IndexWriterConfig.OpenMode.CREATE); + writer = new IndexWriter(idx, config); + + writer.addDocument(createDocument(clooney)); + writer.addDocument(createDocument(pitt)); + + Document document = new Document(); + for (String movie : Arrays.asList("Interview with the Vampire", + "Up in the Air")) { + document.add(new Field("movie", movie, Store.YES, Index.NOT_ANALYZED)); + } + writer.addDocument(document); + + writer.close(); + + IndexReader reader = IndexReader.open(idx); + searcher = new IndexSearcher(reader); + } + + @Test + public void equals_by_id_matches() throws Exception { + testQuery(person.id.eq("actor_1"), "id:actor_1", 1); + } + + @Test + public void equals_by_id_does_not_match() throws Exception { + testQuery(person.id.eq("actor_8"), "id:actor_8", 0); + } + + @Test + public void equals_by_name_matches() throws Exception { + testQuery(person.name.eq("George Clooney"), "name:George Clooney", 1); + } + + @Test(expected = UnsupportedOperationException.class) + public void equals_by_name_ignoring_case_does_not_match() throws Exception { + testQuery(person.name.equalsIgnoreCase("george clooney"), "name:george clooney", 0); + } + + @Test + public void equals_by_name_does_not_match() throws Exception { + testQuery(person.name.eq("George Looney"), "name:George Looney", 0); + } + + @Test + public void starts_with_name_should_match() throws Exception { + testQuery(person.name.startsWith("George C"), "name:George C*", 1); + } + + @Test + public void starts_with_name_should_not_match() throws Exception { + testQuery(person.name.startsWith("George L"), "name:George L*", 0); + } + + @Test + public void ends_with_name_should_match() throws Exception { + testQuery(person.name.endsWith("e Clooney"), "name:*e Clooney", 1); + } + + @Test + public void ends_with_name_should_not_match() throws Exception { + testQuery(person.name.endsWith("e Looney"), "name:*e Looney", 0); + } + + @Test + public void contains_name_should_match() throws Exception { + testQuery(person.name.contains("oney"), "name:*oney*", 1); + } + + @Test + public void contains_name_should_not_match() throws Exception { + testQuery(person.name.contains("bloney"), "name:*bloney*", 0); + } + + @Test + public void in_names_should_match_2() throws Exception { + testQuery(person.name.in("Brad Pitt", "George Clooney"), "name:Brad Pitt name:George Clooney", 2); + } + + @Test + public void or_by_name_should_match_2() throws Exception { + testQuery(person.name.eq("Brad Pitt") + .or(person.name.eq("George Clooney")), "name:Brad Pitt name:George Clooney", 2); + } + + @Test + public void equals_by_birth_date() throws Exception { + testQuery(person.birthDate.eq(clooney.getBirthDate()), "birthDate:1961-04-06", 1); + } + + @Test + public void between_phrase() throws Exception { + testQuery(person.name.between("Brad Pitt","George Clooney"), "name:[Brad Pitt TO George Clooney]", 2); + } + + @Test + public void not_equals_finds_the_actors_and_movies() throws Exception { + testQuery(person.name.ne("Michael Douglas"), "-name:Michael Douglas +*:*", 3); + } + + @Test + public void not_equals_finds_only_clooney_and_movies() throws Exception { + testQuery(person.name.ne("Brad Pitt"), "-name:Brad Pitt +*:*", 2); + } + + @Test + public void and_with_two_not_equals_doesnt_find_the_actors() throws Exception { + testQuery(person.name.ne("Brad Pitt") + .and(person.name.ne("George Clooney")), "+(-name:Brad Pitt +*:*) +(-name:George Clooney +*:*)", 1); + } + + @Test + public void or_with_two_not_equals_finds_movies_and_actors() throws Exception { + testQuery(person.name.ne("Brad Pitt") + .or(person.name.ne("George Clooney")), "(-name:Brad Pitt +*:*) (-name:George Clooney +*:*)", 3); + } + + @Test + public void negation_of_equals_finds_movies_and_actors() throws Exception { + testQuery(person.name.eq("Michael Douglas").not(), "-name:Michael Douglas +*:*", 3); + } + + @Test + public void negation_of_equals_finds_pitt_and_movies() throws Exception { + testQuery(person.name.eq("Brad Pitt").not(), "-name:Brad Pitt +*:*", 2); + } + + @Test + public void multiple_field_search_from_movies() throws Exception { + StringPath movie = Expressions.stringPath("movie"); + testQuery(movie.in("Interview with the Vampire"), "movie:Interview with the Vampire", 1); + testQuery(movie.eq("Up in the Air"), "movie:Up in the Air", 1); + } +} diff --git a/querydsl-lucene3/src/test/java/com/querydsl/lucene3/LuceneSerializerTest.java b/querydsl-lucene3/src/test/java/com/querydsl/lucene3/LuceneSerializerTest.java new file mode 100644 index 0000000000..0df20b4452 --- /dev/null +++ b/querydsl-lucene3/src/test/java/com/querydsl/lucene3/LuceneSerializerTest.java @@ -0,0 +1,672 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.lucene3; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import java.io.StringReader; +import java.util.Arrays; +import java.util.Collections; +import java.util.EnumSet; +import java.util.Set; + +import org.apache.lucene.analysis.standard.StandardAnalyzer; +import org.apache.lucene.document.Document; +import org.apache.lucene.document.Field; +import org.apache.lucene.document.Field.Index; +import org.apache.lucene.document.Field.Store; +import org.apache.lucene.document.NumericField; +import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexWriter; +import org.apache.lucene.index.IndexWriterConfig; +import org.apache.lucene.search.IndexSearcher; +import org.apache.lucene.search.Query; +import org.apache.lucene.search.TopDocs; +import org.apache.lucene.store.RAMDirectory; +import org.apache.lucene.util.NumericUtils; +import org.apache.lucene.util.Version; +import org.junit.After; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; + +import com.querydsl.core.*; +import com.querydsl.core.types.*; +import com.querydsl.core.types.dsl.*; + +/** + * Tests for LuceneSerializer + * + * @author vema + * + */ +public class LuceneSerializerTest { + private LuceneSerializer serializer; + private PathBuilder<Object> entityPath; + private StringPath title; + private StringPath author; + private StringPath text; + private StringPath rating; + private StringPath publisher; + private NumberPath<Integer> year; + private NumberPath<Double> gross; + private CollectionPath<String, StringPath> titles; + + private NumberPath<Long> longField; + private NumberPath<Short> shortField; + private NumberPath<Byte> byteField; + private NumberPath<Float> floatField; + + private static final String YEAR_PREFIX_CODED = NumericUtils.intToPrefixCoded(1990); + private static final String GROSS_PREFIX_CODED = NumericUtils.doubleToPrefixCoded(900.00); + private static final String LONG_PREFIX_CODED = NumericUtils.longToPrefixCoded(1); + private static final String SHORT_PREFIX_CODED = NumericUtils.intToPrefixCoded(1); + private static final String BYTE_PREFIX_CODED = NumericUtils.intToPrefixCoded(1); + private static final String FLOAT_PREFIX_CODED = NumericUtils.floatToPrefixCoded((float) 1.0); + + private IndexWriterConfig config; + private RAMDirectory idx; + private IndexWriter writer; + private IndexSearcher searcher; + + private static final Set<? extends Operator> UNSUPPORTED_OPERATORS = Collections.unmodifiableSet(EnumSet.of(Ops.STARTS_WITH_IC, + Ops.EQ_IGNORE_CASE, Ops.ENDS_WITH_IC, Ops.STRING_CONTAINS_IC)); + + private final QueryMetadata metadata = new DefaultQueryMetadata(); + + private Document createDocument() { + Document doc = new Document(); + + doc.add(new Field("title", new StringReader("Jurassic Park"))); + doc.add(new Field("author", new StringReader("Michael Crichton"))); + doc.add(new Field("text", new StringReader("It's a UNIX system! I know this!"))); + doc.add(new Field("rating", new StringReader("Good"))); + doc.add(new Field("publisher", "", Store.YES, Index.ANALYZED)); + doc.add(new NumericField("year", Store.YES, true).setIntValue(1990)); + doc.add(new NumericField("gross", Store.YES, true).setDoubleValue(900.00)); + + doc.add(new NumericField("longField", Store.YES, true).setLongValue(1)); + doc.add(new NumericField("shortField", Store.YES, true).setIntValue(1)); + doc.add(new NumericField("byteField", Store.YES, true).setIntValue(1)); + doc.add(new NumericField("floatField", Store.YES, true).setFloatValue(1)); + + return doc; + } + + @Before + public void setUp() throws Exception { + serializer = new LuceneSerializer(true,true); + entityPath = new PathBuilder<Object>(Object.class, "obj"); + title = entityPath.getString("title"); + author = entityPath.getString("author"); + text = entityPath.getString("text"); + publisher = entityPath.getString("publisher"); + year = entityPath.getNumber("year", Integer.class); + rating = entityPath.getString("rating"); + gross = entityPath.getNumber("gross", Double.class); + titles = entityPath.getCollection("title", String.class, StringPath.class); + + longField = entityPath.getNumber("longField", Long.class); + shortField = entityPath.getNumber("shortField", Short.class); + byteField = entityPath.getNumber("byteField", Byte.class); + floatField = entityPath.getNumber("floatField", Float.class); + + idx = new RAMDirectory(); + config = new IndexWriterConfig(Version.LUCENE_31, + new StandardAnalyzer(Version.LUCENE_30)) + .setOpenMode(IndexWriterConfig.OpenMode.CREATE); + writer = new IndexWriter(idx, config); + + writer.addDocument(createDocument()); + + writer.close(); + + IndexReader reader = IndexReader.open(idx); + searcher = new IndexSearcher(reader); + } + + @After + public void tearDown() throws Exception { + searcher.close(); + } + + private void testQuery(Expression<?> expr, int expectedHits) throws Exception { + Query query = serializer.toQuery(expr, metadata); + TopDocs docs = searcher.search(query, 100); + assertEquals(expectedHits, docs.totalHits); + } + + private void testQuery(Expression<?> expr, String expectedQuery, int expectedHits) throws Exception { + Query query = serializer.toQuery(expr, metadata); + TopDocs docs = searcher.search(query, 100); + assertEquals(expectedHits, docs.totalHits); + assertEquals(expectedQuery, query.toString()); + } + + @Test + public void queryElement() throws Exception { + Query query1 = serializer.toQuery(author.like("Michael"), metadata); + Query query2 = serializer.toQuery(text.like("Text"), metadata); + + BooleanExpression query = Expressions.anyOf( + new QueryElement(query1), + new QueryElement(query2) + ); + testQuery(query, "author:michael text:text", 1); + } + + @Test + public void like() throws Exception { + testQuery(author.like("*ichael*"), "author:*ichael*", 1); + } + + @Test + public void like_custom_wildcard_single_character() throws Exception { + testQuery(author.like("Mi?hael"), "author:mi?hael", 1); + } + + @Test + public void like_custom_wildcard_multiple_character() throws Exception { + testQuery(text.like("*U*X*"), "text:*u*x*", 1); + } + + @Test + public void like_phrase() throws Exception { + testQuery(title.like("*rassic Par*"), "+title:**rassic* +title:*par**", 1); + } + + @Test + public void like_or_like() throws Exception { + testQuery(title.like("House").or(author.like("*ichae*")), "title:house author:*ichae*", 1); + } + + @Test + public void like_and_like() throws Exception { + testQuery(title.like("*assic*").and(rating.like("G?od")), "+title:*assic* +rating:g?od", 1); + } + + @Test + public void eq() throws Exception { + testQuery(rating.eq("good"), "rating:good", 1); + } + + @Test + public void eq_with_deep_path() throws Exception { + StringPath deepPath = entityPath.get("property1", Object.class).getString("property2"); + testQuery(deepPath.eq("good"), "property1.property2:good", 0); + } + + @Test + public void fuzzyLike() throws Exception { + testQuery(LuceneExpressions.fuzzyLike(rating, "Good"), "rating:Good~0.5", 1); + } + + @Test + public void fuzzyLike_with_similarity() throws Exception { + testQuery(LuceneExpressions.fuzzyLike(rating, "Good", 0.6f), "rating:Good~0.6", 1); + } + + @Test + public void fuzzyLike_with_similarity_and_prefix() throws Exception { + testQuery(LuceneExpressions.fuzzyLike(rating, "Good", 0.6f, 0), "rating:Good~0.6", 1); + } + + @Test + public void eq_numeric_integer() throws Exception { + testQuery(year.eq(1990), "year:" + YEAR_PREFIX_CODED, 1); + } + + @Test + public void eq_numeric_double() throws Exception { + testQuery(gross.eq(900.00), "gross:" + GROSS_PREFIX_CODED, 1); + } + + @Test + public void eq_numeric() throws Exception { + testQuery(longField.eq(1L), "longField:" + LONG_PREFIX_CODED, 1); + testQuery(shortField.eq((short) 1), "shortField:" + SHORT_PREFIX_CODED, 1); + testQuery(byteField.eq((byte) 1), "byteField:" + BYTE_PREFIX_CODED, 1); + testQuery(floatField.eq((float) 1.0), "floatField:" + FLOAT_PREFIX_CODED, 1); + } + + @Test + public void equals_ignores_case() throws Exception { + testQuery(title.eq("Jurassic"), "title:jurassic", 1); + } + + @Test(expected = UnsupportedOperationException.class) + public void title_equals_ignore_case_or_year_equals() throws Exception { + testQuery(title.equalsIgnoreCase("House").or(year.eq(1990)), "title:house year:" + YEAR_PREFIX_CODED, 1); + } + + @Test + public void eq_and_eq() throws Exception { + testQuery(title.eq("Jurassic Park").and(year.eq(1990)), "+title:\"jurassic park\" +year:" + YEAR_PREFIX_CODED, 1); + } + + @Test + public void eq_and_eq_and_eq() throws Exception { + testQuery(title.eq("Jurassic Park").and(year.eq(1990)).and(author.eq("Michael Crichton")), "+(+title:\"jurassic park\" +year:" + YEAR_PREFIX_CODED + ") +author:\"michael crichton\"", 1); + } + + @Test(expected = UnsupportedOperationException.class) + public void equals_ignore_case_and_or() throws Exception { + testQuery(title.equalsIgnoreCase("Jurassic Park").and(rating.equalsIgnoreCase("Bad")).or(author.equalsIgnoreCase("Michael Crichton")), "(+title:\"jurassic park\" +rating:bad) author:\"michael crichton\"", 1); + } + + @Test + public void eq_or_eq_and_eq_does_not_find_results() throws Exception { + testQuery(title.eq("jeeves").or(rating.eq("superb")).and(author.eq("michael crichton")), "+(title:jeeves rating:superb) +author:\"michael crichton\"", 0); + } + + @Test + public void eq_phrase() throws Exception { + testQuery(title.eq("Jurassic Park"), "title:\"jurassic park\"", 1); + } + + @Test + @Ignore("Not easily done in Lucene!") + public void publisher_equals_empty_string() throws Exception { + testQuery(publisher.eq(""), "publisher:", 1); + } + + @Test + public void eq_phrase_should_not_find_results_but_luceNe_semantics_differs_from_querydsls() throws Exception { + testQuery(text.eq("UNIX System"), "text:\"unix system\"", 1); + } + + @Test + public void eq_phrase_does_not_find_results_because_word_in_middle() throws Exception { + testQuery(title.eq("Jurassic Amusement Park"), "title:\"jurassic amusement park\"", 0); + } + + @Test + public void like_not_does_not_find_results() throws Exception { + testQuery(title.like("*H*e*").not(), "-title:*h*e* +*:*", 1); + } + + @Test(expected = UnsupportedOperationException.class) + public void title_equals_ignore_case_negation_or_rating_equals_ignore_case() throws Exception { + testQuery(title.equalsIgnoreCase("House").not().or(rating.equalsIgnoreCase("Good")), "-title:house rating:good", 1); + } + + @Test + public void eq_not_does_not_find_results() throws Exception { + testQuery(title.eq("Jurassic Park").not(), "-title:\"jurassic park\" +*:*", 0); + } + + @Test + public void title_equals_not_house() throws Exception { + testQuery(title.eq("house").not(), "-title:house +*:*", 1); + } + + @Test + public void eq_and_eq_not_does_not_find_results_because_second_expression_finds_nothing() throws Exception { + testQuery(rating.eq("superb").and(title.eq("house").not()), "+rating:superb +(-title:house +*:*)", 0); + } + + @Test + public void not_equals_finds_one() throws Exception { + testQuery(title.ne("house"), "-title:house +*:*", 1); + } + + @Test + public void not_equals_finds_none() throws Exception { + testQuery(title.ne("Jurassic Park"), "-title:\"jurassic park\" +*:*", 0); + } + + @Test + public void nothing_found_with_not_equals_or_equals() throws Exception { + testQuery(title.ne("jurassic park").or(rating.eq("lousy")), "(-title:\"jurassic park\" +*:*) rating:lousy", 0); + } + + @Test + public void ne_and_eq() throws Exception { + testQuery(title.ne("house").and(rating.eq("good")), "+(-title:house +*:*) +rating:good", 1); + } + + @Test + public void startsWith() throws Exception { + testQuery(title.startsWith("Jurassi"), "title:jurassi*", 1); + } + + @Test + public void startsWith_phrase() throws Exception { + testQuery(title.startsWith("jurassic par"), "+title:jurassic* +title:*par*", 1); + } + + @Test(expected = UnsupportedOperationException.class) + public void starts_with_ignore_case_phrase_does_not_find_results() throws Exception { + testQuery(title.startsWithIgnoreCase("urassic Par"), "+title:urassic* +title:*par*", 0); + } + + @Test + public void endsWith() throws Exception { + testQuery(title.endsWith("ark"), "title:*ark", 1); + } + + @Test(expected = UnsupportedOperationException.class) + public void ends_with_ignore_case_phrase() throws Exception { + testQuery(title.endsWithIgnoreCase("sic Park"), "+title:*sic* +title:*park", 1); + } + + @Test(expected = UnsupportedOperationException.class) + public void ends_with_ignore_case_phrase_does_not_find_results() throws Exception { + testQuery(title.endsWithIgnoreCase("sic Par"), "+title:*sic* +title:*par", 0); + } + + @Test + public void contains() throws Exception { + testQuery(title.contains("rassi"), "title:*rassi*", 1); + } + + @Test(expected = UnsupportedOperationException.class) + public void contains_ignore_case_phrase() throws Exception { + testQuery(title.containsIgnoreCase("rassi Pa"), "+title:*rassi* +title:*pa*", 1); + } + + @Test + public void contains_user_inputted_wildcards_dont_work() throws Exception { + testQuery(title.contains("r*i"), "title:*r\\*i*", 0); + } + + @Test + public void between() throws Exception { + testQuery(title.between("Indiana", "Kundun"), "title:[indiana TO kundun]", 1); + } + + @Test + public void between_numeric_integer() throws Exception { + testQuery(year.between(1980, 2000), "year:[1980 TO 2000]", 1); + } + + @Test + public void between_numeric_double() throws Exception { + testQuery(gross.between(10.00, 19030.00), "gross:[10.0 TO 19030.0]", 1); + } + + @Test + public void between_numeric() throws Exception { + testQuery(longField.between(0L,2L), "longField:[0 TO 2]", 1); + testQuery(shortField.between((short) 0,(short) 2), "shortField:[0 TO 2]", 1); + testQuery(byteField.between((byte) 0,(byte) 2), "byteField:[0 TO 2]", 1); + testQuery(floatField.between((float) 0.0,(float) 2.0), "floatField:[0.0 TO 2.0]", 1); + } + + @Test + public void between_is_inclusive_from_start() throws Exception { + testQuery(title.between("Jurassic", "Kundun"), "title:[jurassic TO kundun]", 1); + } + + @Test + public void between_is_inclusive_to_end() throws Exception { + testQuery(title.between("Indiana", "Jurassic"), "title:[indiana TO jurassic]", 1); + } + + @Test + public void between_does_not_find_results() throws Exception { + testQuery(title.between("Indiana", "Jurassib"), "title:[indiana TO jurassib]", 0); + } + + @Test + public void in() throws Exception { + testQuery(title.in(Arrays.asList("jurassic", "park")), "title:jurassic title:park", 1); + testQuery(title.in("jurassic","park"), "title:jurassic title:park", 1); + testQuery(title.eq("jurassic").or(title.eq("park")), "title:jurassic title:park", 1); + } + + @Test + public void lt() throws Exception { + testQuery(rating.lt("Superb"), "rating:{* TO superb}", 1); + } + + @Test + public void lt_numeric_integer() throws Exception { + testQuery(year.lt(1991), "year:{* TO 1991}", 1); + } + + @Test + public void lt_numeric_double() throws Exception { + testQuery(gross.lt(10000.0), "gross:{* TO 10000.0}", 1); + } + + @Test + public void lt_not_in_range_because_equal() throws Exception { + testQuery(rating.lt("Good"), "rating:{* TO good}", 0); + } + + @Test + public void lt_numeric_integer_not_in_range_because_equal() throws Exception { + testQuery(year.lt(1990), "year:{* TO 1990}", 0); + } + + @Test + public void lt_numeric_double_not_in_range_because_equal() throws Exception { + testQuery(gross.lt(900.0), "gross:{* TO 900.0}", 0); + } + + @Test + public void loe() throws Exception { + testQuery(rating.loe("Superb"), "rating:[* TO superb]", 1); + } + + @Test + public void loe_numeric_integer() throws Exception { + testQuery(year.loe(1991), "year:[* TO 1991]", 1); + } + + @Test + public void loe_numeric_double() throws Exception { + testQuery(gross.loe(903.0), "gross:[* TO 903.0]", 1); + } + + @Test + public void loe_equal() throws Exception { + testQuery(rating.loe("Good"), "rating:[* TO good]", 1); + } + + @Test + public void loe_numeric_integer_equal() throws Exception { + testQuery(year.loe(1990), "year:[* TO 1990]", 1); + } + + @Test + public void loe_numeric_double_equal() throws Exception { + testQuery(gross.loe(900.0), "gross:[* TO 900.0]", 1); + } + + @Test + public void loe_not_found() throws Exception { + testQuery(rating.loe("Bad"), "rating:[* TO bad]", 0); + } + + @Test + public void loe_numeric_integer_not_found() throws Exception { + testQuery(year.loe(1989), "year:[* TO 1989]", 0); + } + + @Test + public void loe_numeric_double_not_found() throws Exception { + testQuery(gross.loe(899.9), "gross:[* TO 899.9]", 0); + } + + @Test + public void gt() throws Exception { + testQuery(rating.gt("Bad"), "rating:{bad TO *}", 1); + } + + @Test + public void gt_numeric_integer() throws Exception { + testQuery(year.gt(1989), "year:{1989 TO *}", 1); + } + + @Test + public void gt_numeric_double() throws Exception { + testQuery(gross.gt(100.00), "gross:{100.0 TO *}", 1); + } + + @Test + public void gt_not_in_range_because_equal() throws Exception { + testQuery(rating.gt("Good"), "rating:{good TO *}", 0); + } + + @Test + public void gt_numeric_integer_not_in_range_because_equal() throws Exception { + testQuery(year.gt(1990), "year:{1990 TO *}", 0); + } + + @Test + public void gt_numeric_double_not_in_range_because_equal() throws Exception { + testQuery(gross.gt(900.00), "gross:{900.0 TO *}", 0); + } + + @Test + public void goe() throws Exception { + testQuery(rating.goe("Bad"), "rating:[bad TO *]", 1); + } + + @Test + public void goe_numeric_integer() throws Exception { + testQuery(year.goe(1989), "year:[1989 TO *]", 1); + } + + @Test + public void goe_numeric_double() throws Exception { + testQuery(gross.goe(320.50), "gross:[320.5 TO *]", 1); + } + + @Test + public void goe_equal() throws Exception { + testQuery(rating.goe("Good"), "rating:[good TO *]", 1); + } + + @Test + public void goe_numeric_integer_equal() throws Exception { + testQuery(year.goe(1990), "year:[1990 TO *]", 1); + } + + @Test + public void goe_numeric_double_equal() throws Exception { + testQuery(gross.goe(900.00), "gross:[900.0 TO *]", 1); + } + + @Test + public void goe_not_found() throws Exception { + testQuery(rating.goe("Hood"), "rating:[hood TO *]", 0); + } + + @Test + public void goe_numeric_integer_not_found() throws Exception { + testQuery(year.goe(1991), "year:[1991 TO *]", 0); + } + + @Test + public void goe_numeric_double_not_found() throws Exception { + testQuery(gross.goe(900.10), "gross:[900.1 TO *]", 0); + } + + @Test + public void equals_empty_string() throws Exception { + testQuery(title.eq(""), "title:", 0); + } + + @Test + public void not_equals_empty_string() throws Exception { + testQuery(title.ne(""), "-title: +*:*", 1); + } + + @Test + public void contains_empty_string() throws Exception { + testQuery(title.contains(""), "title:**", 1); + } + + @Test + public void like_empty_string() throws Exception { + testQuery(title.like(""), "title:", 0); + } + + @Test + public void starts_with_empty_string() throws Exception { + testQuery(title.startsWith(""), "title:*", 1); + } + + @Test + public void ends_with_empty_string() throws Exception { + testQuery(title.endsWith(""), "title:*", 1); + } + + @Test + public void between_empty_strings() throws Exception { + testQuery(title.between("", ""), "title:[ TO ]", 0); + } + + @Test + public void booleanBuilder() throws Exception { + testQuery(new BooleanBuilder(gross.goe(900.10)), "gross:[900.1 TO *]", 0); + } + + @Test + @Ignore + public void fuzzy() throws Exception { + fail("Not yet implemented!"); + } + + @Test + @Ignore + public void proximity() throws Exception { + fail("Not yet implemented!"); + } + + @Test + @Ignore + public void boost() throws Exception { + fail("Not yet implemented!"); + } + + @Test + public void pathAny() throws Exception { + testQuery(titles.any().eq("Jurassic"), "title:jurassic", 1); + } + + private boolean unsupportedOperation(Predicate filter) { + return UNSUPPORTED_OPERATORS.contains(((Operation<?>) filter).getOperator()); + } + + @Test + public void various() throws Exception { + MatchingFiltersFactory filters = new MatchingFiltersFactory(QuerydslModule.LUCENE, Target.LUCENE); + for (Predicate filter : filters.string(title, StringConstant.create("jurassic park"))) { + if (unsupportedOperation(filter)) { + continue; + } + testQuery(filter, 1); + } + + for (Predicate filter : filters.string(author, StringConstant.create("michael crichton"))) { + if (unsupportedOperation(filter)) { + continue; + } + testQuery(filter, 1); + } + + for (Predicate filter : filters.string(title, StringConstant.create("1990"))) { + if (unsupportedOperation(filter)) { + continue; + } + testQuery(filter, 0); + } + } + +} diff --git a/querydsl-lucene3/src/test/java/com/querydsl/lucene3/Person.java b/querydsl-lucene3/src/test/java/com/querydsl/lucene3/Person.java new file mode 100644 index 0000000000..6623b4fd66 --- /dev/null +++ b/querydsl-lucene3/src/test/java/com/querydsl/lucene3/Person.java @@ -0,0 +1,45 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.lucene3; + +import org.joda.time.LocalDate; + +import com.querydsl.core.annotations.QueryEntity; + +@QueryEntity +public class Person { + private final String id; + private final String name; + private final LocalDate birthDate; + + public Person(String id, String name, LocalDate birthDate) { + this.id = id; + this.name = name; + this.birthDate = birthDate; + } + + public String getId() { + return id; + } + + public LocalDate getBirthDate() { + return birthDate; + } + + public String getName() { + return name; + } +} + + diff --git a/querydsl-lucene3/src/test/java/com/querydsl/lucene3/PhraseElementTest.java b/querydsl-lucene3/src/test/java/com/querydsl/lucene3/PhraseElementTest.java new file mode 100644 index 0000000000..2af30bf8db --- /dev/null +++ b/querydsl-lucene3/src/test/java/com/querydsl/lucene3/PhraseElementTest.java @@ -0,0 +1,50 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.lucene3; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; + +import org.junit.Test; + +import com.querydsl.core.DefaultQueryMetadata; +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.StringPath; + +public class PhraseElementTest { + + @Test + public void test() { + StringPath title = Expressions.stringPath("title"); + LuceneSerializer serializer = new LuceneSerializer(false,false); + QueryMetadata metadata = new DefaultQueryMetadata(); + assertEquals("title:Hello World", serializer.toQuery(title.eq("Hello World"), metadata).toString()); + assertEquals("title:\"Hello World\"", serializer.toQuery(title.eq(new PhraseElement("Hello World")), metadata).toString()); + } + + @Test + public void equals() { + PhraseElement el1 = new PhraseElement("x"), el2 = new PhraseElement("x"), el3 = new PhraseElement("y"); + assertEquals(el1, el2); + assertFalse(el1.equals(el3)); + } + + @Test + public void hashCode_() { + PhraseElement el1 = new PhraseElement("x"), el2 = new PhraseElement("x"); + assertEquals(el1.hashCode(), el2.hashCode()); + } + +} diff --git a/querydsl-lucene3/src/test/java/com/querydsl/lucene3/QDocument.java b/querydsl-lucene3/src/test/java/com/querydsl/lucene3/QDocument.java new file mode 100644 index 0000000000..e4bea064a6 --- /dev/null +++ b/querydsl-lucene3/src/test/java/com/querydsl/lucene3/QDocument.java @@ -0,0 +1,37 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.lucene3; + +import org.apache.lucene.document.Document; + +import com.querydsl.core.types.PathMetadataFactory; +import com.querydsl.core.types.dsl.EntityPathBase; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.StringPath; + +public class QDocument extends EntityPathBase<Document> { + + private static final long serialVersionUID = -4872833626508344081L; + + public QDocument(final String var) { + super(Document.class, PathMetadataFactory.forVariable(var)); + } + + public final NumberPath<Integer> year = createNumber("year", Integer.class); + + public final StringPath title = createString("title"); + + public final NumberPath<Double> gross = createNumber("gross", Double.class); + +} \ No newline at end of file diff --git a/querydsl-lucene3/src/test/java/com/querydsl/lucene3/QueryElementTest.java b/querydsl-lucene3/src/test/java/com/querydsl/lucene3/QueryElementTest.java new file mode 100644 index 0000000000..6e634c11f8 --- /dev/null +++ b/querydsl-lucene3/src/test/java/com/querydsl/lucene3/QueryElementTest.java @@ -0,0 +1,35 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.lucene3; + +import static org.junit.Assert.assertEquals; + +import org.apache.lucene.index.Term; +import org.apache.lucene.search.TermQuery; +import org.junit.Ignore; +import org.junit.Test; + +public class QueryElementTest { + + @Test + @Ignore + public void test() { + QueryElement element = new QueryElement(new TermQuery(new Term("str","text"))); + assertEquals("str:text",element.toString()); + //assertEquals(element.getQuery().hashCode(), element.hashCode()); + + QueryElement element2 = new QueryElement(new TermQuery(new Term("str","text"))); + assertEquals(element2, element); + } +} diff --git a/querydsl-lucene3/src/test/java/com/querydsl/lucene3/TermElementTest.java b/querydsl-lucene3/src/test/java/com/querydsl/lucene3/TermElementTest.java new file mode 100644 index 0000000000..fac308aa0c --- /dev/null +++ b/querydsl-lucene3/src/test/java/com/querydsl/lucene3/TermElementTest.java @@ -0,0 +1,45 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.lucene3; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; + +import org.junit.Test; + +import com.querydsl.core.DefaultQueryMetadata; +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.StringPath; + +public class TermElementTest { + + @Test + public void test() { + StringPath title = Expressions.stringPath("title"); + LuceneSerializer serializer = new LuceneSerializer(false,true); + QueryMetadata metadata = new DefaultQueryMetadata(); + assertEquals("title:\"Hello World\"", serializer.toQuery(title.eq("Hello World"), metadata).toString()); + assertEquals("title:Hello World", serializer.toQuery(title.eq(new TermElement("Hello World")), metadata).toString()); + } + + @Test + public void testEqualsAndHashCode() { + TermElement el1 = new TermElement("x"), el2 = new TermElement("x"), el3 = new TermElement("y"); + assertEquals(el1, el2); + assertFalse(el1.equals(el3)); + assertEquals(el1.hashCode(), el2.hashCode()); + } + +} diff --git a/querydsl-lucene3/src/test/resources/log4j.properties.example b/querydsl-lucene3/src/test/resources/log4j.properties.example index 2f9467c280..0c3a1143dc 100644 --- a/querydsl-lucene3/src/test/resources/log4j.properties.example +++ b/querydsl-lucene3/src/test/resources/log4j.properties.example @@ -1,9 +1,9 @@ -# Configure an appender that logs to console -log4j.rootLogger=info, A1 -log4j.threshold=debug -log4j.appender.A1=org.apache.log4j.ConsoleAppender -log4j.appender.A1.layout=org.apache.log4j.PatternLayout -log4j.appender.A1.layout.ConversionPattern=%d [%t] %-5p %c{1} - %m%n - -# Configuration of logging levels for different packages -log4j.logger.com.mysema.query.lucene=DEBUG +# Configure an appender that logs to console +log4j.rootLogger=info, A1 +log4j.threshold=debug +log4j.appender.A1=org.apache.log4j.ConsoleAppender +log4j.appender.A1.layout=org.apache.log4j.PatternLayout +log4j.appender.A1.layout.ConversionPattern=%d [%t] %-5p %c{1} - %m%n + +# Configuration of logging levels for different packages +log4j.logger.com.querydsl.lucene3=DEBUG diff --git a/querydsl-lucene3/template.mf b/querydsl-lucene3/template.mf deleted file mode 100644 index 1457c332a6..0000000000 --- a/querydsl-lucene3/template.mf +++ /dev/null @@ -1,11 +0,0 @@ -Bundle-SymbolicName: com.mysema.querydsl.lucene -Bundle-Name: Querydsl Lucene -Bundle-Vendor: Mysema -Bundle-ManifestVersion: 2 -Import-Template: - com.mysema.commons.lang.*;version="${mysema.lang.version}", - com.mysema.query.*;version="${project.version}", - javax.annotation.*;version="0", - com.google.common.*;version="${guava.version}", - org.apache.lucene.*;version="[3.0.0,3.1.0)", - org.slf4j.*;version="${slf4j.version}" \ No newline at end of file diff --git a/querydsl-lucene4/README.md b/querydsl-lucene4/README.md index 0250337fab..c49a988e8f 100644 --- a/querydsl-lucene4/README.md +++ b/querydsl-lucene4/README.md @@ -5,36 +5,32 @@ The Lucene module provides integration with the Lucene 4 indexing library. **Maven integration** Add the following dependencies to your Maven project : - - <dependency> - <groupId>com.mysema.querydsl</groupId> - <artifactId>querydsl-lucene4</artifactId> - <version>${querydsl.version}</version> - </dependency> - - <dependency> - <groupId>org.slf4j</groupId> - <artifactId>slf4j-log4j12</artifactId> - <version>1.6.1</version> - </dependency> - +```XML +<dependency> + <groupId>com.querydsl</groupId> + <artifactId>querydsl-lucene4</artifactId> + <version>${querydsl.version}</version> +</dependency> +``` **Creating the query types** With fields year and title a manually created query type could look something like this: - - public class QDocument extends EntityPathBase<Document>{ - private static final long serialVersionUID = -4872833626508344081L; - - public QDocument(String var) { - super(Document.class, PathMetadataFactory.forVariable(var)); - } - - public final StringPath year = createString("year"); - - public final StringPath title = createString("title"); + +```JAVA +public class QDocument extends EntityPathBase<Document>{ + private static final long serialVersionUID = -4872833626508344081L; + + public QDocument(String var) { + super(Document.class, PathMetadataFactory.forVariable(var)); } + public final StringPath year = createString("year"); + + public final StringPath title = createString("title"); +} +``` + QDocument represents a Lucene document with the fields year and title. Code generation is not available for Lucene, since no schema data is available. @@ -42,17 +38,20 @@ Code generation is not available for Lucene, since no schema data is available. **Querying** Querying with Querydsl Lucene is as simple as this: - - QDocument doc = new QDocument("doc"); - - IndexSearcher searcher = new IndexSearher(index); - LuceneQuery query = new LuceneQuery(true, searcher); - List<Document> documents = query - .where(doc.year.between("1800", "2000").and(doc.title.startsWith("Huckle")) - .list(); + +```JAVA +QDocument doc = new QDocument("doc"); + +IndexSearcher searcher = new IndexSearcher(index); +LuceneQuery query = new LuceneQuery(true, searcher); +List<Document> documents = query + .where(doc.year.between("1800", "2000").and(doc.title.startsWith("Huckle")) + .fetch(); +``` which is transformed into the following Lucene query : - - +year:[1800 TO 2000] +title:huckle* +``` ++year:[1800 TO 2000] +title:huckle* +``` -For more information on the Querydsl Lucene module visit the reference documentation http://www.querydsl.com/static/querydsl/latest/reference/html/ch02s04.html \ No newline at end of file +For more information on the Querydsl Lucene module visit the reference documentation http://www.querydsl.com/static/querydsl/latest/reference/html/ch02s05.html diff --git a/querydsl-lucene4/pom.xml b/querydsl-lucene4/pom.xml index 06f61e4f6a..b393cb52d9 100644 --- a/querydsl-lucene4/pom.xml +++ b/querydsl-lucene4/pom.xml @@ -1,15 +1,15 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0" encoding="UTF-8"?> <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <modelVersion>4.0.0</modelVersion> <parent> - <groupId>com.mysema.querydsl</groupId> + <groupId>com.querydsl</groupId> <artifactId>querydsl-root</artifactId> - <version>3.4.1.BUILD-SNAPSHOT</version> - <relativePath>../querydsl-root/pom.xml</relativePath> + <version>5.1.0</version> + <relativePath>../pom.xml</relativePath> </parent> - <groupId>com.mysema.querydsl</groupId> + <groupId>com.querydsl</groupId> <artifactId>querydsl-lucene4</artifactId> <name>Querydsl - Lucene 4 support</name> <description>Lucene support for Querydsl</description> @@ -24,9 +24,18 @@ <properties> <lucene.version>4.2.1</lucene.version> + <osgi.import.package> + org.apache.lucene.*;version="[4,5)", + ${osgi.import.package.root} + </osgi.import.package> </properties> - <dependencies> + <dependencies> + <dependency> + <groupId>org.jetbrains</groupId> + <artifactId>annotations</artifactId> + <scope>provided</scope> + </dependency> <dependency> <groupId>org.apache.lucene</groupId> <artifactId>lucene-core</artifactId> @@ -52,23 +61,14 @@ <scope>provided</scope> </dependency> <dependency> - <groupId>com.mysema.querydsl</groupId> + <groupId>com.querydsl</groupId> <artifactId>querydsl-core</artifactId> <version>${project.version}</version> </dependency> - <dependency> - <groupId>org.slf4j</groupId> - <artifactId>slf4j-api</artifactId> - </dependency> - <dependency> - <groupId>org.slf4j</groupId> - <artifactId>slf4j-log4j12</artifactId> - </dependency> - <!-- test --> <dependency> - <groupId>com.mysema.querydsl</groupId> + <groupId>com.querydsl</groupId> <artifactId>querydsl-core</artifactId> <version>${project.version}</version> <scope>test</scope> @@ -78,12 +78,12 @@ <dependency> <groupId>joda-time</groupId> <artifactId>joda-time</artifactId> - <version>1.6</version> + <version>${jodatime.version}</version> <scope>test</scope> </dependency> <dependency> - <groupId>com.mysema.querydsl</groupId> + <groupId>com.querydsl</groupId> <artifactId>querydsl-apt</artifactId> <version>${project.version}</version> </dependency> @@ -92,8 +92,20 @@ <build> <plugins> <plugin> - <groupId>com.springsource.bundlor</groupId> - <artifactId>com.springsource.bundlor.maven</artifactId> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-jar-plugin</artifactId> + <configuration> + <archive> + <manifestEntries> + <Automatic-Module-Name>com.querydsl.lucene4</Automatic-Module-Name> + </manifestEntries> + </archive> + </configuration> + </plugin> + + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> </plugin> <plugin> @@ -107,7 +119,7 @@ </goals> <configuration> <outputDirectory>target/generated-test-sources/java</outputDirectory> - <processor>com.mysema.query.apt.QuerydslAnnotationProcessor</processor> + <processor>com.querydsl.apt.QuerydslAnnotationProcessor</processor> <showWarnings>true</showWarnings> </configuration> </execution> @@ -115,4 +127,4 @@ </plugin> </plugins> </build> -</project> +</project> diff --git a/querydsl-lucene4/src/main/java/com/mysema/query/lucene/AbstractLuceneQuery.java b/querydsl-lucene4/src/main/java/com/mysema/query/lucene/AbstractLuceneQuery.java deleted file mode 100644 index f06e872572..0000000000 --- a/querydsl-lucene4/src/main/java/com/mysema/query/lucene/AbstractLuceneQuery.java +++ /dev/null @@ -1,376 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.lucene; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import javax.annotation.Nullable; - -import org.apache.lucene.document.Document; -import org.apache.lucene.queries.ChainedFilter; -import org.apache.lucene.sandbox.queries.DuplicateFilter; -import org.apache.lucene.search.Filter; -import org.apache.lucene.search.IndexSearcher; -import org.apache.lucene.search.MatchAllDocsQuery; -import org.apache.lucene.search.Query; -import org.apache.lucene.search.QueryWrapperFilter; -import org.apache.lucene.search.ScoreDoc; -import org.apache.lucene.search.Sort; - -import com.google.common.base.Function; -import com.google.common.collect.ImmutableList; -import com.mysema.commons.lang.CloseableIterator; -import com.mysema.commons.lang.EmptyCloseableIterator; -import com.mysema.commons.lang.IteratorAdapter; -import com.mysema.query.DefaultQueryMetadata; -import com.mysema.query.NonUniqueResultException; -import com.mysema.query.QueryException; -import com.mysema.query.QueryMetadata; -import com.mysema.query.QueryModifiers; -import com.mysema.query.SearchResults; -import com.mysema.query.SimpleProjectable; -import com.mysema.query.SimpleQuery; -import com.mysema.query.support.QueryMixin; -import com.mysema.query.types.OrderSpecifier; -import com.mysema.query.types.ParamExpression; -import com.mysema.query.types.Path; -import com.mysema.query.types.Predicate; - -/** - * AbstractLuceneQuery is an abstract super class for Lucene query implementations - * - * @author tiwe - * - * @param <T> projection type - * @param <Q> concrete subtype of query - */ -public abstract class AbstractLuceneQuery<T,Q extends AbstractLuceneQuery<T,Q>> implements SimpleQuery<Q>, -SimpleProjectable<T> { - - private final QueryMixin<Q> queryMixin; - - private final IndexSearcher searcher; - - private final LuceneSerializer serializer; - - private final Function<Document, T> transformer; - - @Nullable - private Set<String> fieldsToLoad; - - private List<Filter> filters = ImmutableList.of(); - - @Nullable - private Filter _filter; - - @Nullable - private Sort querySort; - - @SuppressWarnings("unchecked") - public AbstractLuceneQuery(LuceneSerializer serializer, IndexSearcher searcher, - Function<Document, T> transformer) { - queryMixin = new QueryMixin<Q>((Q) this, new DefaultQueryMetadata().noValidate()); - this.serializer = serializer; - this.searcher = searcher; - this.transformer = transformer; - } - - public AbstractLuceneQuery(IndexSearcher searcher, Function<Document, T> transformer) { - this(LuceneSerializer.DEFAULT, searcher, transformer); - } - - @Override - public boolean exists() { - return innerCount() > 0; - } - - @Override - public boolean notExists() { - return innerCount() == 0; - } - - private long innerCount() { - try { - final int maxDoc = searcher.getIndexReader().maxDoc(); - if (maxDoc == 0) { - return 0; - } - return searcher.search(createQuery(), getFilter(), maxDoc, Sort.INDEXORDER, false, false).totalHits; - } catch (IOException e) { - throw new QueryException(e); - } catch (IllegalArgumentException e) { - throw new QueryException(e); - } - } - - @Override - public long count() { - return innerCount(); - } - - protected Query createQuery() { - if (queryMixin.getMetadata().getWhere() == null) { - return new MatchAllDocsQuery(); - } - return serializer.toQuery(queryMixin.getMetadata().getWhere(), queryMixin.getMetadata()); - } - - /** - * Create a filter for constraints defined in this query - * - * @return - */ - public Filter asFilter() { - return new QueryWrapperFilter(createQuery()); - } - - @Override - public Q distinct() { - throw new UnsupportedOperationException("use distinct(path) instead"); - } - - /** - * Add a DuplicateFilter for the field of the given property path - * - * @param property - * @return - */ - public Q distinct(Path<?> property) { - return filter(new DuplicateFilter(serializer.toField(property))); - } - - /** - * Apply the given Lucene filter to the search results - * - * @param filter - * @return - */ - @SuppressWarnings("unchecked") - public Q filter(Filter filter) { - if (filters.isEmpty()) { - this._filter = filter; - filters = ImmutableList.of(filter); - } else { - this._filter = null; - if (filters.size() == 1) { - filters = new ArrayList<Filter>(); - } - filters.add(filter); - } - return (Q)this; - } - - private Filter getFilter() { - if (_filter == null && !filters.isEmpty()) { - _filter = new ChainedFilter(filters.toArray(new Filter[filters.size()])); - } - return _filter; - } - - @Override - public Q limit(long limit) { - return queryMixin.limit(limit); - } - - @Override - public CloseableIterator<T> iterate() { - final QueryMetadata metadata = queryMixin.getMetadata(); - final List<OrderSpecifier<?>> orderBys = metadata.getOrderBy(); - final Integer queryLimit = metadata.getModifiers().getLimitAsInteger(); - final Integer queryOffset = metadata.getModifiers().getOffsetAsInteger(); - Sort sort = querySort; - int limit; - final int offset = queryOffset != null ? queryOffset.intValue() : 0; - try { - limit = maxDoc(); - if (limit == 0) { - return new EmptyCloseableIterator<T>(); - } - } catch (IOException e) { - throw new QueryException(e); - } catch (IllegalArgumentException e) { - throw new QueryException(e); - } - if (queryLimit != null && queryLimit.intValue() < limit) { - limit = queryLimit.intValue(); - } - if (sort == null && !orderBys.isEmpty()) { - sort = serializer.toSort(orderBys); - } - - try { - ScoreDoc[] scoreDocs; - int sumOfLimitAndOffset = limit + offset; - if (sumOfLimitAndOffset < 1) { - throw new QueryException("The given limit (" + limit + ") and offset (" + offset + ") cause an integer overflow."); - } - if (sort != null) { - scoreDocs = searcher.search(createQuery(), getFilter(), sumOfLimitAndOffset, sort, false, false).scoreDocs; - } else { - scoreDocs = searcher.search(createQuery(), getFilter(), sumOfLimitAndOffset, Sort.INDEXORDER, false, false).scoreDocs; - } - if (offset < scoreDocs.length) { - return new ResultIterator<T>(scoreDocs, offset, searcher, fieldsToLoad, transformer); - } - return new EmptyCloseableIterator<T>(); - } catch (final IOException e) { - throw new QueryException(e); - } - } - - private List<T> innerList() { - return new IteratorAdapter<T>(iterate()).asList(); - } - - @Override - public List<T> list() { - return innerList(); - } - - /** - * Set the given fields to load - * - * @param fieldsToLoad - * @return - */ - @SuppressWarnings("unchecked") - public Q load(Set<String> fieldsToLoad) { - this.fieldsToLoad = fieldsToLoad; - return (Q)this; - } - - /** - * Load only the fields of the given paths - * - * @param paths - * @return - */ - @SuppressWarnings("unchecked") - public Q load(Path<?>... paths) { - Set<String> fields = new HashSet<String>(); - for (Path<?> path : paths) { - fields.add(serializer.toField(path)); - } - this.fieldsToLoad = fields; - return (Q)this; - } - - @Override - public SearchResults<T> listResults() { - List<T> documents = innerList(); - /* - * TODO Get rid of count(). It could be implemented by iterating the - * list results in list* from n to m. - */ - return new SearchResults<T>(documents, queryMixin.getMetadata().getModifiers(), innerCount()); - } - - @Override - public Q offset(long offset) { - return queryMixin.offset(offset); - } - - public Q orderBy(OrderSpecifier<?> o) { - return queryMixin.orderBy(o); - } - - @Override - public Q orderBy(OrderSpecifier<?>... o) { - return queryMixin.orderBy(o); - } - - @Override - public Q restrict(QueryModifiers modifiers) { - return queryMixin.restrict(modifiers); - } - - @Override - public <P> Q set(ParamExpression<P> param, P value) { - return queryMixin.set(param, value); - } - - @SuppressWarnings("unchecked") - public Q sort(Sort sort) { - this.querySort = sort; - return (Q)this; - } - - @Nullable - private T oneResult(boolean unique) { - try { - int maxDoc = maxDoc(); - if (maxDoc == 0) { - return null; - } - final ScoreDoc[] scoreDocs = searcher.search(createQuery(), getFilter(), maxDoc, Sort.INDEXORDER, false, false).scoreDocs; - int index = 0; - QueryModifiers modifiers = queryMixin.getMetadata().getModifiers(); - Long offset = modifiers.getOffset(); - if (offset != null) { - index = offset.intValue(); - } - Long limit = modifiers.getLimit(); - if (unique && (limit == null ? scoreDocs.length - index > 1 : - limit > 1 && scoreDocs.length > 1)) { - throw new NonUniqueResultException("Unique result requested, but " + scoreDocs.length + " found."); - } else if (scoreDocs.length > index) { - Document document; - if (fieldsToLoad != null) { - document = searcher.doc(scoreDocs[index].doc, fieldsToLoad); - } else { - document = searcher.doc(scoreDocs[index].doc); - } - return transformer.apply(document); - } else { - return null; - } - } catch (IOException e) { - throw new QueryException(e); - } catch (IllegalArgumentException e) { - throw new QueryException(e); - } - } - - @Override - public T singleResult() { - return oneResult(false); - } - - @Override - public T uniqueResult() { - return oneResult(true); - } - - public Q where(Predicate e) { - return queryMixin.where(e); - } - - @Override - public Q where(Predicate... e) { - return queryMixin.where(e); - } - - @Override - public String toString() { - return createQuery().toString(); - } - - private int maxDoc() throws IOException { - return searcher.getIndexReader().maxDoc(); - } -} diff --git a/querydsl-lucene4/src/main/java/com/mysema/query/lucene/IgnoreCaseUnsupportedException.java b/querydsl-lucene4/src/main/java/com/mysema/query/lucene/IgnoreCaseUnsupportedException.java deleted file mode 100644 index 987f80d1b4..0000000000 --- a/querydsl-lucene4/src/main/java/com/mysema/query/lucene/IgnoreCaseUnsupportedException.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.lucene; - -/** - * @author tiwe - * - */ -public class IgnoreCaseUnsupportedException extends UnsupportedOperationException{ - - private static final long serialVersionUID = 412913389929530788L; - - public IgnoreCaseUnsupportedException() { - super("Ignore case queries are not supported with Lucene"); - } - -} diff --git a/querydsl-lucene4/src/main/java/com/mysema/query/lucene/LuceneExpressions.java b/querydsl-lucene4/src/main/java/com/mysema/query/lucene/LuceneExpressions.java deleted file mode 100644 index 4f96f18de4..0000000000 --- a/querydsl-lucene4/src/main/java/com/mysema/query/lucene/LuceneExpressions.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.lucene; - -import org.apache.lucene.index.Term; -import org.apache.lucene.search.FuzzyQuery; - -import com.mysema.query.types.Path; -import com.mysema.query.types.expr.BooleanExpression; - -/** - * Utility methods to create filter expressions for Lucene queries that are not covered by the - * Querydsl standard expression model - * - * @author tiwe - * - */ -public final class LuceneExpressions { - - /** - * Create a fuzzy query - * - * @param path - * @param value - * @return - */ - public static BooleanExpression fuzzyLike(Path<String> path, String value) { - Term term = new Term(path.getMetadata().getName(), value); - return new QueryElement(new FuzzyQuery(term)); - } - - /** - * Create a fuzzy query - * - * @param path - * @param value - * @param maxEdits - * @return - */ - public static BooleanExpression fuzzyLike(Path<String> path, String value, int maxEdits) { - Term term = new Term(path.getMetadata().getName(), value); - return new QueryElement(new FuzzyQuery(term, maxEdits)); - } - - /** - * Create a fuzzy query - * - * @param path - * @param value - * @param maxEdits - * @param prefixLength - * @return - */ - public static BooleanExpression fuzzyLike(Path<String> path, String value, - int maxEdits, int prefixLength) { - Term term = new Term(path.getMetadata().getName(), value); - return new QueryElement(new FuzzyQuery(term, maxEdits, prefixLength)); - } - - private LuceneExpressions() {} - -} diff --git a/querydsl-lucene4/src/main/java/com/mysema/query/lucene/LuceneOps.java b/querydsl-lucene4/src/main/java/com/mysema/query/lucene/LuceneOps.java deleted file mode 100644 index 6aff0aea21..0000000000 --- a/querydsl-lucene4/src/main/java/com/mysema/query/lucene/LuceneOps.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.lucene; - -import com.mysema.query.types.Operator; -import com.mysema.query.types.OperatorImpl; - -/** - * @author tiwe - * - */ -public final class LuceneOps { - - private static final String NS = LuceneOps.class.getName(); - - static final Operator<Object> LUCENE_QUERY = new OperatorImpl<Object>(NS, "QUERY"); - - static final Operator<String> PHRASE = new OperatorImpl<String>(NS, "PHRASE"); - - static final Operator<String> TERM = new OperatorImpl<String>(NS, "TERM"); - - private LuceneOps() {} - -} diff --git a/querydsl-lucene4/src/main/java/com/mysema/query/lucene/LuceneQuery.java b/querydsl-lucene4/src/main/java/com/mysema/query/lucene/LuceneQuery.java deleted file mode 100644 index 96a6b74646..0000000000 --- a/querydsl-lucene4/src/main/java/com/mysema/query/lucene/LuceneQuery.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.lucene; - -import org.apache.lucene.document.Document; -import org.apache.lucene.search.IndexSearcher; - -import com.google.common.base.Function; - -/** - * LuceneQuery is a Querydsl query implementation for Lucene queries. - * - * @author vema - */ -public class LuceneQuery extends AbstractLuceneQuery<Document, LuceneQuery> { - - private static final Function<Document,Document> TRANSFORMER = new Function<Document,Document>() { - @Override - public Document apply(Document input) { - return input; - } - }; - - public LuceneQuery(IndexSearcher searcher) { - super(searcher, TRANSFORMER); - } - - public LuceneQuery(LuceneSerializer luceneSerializer, IndexSearcher searcher) { - super(luceneSerializer, searcher, TRANSFORMER); - } - -} diff --git a/querydsl-lucene4/src/main/java/com/mysema/query/lucene/LuceneSerializer.java b/querydsl-lucene4/src/main/java/com/mysema/query/lucene/LuceneSerializer.java deleted file mode 100644 index 82a3d02a0e..0000000000 --- a/querydsl-lucene4/src/main/java/com/mysema/query/lucene/LuceneSerializer.java +++ /dev/null @@ -1,569 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.lucene; - -import java.math.BigDecimal; -import java.math.BigInteger; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.regex.Pattern; - -import javax.annotation.Nullable; - -import org.apache.lucene.index.Term; -import org.apache.lucene.queryparser.classic.QueryParser; -import org.apache.lucene.search.BooleanClause; -import org.apache.lucene.search.BooleanClause.Occur; -import org.apache.lucene.search.BooleanQuery; -import org.apache.lucene.search.MatchAllDocsQuery; -import org.apache.lucene.search.NumericRangeQuery; -import org.apache.lucene.search.PhraseQuery; -import org.apache.lucene.search.PrefixQuery; -import org.apache.lucene.search.Query; -import org.apache.lucene.search.Sort; -import org.apache.lucene.search.SortField; -import org.apache.lucene.search.TermQuery; -import org.apache.lucene.search.TermRangeQuery; -import org.apache.lucene.search.WildcardQuery; -import org.apache.lucene.util.BytesRef; -import org.apache.lucene.util.NumericUtils; - -import com.google.common.base.Splitter; -import com.google.common.collect.Iterables; -import com.mysema.query.QueryMetadata; -import com.mysema.query.types.Constant; -import com.mysema.query.types.Expression; -import com.mysema.query.types.ExpressionUtils; -import com.mysema.query.types.Operation; -import com.mysema.query.types.Operator; -import com.mysema.query.types.Ops; -import com.mysema.query.types.OrderSpecifier; -import com.mysema.query.types.ParamExpression; -import com.mysema.query.types.ParamNotSetException; -import com.mysema.query.types.Path; -import com.mysema.query.types.PathType; - -/** - * Serializes Querydsl queries to Lucene queries. - * - * @author vema - * - */ -public class LuceneSerializer { - private static final Map<Class<?>, SortField.Type> sortFields = new HashMap<Class<?>, SortField.Type>(); - - static { - sortFields.put(Integer.class, SortField.Type.INT); - sortFields.put(Float.class, SortField.Type.FLOAT); - sortFields.put(Long.class, SortField.Type.LONG); - sortFields.put(Double.class, SortField.Type.DOUBLE); - sortFields.put(Short.class, SortField.Type.SHORT); - sortFields.put(Byte.class, SortField.Type.BYTE); - sortFields.put(BigDecimal.class, SortField.Type.DOUBLE); - sortFields.put(BigInteger.class, SortField.Type.LONG); - } - - private static final Splitter WS_SPLITTER = Splitter.on(Pattern.compile("\\s+")); - - public static final LuceneSerializer DEFAULT = new LuceneSerializer(false, true); - - private final boolean lowerCase; - - private final boolean splitTerms; - - private final Locale sortLocale; - - public LuceneSerializer(boolean lowerCase, boolean splitTerms) { - this(lowerCase, splitTerms, Locale.getDefault()); - } - - public LuceneSerializer(boolean lowerCase, boolean splitTerms, Locale sortLocale) { - this.lowerCase = lowerCase; - this.splitTerms = splitTerms; - this.sortLocale = sortLocale; - } - - private Query toQuery(Operation<?> operation, QueryMetadata metadata) { - Operator<?> op = operation.getOperator(); - if (op == Ops.OR) { - return toTwoHandSidedQuery(operation, Occur.SHOULD, metadata); - } else if (op == Ops.AND) { - return toTwoHandSidedQuery(operation, Occur.MUST, metadata); - } else if (op == Ops.NOT) { - BooleanQuery bq = new BooleanQuery(); - bq.add(new BooleanClause(toQuery(operation.getArg(0), metadata), Occur.MUST_NOT)); - bq.add(new BooleanClause(new MatchAllDocsQuery(), Occur.MUST)); - return bq; - } else if (op == Ops.LIKE) { - return like(operation, metadata); - } else if (op == Ops.EQ) { - return eq(operation, metadata, false); - } else if (op == Ops.EQ_IGNORE_CASE) { - throw new IgnoreCaseUnsupportedException(); - } else if (op == Ops.NE) { - return ne(operation, metadata, false); - } else if (op == Ops.STARTS_WITH) { - return startsWith(metadata, operation, false); - } else if (op == Ops.STARTS_WITH_IC) { - throw new IgnoreCaseUnsupportedException(); - } else if (op == Ops.ENDS_WITH) { - return endsWith(operation, metadata, false); - } else if (op == Ops.ENDS_WITH_IC) { - throw new IgnoreCaseUnsupportedException(); - } else if (op == Ops.STRING_CONTAINS) { - return stringContains(operation, metadata, false); - } else if (op == Ops.STRING_CONTAINS_IC) { - throw new IgnoreCaseUnsupportedException(); - } else if (op == Ops.BETWEEN) { - return between(operation, metadata); - } else if (op == Ops.IN) { - return in(operation, metadata, false); - } else if (op == Ops.NOT_IN) { - return notIn(operation, metadata, false); - } else if (op == Ops.LT) { - return lt(operation, metadata); - } else if (op == Ops.GT) { - return gt(operation, metadata); - } else if (op == Ops.LOE) { - return le(operation, metadata); - } else if (op == Ops.GOE) { - return ge(operation, metadata); - } else if (op == LuceneOps.LUCENE_QUERY) { - return ((Constant<Query>)operation.getArg(0)).getConstant(); - } - throw new UnsupportedOperationException("Illegal operation " + operation); - } - - private Query toTwoHandSidedQuery(Operation<?> operation, Occur occur, QueryMetadata metadata) { - Query lhs = toQuery(operation.getArg(0), metadata); - Query rhs = toQuery(operation.getArg(1), metadata); - BooleanQuery bq = new BooleanQuery(); - bq.add(createBooleanClause(lhs, occur)); - bq.add(createBooleanClause(rhs, occur)); - return bq; - } - - /** - * If the query is a BooleanQuery and it contains a single Occur.MUST_NOT - * clause it will be returned as is. Otherwise it will be wrapped in a - * BooleanClause with the given Occur. - */ - private BooleanClause createBooleanClause(Query query, Occur occur) { - if (query instanceof BooleanQuery) { - BooleanClause[] clauses = ((BooleanQuery) query).getClauses(); - if (clauses.length == 1 && clauses[0].getOccur().equals(Occur.MUST_NOT)) { - return clauses[0]; - } - } - return new BooleanClause(query, occur); - } - - protected Query like(Operation<?> operation, QueryMetadata metadata) { - verifyArguments(operation); - Path<?> path = getPath(operation.getArg(0)); - String field = toField(path); - String[] terms = convert(path, operation.getArg(1)); - if (terms.length > 1) { - BooleanQuery bq = new BooleanQuery(); - for (String s : terms) { - bq.add(new WildcardQuery(new Term(field, "*" + s + "*")), Occur.MUST); - } - return bq; - } - return new WildcardQuery(new Term(field, terms[0])); - } - - @SuppressWarnings("unchecked") - protected Query eq(Operation<?> operation, QueryMetadata metadata, boolean ignoreCase) { - verifyArguments(operation); - Path<?> path = getPath(operation.getArg(0)); - String field = toField(path); - - if (Number.class.isAssignableFrom(operation.getArg(1).getType())) { - return new TermQuery(new Term(field, convertNumber(((Constant<Number>) operation - .getArg(1)).getConstant()))); - } - - return eq(field, convert(path, operation.getArg(1), metadata), ignoreCase); - } - - - private BytesRef convertNumber(Number number) { - if (Integer.class.isInstance(number) || Byte.class.isInstance(number) || Short.class.isInstance(number)) { - BytesRef bytes = new BytesRef(NumericUtils.BUF_SIZE_INT); - NumericUtils.intToPrefixCoded(number.intValue(), 0, bytes); - return bytes; - } else if (Double.class.isInstance(number) || BigDecimal.class.isInstance(number)) { - BytesRef bytes = new BytesRef(NumericUtils.BUF_SIZE_LONG); - long l = NumericUtils.doubleToSortableLong(number.doubleValue()); - NumericUtils.longToPrefixCoded(l, 0, bytes); - return bytes; - } else if (Long.class.isInstance(number) || BigInteger.class.isInstance(number)) { - BytesRef bytes = new BytesRef(NumericUtils.BUF_SIZE_LONG); - NumericUtils.longToPrefixCoded(number.longValue(), 0, bytes); - return bytes; - } else if (Float.class.isInstance(number)) { - BytesRef bytes = new BytesRef(NumericUtils.BUF_SIZE_INT); - int i = NumericUtils.floatToSortableInt(number.floatValue()); - NumericUtils.intToPrefixCoded(i, 0, bytes); - return bytes; - } else { - throw new IllegalArgumentException("Unsupported numeric type " - + number.getClass().getName()); - } - } - - protected Query eq(String field, String[] terms, boolean ignoreCase) { - if (terms.length > 1) { - PhraseQuery pq = new PhraseQuery(); - for (String s : terms) { - pq.add(new Term(field, s)); - } - return pq; - } - return new TermQuery(new Term(field, terms[0])); - } - - protected Query in(Operation<?> operation, QueryMetadata metadata, boolean ignoreCase) { - Path<?> path = getPath(operation.getArg(0)); - String field = toField(path); - Collection<?> values = (Collection<?>) ((Constant<?>) operation.getArg(1)).getConstant(); - BooleanQuery bq = new BooleanQuery(); - for (Object value : values) { - String[] str = convert(path, value); - bq.add(eq(field, str, ignoreCase), Occur.SHOULD); - } - return bq; - } - - protected Query notIn(Operation<?> operation, QueryMetadata metadata, boolean ignoreCase) { - BooleanQuery bq = new BooleanQuery(); - bq.add(new BooleanClause(in(operation, metadata, false), Occur.MUST_NOT)); - bq.add(new BooleanClause(new MatchAllDocsQuery(), Occur.MUST)); - return bq; - } - - protected Query ne(Operation<?> operation, QueryMetadata metadata, boolean ignoreCase) { - BooleanQuery bq = new BooleanQuery(); - bq.add(new BooleanClause(eq(operation, metadata, ignoreCase), Occur.MUST_NOT)); - bq.add(new BooleanClause(new MatchAllDocsQuery(), Occur.MUST)); - return bq; - } - - protected Query startsWith(QueryMetadata metadata, Operation<?> operation, boolean ignoreCase) { - verifyArguments(operation); - Path<?> path = getPath(operation.getArg(0)); - String field = toField(path); - String[] terms = convertEscaped(path, operation.getArg(1), metadata); - if (terms.length > 1) { - BooleanQuery bq = new BooleanQuery(); - for (int i = 0; i < terms.length; ++i) { - String s = i == 0 ? terms[i] + "*" : "*" + terms[i] + "*"; - bq.add(new WildcardQuery(new Term(field, s)), Occur.MUST); - } - return bq; - } - return new PrefixQuery(new Term(field, terms[0])); - } - - - - protected Query stringContains(Operation<?> operation, QueryMetadata metadata, boolean ignoreCase) { - verifyArguments(operation); - Path<?> path = getPath(operation.getArg(0)); - String field = toField(path); - String[] terms = convertEscaped(path, operation.getArg(1), metadata); - if (terms.length > 1) { - BooleanQuery bq = new BooleanQuery(); - for (String s : terms) { - bq.add(new WildcardQuery(new Term(field, "*" + s + "*")), Occur.MUST); - } - return bq; - } - return new WildcardQuery(new Term(field, "*" + terms[0] + "*")); - } - - protected Query endsWith(Operation<?> operation, QueryMetadata metadata, boolean ignoreCase) { - verifyArguments(operation); - Path<?> path = getPath(operation.getArg(0)); - String field = toField(path); - String[] terms = convertEscaped(path, operation.getArg(1), metadata); - if (terms.length > 1) { - BooleanQuery bq = new BooleanQuery(); - for (int i = 0; i < terms.length; ++i) { - String s = i == terms.length - 1 ? "*" + terms[i] : "*" + terms[i] + "*"; - bq.add(new WildcardQuery(new Term(field, s)), Occur.MUST); - } - return bq; - } - return new WildcardQuery(new Term(field, "*" + terms[0])); - } - - protected Query between(Operation<?> operation, QueryMetadata metadata) { - verifyArguments(operation); - Path<?> path = getPath(operation.getArg(0)); - // TODO Phrase not properly supported - return range( - path, - toField(path), - operation.getArg(1), - operation.getArg(2), - true, - true, - metadata); - } - - protected Query lt(Operation<?> operation, QueryMetadata metadata) { - verifyArguments(operation); - Path<?> path = getPath(operation.getArg(0)); - return range( - path, - toField(path), - null, - operation.getArg(1), - false, - false, - metadata); - } - - protected Query gt(Operation<?> operation, QueryMetadata metadata) { - verifyArguments(operation); - Path<?> path = getPath(operation.getArg(0)); - return range( - path, - toField(path), - operation.getArg(1), - null, - false, - false, - metadata); - } - - protected Query le(Operation<?> operation, QueryMetadata metadata) { - verifyArguments(operation); - Path<?> path = getPath(operation.getArg(0)); - return range( - path, - toField(path), - null, - operation.getArg(1), - true, - true, - metadata); - } - - protected Query ge(Operation<?> operation, QueryMetadata metadata) { - verifyArguments(operation); - Path<?> path = getPath(operation.getArg(0)); - return range( - path, - toField(path), - operation.getArg(1), - null, - true, - true, - metadata); - } - - @SuppressWarnings({"unchecked"}) - protected Query range(Path<?> leftHandSide, String field, @Nullable Expression<?> min, - @Nullable Expression<?> max, boolean minInc, boolean maxInc, QueryMetadata metadata) { - if (min != null && Number.class.isAssignableFrom(min.getType()) || max != null - && Number.class.isAssignableFrom(max.getType())) { - Class<? extends Number> numType = (Class) (min != null ? min.getType() : max.getType()); - return numericRange((Class) numType, field, (Number) (min == null ? null - : ((Constant) min).getConstant()), (Number) (max == null ? null - : ((Constant) max).getConstant()), minInc, maxInc); - } - return stringRange(leftHandSide, field, min, max, minInc, maxInc, metadata); - } - - protected <N extends Number> NumericRangeQuery<?> numericRange(Class<N> clazz, String field, - @Nullable N min, @Nullable N max, boolean minInc, boolean maxInc) { - if (clazz.equals(Integer.class)) { - return NumericRangeQuery.newIntRange(field, (Integer) min, (Integer) max, minInc, maxInc); - } else if (clazz.equals(Double.class)) { - return NumericRangeQuery.newDoubleRange(field, (Double) min, (Double) max, minInc, minInc); - } else if (clazz.equals(Float.class)) { - return NumericRangeQuery.newFloatRange(field, (Float) min, (Float) max, minInc, minInc); - } else if (clazz.equals(Long.class)) { - return NumericRangeQuery.newLongRange(field, (Long) min, (Long) max, minInc, minInc); - } else if (clazz.equals(Byte.class) || clazz.equals(Short.class)) { - return NumericRangeQuery.newIntRange(field, min != null ? min.intValue() : null, - max != null ? max.intValue() : null, minInc, maxInc); - } else { - throw new IllegalArgumentException("Unsupported numeric type " + clazz.getName()); - } - } - - protected Query stringRange( - Path<?> leftHandSide, - String field, - @Nullable Expression<?> min, - @Nullable Expression<?> max, - boolean minInc, - boolean maxInc, - QueryMetadata metadata) { - - if (min == null) { - return TermRangeQuery.newStringRange( - field, null, convert(leftHandSide, max, metadata)[0], minInc, maxInc); - } else if (max == null) { - return TermRangeQuery.newStringRange( - field, convert(leftHandSide, min, metadata)[0], - null, minInc, maxInc); - } else { - return TermRangeQuery.newStringRange( - field, convert(leftHandSide, min, metadata)[0], - convert(leftHandSide, max, metadata)[0], - minInc, maxInc); - } - } - - private Path<?> getPath(Expression<?> leftHandSide) { - if (leftHandSide instanceof Path<?>) { - return (Path<?>)leftHandSide; - } else if (leftHandSide instanceof Operation<?>) { - Operation<?> operation = (Operation<?>) leftHandSide; - if (operation.getOperator() == Ops.LOWER || operation.getOperator() == Ops.UPPER) { - return (Path<?>)operation.getArg(0); - } - } - throw new IllegalArgumentException("Unable to transform " + leftHandSide + " to path"); - } - - /** - * template method, override to customize - * - * @param path - * @return - */ - protected String toField(Path<?> path) { - String rv = path.getMetadata().getName(); - if (path.getMetadata().getParent() != null) { - Path<?> parent = path.getMetadata().getParent(); - if (parent.getMetadata().getPathType() != PathType.VARIABLE) { - rv = toField(parent) + "." + rv; - } - } - return rv; - } - - private void verifyArguments(Operation<?> operation) { - List<Expression<?>> arguments = operation.getArgs(); - for (int i = 1; i < arguments.size(); ++i) { - if (!(arguments.get(i) instanceof Constant<?>) - && !(arguments.get(i) instanceof ParamExpression<?>) - && !(arguments.get(i) instanceof PhraseElement) - && !(arguments.get(i) instanceof TermElement)) { - throw new IllegalArgumentException("operand was of unsupported type " - + arguments.get(i).getClass().getName()); - } - } - } - - /** - * template method - * - * @param leftHandSide - * @param rightHandSide - * @return - */ - protected String[] convert(Path<?> leftHandSide, Expression<?> rightHandSide, QueryMetadata metadata) { - if (rightHandSide instanceof Operation) { - Operation<?> operation = (Operation<?>)rightHandSide; - if (operation.getOperator() == LuceneOps.PHRASE) { - return Iterables.toArray(WS_SPLITTER.split(operation.getArg(0).toString()), String.class); - } else if (operation.getOperator() == LuceneOps.TERM) { - return new String[] { operation.getArg(0).toString() }; - } else { - throw new IllegalArgumentException(rightHandSide.toString()); - } - } else if (rightHandSide instanceof ParamExpression<?>) { - Object value = metadata.getParams().get(rightHandSide); - if (value == null) { - throw new ParamNotSetException((ParamExpression<?>) rightHandSide); - } - return convert(leftHandSide, value); - - } else if (rightHandSide instanceof Constant<?>) { - return convert(leftHandSide, ((Constant<?>)rightHandSide).getConstant()); - } else { - throw new IllegalArgumentException(rightHandSide.toString()); - } - } - - /** - * template method - * - * @param leftHandSide - * @param rightHandSide - * @return - */ - protected String[] convert(Path<?> leftHandSide, Object rightHandSide) { - String str = rightHandSide.toString(); - if (lowerCase) { - str = str.toLowerCase(); - } - if (splitTerms) { - if (str.equals("")) { - return new String[] { str }; - } else { - return Iterables.toArray(WS_SPLITTER.split(str), String.class); - } - } else { - return new String[] { str }; - } - } - - private String[] convertEscaped(Path<?> leftHandSide, Expression<?> rightHandSide, QueryMetadata metadata) { - String[] str = convert(leftHandSide, rightHandSide, metadata); - for (int i = 0; i < str.length; i++) { - str[i] = QueryParser.escape(str[i]); - } - return str; - } - - public Query toQuery(Expression<?> expr, QueryMetadata metadata) { - if (expr instanceof Operation<?>) { - return toQuery((Operation<?>) expr, metadata); - } else { - return toQuery(ExpressionUtils.extract(expr), metadata); - } - } - - public Sort toSort(List<? extends OrderSpecifier<?>> orderBys) { - List<SortField> sorts = new ArrayList<SortField>(orderBys.size()); - for (OrderSpecifier<?> order : orderBys) { - if (!(order.getTarget() instanceof Path<?>)) { - throw new IllegalArgumentException("argument was not of type Path."); - } - Class<?> type = order.getTarget().getType(); - boolean reverse = !order.isAscending(); - Path<?> path = getPath(order.getTarget()); - if (Number.class.isAssignableFrom(type)) { - sorts.add(new SortField(toField(path), sortFields.get(type), reverse)); - } else { - sorts.add(new SortField(toField(path), SortField.Type.STRING, reverse)); - } - } - Sort sort = new Sort(); - sort.setSort(sorts.toArray(new SortField[sorts.size()])); - return sort; - } -} diff --git a/querydsl-lucene4/src/main/java/com/mysema/query/lucene/PhraseElement.java b/querydsl-lucene4/src/main/java/com/mysema/query/lucene/PhraseElement.java deleted file mode 100644 index 6cf5f4d638..0000000000 --- a/querydsl-lucene4/src/main/java/com/mysema/query/lucene/PhraseElement.java +++ /dev/null @@ -1,33 +0,0 @@ - /* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.lucene; - -import com.mysema.query.types.ConstantImpl; -import com.mysema.query.types.expr.StringOperation; - -/** - * PhraseElement represents the embedded String as a phrase - * - * @author tiwe - * - */ -public class PhraseElement extends StringOperation { - - private static final long serialVersionUID = 2350215644019186076L; - - public PhraseElement(String str) { - super(LuceneOps.PHRASE, ConstantImpl.create(str)); - } - -} diff --git a/querydsl-lucene4/src/main/java/com/mysema/query/lucene/QueryElement.java b/querydsl-lucene4/src/main/java/com/mysema/query/lucene/QueryElement.java deleted file mode 100644 index 6e81e3531e..0000000000 --- a/querydsl-lucene4/src/main/java/com/mysema/query/lucene/QueryElement.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.lucene; - -import org.apache.lucene.search.Query; - -import com.mysema.query.types.ConstantImpl; -import com.mysema.query.types.expr.BooleanOperation; - -/** - * QueryElement wraps a Lucene Query - * - * @author tiwe - * - */ -public class QueryElement extends BooleanOperation { - - private static final long serialVersionUID = 470868107363840155L; - - public QueryElement(Query query) { - super(LuceneOps.LUCENE_QUERY, ConstantImpl.create(query)); - } - -} diff --git a/querydsl-lucene4/src/main/java/com/mysema/query/lucene/ResultIterator.java b/querydsl-lucene4/src/main/java/com/mysema/query/lucene/ResultIterator.java deleted file mode 100644 index 0139920fbe..0000000000 --- a/querydsl-lucene4/src/main/java/com/mysema/query/lucene/ResultIterator.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.lucene; - -import java.io.IOException; -import java.util.Set; - -import javax.annotation.Nullable; - -import org.apache.lucene.document.Document; -import org.apache.lucene.search.IndexSearcher; -import org.apache.lucene.search.ScoreDoc; - -import com.google.common.base.Function; -import com.mysema.commons.lang.CloseableIterator; -import com.mysema.query.QueryException; - -/** - * ResultIterator is a {@link CloseableIterator} implementation for Lucene query results - * - * @author tiwe - * - * @param <T> - */ -public final class ResultIterator<T> implements CloseableIterator<T> { - - private final ScoreDoc[] scoreDocs; - - private int cursor; - - private final IndexSearcher searcher; - - @Nullable - private final Set<String> fieldsToLoad; - - private final Function<Document,T> transformer; - - public ResultIterator(ScoreDoc[] scoreDocs, int offset, IndexSearcher searcher, - @Nullable Set<String> fieldsToLoad, Function<Document, T> transformer) { - this.scoreDocs = scoreDocs.clone(); - this.cursor = offset; - this.searcher = searcher; - this.fieldsToLoad = fieldsToLoad; - this.transformer = transformer; - } - - @Override - public boolean hasNext() { - return cursor != scoreDocs.length; - } - - @Override - public T next() { - try { - Document document; - if (fieldsToLoad != null) { - document = searcher.doc(scoreDocs[cursor++].doc, fieldsToLoad); - } else { - document = searcher.doc(scoreDocs[cursor++].doc); - } - return transformer.apply(document); - } catch (IOException e) { - throw new QueryException(e); - } - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - - @Override - public void close() { - - } - -} \ No newline at end of file diff --git a/querydsl-lucene4/src/main/java/com/mysema/query/lucene/TermElement.java b/querydsl-lucene4/src/main/java/com/mysema/query/lucene/TermElement.java deleted file mode 100644 index 0309847683..0000000000 --- a/querydsl-lucene4/src/main/java/com/mysema/query/lucene/TermElement.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.lucene; - -import com.mysema.query.types.ConstantImpl; -import com.mysema.query.types.expr.StringOperation; - -/** - * TermElement represents the embedded String as a term - * - * @author tiwe - * - */ -public class TermElement extends StringOperation { - - private static final long serialVersionUID = 2350215644019186076L; - - public TermElement(String str) { - super(LuceneOps.TERM, ConstantImpl.create(str)); - } - -} diff --git a/querydsl-lucene4/src/main/java/com/mysema/query/lucene/TypedQuery.java b/querydsl-lucene4/src/main/java/com/mysema/query/lucene/TypedQuery.java deleted file mode 100644 index b6fa4b9884..0000000000 --- a/querydsl-lucene4/src/main/java/com/mysema/query/lucene/TypedQuery.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.lucene; - -import org.apache.lucene.document.Document; -import org.apache.lucene.search.IndexSearcher; - -import com.google.common.base.Function; - -/** - * TypedQuery is a typed query implementation for Lucene queries. - * - * @author laim - * @author tiwe - */ -public class TypedQuery<T> extends AbstractLuceneQuery<T, TypedQuery<T>> { - - public TypedQuery(IndexSearcher searcher, Function<Document, T> transformer) { - super(searcher, transformer); - } - - public TypedQuery(LuceneSerializer serializer, IndexSearcher searcher, Function<Document, T> transformer) { - super(serializer, searcher, transformer); - } - -} diff --git a/querydsl-lucene4/src/main/java/com/mysema/query/lucene/package-info.java b/querydsl-lucene4/src/main/java/com/mysema/query/lucene/package-info.java deleted file mode 100644 index 0f6c4a03a6..0000000000 --- a/querydsl-lucene4/src/main/java/com/mysema/query/lucene/package-info.java +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ - -package com.mysema.query.lucene; diff --git a/querydsl-lucene4/src/main/java/com/querydsl/lucene4/AbstractLuceneQuery.java b/querydsl-lucene4/src/main/java/com/querydsl/lucene4/AbstractLuceneQuery.java new file mode 100644 index 0000000000..83c0218091 --- /dev/null +++ b/querydsl-lucene4/src/main/java/com/querydsl/lucene4/AbstractLuceneQuery.java @@ -0,0 +1,362 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.lucene4; + +import com.mysema.commons.lang.CloseableIterator; +import com.mysema.commons.lang.EmptyCloseableIterator; +import com.mysema.commons.lang.IteratorAdapter; +import com.querydsl.core.DefaultQueryMetadata; +import com.querydsl.core.Fetchable; +import com.querydsl.core.NonUniqueResultException; +import com.querydsl.core.QueryException; +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.QueryModifiers; +import com.querydsl.core.QueryResults; +import com.querydsl.core.SimpleQuery; +import com.querydsl.core.support.QueryMixin; +import com.querydsl.core.types.OrderSpecifier; +import com.querydsl.core.types.ParamExpression; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.Predicate; +import org.apache.lucene.document.Document; +import org.apache.lucene.queries.ChainedFilter; +import org.apache.lucene.sandbox.queries.DuplicateFilter; +import org.apache.lucene.search.Filter; +import org.apache.lucene.search.IndexSearcher; +import org.apache.lucene.search.MatchAllDocsQuery; +import org.apache.lucene.search.Query; +import org.apache.lucene.search.QueryWrapperFilter; +import org.apache.lucene.search.ScoreDoc; +import org.apache.lucene.search.Sort; +import org.apache.lucene.search.TotalHitCountCollector; +import org.jetbrains.annotations.Nullable; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.function.Function; + +/** + * AbstractLuceneQuery is an abstract super class for Lucene query implementations + * + * @author tiwe + * + * @param <T> projection type + * @param <Q> concrete subtype of querydsl + */ +public abstract class AbstractLuceneQuery<T,Q extends AbstractLuceneQuery<T,Q>> implements SimpleQuery<Q>, Fetchable<T> { + + private static final String JAVA_ISO_CONTROL = "[\\p{Cntrl}&&[^\r\n\t]]"; + + private final QueryMixin<Q> queryMixin; + + private final IndexSearcher searcher; + + private final LuceneSerializer serializer; + + private final Function<Document, T> transformer; + + @Nullable + private Set<String> fieldsToLoad; + + private List<Filter> filters = Collections.emptyList(); + + @Nullable + private Filter filter; + + @Nullable + private Sort querySort; + + @SuppressWarnings("unchecked") + public AbstractLuceneQuery(LuceneSerializer serializer, IndexSearcher searcher, + Function<Document, T> transformer) { + queryMixin = new QueryMixin<Q>((Q) this, new DefaultQueryMetadata()); + this.serializer = serializer; + this.searcher = searcher; + this.transformer = transformer; + } + + public AbstractLuceneQuery(IndexSearcher searcher, Function<Document, T> transformer) { + this(LuceneSerializer.DEFAULT, searcher, transformer); + } + + private long innerCount() { + try { + final int maxDoc = searcher.getIndexReader().maxDoc(); + if (maxDoc == 0) { + return 0; + } + TotalHitCountCollector collector = new TotalHitCountCollector(); + searcher.search(createQuery(), getFilter(), collector); + return collector.getTotalHits(); + } catch (IOException | IllegalArgumentException e) { + throw new QueryException(e); + } + } + + @Override + public long fetchCount() { + return innerCount(); + } + + protected Query createQuery() { + if (queryMixin.getMetadata().getWhere() == null) { + return new MatchAllDocsQuery(); + } + return serializer.toQuery(queryMixin.getMetadata().getWhere(), queryMixin.getMetadata()); + } + + /** + * Create a filter for constraints defined in this querydsl + * + * @return filter + */ + public Filter asFilter() { + return new QueryWrapperFilter(createQuery()); + } + + @Override + public Q distinct() { + throw new UnsupportedOperationException("use distinct(path) instead"); + } + + /** + * Add a DuplicateFilter for the field of the given property path + * + * @param property distinct property + * @return the current object + */ + public Q distinct(Path<?> property) { + return filter(new DuplicateFilter(serializer.toField(property))); + } + + /** + * Apply the given Lucene filter to the search results + * + * @param filter filter + * @return the current object + */ + @SuppressWarnings("unchecked") + public Q filter(Filter filter) { + if (filters.isEmpty()) { + this.filter = filter; + filters = Collections.singletonList(filter); + } else { + this.filter = null; + if (filters.size() == 1) { + filters = new ArrayList<Filter>(); + } + filters.add(filter); + } + return (Q) this; + } + + private Filter getFilter() { + if (filter == null && !filters.isEmpty()) { + filter = new ChainedFilter(filters.toArray(new Filter[0])); + } + return filter; + } + + @Override + public Q limit(long limit) { + return queryMixin.limit(limit); + } + + @Override + public CloseableIterator<T> iterate() { + final QueryMetadata metadata = queryMixin.getMetadata(); + final List<OrderSpecifier<?>> orderBys = metadata.getOrderBy(); + final Integer queryLimit = metadata.getModifiers().getLimitAsInteger(); + final Integer queryOffset = metadata.getModifiers().getOffsetAsInteger(); + Sort sort = querySort; + int limit; + final int offset = queryOffset != null ? queryOffset : 0; + try { + limit = maxDoc(); + if (limit == 0) { + return new EmptyCloseableIterator<T>(); + } + } catch (IOException | IllegalArgumentException e) { + throw new QueryException(e); + } + if (queryLimit != null && queryLimit < limit) { + limit = queryLimit; + } + if (sort == null && !orderBys.isEmpty()) { + sort = serializer.toSort(orderBys); + } + + try { + ScoreDoc[] scoreDocs; + int sumOfLimitAndOffset = limit + offset; + if (sumOfLimitAndOffset < 1) { + throw new QueryException("The given limit (" + limit + ") and offset (" + offset + ") cause an integer overflow."); + } + if (sort != null) { + scoreDocs = searcher.search(createQuery(), getFilter(), sumOfLimitAndOffset, sort, false, false).scoreDocs; + } else { + scoreDocs = searcher.search(createQuery(), getFilter(), sumOfLimitAndOffset, Sort.INDEXORDER, false, false).scoreDocs; + } + if (offset < scoreDocs.length) { + return new ResultIterator<T>(scoreDocs, offset, searcher, fieldsToLoad, transformer); + } + return new EmptyCloseableIterator<T>(); + } catch (final IOException e) { + throw new QueryException(e); + } + } + + private List<T> innerList() { + return new IteratorAdapter<T>(iterate()).asList(); + } + + @Override + public List<T> fetch() { + return innerList(); + } + + /** + * Set the given fields to load + * + * @param fieldsToLoad fields to load + * @return the current object + */ + @SuppressWarnings("unchecked") + public Q load(Set<String> fieldsToLoad) { + this.fieldsToLoad = fieldsToLoad; + return (Q) this; + } + + /** + * Load only the fields of the given paths + * + * @param paths fields to load + * @return the current object + */ + @SuppressWarnings("unchecked") + public Q load(Path<?>... paths) { + Set<String> fields = new HashSet<String>(); + for (Path<?> path : paths) { + fields.add(serializer.toField(path)); + } + this.fieldsToLoad = fields; + return (Q) this; + } + + @Override + public QueryResults<T> fetchResults() { + List<T> documents = innerList(); + /* + * TODO Get rid of fetchCount(). It could be implemented by iterating the + * fetch results in fetch* from n to m. + */ + return new QueryResults<T>(documents, queryMixin.getMetadata().getModifiers(), innerCount()); + } + + @Override + public Q offset(long offset) { + return queryMixin.offset(offset); + } + + public Q orderBy(OrderSpecifier<?> o) { + return queryMixin.orderBy(o); + } + + @Override + public Q orderBy(OrderSpecifier<?>... o) { + return queryMixin.orderBy(o); + } + + @Override + public Q restrict(QueryModifiers modifiers) { + return queryMixin.restrict(modifiers); + } + + @Override + public <P> Q set(ParamExpression<P> param, P value) { + return queryMixin.set(param, value); + } + + @SuppressWarnings("unchecked") + public Q sort(Sort sort) { + this.querySort = sort; + return (Q) this; + } + + @Nullable + private T oneResult(boolean unique) { + try { + int maxDoc = maxDoc(); + if (maxDoc == 0) { + return null; + } + final ScoreDoc[] scoreDocs = searcher.search(createQuery(), getFilter(), maxDoc, Sort.INDEXORDER, false, false).scoreDocs; + int index = 0; + QueryModifiers modifiers = queryMixin.getMetadata().getModifiers(); + Long offset = modifiers.getOffset(); + if (offset != null) { + index = offset.intValue(); + } + Long limit = modifiers.getLimit(); + if (unique && (limit == null ? scoreDocs.length - index > 1 : + limit > 1 && scoreDocs.length > 1)) { + throw new NonUniqueResultException("Unique result requested, but " + scoreDocs.length + " found."); + } else if (scoreDocs.length > index) { + Document document; + if (fieldsToLoad != null) { + document = searcher.doc(scoreDocs[index].doc, fieldsToLoad); + } else { + document = searcher.doc(scoreDocs[index].doc); + } + return transformer.apply(document); + } else { + return null; + } + } catch (IOException | IllegalArgumentException e) { + throw new QueryException(e); + } + } + + @Override + public T fetchFirst() { + return oneResult(false); + } + + @Override + public T fetchOne() throws NonUniqueResultException { + return oneResult(true); + } + + public Q where(Predicate e) { + return queryMixin.where(e); + } + + @Override + public Q where(Predicate... e) { + return queryMixin.where(e); + } + + @Override + public String toString() { + return createQuery().toString().replaceAll(JAVA_ISO_CONTROL, "_"); + } + + private int maxDoc() throws IOException { + return searcher.getIndexReader().maxDoc(); + } +} diff --git a/querydsl-lucene4/src/main/java/com/querydsl/lucene4/IgnoreCaseUnsupportedException.java b/querydsl-lucene4/src/main/java/com/querydsl/lucene4/IgnoreCaseUnsupportedException.java new file mode 100644 index 0000000000..3c534a279b --- /dev/null +++ b/querydsl-lucene4/src/main/java/com/querydsl/lucene4/IgnoreCaseUnsupportedException.java @@ -0,0 +1,30 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.lucene4; + +/** + * Thrown for case ignore usage + * + * @author tiwe + * + */ +public class IgnoreCaseUnsupportedException extends UnsupportedOperationException { + + private static final long serialVersionUID = 412913389929530788L; + + public IgnoreCaseUnsupportedException() { + super("Ignore case queries are not supported with Lucene"); + } + +} diff --git a/querydsl-lucene4/src/main/java/com/querydsl/lucene4/LuceneExpressions.java b/querydsl-lucene4/src/main/java/com/querydsl/lucene4/LuceneExpressions.java new file mode 100644 index 0000000000..8d4f87c343 --- /dev/null +++ b/querydsl-lucene4/src/main/java/com/querydsl/lucene4/LuceneExpressions.java @@ -0,0 +1,74 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.lucene4; + +import org.apache.lucene.index.Term; +import org.apache.lucene.search.FuzzyQuery; +import org.apache.lucene.util.automaton.LevenshteinAutomata; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.dsl.BooleanExpression; + +/** + * Utility methods to create filter expressions for Lucene queries that are not covered by the + * Querydsl standard expression model + * + * @author tiwe + * + */ +public final class LuceneExpressions { + + /** + * Create a fuzzy query + * + * @param path path + * @param value value to match + * @return condition + */ + public static BooleanExpression fuzzyLike(Path<String> path, String value) { + Term term = new Term(path.getMetadata().getName(), value); + return new QueryElement(new FuzzyQuery(term)); + } + + /** + * Create a fuzzy query + * + * @param path path + * @param value value to match + * @param maxEdits must be >= 0 and <= {@link LevenshteinAutomata#MAXIMUM_SUPPORTED_DISTANCE}. + * @return condition + */ + public static BooleanExpression fuzzyLike(Path<String> path, String value, int maxEdits) { + Term term = new Term(path.getMetadata().getName(), value); + return new QueryElement(new FuzzyQuery(term, maxEdits)); + } + + /** + * Create a fuzzy query + * + * @param path path + * @param value value to match + * @param maxEdits must be >= 0 and <= {@link LevenshteinAutomata#MAXIMUM_SUPPORTED_DISTANCE}. + * @param prefixLength length of common (non-fuzzy) prefix + * @return condition + */ + public static BooleanExpression fuzzyLike(Path<String> path, String value, + int maxEdits, int prefixLength) { + Term term = new Term(path.getMetadata().getName(), value); + return new QueryElement(new FuzzyQuery(term, maxEdits, prefixLength)); + } + + private LuceneExpressions() { } + +} diff --git a/querydsl-lucene4/src/main/java/com/querydsl/lucene4/LuceneOps.java b/querydsl-lucene4/src/main/java/com/querydsl/lucene4/LuceneOps.java new file mode 100644 index 0000000000..eacf1742c1 --- /dev/null +++ b/querydsl-lucene4/src/main/java/com/querydsl/lucene4/LuceneOps.java @@ -0,0 +1,39 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.lucene4; + +import com.querydsl.core.types.Operator; + +/** + * Lucene specific operators + * + * @author tiwe + * + */ +public enum LuceneOps implements Operator { + LUCENE_QUERY(Object.class), + PHRASE(String.class), + TERM(String.class); + + private final Class<?> type; + + LuceneOps(Class<?> type) { + this.type = type; + } + + @Override + public Class<?> getType() { + return type; + } +} diff --git a/querydsl-lucene4/src/main/java/com/querydsl/lucene4/LuceneQuery.java b/querydsl-lucene4/src/main/java/com/querydsl/lucene4/LuceneQuery.java new file mode 100644 index 0000000000..ab1b96cf84 --- /dev/null +++ b/querydsl-lucene4/src/main/java/com/querydsl/lucene4/LuceneQuery.java @@ -0,0 +1,55 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.lucene4; + +import org.apache.lucene.document.Document; +import org.apache.lucene.search.IndexSearcher; + +import java.util.function.Function; + +/** + * {@code LuceneQuery} is a Querydsl query implementation for Lucene queries. + + * <p>Example:</p> + * + * <pre>{@code + * QDocument doc = new QDocument("doc"); + * + * IndexSearcher searcher = new IndexSearcher(index); + * LuceneQuery query = new LuceneQuery(true, searcher); + * List<Document> documents = query + * .where(doc.year.between("1800", "2000").and(doc.title.startsWith("Huckle")) + * .fetch(); + * }</pre> + * + * @author vema + */ +public class LuceneQuery extends AbstractLuceneQuery<Document, LuceneQuery> { + + private static final Function<Document,Document> TRANSFORMER = new Function<Document,Document>() { + @Override + public Document apply(Document input) { + return input; + } + }; + + public LuceneQuery(IndexSearcher searcher) { + super(searcher, TRANSFORMER); + } + + public LuceneQuery(LuceneSerializer luceneSerializer, IndexSearcher searcher) { + super(luceneSerializer, searcher, TRANSFORMER); + } + +} diff --git a/querydsl-lucene4/src/main/java/com/querydsl/lucene4/LuceneSerializer.java b/querydsl-lucene4/src/main/java/com/querydsl/lucene4/LuceneSerializer.java new file mode 100644 index 0000000000..9cda305400 --- /dev/null +++ b/querydsl-lucene4/src/main/java/com/querydsl/lucene4/LuceneSerializer.java @@ -0,0 +1,564 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.lucene4; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.*; + +import org.jetbrains.annotations.Nullable; + +import org.apache.lucene.index.Term; +import org.apache.lucene.queryparser.classic.QueryParser; +import org.apache.lucene.search.*; +import org.apache.lucene.search.BooleanClause.Occur; +import org.apache.lucene.util.BytesRef; +import org.apache.lucene.util.NumericUtils; + +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.types.*; + +/** + * Serializes Querydsl queries to Lucene queries. + * + * @author vema + * + */ +public class LuceneSerializer { + private static final Map<Class<?>, SortField.Type> sortFields = new HashMap<Class<?>, SortField.Type>(); + + static { + sortFields.put(Integer.class, SortField.Type.INT); + sortFields.put(Float.class, SortField.Type.FLOAT); + sortFields.put(Long.class, SortField.Type.LONG); + sortFields.put(Double.class, SortField.Type.DOUBLE); + sortFields.put(Short.class, SortField.Type.SHORT); + sortFields.put(Byte.class, SortField.Type.BYTE); + sortFields.put(BigDecimal.class, SortField.Type.DOUBLE); + sortFields.put(BigInteger.class, SortField.Type.LONG); + } + + public static final LuceneSerializer DEFAULT = new LuceneSerializer(false, true); + + private final boolean lowerCase; + + private final boolean splitTerms; + + private final Locale sortLocale; + + public LuceneSerializer(boolean lowerCase, boolean splitTerms) { + this(lowerCase, splitTerms, Locale.getDefault()); + } + + public LuceneSerializer(boolean lowerCase, boolean splitTerms, Locale sortLocale) { + this.lowerCase = lowerCase; + this.splitTerms = splitTerms; + this.sortLocale = sortLocale; + } + + private Query toQuery(Operation<?> operation, QueryMetadata metadata) { + Operator op = operation.getOperator(); + if (op == Ops.OR) { + return toTwoHandSidedQuery(operation, Occur.SHOULD, metadata); + } else if (op == Ops.AND) { + return toTwoHandSidedQuery(operation, Occur.MUST, metadata); + } else if (op == Ops.NOT) { + BooleanQuery bq = new BooleanQuery(); + bq.add(new BooleanClause(toQuery(operation.getArg(0), metadata), Occur.MUST_NOT)); + bq.add(new BooleanClause(new MatchAllDocsQuery(), Occur.MUST)); + return bq; + } else if (op == Ops.LIKE) { + return like(operation, metadata); + } else if (op == Ops.LIKE_IC) { + throw new IgnoreCaseUnsupportedException(); + } else if (op == Ops.EQ) { + return eq(operation, metadata, false); + } else if (op == Ops.EQ_IGNORE_CASE) { + throw new IgnoreCaseUnsupportedException(); + } else if (op == Ops.NE) { + return ne(operation, metadata, false); + } else if (op == Ops.STARTS_WITH) { + return startsWith(metadata, operation, false); + } else if (op == Ops.STARTS_WITH_IC) { + throw new IgnoreCaseUnsupportedException(); + } else if (op == Ops.ENDS_WITH) { + return endsWith(operation, metadata, false); + } else if (op == Ops.ENDS_WITH_IC) { + throw new IgnoreCaseUnsupportedException(); + } else if (op == Ops.STRING_CONTAINS) { + return stringContains(operation, metadata, false); + } else if (op == Ops.STRING_CONTAINS_IC) { + throw new IgnoreCaseUnsupportedException(); + } else if (op == Ops.BETWEEN) { + return between(operation, metadata); + } else if (op == Ops.IN) { + return in(operation, metadata, false); + } else if (op == Ops.NOT_IN) { + return notIn(operation, metadata, false); + } else if (op == Ops.LT) { + return lt(operation, metadata); + } else if (op == Ops.GT) { + return gt(operation, metadata); + } else if (op == Ops.LOE) { + return le(operation, metadata); + } else if (op == Ops.GOE) { + return ge(operation, metadata); + } else if (op == LuceneOps.LUCENE_QUERY) { + @SuppressWarnings("unchecked") //this is the expected type + Constant<Query> expectedConstant = (Constant<Query>) operation.getArg(0); + return expectedConstant.getConstant(); + } + throw new UnsupportedOperationException("Illegal operation " + operation); + } + + private Query toTwoHandSidedQuery(Operation<?> operation, Occur occur, QueryMetadata metadata) { + Query lhs = toQuery(operation.getArg(0), metadata); + Query rhs = toQuery(operation.getArg(1), metadata); + BooleanQuery bq = new BooleanQuery(); + bq.add(createBooleanClause(lhs, occur)); + bq.add(createBooleanClause(rhs, occur)); + return bq; + } + + /** + * If the query is a BooleanQuery and it contains a single Occur.MUST_NOT + * clause it will be returned as is. Otherwise it will be wrapped in a + * BooleanClause with the given Occur. + */ + private BooleanClause createBooleanClause(Query query, Occur occur) { + if (query instanceof BooleanQuery) { + BooleanClause[] clauses = ((BooleanQuery) query).getClauses(); + if (clauses.length == 1 && clauses[0].getOccur().equals(Occur.MUST_NOT)) { + return clauses[0]; + } + } + return new BooleanClause(query, occur); + } + + protected Query like(Operation<?> operation, QueryMetadata metadata) { + verifyArguments(operation); + Path<?> path = getPath(operation.getArg(0)); + String field = toField(path); + String[] terms = convert(path, operation.getArg(1)); + if (terms.length > 1) { + BooleanQuery bq = new BooleanQuery(); + for (String s : terms) { + bq.add(new WildcardQuery(new Term(field, "*" + s + "*")), Occur.MUST); + } + return bq; + } + return new WildcardQuery(new Term(field, terms[0])); + } + + protected Query eq(Operation<?> operation, QueryMetadata metadata, boolean ignoreCase) { + verifyArguments(operation); + Path<?> path = getPath(operation.getArg(0)); + String field = toField(path); + + if (Number.class.isAssignableFrom(operation.getArg(1).getType())) { + @SuppressWarnings("unchecked") //guarded by previous check + Constant<? extends Number> rightArg = (Constant<? extends Number>) operation.getArg(1); + return new TermQuery(new Term(field, convertNumber(rightArg.getConstant()))); + } + + return eq(field, convert(path, operation.getArg(1), metadata), ignoreCase); + } + + + private BytesRef convertNumber(Number number) { + if (Integer.class.isInstance(number) || Byte.class.isInstance(number) || Short.class.isInstance(number)) { + BytesRef bytes = new BytesRef(NumericUtils.BUF_SIZE_INT); + NumericUtils.intToPrefixCoded(number.intValue(), 0, bytes); + return bytes; + } else if (Double.class.isInstance(number) || BigDecimal.class.isInstance(number)) { + BytesRef bytes = new BytesRef(NumericUtils.BUF_SIZE_LONG); + long l = NumericUtils.doubleToSortableLong(number.doubleValue()); + NumericUtils.longToPrefixCoded(l, 0, bytes); + return bytes; + } else if (Long.class.isInstance(number) || BigInteger.class.isInstance(number)) { + BytesRef bytes = new BytesRef(NumericUtils.BUF_SIZE_LONG); + NumericUtils.longToPrefixCoded(number.longValue(), 0, bytes); + return bytes; + } else if (Float.class.isInstance(number)) { + BytesRef bytes = new BytesRef(NumericUtils.BUF_SIZE_INT); + int i = NumericUtils.floatToSortableInt(number.floatValue()); + NumericUtils.intToPrefixCoded(i, 0, bytes); + return bytes; + } else { + throw new IllegalArgumentException("Unsupported numeric type " + + number.getClass().getName()); + } + } + + protected Query eq(String field, String[] terms, boolean ignoreCase) { + if (terms.length > 1) { + PhraseQuery pq = new PhraseQuery(); + for (String s : terms) { + pq.add(new Term(field, s)); + } + return pq; + } + return new TermQuery(new Term(field, terms[0])); + } + + protected Query in(Operation<?> operation, QueryMetadata metadata, boolean ignoreCase) { + Path<?> path = getPath(operation.getArg(0)); + String field = toField(path); + @SuppressWarnings("unchecked") //this is the expected type + Constant<Collection<?>> expectedConstant = (Constant<Collection<?>>) operation.getArg(1); + Collection<?> values = expectedConstant.getConstant(); + BooleanQuery bq = new BooleanQuery(); + if (Number.class.isAssignableFrom(path.getType())) { + for (Object value : values) { + TermQuery eq = new TermQuery(new Term(field, convertNumber((Number) value))); + bq.add(eq, Occur.SHOULD); + } + } else { + for (Object value : values) { + String[] str = convert(path, value); + bq.add(eq(field, str, ignoreCase), Occur.SHOULD); + } + } + return bq; + } + + protected Query notIn(Operation<?> operation, QueryMetadata metadata, boolean ignoreCase) { + BooleanQuery bq = new BooleanQuery(); + bq.add(new BooleanClause(in(operation, metadata, false), Occur.MUST_NOT)); + bq.add(new BooleanClause(new MatchAllDocsQuery(), Occur.MUST)); + return bq; + } + + protected Query ne(Operation<?> operation, QueryMetadata metadata, boolean ignoreCase) { + BooleanQuery bq = new BooleanQuery(); + bq.add(new BooleanClause(eq(operation, metadata, ignoreCase), Occur.MUST_NOT)); + bq.add(new BooleanClause(new MatchAllDocsQuery(), Occur.MUST)); + return bq; + } + + protected Query startsWith(QueryMetadata metadata, Operation<?> operation, boolean ignoreCase) { + verifyArguments(operation); + Path<?> path = getPath(operation.getArg(0)); + String field = toField(path); + String[] terms = convertEscaped(path, operation.getArg(1), metadata); + if (terms.length > 1) { + BooleanQuery bq = new BooleanQuery(); + for (int i = 0; i < terms.length; ++i) { + String s = i == 0 ? terms[i] + "*" : "*" + terms[i] + "*"; + bq.add(new WildcardQuery(new Term(field, s)), Occur.MUST); + } + return bq; + } + return new PrefixQuery(new Term(field, terms[0])); + } + + + + protected Query stringContains(Operation<?> operation, QueryMetadata metadata, boolean ignoreCase) { + verifyArguments(operation); + Path<?> path = getPath(operation.getArg(0)); + String field = toField(path); + String[] terms = convertEscaped(path, operation.getArg(1), metadata); + if (terms.length > 1) { + BooleanQuery bq = new BooleanQuery(); + for (String s : terms) { + bq.add(new WildcardQuery(new Term(field, "*" + s + "*")), Occur.MUST); + } + return bq; + } + return new WildcardQuery(new Term(field, "*" + terms[0] + "*")); + } + + protected Query endsWith(Operation<?> operation, QueryMetadata metadata, boolean ignoreCase) { + verifyArguments(operation); + Path<?> path = getPath(operation.getArg(0)); + String field = toField(path); + String[] terms = convertEscaped(path, operation.getArg(1), metadata); + if (terms.length > 1) { + BooleanQuery bq = new BooleanQuery(); + for (int i = 0; i < terms.length; ++i) { + String s = i == terms.length - 1 ? "*" + terms[i] : "*" + terms[i] + "*"; + bq.add(new WildcardQuery(new Term(field, s)), Occur.MUST); + } + return bq; + } + return new WildcardQuery(new Term(field, "*" + terms[0])); + } + + protected Query between(Operation<?> operation, QueryMetadata metadata) { + verifyArguments(operation); + Path<?> path = getPath(operation.getArg(0)); + // TODO Phrase not properly supported + return range( + path, + toField(path), + operation.getArg(1), + operation.getArg(2), + true, + true, + metadata); + } + + protected Query lt(Operation<?> operation, QueryMetadata metadata) { + verifyArguments(operation); + Path<?> path = getPath(operation.getArg(0)); + return range( + path, + toField(path), + null, + operation.getArg(1), + false, + false, + metadata); + } + + protected Query gt(Operation<?> operation, QueryMetadata metadata) { + verifyArguments(operation); + Path<?> path = getPath(operation.getArg(0)); + return range( + path, + toField(path), + operation.getArg(1), + null, + false, + false, + metadata); + } + + protected Query le(Operation<?> operation, QueryMetadata metadata) { + verifyArguments(operation); + Path<?> path = getPath(operation.getArg(0)); + return range( + path, + toField(path), + null, + operation.getArg(1), + true, + true, + metadata); + } + + protected Query ge(Operation<?> operation, QueryMetadata metadata) { + verifyArguments(operation); + Path<?> path = getPath(operation.getArg(0)); + return range( + path, + toField(path), + operation.getArg(1), + null, + true, + true, + metadata); + } + + protected Query range(Path<?> leftHandSide, String field, @Nullable Expression<?> min, + @Nullable Expression<?> max, boolean minInc, boolean maxInc, QueryMetadata metadata) { + if (min != null && Number.class.isAssignableFrom(min.getType()) || max != null + && Number.class.isAssignableFrom(max.getType())) { + @SuppressWarnings("unchecked") //guarded by previous check + Constant<? extends Number> minConstant = (Constant<? extends Number>) min; + @SuppressWarnings("unchecked") //guarded by previous check + Constant<? extends Number> maxConstant = (Constant<? extends Number>) max; + + Class<? extends Number> numType = minConstant != null ? minConstant.getType() : maxConstant.getType(); + //this is not necessarily safe, but compile time checking + //on the user side mandates these types to be interchangeable + @SuppressWarnings("unchecked") + Class<Number> unboundedNumType = (Class<Number>) numType; + return numericRange(unboundedNumType, field, minConstant == null ? null + : minConstant.getConstant(), maxConstant == null ? null + : maxConstant.getConstant(), minInc, maxInc); + } + return stringRange(leftHandSide, field, min, max, minInc, maxInc, metadata); + } + + protected <N extends Number> NumericRangeQuery<?> numericRange(Class<N> clazz, String field, + @Nullable N min, @Nullable N max, boolean minInc, boolean maxInc) { + if (clazz.equals(Integer.class)) { + return NumericRangeQuery.newIntRange(field, (Integer) min, (Integer) max, minInc, maxInc); + } else if (clazz.equals(Double.class)) { + return NumericRangeQuery.newDoubleRange(field, (Double) min, (Double) max, minInc, minInc); + } else if (clazz.equals(Float.class)) { + return NumericRangeQuery.newFloatRange(field, (Float) min, (Float) max, minInc, minInc); + } else if (clazz.equals(Long.class)) { + return NumericRangeQuery.newLongRange(field, (Long) min, (Long) max, minInc, minInc); + } else if (clazz.equals(Byte.class) || clazz.equals(Short.class)) { + return NumericRangeQuery.newIntRange(field, min != null ? min.intValue() : null, + max != null ? max.intValue() : null, minInc, maxInc); + } else { + throw new IllegalArgumentException("Unsupported numeric type " + clazz.getName()); + } + } + + protected Query stringRange( + Path<?> leftHandSide, + String field, + @Nullable Expression<?> min, + @Nullable Expression<?> max, + boolean minInc, + boolean maxInc, + QueryMetadata metadata) { + + if (min == null) { + return TermRangeQuery.newStringRange( + field, null, convert(leftHandSide, max, metadata)[0], minInc, maxInc); + } else if (max == null) { + return TermRangeQuery.newStringRange( + field, convert(leftHandSide, min, metadata)[0], + null, minInc, maxInc); + } else { + return TermRangeQuery.newStringRange( + field, convert(leftHandSide, min, metadata)[0], + convert(leftHandSide, max, metadata)[0], + minInc, maxInc); + } + } + + private Path<?> getPath(Expression<?> leftHandSide) { + if (leftHandSide instanceof Path<?>) { + return (Path<?>) leftHandSide; + } else if (leftHandSide instanceof Operation<?>) { + Operation<?> operation = (Operation<?>) leftHandSide; + if (operation.getOperator() == Ops.LOWER || operation.getOperator() == Ops.UPPER) { + return (Path<?>) operation.getArg(0); + } + } + throw new IllegalArgumentException("Unable to transform " + leftHandSide + " to path"); + } + + /** + * template method, override to customize + * + * @param path path + * @return field name + */ + protected String toField(Path<?> path) { + PathMetadata md = path.getMetadata(); + if (md.getPathType() == PathType.COLLECTION_ANY) { + return toField(md.getParent()); + } else { + String rv = md.getName(); + if (md.getParent() != null) { + Path<?> parent = md.getParent(); + if (parent.getMetadata().getPathType() != PathType.VARIABLE) { + rv = toField(parent) + "." + rv; + } + } + return rv; + } + } + + private void verifyArguments(Operation<?> operation) { + List<Expression<?>> arguments = operation.getArgs(); + for (int i = 1; i < arguments.size(); ++i) { + if (!(arguments.get(i) instanceof Constant<?>) + && !(arguments.get(i) instanceof ParamExpression<?>) + && !(arguments.get(i) instanceof PhraseElement) + && !(arguments.get(i) instanceof TermElement)) { + throw new IllegalArgumentException("operand was of unsupported type " + + arguments.get(i).getClass().getName()); + } + } + } + + /** + * template method + * + * @param leftHandSide left hand side + * @param rightHandSide right hand side + * @return results + */ + protected String[] convert(Path<?> leftHandSide, Expression<?> rightHandSide, QueryMetadata metadata) { + if (rightHandSide instanceof Operation) { + Operation<?> operation = (Operation<?>) rightHandSide; + if (operation.getOperator() == LuceneOps.PHRASE) { + return operation.getArg(0).toString().split("\\s+"); + } else if (operation.getOperator() == LuceneOps.TERM) { + return new String[] {operation.getArg(0).toString()}; + } else { + throw new IllegalArgumentException(rightHandSide.toString()); + } + } else if (rightHandSide instanceof ParamExpression<?>) { + Object value = metadata.getParams().get(rightHandSide); + if (value == null) { + throw new ParamNotSetException((ParamExpression<?>) rightHandSide); + } + return convert(leftHandSide, value); + + } else if (rightHandSide instanceof Constant<?>) { + return convert(leftHandSide, ((Constant<?>) rightHandSide).getConstant()); + } else { + throw new IllegalArgumentException(rightHandSide.toString()); + } + } + + /** + * template method + * + * @param leftHandSide left hand side + * @param rightHandSide right hand side + * @return results + */ + protected String[] convert(Path<?> leftHandSide, Object rightHandSide) { + String str = rightHandSide.toString(); + if (lowerCase) { + str = str.toLowerCase(); + } + if (splitTerms) { + if (str.equals("")) { + return new String[] {str}; + } else { + return str.split("\\s+"); + } + } else { + return new String[] {str}; + } + } + + private String[] convertEscaped(Path<?> leftHandSide, Expression<?> rightHandSide, QueryMetadata metadata) { + String[] str = convert(leftHandSide, rightHandSide, metadata); + for (int i = 0; i < str.length; i++) { + str[i] = QueryParser.escape(str[i]); + } + return str; + } + + public Query toQuery(Expression<?> expr, QueryMetadata metadata) { + if (expr instanceof Operation<?>) { + return toQuery((Operation<?>) expr, metadata); + } else { + return toQuery(ExpressionUtils.extract(expr), metadata); + } + } + + public Sort toSort(List<? extends OrderSpecifier<?>> orderBys) { + List<SortField> sorts = new ArrayList<SortField>(orderBys.size()); + for (OrderSpecifier<?> order : orderBys) { + if (!(order.getTarget() instanceof Path<?>)) { + throw new IllegalArgumentException("argument was not of type Path."); + } + Class<?> type = order.getTarget().getType(); + boolean reverse = !order.isAscending(); + Path<?> path = getPath(order.getTarget()); + if (Number.class.isAssignableFrom(type)) { + sorts.add(new SortField(toField(path), sortFields.get(type), reverse)); + } else { + sorts.add(new SortField(toField(path), SortField.Type.STRING, reverse)); + } + } + Sort sort = new Sort(); + sort.setSort(sorts.toArray(new SortField[0])); + return sort; + } +} diff --git a/querydsl-lucene4/src/main/java/com/querydsl/lucene4/PhraseElement.java b/querydsl-lucene4/src/main/java/com/querydsl/lucene4/PhraseElement.java new file mode 100644 index 0000000000..bf9e323b85 --- /dev/null +++ b/querydsl-lucene4/src/main/java/com/querydsl/lucene4/PhraseElement.java @@ -0,0 +1,33 @@ + /* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.lucene4; + +import com.querydsl.core.types.ConstantImpl; +import com.querydsl.core.types.dsl.StringOperation; + +/** + * {@code PhraseElement} represents the embedded String as a phrase + * + * @author tiwe + * + */ +public class PhraseElement extends StringOperation { + + private static final long serialVersionUID = 2350215644019186076L; + + public PhraseElement(String str) { + super(LuceneOps.PHRASE, ConstantImpl.create(str)); + } + +} diff --git a/querydsl-lucene4/src/main/java/com/querydsl/lucene4/QueryElement.java b/querydsl-lucene4/src/main/java/com/querydsl/lucene4/QueryElement.java new file mode 100644 index 0000000000..a5e3c2c7db --- /dev/null +++ b/querydsl-lucene4/src/main/java/com/querydsl/lucene4/QueryElement.java @@ -0,0 +1,35 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.lucene4; + +import org.apache.lucene.search.Query; + +import com.querydsl.core.types.ConstantImpl; +import com.querydsl.core.types.dsl.BooleanOperation; + +/** + * {@code QueryElement} wraps a Lucene Query + * + * @author tiwe + * + */ +public class QueryElement extends BooleanOperation { + + private static final long serialVersionUID = 470868107363840155L; + + public QueryElement(Query query) { + super(LuceneOps.LUCENE_QUERY, ConstantImpl.create(query)); + } + +} diff --git a/querydsl-lucene4/src/main/java/com/querydsl/lucene4/ResultIterator.java b/querydsl-lucene4/src/main/java/com/querydsl/lucene4/ResultIterator.java new file mode 100644 index 0000000000..38b827c66f --- /dev/null +++ b/querydsl-lucene4/src/main/java/com/querydsl/lucene4/ResultIterator.java @@ -0,0 +1,86 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.lucene4; + +import com.mysema.commons.lang.CloseableIterator; +import com.querydsl.core.QueryException; +import org.apache.lucene.document.Document; +import org.apache.lucene.search.IndexSearcher; +import org.apache.lucene.search.ScoreDoc; +import org.jetbrains.annotations.Nullable; + +import java.io.IOException; +import java.util.Set; +import java.util.function.Function; + +/** + * {@code ResultIterator} is a {@link CloseableIterator} implementation for Lucene query results + * + * @author tiwe + * + * @param <T> + */ +public final class ResultIterator<T> implements CloseableIterator<T> { + + private final ScoreDoc[] scoreDocs; + + private int cursor; + + private final IndexSearcher searcher; + + @Nullable + private final Set<String> fieldsToLoad; + + private final Function<Document,T> transformer; + + public ResultIterator(ScoreDoc[] scoreDocs, int offset, IndexSearcher searcher, + @Nullable Set<String> fieldsToLoad, Function<Document, T> transformer) { + this.scoreDocs = scoreDocs.clone(); + this.cursor = offset; + this.searcher = searcher; + this.fieldsToLoad = fieldsToLoad; + this.transformer = transformer; + } + + @Override + public boolean hasNext() { + return cursor != scoreDocs.length; + } + + @Override + public T next() { + try { + Document document; + if (fieldsToLoad != null) { + document = searcher.doc(scoreDocs[cursor++].doc, fieldsToLoad); + } else { + document = searcher.doc(scoreDocs[cursor++].doc); + } + return transformer.apply(document); + } catch (IOException e) { + throw new QueryException(e); + } + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + + @Override + public void close() { + + } + +} \ No newline at end of file diff --git a/querydsl-lucene4/src/main/java/com/querydsl/lucene4/TermElement.java b/querydsl-lucene4/src/main/java/com/querydsl/lucene4/TermElement.java new file mode 100644 index 0000000000..48a94127e6 --- /dev/null +++ b/querydsl-lucene4/src/main/java/com/querydsl/lucene4/TermElement.java @@ -0,0 +1,33 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.lucene4; + +import com.querydsl.core.types.ConstantImpl; +import com.querydsl.core.types.dsl.StringOperation; + +/** + * {@code TermElement} represents the embedded String as a term + * + * @author tiwe + * + */ +public class TermElement extends StringOperation { + + private static final long serialVersionUID = 2350215644019186076L; + + public TermElement(String str) { + super(LuceneOps.TERM, ConstantImpl.create(str)); + } + +} diff --git a/querydsl-lucene4/src/main/java/com/querydsl/lucene4/TypedQuery.java b/querydsl-lucene4/src/main/java/com/querydsl/lucene4/TypedQuery.java new file mode 100644 index 0000000000..af6855143c --- /dev/null +++ b/querydsl-lucene4/src/main/java/com/querydsl/lucene4/TypedQuery.java @@ -0,0 +1,54 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.lucene4; + +import org.apache.lucene.document.Document; +import org.apache.lucene.search.IndexSearcher; + +import java.util.function.Function; + +/** + * {@code TypedQuery} is a typed query implementation for Lucene queries. + * + * <p>Converts Lucene documents to typed results via a constructor supplied transformer</p> + * + * @param <T> result type + * + * @author laim + * @author tiwe + */ +public class TypedQuery<T> extends AbstractLuceneQuery<T, TypedQuery<T>> { + + /** + * Create a new TypedQuery instance + * + * @param searcher index searcher + * @param transformer transformer to transform Lucene documents to result objects + */ + public TypedQuery(IndexSearcher searcher, Function<Document, T> transformer) { + super(searcher, transformer); + } + + /** + * Create a new TypedQuery instance + * + * @param serializer serializer + * @param searcher index searcher + * @param transformer transformer to transform Lucene documents to result objects + */ + public TypedQuery(LuceneSerializer serializer, IndexSearcher searcher, Function<Document, T> transformer) { + super(serializer, searcher, transformer); + } + +} diff --git a/querydsl-lucene4/src/main/java/com/querydsl/lucene4/package-info.java b/querydsl-lucene4/src/main/java/com/querydsl/lucene4/package-info.java new file mode 100644 index 0000000000..277d096d54 --- /dev/null +++ b/querydsl-lucene4/src/main/java/com/querydsl/lucene4/package-info.java @@ -0,0 +1,18 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ + +/** + * Lucene 4 support + */ +package com.querydsl.lucene4; diff --git a/querydsl-lucene4/src/test/java/com/mysema/query/LuceneSerializerNotTokenizedTest.java b/querydsl-lucene4/src/test/java/com/mysema/query/LuceneSerializerNotTokenizedTest.java deleted file mode 100644 index f1bce88607..0000000000 --- a/querydsl-lucene4/src/test/java/com/mysema/query/LuceneSerializerNotTokenizedTest.java +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query; -import static com.mysema.query.QPerson.person; -import static org.junit.Assert.assertEquals; - -import java.util.Arrays; - -import org.apache.lucene.analysis.standard.StandardAnalyzer; -import org.apache.lucene.document.Document; -import org.apache.lucene.document.Field; -import org.apache.lucene.document.Field.Index; -import org.apache.lucene.document.Field.Store; -import org.apache.lucene.index.IndexReader; -import org.apache.lucene.index.IndexWriter; -import org.apache.lucene.index.IndexWriterConfig; -import org.apache.lucene.search.IndexSearcher; -import org.apache.lucene.search.Query; -import org.apache.lucene.search.TopDocs; -import org.apache.lucene.store.RAMDirectory; -import org.apache.lucene.util.Version; -import org.joda.time.LocalDate; -import org.junit.Before; -import org.junit.Test; - -import com.mysema.query.lucene.LuceneSerializer; -import com.mysema.query.types.Expression; -import com.mysema.query.types.path.StringPath; - -public class LuceneSerializerNotTokenizedTest { - private RAMDirectory idx; - private IndexWriter writer; - private IndexSearcher searcher; - private LuceneSerializer serializer; - - private final QueryMetadata metadata = new DefaultQueryMetadata(); - - private final Person clooney = new Person("actor_1", "George Clooney", new LocalDate(1961, 4, 6)); - private final Person pitt = new Person("actor_2", "Brad Pitt", new LocalDate(1963, 12, 18)); - - private void testQuery(Expression<?> expr, String expectedQuery, int expectedHits) throws Exception { - Query query = serializer.toQuery(expr, metadata); - TopDocs docs = searcher.search(query, 100); - assertEquals(expectedHits, docs.totalHits); - assertEquals(expectedQuery, query.toString()); - } - - private Document createDocument(Person person) { - Document doc = new Document(); - doc.add(new Field("id", person.getId(), Store.YES, Index.NOT_ANALYZED)); - doc.add(new Field("name", person.getName(), Store.YES, Index.NOT_ANALYZED)); - doc.add(new Field("birthDate", person.getBirthDate().toString(), Store.YES, Index.NOT_ANALYZED)); - return doc; - } - - @Before - public void Before() throws Exception { - serializer = new LuceneSerializer(false, false); - idx = new RAMDirectory(); - IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_31, - new StandardAnalyzer(Version.LUCENE_30)) - .setOpenMode(IndexWriterConfig.OpenMode.CREATE); - writer = new IndexWriter(idx, config); - - writer.addDocument(createDocument(clooney)); - writer.addDocument(createDocument(pitt)); - - Document document = new Document(); - for (String movie : Arrays.asList("Interview with the Vampire", - "Up in the Air")) { - document.add(new Field("movie", movie, Store.YES, Index.NOT_ANALYZED)); - } - writer.addDocument(document); - - writer.close(); - - IndexReader reader = IndexReader.open(idx); - searcher = new IndexSearcher(reader); - } - - @Test - public void Equals_By_Id_Matches() throws Exception { - testQuery(person.id.eq("actor_1"), "id:actor_1", 1); - } - - @Test - public void Equals_By_Id_Does_Not_Match() throws Exception { - testQuery(person.id.eq("actor_8"), "id:actor_8", 0); - } - - @Test - public void Equals_By_Name_Matches() throws Exception { - testQuery(person.name.eq("George Clooney"), "name:George Clooney", 1); - } - - @Test(expected=UnsupportedOperationException.class) - public void Equals_By_Name_Ignoring_Case_Does_Not_Match() throws Exception { - testQuery(person.name.equalsIgnoreCase("george clooney"), "name:george clooney", 0); - } - - @Test - public void Equals_By_Name_Does_Not_Match() throws Exception { - testQuery(person.name.eq("George Looney"), "name:George Looney", 0); - } - - @Test - public void Starts_With_Name_Should_Match() throws Exception { - testQuery(person.name.startsWith("George C"), "name:George C*", 1); - } - - @Test - public void Starts_With_Name_Should_Not_Match() throws Exception { - testQuery(person.name.startsWith("George L"), "name:George L*", 0); - } - - @Test - public void Ends_With_Name_Should_Match() throws Exception { - testQuery(person.name.endsWith("e Clooney"), "name:*e Clooney", 1); - } - - @Test - public void Ends_With_Name_Should_Not_Match() throws Exception { - testQuery(person.name.endsWith("e Looney"), "name:*e Looney", 0); - } - - @Test - public void Contains_Name_Should_Match() throws Exception { - testQuery(person.name.contains("oney"), "name:*oney*", 1); - } - - @Test - public void Contains_Name_Should_Not_Match() throws Exception { - testQuery(person.name.contains("bloney"), "name:*bloney*", 0); - } - - @Test - public void In_Names_Should_Match_2() throws Exception { - testQuery(person.name.in("Brad Pitt", "George Clooney"), "name:Brad Pitt name:George Clooney", 2); - } - - @Test - public void Or_By_Name_Should_Match_2() throws Exception { - testQuery( person.name.eq("Brad Pitt") - .or(person.name.eq("George Clooney")), "name:Brad Pitt name:George Clooney", 2); - } - - @Test - public void Equals_By_Birth_Date() throws Exception { - testQuery(person.birthDate.eq(clooney.getBirthDate()), "birthDate:1961-04-06", 1); - } - - @Test - public void Between_Phrase() throws Exception { - testQuery(person.name.between("Brad Pitt","George Clooney"), "name:[Brad Pitt TO George Clooney]", 2); - } - - @Test - public void Not_Equals_Finds_The_Actors_And_Movies() throws Exception { - testQuery(person.name.ne("Michael Douglas"), "-name:Michael Douglas +*:*", 3); - } - - @Test - public void Not_Equals_Finds_Only_Clooney_And_Movies() throws Exception { - testQuery(person.name.ne("Brad Pitt"), "-name:Brad Pitt +*:*", 2); - } - - @Test - public void And_With_Two_Not_Equals_Doesnt_Find_The_Actors() throws Exception { - testQuery( person.name.ne("Brad Pitt") - .and(person.name.ne("George Clooney")), "+(-name:Brad Pitt +*:*) +(-name:George Clooney +*:*)", 1); - } - - @Test - public void Or_With_Two_Not_Equals_Finds_Movies_And_Actors() throws Exception { - testQuery( person.name.ne("Brad Pitt") - .or(person.name.ne("George Clooney")), "(-name:Brad Pitt +*:*) (-name:George Clooney +*:*)", 3); - } - - @Test - public void Negation_Of_Equals_Finds_Movies_And_Actors() throws Exception { - testQuery(person.name.eq("Michael Douglas").not(), "-name:Michael Douglas +*:*", 3); - } - - @Test - public void Negation_Of_Equals_Finds_Pitt_And_Movies() throws Exception { - testQuery(person.name.eq("Brad Pitt").not(), "-name:Brad Pitt +*:*", 2); - } - - @Test - public void Multiple_Field_Search_From_Movies() throws Exception { - StringPath movie = new StringPath("movie"); - testQuery(movie.in("Interview with the Vampire"), "movie:Interview with the Vampire", 1); - testQuery(movie.eq("Up in the Air"), "movie:Up in the Air", 1); - } -} diff --git a/querydsl-lucene4/src/test/java/com/mysema/query/LuceneSerializerTest.java b/querydsl-lucene4/src/test/java/com/mysema/query/LuceneSerializerTest.java deleted file mode 100644 index db9174a082..0000000000 --- a/querydsl-lucene4/src/test/java/com/mysema/query/LuceneSerializerTest.java +++ /dev/null @@ -1,671 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query; - -import java.io.StringReader; -import java.util.Arrays; - -import com.mysema.query.lucene.LuceneExpressions; -import com.mysema.query.lucene.LuceneSerializer; -import com.mysema.query.lucene.QueryElement; -import com.mysema.query.types.*; -import com.mysema.query.types.expr.BooleanExpression; -import com.mysema.query.types.path.NumberPath; -import com.mysema.query.types.path.PathBuilder; -import com.mysema.query.types.path.StringPath; -import org.apache.lucene.analysis.standard.StandardAnalyzer; -import org.apache.lucene.document.*; -import org.apache.lucene.document.Field.Index; -import org.apache.lucene.document.Field.Store; -import org.apache.lucene.index.IndexReader; -import org.apache.lucene.index.IndexWriter; -import org.apache.lucene.index.IndexWriterConfig; -import org.apache.lucene.search.IndexSearcher; -import org.apache.lucene.search.Query; -import org.apache.lucene.search.TopDocs; -import org.apache.lucene.store.RAMDirectory; -import org.apache.lucene.util.Version; -import org.junit.After; -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; - -/** - * Tests for LuceneSerializer - * - * @author vema - * - */ -public class LuceneSerializerTest { - private LuceneSerializer serializer; - private PathBuilder<Object> entityPath; - private StringPath title; - private StringPath author; - private StringPath text; - private StringPath rating; - private StringPath publisher; - private NumberPath<Integer> year; - private NumberPath<Double> gross; - - private NumberPath<Long> longField; - private NumberPath<Short> shortField; - private NumberPath<Byte> byteField; - private NumberPath<Float> floatField; - - private static final String YEAR_PREFIX_CODED = ""; - private static final String GROSS_PREFIX_CODED = ""; - private static final String LONG_PREFIX_CODED = ""; - private static final String SHORT_PREFIX_CODED = ""; - private static final String BYTE_PREFIX_CODED = ""; - private static final String FLOAT_PREFIX_CODED = ""; - - private IndexWriterConfig config; - private RAMDirectory idx; - private IndexWriter writer; - private IndexSearcher searcher; - - private final QueryMetadata metadata = new DefaultQueryMetadata(); - - private Document createDocument() { - Document doc = new Document(); - - doc.add(new Field("title", new StringReader("Jurassic Park"))); - doc.add(new Field("author", new StringReader("Michael Crichton"))); - doc.add(new Field("text", new StringReader("It's a UNIX system! I know this!"))); - doc.add(new Field("rating", new StringReader("Good"))); - doc.add(new Field("publisher", "", Store.YES, Index.ANALYZED)); - doc.add(new IntField("year", 1990, Store.YES)); - doc.add(new DoubleField("gross", 900.0, Store.YES)); - - doc.add(new LongField("longField", 1, Store.YES)); - doc.add(new IntField("shortField", 1, Store.YES)); - doc.add(new IntField("byteField", 1, Store.YES)); - doc.add(new FloatField("floatField", 1, Store.YES)); - - return doc; - } - - @Before - public void setUp() throws Exception { - serializer = new LuceneSerializer(true,true); - entityPath = new PathBuilder<Object>(Object.class, "obj"); - title = entityPath.getString("title"); - author = entityPath.getString("author"); - text = entityPath.getString("text"); - publisher = entityPath.getString("publisher"); - year = entityPath.getNumber("year", Integer.class); - rating = entityPath.getString("rating"); - gross = entityPath.getNumber("gross", Double.class); - - longField = entityPath.getNumber("longField", Long.class); - shortField = entityPath.getNumber("shortField", Short.class); - byteField = entityPath.getNumber("byteField", Byte.class); - floatField = entityPath.getNumber("floatField", Float.class); - - idx = new RAMDirectory(); - config = new IndexWriterConfig(Version.LUCENE_42, - new StandardAnalyzer(Version.LUCENE_42)) - .setOpenMode(IndexWriterConfig.OpenMode.CREATE); - writer = new IndexWriter(idx, config); - - writer.addDocument(createDocument()); - - writer.close(); - - IndexReader reader = IndexReader.open(idx); - searcher = new IndexSearcher(reader); - } - - @After - public void tearDown() throws Exception { - searcher.getIndexReader().close(); - } - - private void testQuery(Expression<?> expr, int expectedHits) throws Exception { - Query query = serializer.toQuery(expr, metadata); - TopDocs docs = searcher.search(query, 100); - assertEquals(expectedHits, docs.totalHits); - } - - private void testQuery(Expression<?> expr, String expectedQuery, int expectedHits) throws Exception { - Query query = serializer.toQuery(expr, metadata); - TopDocs docs = searcher.search(query, 100); - assertEquals(expectedHits, docs.totalHits); - assertEquals(expectedQuery, query.toString()); - } - - @Test - public void QueryElement() throws Exception{ - Query query1 = serializer.toQuery(author.like("Michael"), metadata); - Query query2 = serializer.toQuery(text.like("Text"), metadata); - - BooleanExpression query = BooleanExpression.anyOf( - new QueryElement(query1), - new QueryElement(query2) - ); - testQuery(query, "author:michael text:text", 1); - } - - @Test - public void Like() throws Exception { - testQuery(author.like("*ichael*"), "author:*ichael*", 1); - } - - @Test - public void Like_Custom_Wildcard_Single_Character() throws Exception { - testQuery(author.like("Mi?hael"), "author:mi?hael", 1); - } - - @Test - public void Like_Custom_Wildcard_Multiple_Character() throws Exception { - testQuery(text.like("*U*X*"), "text:*u*x*", 1); - } - - @Test - public void Like_Phrase() throws Exception { - testQuery(title.like("*rassic Par*"), "+title:**rassic* +title:*par**", 1); - } - - @Test - public void Like_or_like() throws Exception { - testQuery(title.like("House").or(author.like("*ichae*")), "title:house author:*ichae*", 1); - } - - @Test - public void Like_and_like() throws Exception { - testQuery(title.like("*assic*").and(rating.like("G?od")), "+title:*assic* +rating:g?od", 1); - } - - @Test - public void Eq() throws Exception { - testQuery(rating.eq("good"), "rating:good", 1); - } - - @Test - public void Eq_with_deep_path() throws Exception{ - StringPath deepPath = entityPath.get("property1", Object.class).getString("property2"); - testQuery(deepPath.eq("good"), "property1.property2:good", 0); - } - - @Test - public void FuzzyLike() throws Exception{ - testQuery(LuceneExpressions.fuzzyLike(rating, "Good"), "rating:Good~2", 1); - } - - @Test - public void FuzzyLike_with_Similarity() throws Exception{ - testQuery(LuceneExpressions.fuzzyLike(rating, "Good", 2), "rating:Good~2", 1); - } - - @Test - public void FuzzyLike_with_Similarity_and_prefix() throws Exception{ - testQuery(LuceneExpressions.fuzzyLike(rating, "Good", 2, 0), "rating:Good~2", 1); - } - - @Test - @Ignore - public void Eq_Numeric_Integer() throws Exception { - testQuery(year.eq(1990), "year:" + YEAR_PREFIX_CODED, 1); - } - - @Test - @Ignore - public void Eq_Numeric_Double() throws Exception { - testQuery(gross.eq(900.00), "gross:" + GROSS_PREFIX_CODED, 1); - } - - @Test - @Ignore - public void Eq_Numeric() throws Exception{ - testQuery(longField.eq(1l), "longField:" + LONG_PREFIX_CODED, 1); - testQuery(shortField.eq((short)1), "shortField:" + SHORT_PREFIX_CODED, 1); - testQuery(byteField.eq((byte)1), "byteField:" + BYTE_PREFIX_CODED, 1); - testQuery(floatField.eq((float)1.0), "floatField:" + FLOAT_PREFIX_CODED, 1); - } - - @Test - public void Equals_Ignores_Case() throws Exception { - testQuery(title.eq("Jurassic"), "title:jurassic", 1); - } - - @Test(expected=UnsupportedOperationException.class) - public void Title_Equals_Ignore_Case_Or_Year_Equals() throws Exception { - testQuery(title.equalsIgnoreCase("House").or(year.eq(1990)), "title:house year:" + YEAR_PREFIX_CODED, 1); - } - - @Test - @Ignore - public void Eq_and_eq() throws Exception { - testQuery(title.eq("Jurassic Park").and(year.eq(1990)), "+title:\"jurassic park\" +year:" + YEAR_PREFIX_CODED, 1); - } - - @Test - @Ignore - public void Eq_and_Eq_and_eq() throws Exception { - testQuery(title.eq("Jurassic Park").and(year.eq(1990)).and(author.eq("Michael Crichton")), "+(+title:\"jurassic park\" +year:" + YEAR_PREFIX_CODED + ") +author:\"michael crichton\"", 1); - } - - @Test(expected=UnsupportedOperationException.class) - public void Equals_Ignore_Case_And_Or() throws Exception { - testQuery(title.equalsIgnoreCase("Jurassic Park").and(rating.equalsIgnoreCase("Bad")).or(author.equalsIgnoreCase("Michael Crichton")), "(+title:\"jurassic park\" +rating:bad) author:\"michael crichton\"", 1); - } - - @Test - public void Eq_or_Eq_and_Eq_Does_Not_Find_Results() throws Exception { - testQuery(title.eq("jeeves").or(rating.eq("superb")).and(author.eq("michael crichton")), "+(title:jeeves rating:superb) +author:\"michael crichton\"", 0); - } - - @Test - public void Eq_Phrase() throws Exception { - testQuery(title.eq("Jurassic Park"), "title:\"jurassic park\"", 1); - } - - @Test - @Ignore("Not easily done in Lucene!") - public void Publisher_Equals_Empty_String() throws Exception { - testQuery(publisher.eq(""), "publisher:", 1); - } - - @Test - public void Eq_Phrase_Should_Not_Find_Results_But_LuceNe_Semantics_Differs_From_Querydsls() throws Exception { - testQuery(text.eq("UNIX System"), "text:\"unix system\"", 1); - } - - @Test - public void Eq_Phrase_Does_Not_Find_Results_Because_Word_In_Middle() throws Exception { - testQuery(title.eq("Jurassic Amusement Park"), "title:\"jurassic amusement park\"", 0); - } - - @Test - public void Like_not_Does_Not_Find_Results() throws Exception { - testQuery(title.like("*H*e*").not(), "-title:*h*e* +*:*", 1); - } - - @Test(expected=UnsupportedOperationException.class) - public void Title_Equals_Ignore_Case_Negation_Or_Rating_Equals_Ignore_Case() throws Exception { - testQuery(title.equalsIgnoreCase("House").not().or(rating.equalsIgnoreCase("Good")), "-title:house rating:good", 1); - } - - @Test - public void Eq_not_Does_Not_Find_Results() throws Exception { - testQuery(title.eq("Jurassic Park").not(), "-title:\"jurassic park\" +*:*", 0); - } - - @Test - public void Title_Equals_Not_House() throws Exception { - testQuery(title.eq("house").not(), "-title:house +*:*", 1); - } - - @Test - public void Eq_and_Eq_not_Does_Not_Find_Results_Because_Second_Expression_Finds_Nothing() throws Exception { - testQuery(rating.eq("superb").and(title.eq("house").not()), "+rating:superb +(-title:house +*:*)", 0); - } - - @Test - public void Not_Equals_Finds_One() throws Exception { - testQuery(title.ne("house"), "-title:house +*:*", 1); - } - - @Test - public void Not_Equals_Finds_None() throws Exception { - testQuery(title.ne("Jurassic Park"), "-title:\"jurassic park\" +*:*", 0); - } - - @Test - public void Nothing_Found_With_Not_Equals_Or_Equals() throws Exception { - testQuery(title.ne("jurassic park").or(rating.eq("lousy")), "(-title:\"jurassic park\" +*:*) rating:lousy", 0); - } - - @Test - public void Ne_and_eq() throws Exception { - testQuery(title.ne("house").and(rating.eq("good")), "+(-title:house +*:*) +rating:good", 1); - } - - @Test - public void StartsWith() throws Exception { - testQuery(title.startsWith("Jurassi"), "title:jurassi*", 1); - } - - @Test - public void StartsWith_Phrase() throws Exception { - testQuery(title.startsWith("jurassic par"), "+title:jurassic* +title:*par*", 1); - } - - @Test(expected=UnsupportedOperationException.class) - public void Starts_With_Ignore_Case_Phrase_Does_Not_Find_Results() throws Exception { - testQuery(title.startsWithIgnoreCase("urassic Par"), "+title:urassic* +title:*par*", 0); - } - - @Test - public void EndsWith() throws Exception { - testQuery(title.endsWith("ark"), "title:*ark", 1); - } - - @Test(expected=UnsupportedOperationException.class) - public void Ends_With_Ignore_Case_Phrase() throws Exception { - testQuery(title.endsWithIgnoreCase("sic Park"), "+title:*sic* +title:*park", 1); - } - - @Test(expected=UnsupportedOperationException.class) - public void Ends_With_Ignore_Case_Phrase_Does_Not_Find_Results() throws Exception { - testQuery(title.endsWithIgnoreCase("sic Par"), "+title:*sic* +title:*par", 0); - } - - @Test - public void Contains() throws Exception { - testQuery(title.contains("rassi"), "title:*rassi*", 1); - } - - @Test(expected=UnsupportedOperationException.class) - public void Contains_Ignore_Case_Phrase() throws Exception { - testQuery(title.containsIgnoreCase("rassi Pa"), "+title:*rassi* +title:*pa*", 1); - } - - @Test - public void Contains_User_Inputted_Wildcards_Dont_Work() throws Exception { - testQuery(title.contains("r*i"), "title:*r\\*i*", 0); - } - - @Test - public void Between() throws Exception { - testQuery(title.between("Indiana", "Kundun"), "title:[indiana TO kundun]", 1); - } - - @Test - public void Between_Numeric_Integer() throws Exception { - testQuery(year.between(1980, 2000), "year:[1980 TO 2000]", 1); - } - - @Test - public void Between_Numeric_Double() throws Exception { - testQuery(gross.between(10.00, 19030.00), "gross:[10.0 TO 19030.0]", 1); - } - - @Test - public void Between_Numeric() throws Exception{ - testQuery(longField.between(0l,2l), "longField:[0 TO 2]", 1); - testQuery(shortField.between((short)0,(short)2), "shortField:[0 TO 2]", 1); - testQuery(byteField.between((byte)0,(byte)2), "byteField:[0 TO 2]", 1); - testQuery(floatField.between((float)0.0,(float)2.0), "floatField:[0.0 TO 2.0]", 1); - } - - @Test - public void Between_Is_Inclusive_From_Start() throws Exception { - testQuery(title.between("Jurassic", "Kundun"), "title:[jurassic TO kundun]", 1); - } - - @Test - public void Between_Is_Inclusive_To_End() throws Exception { - testQuery(title.between("Indiana", "Jurassic"), "title:[indiana TO jurassic]", 1); - } - - @Test - public void Between_Does_Not_Find_Results() throws Exception { - testQuery(title.between("Indiana", "Jurassib"), "title:[indiana TO jurassib]", 0); - } - - @Test - public void In() throws Exception { - testQuery(title.in(Arrays.asList("jurassic", "park")), "title:jurassic title:park", 1); - testQuery(title.in("jurassic","park"), "title:jurassic title:park", 1); - testQuery(title.eq("jurassic").or(title.eq("park")), "title:jurassic title:park", 1); - } - - @Test - public void Lt() throws Exception { - testQuery(rating.lt("Superb"), "rating:{* TO superb}", 1); - } - - @Test - public void Lt_Numeric_Integer() throws Exception { - testQuery(year.lt(1991), "year:{* TO 1991}", 1); - } - - @Test - public void Lt_Numeric_Double() throws Exception { - testQuery(gross.lt(10000.0), "gross:{* TO 10000.0}", 1); - } - - @Test - public void Lt_Not_In_Range_Because_Equal() throws Exception { - testQuery(rating.lt("Good"), "rating:{* TO good}", 0); - } - - @Test - public void Lt_Numeric_Integer_Not_In_Range_Because_Equal() throws Exception { - testQuery(year.lt(1990), "year:{* TO 1990}", 0); - } - - @Test - public void Lt_Numeric_Double_Not_In_Range_Because_Equal() throws Exception { - testQuery(gross.lt(900.0), "gross:{* TO 900.0}", 0); - } - - @Test - public void Loe() throws Exception { - testQuery(rating.loe("Superb"), "rating:[* TO superb]", 1); - } - - @Test - public void Loe_Numeric_Integer() throws Exception { - testQuery(year.loe(1991), "year:[* TO 1991]", 1); - } - - @Test - public void Loe_Numeric_Double() throws Exception { - testQuery(gross.loe(903.0), "gross:[* TO 903.0]", 1); - } - - @Test - public void Loe_Equal() throws Exception { - testQuery(rating.loe("Good"), "rating:[* TO good]", 1); - } - - @Test - public void Loe_Numeric_Integer_Equal() throws Exception { - testQuery(year.loe(1990), "year:[* TO 1990]", 1); - } - - @Test - public void Loe_Numeric_Double_Equal() throws Exception { - testQuery(gross.loe(900.0), "gross:[* TO 900.0]", 1); - } - - @Test - public void Loe_Not_Found() throws Exception { - testQuery(rating.loe("Bad"), "rating:[* TO bad]", 0); - } - - @Test - public void Loe_Numeric_Integer_Not_Found() throws Exception { - testQuery(year.loe(1989), "year:[* TO 1989]", 0); - } - - @Test - public void Loe_Numeric_Double_Not_Found() throws Exception { - testQuery(gross.loe(899.9), "gross:[* TO 899.9]", 0); - } - - @Test - public void Gt() throws Exception { - testQuery(rating.gt("Bad"), "rating:{bad TO *}", 1); - } - - @Test - public void Gt_Numeric_Integer() throws Exception { - testQuery(year.gt(1989), "year:{1989 TO *}", 1); - } - - @Test - public void Gt_Numeric_Double() throws Exception { - testQuery(gross.gt(100.00), "gross:{100.0 TO *}", 1); - } - - @Test - public void Gt_Not_In_Range_Because_Equal() throws Exception { - testQuery(rating.gt("Good"), "rating:{good TO *}", 0); - } - - @Test - public void Gt_Numeric_Integer_Not_In_Range_Because_Equal() throws Exception { - testQuery(year.gt(1990), "year:{1990 TO *}", 0); - } - - @Test - public void Gt_Numeric_Double_Not_In_Range_Because_Equal() throws Exception { - testQuery(gross.gt(900.00), "gross:{900.0 TO *}", 0); - } - - @Test - public void Goe() throws Exception { - testQuery(rating.goe("Bad"), "rating:[bad TO *]", 1); - } - - @Test - public void Goe_Numeric_Integer() throws Exception { - testQuery(year.goe(1989), "year:[1989 TO *]", 1); - } - - @Test - public void Goe_Numeric_Double() throws Exception { - testQuery(gross.goe(320.50), "gross:[320.5 TO *]", 1); - } - - @Test - public void Goe_Equal() throws Exception { - testQuery(rating.goe("Good"), "rating:[good TO *]", 1); - } - - @Test - public void Goe_Numeric_Integer_Equal() throws Exception { - testQuery(year.goe(1990), "year:[1990 TO *]", 1); - } - - @Test - public void Goe_Numeric_Double_Equal() throws Exception { - testQuery(gross.goe(900.00), "gross:[900.0 TO *]", 1); - } - - @Test - public void Goe_Not_Found() throws Exception { - testQuery(rating.goe("Hood"), "rating:[hood TO *]", 0); - } - - @Test - public void Goe_Numeric_Integer_Not_Found() throws Exception { - testQuery(year.goe(1991), "year:[1991 TO *]", 0); - } - - @Test - public void Goe_Numeric_Double_Not_Found() throws Exception { - testQuery(gross.goe(900.10), "gross:[900.1 TO *]", 0); - } - - @Test - public void Equals_Empty_String() throws Exception { - testQuery(title.eq(""), "title:", 0); - } - - @Test - public void Not_Equals_Empty_String() throws Exception { - testQuery(title.ne(""), "-title: +*:*", 1); - } - - @Test - public void Contains_Empty_String() throws Exception { - testQuery(title.contains(""), "title:**", 1); - } - - @Test - public void Like_Empty_String() throws Exception { - testQuery(title.like(""), "title:", 0); - } - - @Test - public void Starts_With_Empty_String() throws Exception { - testQuery(title.startsWith(""), "title:*", 1); - } - - @Test - public void Ends_With_Empty_String() throws Exception { - testQuery(title.endsWith(""), "title:*", 1); - } - - @Test - public void Between_Empty_Strings() throws Exception { - testQuery(title.between("", ""), "title:[ TO ]", 0); - } - - @Test - public void BooleanBuilder() throws Exception{ - testQuery(new BooleanBuilder(gross.goe(900.10)), "gross:[900.1 TO *]", 0); - } - - @Test - @Ignore - public void Fuzzy() throws Exception { - fail("Not yet implemented!"); - } - - @Test - @Ignore - public void Proximity() throws Exception { - fail("Not yet implemented!"); - } - - @Test - @Ignore - public void Boost() throws Exception { - fail("Not yet implemented!"); - } - - private boolean unsupportedOperation(Predicate filter) { - if (filter instanceof Operation<?>) { - Operator<?> op = ((Operation<?>) filter).getOperator(); - if (op == Ops.STARTS_WITH_IC || op == Ops.EQ_IGNORE_CASE || op == Ops.STARTS_WITH_IC - || op == Ops.ENDS_WITH_IC || op == Ops.STRING_CONTAINS_IC) { - return true; - } - } - return false; - } - - @Test - public void various() throws Exception{ - MatchingFiltersFactory filters = new MatchingFiltersFactory(Module.LUCENE, Target.LUCENE); - for (Predicate filter : filters.string(title, StringConstant.create("jurassic park"))) { - if (unsupportedOperation(filter)) { - continue; - } - testQuery(filter, 1); - } - - for (Predicate filter : filters.string(author, StringConstant.create("michael crichton"))) { - if (unsupportedOperation(filter)) { - continue; - } - testQuery(filter, 1); - } - - for (Predicate filter : filters.string(title, StringConstant.create("1990"))) { - if (unsupportedOperation(filter)) { - continue; - } - testQuery(filter, 0); - } - } - -} diff --git a/querydsl-lucene4/src/test/java/com/mysema/query/Person.java b/querydsl-lucene4/src/test/java/com/mysema/query/Person.java deleted file mode 100644 index 32a1ad42e9..0000000000 --- a/querydsl-lucene4/src/test/java/com/mysema/query/Person.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query; - -import org.joda.time.LocalDate; - -import com.mysema.query.annotations.QueryEntity; - -@QueryEntity -public class Person { - private final String id; - private final String name; - private final LocalDate birthDate; - - public Person(String id, String name, LocalDate birthDate) { - this.id = id; - this.name = name; - this.birthDate = birthDate; - } - - public String getId() { - return id; - } - - public LocalDate getBirthDate() { - return birthDate; - } - - public String getName() { - return name; - } -} - - diff --git a/querydsl-lucene4/src/test/java/com/mysema/query/lucene/LuceneQueryTest.java b/querydsl-lucene4/src/test/java/com/mysema/query/lucene/LuceneQueryTest.java deleted file mode 100644 index e2f2563f0e..0000000000 --- a/querydsl-lucene4/src/test/java/com/mysema/query/lucene/LuceneQueryTest.java +++ /dev/null @@ -1,747 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.lucene; - -import static org.easymock.EasyMock.createMockBuilder; -import static org.easymock.EasyMock.expect; -import static org.easymock.EasyMock.replay; -import static org.easymock.EasyMock.verify; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -import java.io.IOException; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.Locale; - -import org.apache.lucene.analysis.standard.StandardAnalyzer; -import org.apache.lucene.document.Document; -import org.apache.lucene.document.DoubleField; -import org.apache.lucene.document.Field; -import org.apache.lucene.document.Field.Index; -import org.apache.lucene.document.Field.Store; -import org.apache.lucene.document.IntField; -import org.apache.lucene.document.TextField; -import org.apache.lucene.index.IndexReader; -import org.apache.lucene.index.IndexWriter; -import org.apache.lucene.index.IndexWriterConfig; -import org.apache.lucene.sandbox.queries.DuplicateFilter; -import org.apache.lucene.search.Filter; -import org.apache.lucene.search.IndexSearcher; -import org.apache.lucene.search.Sort; -import org.apache.lucene.store.RAMDirectory; -import org.apache.lucene.util.Version; -import org.junit.After; -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; - -import com.google.common.collect.Sets; -import com.mysema.query.NonUniqueResultException; -import com.mysema.query.QueryException; -import com.mysema.query.QueryModifiers; -import com.mysema.query.SearchResults; -import com.mysema.query.types.ParamNotSetException; -import com.mysema.query.types.expr.Param; -import com.mysema.query.types.path.NumberPath; -import com.mysema.query.types.path.StringPath; - -/** - * Tests for LuceneQuery - * - * @author vema - * - */ -public class LuceneQueryTest { - - private LuceneQuery query; - private StringPath title; - private NumberPath<Integer> year; - private NumberPath<Double> gross; - - private final StringPath sort = new StringPath("sort"); - - private RAMDirectory idx; - private IndexWriter writer; - private IndexSearcher searcher; - - private Document createDocument(final String docTitle, - final String docAuthor, final String docText, final int docYear, - final double docGross) { - final Document doc = new Document(); - - doc.add(new TextField("title", docTitle, Store.YES)); - doc.add(new TextField("author", docAuthor, Store.YES)); - doc.add(new TextField("text", docText, Store.YES)); - doc.add(new IntField("year", docYear, Store.YES)); - doc.add(new DoubleField("gross", docGross, Store.YES)); - - return doc; - } - - @Before - public void setUp() throws Exception { - final QDocument entityPath = new QDocument("doc"); - title = entityPath.title; - year = entityPath.year; - gross = entityPath.gross; - - - idx = new RAMDirectory(); - writer = createWriter(idx); - - writer.addDocument(createDocument("Jurassic Park", "Michael Crichton", - "It's a UNIX system! I know this!", 1990, 90.00)); - writer.addDocument(createDocument("Nummisuutarit", "Aleksis Kivi", - "ESKO. Ja iloitset ja riemuitset?", 1864, 10.00)); - writer - .addDocument(createDocument( - "The Lord of the Rings", - "John R. R. Tolkien", - "One Ring to rule them all, One Ring to find them, One Ring to bring them all and in the darkness bind them", - 1954, 89.00)); - writer - .addDocument(createDocument( - "Introduction to Algorithms", - "Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein", - "Bubble sort", 1990, 30.50)); - - writer.close(); - - IndexReader reader = IndexReader.open(idx); - searcher = new IndexSearcher(reader); - query = new LuceneQuery(new LuceneSerializer(true, true), searcher); - } - - private IndexWriter createWriter(RAMDirectory idx) throws Exception { - IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_31, - new StandardAnalyzer(Version.LUCENE_42)) - .setOpenMode(IndexWriterConfig.OpenMode.CREATE); - return new IndexWriter(idx, config); - } - - @After - public void tearDown() throws Exception { - searcher.getIndexReader().close(); - } - - @Test - public void Count_Empty_Where_Clause() { - assertEquals(4, query.count()); - } - - @Test - public void Exists() { - assertTrue(query.where(title.eq("Jurassic Park")).exists()); - assertFalse(query.where(title.eq("Jurassic Park X")).exists()); - } - - @Test - public void NotExists() { - assertFalse(query.where(title.eq("Jurassic Park")).notExists()); - assertTrue(query.where(title.eq("Jurassic Park X")).notExists()); - } - - @Test - public void Count() { - query.where(title.eq("Jurassic Park")); - assertEquals(1, query.count()); - } - - @Test(expected = QueryException.class) - @Ignore - public void Count_Index_Problem() throws IOException { - searcher = createMockBuilder(IndexSearcher.class).addMockedMethod( - "maxDoc").createMock(); - query = new LuceneQuery(new LuceneSerializer(true, true), searcher); - expect(searcher.getIndexReader().maxDoc()).andThrow(new IllegalArgumentException()); - replay(searcher); - query.where(title.eq("Jurassic Park")); - query.count(); - verify(searcher); - } - - @Test(expected=UnsupportedOperationException.class) - public void CountDistinct() { - query.where(year.between(1900, 3000)); - assertEquals(3, query.distinct().count()); - } - - @Test - public void List_Sorted_By_Year_Ascending() { - query.where(year.between(1800, 2000)); - query.orderBy(year.asc()); - final List<Document> documents = query.list(); - assertFalse(documents.isEmpty()); - assertEquals(4, documents.size()); - } - - @Test - public void List_Not_Sorted() { - query.where(year.between(1800, 2000)); - final List<Document> documents = query.list(); - assertFalse(documents.isEmpty()); - assertEquals(4, documents.size()); - } - - @Test - @Ignore // FIXME - public void Sorted_By_Different_Locales() throws Exception { - Document d1 = new Document(); - Document d2 = new Document(); - Document d3 = new Document(); - d1.add(new Field("sort", "a\u00c4",Store.YES, Index.NOT_ANALYZED)); - d2.add(new Field("sort", "ab",Store.YES, Index.NOT_ANALYZED)); - d3.add(new Field("sort", "aa",Store.YES, Index.NOT_ANALYZED)); - writer = createWriter(idx); - writer.addDocument(d1); - writer.addDocument(d2); - writer.addDocument(d3); - writer.close(); - - IndexReader reader = IndexReader.open(idx); - searcher = new IndexSearcher(reader); - query = new LuceneQuery(new LuceneSerializer(true, true, Locale.ENGLISH), searcher); - assertEquals(3, query.list().size()); - List<Document> results = query.where(sort.startsWith("a")).orderBy(sort.asc()).list(); - assertEquals(3, results.size()); - assertEquals("aa", results.get(0).getField("sort").stringValue()); - assertEquals("a\u00c4", results.get(1).getField("sort").stringValue()); - assertEquals("ab", results.get(2).getField("sort").stringValue()); - - query = new LuceneQuery(new LuceneSerializer(true, true, new Locale("fi", "FI")), searcher); - results = query.where(sort.startsWith("a")).orderBy(sort.asc()).list(); - assertEquals("aa", results.get(0).getField("sort").stringValue()); - assertEquals("ab", results.get(1).getField("sort").stringValue()); - assertEquals("a\u00c4", results.get(2).getField("sort").stringValue()); - } - - @Test - public void List_Not_Sorted_Limit_2() { - query.where(year.between(1800, 2000)); - query.limit(2); - final List<Document> documents = query.list(); - assertFalse(documents.isEmpty()); - assertEquals(2, documents.size()); - } - - @Test - public void List_Sorted_By_Year_Limit_1() { - query.where(year.between(1800, 2000)); - query.limit(1); - query.orderBy(year.asc()); - final List<Document> documents = query.list(); - assertFalse(documents.isEmpty()); - assertEquals(1, documents.size()); - } - - @Test - public void List_Not_Sorted_Offset_2() { - query.where(year.between(1800, 2000)); - query.offset(2); - final List<Document> documents = query.list(); - assertFalse(documents.isEmpty()); - assertEquals(2, documents.size()); - } - - @Test - public void List_Sorted_Ascending_By_Year_Offset_2() { - query.where(year.between(1800, 2000)); - query.offset(2); - query.orderBy(year.asc()); - final List<Document> documents = query.list(); - assertFalse(documents.isEmpty()); - assertEquals(2, documents.size()); - assertEquals("1990", documents.get(0).get("year")); - assertEquals("1990", documents.get(1).get("year")); - } - - @Test - public void List_Sorted_Ascending_By_Year_Restrict_Limit_2_Offset_1() { - query.where(year.between(1800, 2000)); - query.restrict(new QueryModifiers(2l, 1l)); - query.orderBy(year.asc()); - final List<Document> documents = query.list(); - assertFalse(documents.isEmpty()); - assertEquals(2, documents.size()); - assertEquals("1954", documents.get(0).get("year")); - assertEquals("1990", documents.get(1).get("year")); - } - - @Test - public void List_Sorted_Ascending_By_Year() { - query.where(year.between(1800, 2000)); - query.orderBy(year.asc()); - final List<Document> documents = query.list(); - assertFalse(documents.isEmpty()); - assertEquals(4, documents.size()); - assertEquals("1864", documents.get(0).get("year")); - assertEquals("1954", documents.get(1).get("year")); - assertEquals("1990", documents.get(2).get("year")); - assertEquals("1990", documents.get(3).get("year")); - } - - - @Test - public void List_Sort() { - Sort sort = LuceneSerializer.DEFAULT.toSort(Collections.singletonList(year.asc())); - - query.where(year.between(1800, 2000)); - //query.orderBy(year.asc()); - query.sort(sort); - final List<Document> documents = query.list(); - assertFalse(documents.isEmpty()); - assertEquals(4, documents.size()); - assertEquals("1864", documents.get(0).get("year")); - assertEquals("1954", documents.get(1).get("year")); - assertEquals("1990", documents.get(2).get("year")); - assertEquals("1990", documents.get(3).get("year")); - } - - @Test - public void List_Distinct_Property() { - assertEquals(4, query.list().size()); - assertEquals(3, query.distinct(year).list().size()); - } - - @Test - public void List_With_Filter() { - Filter filter = new DuplicateFilter("year"); - assertEquals(4, query.list().size()); - assertEquals(3, query.filter(filter).list().size()); - } - - @Test - public void Count_Distinct_Property() { - assertEquals(4l, query.count()); - assertEquals(3l, query.distinct(year).count()); - } - - @Test - public void List_Sorted_Descending_By_Year() { - query.where(year.between(1800, 2000)); - query.orderBy(year.desc()); - final List<Document> documents = query.list(); - assertFalse(documents.isEmpty()); - assertEquals(4, documents.size()); - assertEquals("1990", documents.get(0).get("year")); - assertEquals("1990", documents.get(1).get("year")); - assertEquals("1954", documents.get(2).get("year")); - assertEquals("1864", documents.get(3).get("year")); - } - - - @Test - public void List_Sorted_Descending_By_Gross() { - query.where(gross.between(0.0, 1000.00)); - query.orderBy(gross.desc()); - final List<Document> documents = query.list(); - assertFalse(documents.isEmpty()); - assertEquals(4, documents.size()); - assertEquals("90.0", documents.get(0).get("gross")); - assertEquals("89.0", documents.get(1).get("gross")); - assertEquals("30.5", documents.get(2).get("gross")); - assertEquals("10.0", documents.get(3).get("gross")); - } - - @Test - public void List_Sorted_Descending_By_Year_And_Ascending_By_Title() { - query.where(year.between(1800, 2000)); - query.orderBy(year.desc()); - query.orderBy(title.asc()); - final List<Document> documents = query.list(); - assertFalse(documents.isEmpty()); - assertEquals(4, documents.size()); - assertEquals("1990", documents.get(0).get("year")); - assertEquals("1990", documents.get(1).get("year")); - assertEquals("Introduction to Algorithms", documents.get(0) - .get("title")); - assertEquals("Jurassic Park", documents.get(1).get("title")); - } - - @Test - public void List_Sorted_Descending_By_Year_And_Descending_By_Title() { - query.where(year.between(1800, 2000)); - query.orderBy(year.desc()); - query.orderBy(title.desc()); - final List<Document> documents = query.list(); - assertFalse(documents.isEmpty()); - assertEquals(4, documents.size()); - assertEquals("1990", documents.get(0).get("year")); - assertEquals("1990", documents.get(1).get("year")); - assertEquals("Jurassic Park", documents.get(0).get("title")); - assertEquals("Introduction to Algorithms", documents.get(1) - .get("title")); - } - - @Ignore - @Test(expected = QueryException.class) - public void List_Index_Problem_In_Max_Doc() throws IOException { - searcher = createMockBuilder(IndexSearcher.class).addMockedMethod( - "maxDoc").createMock(); - query = new LuceneQuery(new LuceneSerializer(true, true), searcher); - expect(searcher.getIndexReader().maxDoc()).andThrow(new IOException()); - replay(searcher); - query.where(title.eq("Jurassic Park")); - query.list(); - verify(searcher); - } - - @Ignore - @Test(expected = QueryException.class) - public void List_Sorted_Index_Problem_In_Max_Doc() throws IOException { - searcher = createMockBuilder(IndexSearcher.class).addMockedMethod( - "maxDoc").createMock(); - query = new LuceneQuery(new LuceneSerializer(true, true), searcher); - expect(searcher.getIndexReader().maxDoc()).andThrow(new IOException()); - replay(searcher); - query.where(title.eq("Jurassic Park")); - query.orderBy(title.asc()); - query.list(); - verify(searcher); - } - - @Test - public void Offset() { - assertTrue(query.where(title.eq("Jurassic Park")).offset(30).list() - .isEmpty()); - } - - - @Test - public void Load_List() { - Document document = query.where(title.ne("")).load(title).list().get(0); - assertNotNull(document.get("title")); - assertNull(document.get("year")); - } - - @Test - public void Load_List_FieldSelector() { - Document document = query.where(title.ne("")).load(Sets.newHashSet("title")).list().get(0); - assertNotNull(document.get("title")); - assertNull(document.get("year")); - } - - @Test - public void Load_SingleResult() { - Document document = query.where(title.ne("")).load(title).singleResult(); - assertNotNull(document.get("title")); - assertNull(document.get("year")); - } - - @Test - public void Load_SingleResult_FieldSelector() { - Document document = query.where(title.ne("")).load(Sets.newHashSet("title")).singleResult(); - assertNotNull(document.get("title")); - assertNull(document.get("year")); - } - - @Test - public void SingleResult() { - assertNotNull(query.where(title.ne("")).singleResult()); - } - - @Test - public void Single_Result_Takes_Limit() { - assertEquals("Jurassic Park", query - .where(title.ne("")) - .limit(1) - .singleResult().get("title")); - } - - @Test - public void Single_Result_Considers_Limit_And_Actual_Result_Size() { - query.where(title.startsWith("Nummi")); - final Document document = query.limit(3).singleResult(); - assertEquals("Nummisuutarit", document.get("title")); - } - - @Test - public void Single_Result_Returns_Null_If_Nothing_Is_In_Range() { - query.where(title.startsWith("Nummi")); - assertNull(query.offset(10).singleResult()); - } - - @Test - public void Single_Result_Considers_Offset() { - assertEquals("Introduction to Algorithms", query.where(title.ne("")).offset(3).singleResult().get("title")); - } - - @Test - public void Single_Result_Considers_Limit_And_Offset() { - assertEquals("The Lord of the Rings", query.where(title.ne("")).limit(1).offset(2).singleResult().get("title")); - } - - @Test(expected=NonUniqueResultException.class) - public void UniqueResult_Contract() { - query.where(title.ne("")).uniqueResult(); - } - - @Test - public void Unique_Result_Takes_Limit() { - assertEquals("Jurassic Park", query - .where(title.ne("")) - .limit(1) - .uniqueResult().get("title")); - } - - @Test - public void Unique_Result_Considers_Limit_And_Actual_Result_Size() { - query.where(title.startsWith("Nummi")); - final Document document = query.limit(3).uniqueResult(); - assertEquals("Nummisuutarit", document.get("title")); - } - - @Test - public void Unique_Result_Returns_Null_If_Nothing_Is_In_Range() { - query.where(title.startsWith("Nummi")); - assertNull(query.offset(10).uniqueResult()); - } - - @Test - public void Unique_Result_Considers_Offset() { - assertEquals("Introduction to Algorithms", query.where(title.ne("")).offset(3).uniqueResult().get("title")); - } - - @Test - public void Unique_Result_Considers_Limit_And_Offset() { - assertEquals("The Lord of the Rings", query.where(title.ne("")).limit(1).offset(2).uniqueResult().get("title")); - } - - @Test - public void UniqueResult() { - query.where(title.startsWith("Nummi")); - final Document document = query.uniqueResult(); - assertEquals("Nummisuutarit", document.get("title")); - } - - @Test - public void UniqueResult_With_Param() { - final Param<String> param = new Param<String>(String.class, "title"); - query.set(param, "Nummi"); - query.where(title.startsWith(param)); - final Document document = query.uniqueResult(); - assertEquals("Nummisuutarit", document.get("title")); - } - - @Test(expected = ParamNotSetException.class) - public void UniqueResult_Param_Not_Set() { - final Param<String> param = new Param<String>(String.class, "title"); - query.where(title.startsWith(param)); - query.uniqueResult(); - } - - @Test(expected = QueryException.class) - public void UniqueResult_Finds_More_Than_One_Result() { - query.where(year.eq(1990)); - query.uniqueResult(); - } - - @Test - public void UniqueResult_Finds_No_Results() { - query.where(year.eq(2200)); - assertNull(query.uniqueResult()); - } - - @Test - @Ignore - public void UniqueResult_Finds_No_Results_Because_No_Documents_In_Index() - throws IOException { - searcher = createMockBuilder(IndexSearcher.class).addMockedMethod( - "maxDoc").createMock(); - query = new LuceneQuery(new LuceneSerializer(true, true), searcher); - expect(searcher.getIndexReader().maxDoc()).andReturn(0); - replay(searcher); - assertNull(query.where(year.eq(3000)).uniqueResult()); - verify(searcher); - } - - @Test(expected = QueryException.class) - @Ignore - public void UniqueResult_Sorted_Index_Problem_In_Max_Doc() - throws IOException { - searcher = createMockBuilder(IndexSearcher.class).addMockedMethod( - "maxDoc").createMock(); - query = new LuceneQuery(new LuceneSerializer(true, true), searcher); - expect(searcher.getIndexReader().maxDoc()).andThrow(new IllegalArgumentException()); - replay(searcher); - query.where(title.eq("Jurassic Park")); - query.uniqueResult(); - verify(searcher); - } - - @Test - @Ignore - public void Count_Returns_0_Because_No_Documents_In_Index() - throws IOException { - searcher = createMockBuilder(IndexSearcher.class).addMockedMethod( - "maxDoc").createMock(); - query = new LuceneQuery(new LuceneSerializer(true, true), searcher); - expect(searcher.getIndexReader().maxDoc()).andReturn(0); - replay(searcher); - assertEquals(0, query.where(year.eq(3000)).count()); - verify(searcher); - } - - @Test(expected=UnsupportedOperationException.class) - public void ListDistinct() { - query.where(year.between(1900, 2000).or(title.startsWith("Jura"))); - query.orderBy(year.asc()); - final List<Document> documents = query.distinct().list(); - assertFalse(documents.isEmpty()); - assertEquals(3, documents.size()); - } - - @Test - public void ListResults() { - query.where(year.between(1800, 2000)); - query.restrict(new QueryModifiers(2l, 1l)); - query.orderBy(year.asc()); - final SearchResults<Document> results = query.listResults(); - assertFalse(results.isEmpty()); - assertEquals("1954", results.getResults().get(0).get("year")); - assertEquals("1990", results.getResults().get(1).get("year")); - assertEquals(2, results.getLimit()); - assertEquals(1, results.getOffset()); - assertEquals(4, results.getTotal()); - } - - @Test(expected=UnsupportedOperationException.class) - public void ListDistinctResults() { - query.where(year.between(1800, 2000).or( - title.eq("The Lord of the Rings"))); - query.restrict(new QueryModifiers(1l, 1l)); - query.orderBy(year.asc()); - final SearchResults<Document> results = query.distinct().listResults(); - assertFalse(results.isEmpty()); - assertEquals("1954", results.getResults().get(0).get("year")); - assertEquals(1, results.getLimit()); - assertEquals(1, results.getOffset()); - assertEquals(4, results.getTotal()); - } - - @Test - public void List_All() { - final List<Document> results = query.where(title.like("*")).orderBy( - title.asc(), year.desc()).list(); - assertEquals(4, results.size()); - } - - @Test(expected = IllegalArgumentException.class) - public void List_Sorted_Ascending_Limit_Negative() { - query.where(year.between(1800, 2000)); - query.limit(-1); - query.orderBy(year.asc()); - query.list(); - } - - @Test(expected = IllegalArgumentException.class) - public void List_Not_Sorted_Limit_Negative() { - query.where(year.between(1800, 2000)); - query.limit(-1); - query.list(); - } - - @Test(expected = IllegalArgumentException.class) - public void List_Sorted_Ascending_Limit_0() { - query.where(year.between(1800, 2000)); - query.limit(0); - query.orderBy(year.asc()); - query.list(); - } - - @Test(expected = IllegalArgumentException.class) - public void List_Not_Sorted_Limit_0() { - query.where(year.between(1800, 2000)); - query.limit(0); - query.list(); - } - - @Test(expected = IllegalArgumentException.class) - public void List_Sorted_Ascending_Offset_Negative() { - query.where(year.between(1800, 2000)); - query.offset(-1); - query.orderBy(year.asc()); - query.list(); - } - - @Test(expected = IllegalArgumentException.class) - public void List_Not_Sorted_Offset_Negative() { - query.where(year.between(1800, 2000)); - query.offset(-1); - query.list(); - } - - @Test - public void List_Sorted_Ascending_Offset_0() { - query.where(year.between(1800, 2000)); - query.offset(0); - query.orderBy(year.asc()); - final List<Document> documents = query.list(); - assertFalse(documents.isEmpty()); - assertEquals(4, documents.size()); - } - - @Test - public void List_Not_Sorted_Offset_0() { - query.where(year.between(1800, 2000)); - query.offset(0); - final List<Document> documents = query.list(); - assertFalse(documents.isEmpty()); - assertEquals(4, documents.size()); - } - - @Test - public void Iterate() { - query.where(year.between(1800, 2000)); - final Iterator<Document> iterator = query.iterate(); - int count = 0; - while (iterator.hasNext()) { - iterator.next(); - ++count; - } - assertEquals(4, count); - } - - @Test - public void All_By_Excluding_Where() { - assertEquals(4, query.list().size()); - } - - @Test - public void Empty_Index_Should_Return_Empty_List() throws Exception { - idx = new RAMDirectory(); - - writer = createWriter(idx); - writer.close(); - IndexReader reader = IndexReader.open(idx); - searcher = new IndexSearcher(reader); - query = new LuceneQuery(new LuceneSerializer(true, true), searcher); - assertTrue(query.list().isEmpty()); - } - - @Test(expected = QueryException.class) - public void List_Results_Throws_An_Illegal_Argument_Exception_When_Sum_Of_Limit_And_Offset_Is_Negative() { - query.limit(1).offset(Integer.MAX_VALUE).listResults(); - } - - @Test - public void Limit_Max_Value() { - assertEquals(4, query.limit(Long.MAX_VALUE).list().size()); - } -} diff --git a/querydsl-lucene4/src/test/java/com/mysema/query/lucene/PhraseElementTest.java b/querydsl-lucene4/src/test/java/com/mysema/query/lucene/PhraseElementTest.java deleted file mode 100644 index 2cad5c07f8..0000000000 --- a/querydsl-lucene4/src/test/java/com/mysema/query/lucene/PhraseElementTest.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.lucene; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; - -import org.junit.Test; - -import com.mysema.query.DefaultQueryMetadata; -import com.mysema.query.QueryMetadata; -import com.mysema.query.types.path.StringPath; - -public class PhraseElementTest { - - @Test - public void test() { - StringPath title = new StringPath("title"); - LuceneSerializer serializer = new LuceneSerializer(false,false); - QueryMetadata metadata = new DefaultQueryMetadata(); - assertEquals("title:Hello World", serializer.toQuery(title.eq("Hello World"), metadata).toString()); - assertEquals("title:\"Hello World\"", serializer.toQuery(title.eq(new PhraseElement("Hello World")), metadata).toString()); - } - - @Test - public void Equals() { - PhraseElement el1 = new PhraseElement("x"), el2 = new PhraseElement("x"), el3 = new PhraseElement("y"); - assertEquals(el1, el2); - assertFalse(el1.equals(el3)); - } - - @Test - public void HashCode() { - PhraseElement el1 = new PhraseElement("x"), el2 = new PhraseElement("x"); - assertEquals(el1.hashCode(), el2.hashCode()); - } - -} diff --git a/querydsl-lucene4/src/test/java/com/mysema/query/lucene/QDocument.java b/querydsl-lucene4/src/test/java/com/mysema/query/lucene/QDocument.java deleted file mode 100644 index f8583ca853..0000000000 --- a/querydsl-lucene4/src/test/java/com/mysema/query/lucene/QDocument.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.lucene; - -import org.apache.lucene.document.Document; - -import com.mysema.query.types.PathMetadataFactory; -import com.mysema.query.types.path.EntityPathBase; -import com.mysema.query.types.path.NumberPath; -import com.mysema.query.types.path.StringPath; - -public class QDocument extends EntityPathBase<Document> { - - private static final long serialVersionUID = -4872833626508344081L; - - public QDocument(final String var) { - super(Document.class, PathMetadataFactory.forVariable(var)); - } - - public final NumberPath<Integer> year = createNumber("year", Integer.class); - - public final StringPath title = createString("title"); - - public final NumberPath<Double> gross = createNumber("gross", Double.class); - -} \ No newline at end of file diff --git a/querydsl-lucene4/src/test/java/com/mysema/query/lucene/QueryElementTest.java b/querydsl-lucene4/src/test/java/com/mysema/query/lucene/QueryElementTest.java deleted file mode 100644 index c28949bd0f..0000000000 --- a/querydsl-lucene4/src/test/java/com/mysema/query/lucene/QueryElementTest.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.lucene; - -import static org.junit.Assert.assertEquals; - -import org.apache.lucene.index.Term; -import org.apache.lucene.search.TermQuery; -import org.junit.Ignore; -import org.junit.Test; - -public class QueryElementTest { - - @Test - @Ignore - public void test() { - QueryElement element = new QueryElement(new TermQuery(new Term("str","text"))); - assertEquals("str:text",element.toString()); - //assertEquals(element.getQuery().hashCode(), element.hashCode()); - - QueryElement element2 = new QueryElement(new TermQuery(new Term("str","text"))); - assertEquals(element2, element); - } -} diff --git a/querydsl-lucene4/src/test/java/com/mysema/query/lucene/TermElementTest.java b/querydsl-lucene4/src/test/java/com/mysema/query/lucene/TermElementTest.java deleted file mode 100644 index 2020cfad62..0000000000 --- a/querydsl-lucene4/src/test/java/com/mysema/query/lucene/TermElementTest.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.lucene; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; - -import org.junit.Test; - -import com.mysema.query.DefaultQueryMetadata; -import com.mysema.query.QueryMetadata; -import com.mysema.query.types.path.StringPath; - -public class TermElementTest { - - @Test - public void test() { - StringPath title = new StringPath("title"); - LuceneSerializer serializer = new LuceneSerializer(false,true); - QueryMetadata metadata = new DefaultQueryMetadata(); - assertEquals("title:\"Hello World\"", serializer.toQuery(title.eq("Hello World"), metadata).toString()); - assertEquals("title:Hello World", serializer.toQuery(title.eq(new TermElement("Hello World")), metadata).toString()); - } - - @Test - public void testEqualsAndHashCode() { - TermElement el1 = new TermElement("x"), el2 = new TermElement("x"), el3 = new TermElement("y"); - assertEquals(el1, el2); - assertFalse(el1.equals(el3)); - assertEquals(el1.hashCode(), el2.hashCode()); - } - -} diff --git a/querydsl-lucene4/src/test/java/com/querydsl/lucene4/LuceneQueryTest.java b/querydsl-lucene4/src/test/java/com/querydsl/lucene4/LuceneQueryTest.java new file mode 100644 index 0000000000..e1b215bdb3 --- /dev/null +++ b/querydsl-lucene4/src/test/java/com/querydsl/lucene4/LuceneQueryTest.java @@ -0,0 +1,756 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.lucene4; + +import static org.easymock.EasyMock.*; +import static org.junit.Assert.*; + +import java.io.IOException; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; + +import org.apache.lucene.analysis.standard.StandardAnalyzer; +import org.apache.lucene.document.*; +import org.apache.lucene.document.Field.Index; +import org.apache.lucene.document.Field.Store; +import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexWriter; +import org.apache.lucene.index.IndexWriterConfig; +import org.apache.lucene.sandbox.queries.DuplicateFilter; +import org.apache.lucene.search.Filter; +import org.apache.lucene.search.IndexSearcher; +import org.apache.lucene.search.Sort; +import org.apache.lucene.store.RAMDirectory; +import org.apache.lucene.util.Version; +import org.junit.After; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; + +import com.querydsl.core.NonUniqueResultException; +import com.querydsl.core.QueryException; +import com.querydsl.core.QueryModifiers; +import com.querydsl.core.QueryResults; +import com.querydsl.core.types.ParamNotSetException; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.Param; +import com.querydsl.core.types.dsl.StringPath; + +/** + * Tests for LuceneQuery + * + * @author vema + * + */ +public class LuceneQueryTest { + + private LuceneQuery query; + private StringPath title; + private NumberPath<Integer> year; + private NumberPath<Double> gross; + + private final StringPath sort = Expressions.stringPath("sort"); + + private RAMDirectory idx; + private IndexWriter writer; + private IndexSearcher searcher; + + private Document createDocument(final String docTitle, + final String docAuthor, final String docText, final int docYear, + final double docGross) { + final Document doc = new Document(); + + doc.add(new TextField("title", docTitle, Store.YES)); + doc.add(new TextField("author", docAuthor, Store.YES)); + doc.add(new TextField("text", docText, Store.YES)); + doc.add(new IntField("year", docYear, Store.YES)); + doc.add(new DoubleField("gross", docGross, Store.YES)); + + return doc; + } + + @Before + public void setUp() throws Exception { + final QDocument entityPath = new QDocument("doc"); + title = entityPath.title; + year = entityPath.year; + gross = entityPath.gross; + + + idx = new RAMDirectory(); + writer = createWriter(idx); + + writer.addDocument(createDocument("Jurassic Park", "Michael Crichton", + "It's a UNIX system! I know this!", 1990, 90.00)); + writer.addDocument(createDocument("Nummisuutarit", "Aleksis Kivi", + "ESKO. Ja iloitset ja riemuitset?", 1864, 10.00)); + writer + .addDocument(createDocument( + "The Lord of the Rings", + "John R. R. Tolkien", + "One Ring to rule them all, One Ring to find them, One Ring to bring them all and in the darkness bind them", + 1954, 89.00)); + writer + .addDocument(createDocument( + "Introduction to Algorithms", + "Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein", + "Bubble sort", 1990, 30.50)); + + writer.close(); + + IndexReader reader = IndexReader.open(idx); + searcher = new IndexSearcher(reader); + query = new LuceneQuery(new LuceneSerializer(true, true), searcher); + } + + private IndexWriter createWriter(RAMDirectory idx) throws Exception { + IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_31, + new StandardAnalyzer(Version.LUCENE_42)) + .setOpenMode(IndexWriterConfig.OpenMode.CREATE); + return new IndexWriter(idx, config); + } + + @After + public void tearDown() throws Exception { + searcher.getIndexReader().close(); + } + + @Test + public void between() { + assertEquals(3, query.where(year.between(1950, 1990)).fetchCount()); + } + + @Test + public void count_empty_where_clause() { + assertEquals(4, query.fetchCount()); + } + + @Test + public void exists() { + assertTrue(query.where(title.eq("Jurassic Park")).fetchCount() > 0); + assertFalse(query.where(title.eq("Jurassic Park X")).fetchCount() > 0); + } + + @Test + public void notExists() { + assertFalse(query.where(title.eq("Jurassic Park")).fetchCount() == 0); + assertTrue(query.where(title.eq("Jurassic Park X")).fetchCount() == 0); + } + + @Test + public void count() { + query.where(title.eq("Jurassic Park")); + assertEquals(1, query.fetchCount()); + } + + @Test(expected = QueryException.class) + @Ignore + public void count_index_problem() throws IOException { + searcher = createMockBuilder(IndexSearcher.class).addMockedMethod( + "maxDoc").createMock(); + query = new LuceneQuery(new LuceneSerializer(true, true), searcher); + expect(searcher.getIndexReader().maxDoc()).andThrow(new IllegalArgumentException()); + replay(searcher); + query.where(title.eq("Jurassic Park")); + query.fetchCount(); + verify(searcher); + } + + @Test(expected = UnsupportedOperationException.class) + public void countDistinct() { + query.where(year.between(1900, 3000)); + assertEquals(3, query.distinct().fetchCount()); + } + + @Test + public void in() { + assertEquals(2, query.where(title.in("Jurassic Park", "Nummisuutarit")).fetchCount()); + } + + @Test + public void in2() { + assertEquals(3, query.where(year.in(1990, 1864)).fetchCount()); + } + + @Test + public void in_toString() { + assertEquals("year:`____F year:`____H", query.where(year.in(1990, 1864)).toString()); + } + + @Test + public void list_sorted_by_year_ascending() { + query.where(year.between(1800, 2000)); + query.orderBy(year.asc()); + final List<Document> documents = query.fetch(); + assertFalse(documents.isEmpty()); + assertEquals(4, documents.size()); + } + + @Test + public void list_not_sorted() { + query.where(year.between(1800, 2000)); + final List<Document> documents = query.fetch(); + assertFalse(documents.isEmpty()); + assertEquals(4, documents.size()); + } + + @Test + @Ignore // FIXME + public void sorted_by_different_locales() throws Exception { + Document d1 = new Document(); + Document d2 = new Document(); + Document d3 = new Document(); + d1.add(new Field("sort", "a\u00c4",Store.YES, Index.NOT_ANALYZED)); + d2.add(new Field("sort", "ab",Store.YES, Index.NOT_ANALYZED)); + d3.add(new Field("sort", "aa",Store.YES, Index.NOT_ANALYZED)); + writer = createWriter(idx); + writer.addDocument(d1); + writer.addDocument(d2); + writer.addDocument(d3); + writer.close(); + + IndexReader reader = IndexReader.open(idx); + searcher = new IndexSearcher(reader); + query = new LuceneQuery(new LuceneSerializer(true, true, Locale.ENGLISH), searcher); + assertEquals(3, query.fetch().size()); + List<Document> results = query.where(sort.startsWith("a")).orderBy(sort.asc()).fetch(); + assertEquals(3, results.size()); + assertEquals("aa", results.get(0).getField("sort").stringValue()); + assertEquals("a\u00c4", results.get(1).getField("sort").stringValue()); + assertEquals("ab", results.get(2).getField("sort").stringValue()); + + query = new LuceneQuery(new LuceneSerializer(true, true, new Locale("fi", "FI")), searcher); + results = query.where(sort.startsWith("a")).orderBy(sort.asc()).fetch(); + assertEquals("aa", results.get(0).getField("sort").stringValue()); + assertEquals("ab", results.get(1).getField("sort").stringValue()); + assertEquals("a\u00c4", results.get(2).getField("sort").stringValue()); + } + + @Test + public void list_not_sorted_limit_2() { + query.where(year.between(1800, 2000)); + query.limit(2); + final List<Document> documents = query.fetch(); + assertFalse(documents.isEmpty()); + assertEquals(2, documents.size()); + } + + @Test + public void list_sorted_by_year_limit_1() { + query.where(year.between(1800, 2000)); + query.limit(1); + query.orderBy(year.asc()); + final List<Document> documents = query.fetch(); + assertFalse(documents.isEmpty()); + assertEquals(1, documents.size()); + } + + @Test + public void list_not_sorted_offset_2() { + query.where(year.between(1800, 2000)); + query.offset(2); + final List<Document> documents = query.fetch(); + assertFalse(documents.isEmpty()); + assertEquals(2, documents.size()); + } + + @Test + public void list_sorted_ascending_by_year_offset_2() { + query.where(year.between(1800, 2000)); + query.offset(2); + query.orderBy(year.asc()); + final List<Document> documents = query.fetch(); + assertFalse(documents.isEmpty()); + assertEquals(2, documents.size()); + assertEquals("1990", documents.get(0).get("year")); + assertEquals("1990", documents.get(1).get("year")); + } + + @Test + public void list_sorted_ascending_by_year_restrict_limit_2_offset_1() { + query.where(year.between(1800, 2000)); + query.restrict(new QueryModifiers(2L, 1L)); + query.orderBy(year.asc()); + final List<Document> documents = query.fetch(); + assertFalse(documents.isEmpty()); + assertEquals(2, documents.size()); + assertEquals("1954", documents.get(0).get("year")); + assertEquals("1990", documents.get(1).get("year")); + } + + @Test + public void list_sorted_ascending_by_year() { + query.where(year.between(1800, 2000)); + query.orderBy(year.asc()); + final List<Document> documents = query.fetch(); + assertFalse(documents.isEmpty()); + assertEquals(4, documents.size()); + assertEquals("1864", documents.get(0).get("year")); + assertEquals("1954", documents.get(1).get("year")); + assertEquals("1990", documents.get(2).get("year")); + assertEquals("1990", documents.get(3).get("year")); + } + + + @Test + public void list_sort() { + Sort sort = LuceneSerializer.DEFAULT.toSort(Collections.singletonList(year.asc())); + + query.where(year.between(1800, 2000)); + //query.orderBy(year.asc()); + query.sort(sort); + final List<Document> documents = query.fetch(); + assertFalse(documents.isEmpty()); + assertEquals(4, documents.size()); + assertEquals("1864", documents.get(0).get("year")); + assertEquals("1954", documents.get(1).get("year")); + assertEquals("1990", documents.get(2).get("year")); + assertEquals("1990", documents.get(3).get("year")); + } + + @Test + public void list_distinct_property() { + assertEquals(4, query.fetch().size()); + assertEquals(3, query.distinct(year).fetch().size()); + } + + @Test + public void list_with_filter() { + Filter filter = new DuplicateFilter("year"); + assertEquals(4, query.fetch().size()); + assertEquals(3, query.filter(filter).fetch().size()); + } + + @Test + public void count_distinct_property() { + assertEquals(4L, query.fetchCount()); + assertEquals(3L, query.distinct(year).fetchCount()); + } + + @Test + public void list_sorted_descending_by_year() { + query.where(year.between(1800, 2000)); + query.orderBy(year.desc()); + final List<Document> documents = query.fetch(); + assertFalse(documents.isEmpty()); + assertEquals(4, documents.size()); + assertEquals("1990", documents.get(0).get("year")); + assertEquals("1990", documents.get(1).get("year")); + assertEquals("1954", documents.get(2).get("year")); + assertEquals("1864", documents.get(3).get("year")); + } + + + @Test + public void list_sorted_descending_by_gross() { + query.where(gross.between(0.0, 1000.00)); + query.orderBy(gross.desc()); + final List<Document> documents = query.fetch(); + assertFalse(documents.isEmpty()); + assertEquals(4, documents.size()); + assertEquals("90.0", documents.get(0).get("gross")); + assertEquals("89.0", documents.get(1).get("gross")); + assertEquals("30.5", documents.get(2).get("gross")); + assertEquals("10.0", documents.get(3).get("gross")); + } + + @Test + public void list_sorted_descending_by_year_and_ascending_by_title() { + query.where(year.between(1800, 2000)); + query.orderBy(year.desc()); + query.orderBy(title.asc()); + final List<Document> documents = query.fetch(); + assertFalse(documents.isEmpty()); + assertEquals(4, documents.size()); + assertEquals("1990", documents.get(0).get("year")); + assertEquals("1990", documents.get(1).get("year")); + assertEquals("Introduction to Algorithms", documents.get(0) + .get("title")); + assertEquals("Jurassic Park", documents.get(1).get("title")); + } + + @Test + public void list_sorted_descending_by_year_and_descending_by_title() { + query.where(year.between(1800, 2000)); + query.orderBy(year.desc()); + query.orderBy(title.desc()); + final List<Document> documents = query.fetch(); + assertFalse(documents.isEmpty()); + assertEquals(4, documents.size()); + assertEquals("1990", documents.get(0).get("year")); + assertEquals("1990", documents.get(1).get("year")); + assertEquals("Jurassic Park", documents.get(0).get("title")); + assertEquals("Introduction to Algorithms", documents.get(1) + .get("title")); + } + + @Ignore + @Test(expected = QueryException.class) + public void list_index_problem_in_max_doc() throws IOException { + searcher = createMockBuilder(IndexSearcher.class).addMockedMethod( + "maxDoc").createMock(); + query = new LuceneQuery(new LuceneSerializer(true, true), searcher); + expect(searcher.getIndexReader().maxDoc()).andThrow(new IOException()); + replay(searcher); + query.where(title.eq("Jurassic Park")); + query.fetch(); + verify(searcher); + } + + @Ignore + @Test(expected = QueryException.class) + public void list_sorted_index_problem_in_max_doc() throws IOException { + searcher = createMockBuilder(IndexSearcher.class).addMockedMethod( + "maxDoc").createMock(); + query = new LuceneQuery(new LuceneSerializer(true, true), searcher); + expect(searcher.getIndexReader().maxDoc()).andThrow(new IOException()); + replay(searcher); + query.where(title.eq("Jurassic Park")); + query.orderBy(title.asc()); + query.fetch(); + verify(searcher); + } + + @Test + public void offset() { + assertTrue(query.where(title.eq("Jurassic Park")).offset(30).fetch() + .isEmpty()); + } + + + @Test + public void load_list() { + Document document = query.where(title.ne("")).load(title).fetch().get(0); + assertNotNull(document.get("title")); + assertNull(document.get("year")); + } + + @Test + public void load_list_fieldSelector() { + Document document = query.where(title.ne("")).load(Collections.singleton("title")).fetch().get(0); + assertNotNull(document.get("title")); + assertNull(document.get("year")); + } + + @Test + public void load_singleResult() { + Document document = query.where(title.ne("")).load(title).fetchFirst(); + assertNotNull(document.get("title")); + assertNull(document.get("year")); + } + + @Test + public void load_singleResult_fieldSelector() { + Document document = query.where(title.ne("")).load(Collections.singleton("title")).fetchFirst(); + assertNotNull(document.get("title")); + assertNull(document.get("year")); + } + + @Test + public void singleResult() { + assertNotNull(query.where(title.ne("")).fetchFirst()); + } + + @Test + public void single_result_takes_limit() { + assertEquals("Jurassic Park", query + .where(title.ne("")) + .limit(1) + .fetchFirst().get("title")); + } + + @Test + public void single_result_considers_limit_and_actual_result_size() { + query.where(title.startsWith("Nummi")); + final Document document = query.limit(3).fetchFirst(); + assertEquals("Nummisuutarit", document.get("title")); + } + + @Test + public void single_result_returns_null_if_nothing_is_in_range() { + query.where(title.startsWith("Nummi")); + assertNull(query.offset(10).fetchFirst()); + } + + @Test + public void single_result_considers_offset() { + assertEquals("Introduction to Algorithms", query.where(title.ne("")).offset(3).fetchFirst().get("title")); + } + + @Test + public void single_result_considers_limit_and_offset() { + assertEquals("The Lord of the Rings", query.where(title.ne("")).limit(1).offset(2).fetchFirst().get("title")); + } + + @Test(expected = NonUniqueResultException.class) + public void uniqueResult_contract() { + query.where(title.ne("")).fetchOne(); + } + + @Test + public void unique_result_takes_limit() { + assertEquals("Jurassic Park", query + .where(title.ne("")) + .limit(1) + .fetchOne().get("title")); + } + + @Test + public void unique_result_considers_limit_and_actual_result_size() { + query.where(title.startsWith("Nummi")); + final Document document = query.limit(3).fetchOne(); + assertEquals("Nummisuutarit", document.get("title")); + } + + @Test + public void unique_result_returns_null_if_nothing_is_in_range() { + query.where(title.startsWith("Nummi")); + assertNull(query.offset(10).fetchOne()); + } + + @Test + public void unique_result_considers_offset() { + assertEquals("Introduction to Algorithms", query.where(title.ne("")).offset(3).fetchOne().get("title")); + } + + @Test + public void unique_result_considers_limit_and_offset() { + assertEquals("The Lord of the Rings", query.where(title.ne("")).limit(1).offset(2).fetchOne().get("title")); + } + + @Test + public void uniqueResult() { + query.where(title.startsWith("Nummi")); + final Document document = query.fetchOne(); + assertEquals("Nummisuutarit", document.get("title")); + } + + @Test + public void uniqueResult_with_param() { + final Param<String> param = new Param<String>(String.class, "title"); + query.set(param, "Nummi"); + query.where(title.startsWith(param)); + final Document document = query.fetchOne(); + assertEquals("Nummisuutarit", document.get("title")); + } + + @Test(expected = ParamNotSetException.class) + public void uniqueResult_param_not_set() { + final Param<String> param = new Param<String>(String.class, "title"); + query.where(title.startsWith(param)); + query.fetchOne(); + } + + @Test(expected = QueryException.class) + public void uniqueResult_finds_more_than_one_result() { + query.where(year.eq(1990)); + query.fetchOne(); + } + + @Test + public void uniqueResult_finds_no_results() { + query.where(year.eq(2200)); + assertNull(query.fetchOne()); + } + + @Test + @Ignore + public void uniqueResult_finds_no_results_because_no_documents_in_index() + throws IOException { + searcher = createMockBuilder(IndexSearcher.class).addMockedMethod( + "maxDoc").createMock(); + query = new LuceneQuery(new LuceneSerializer(true, true), searcher); + expect(searcher.getIndexReader().maxDoc()).andReturn(0); + replay(searcher); + assertNull(query.where(year.eq(3000)).fetchOne()); + verify(searcher); + } + + @Test(expected = QueryException.class) + @Ignore + public void uniqueResult_sorted_index_problem_in_max_doc() + throws IOException { + searcher = createMockBuilder(IndexSearcher.class).addMockedMethod( + "maxDoc").createMock(); + query = new LuceneQuery(new LuceneSerializer(true, true), searcher); + expect(searcher.getIndexReader().maxDoc()).andThrow(new IllegalArgumentException()); + replay(searcher); + query.where(title.eq("Jurassic Park")); + query.fetchOne(); + verify(searcher); + } + + @Test + @Ignore + public void count_returns_0_because_no_documents_in_index() + throws IOException { + searcher = createMockBuilder(IndexSearcher.class).addMockedMethod( + "maxDoc").createMock(); + query = new LuceneQuery(new LuceneSerializer(true, true), searcher); + expect(searcher.getIndexReader().maxDoc()).andReturn(0); + replay(searcher); + assertEquals(0, query.where(year.eq(3000)).fetchCount()); + verify(searcher); + } + + @Test(expected = UnsupportedOperationException.class) + public void listDistinct() { + query.where(year.between(1900, 2000).or(title.startsWith("Jura"))); + query.orderBy(year.asc()); + final List<Document> documents = query.distinct().fetch(); + assertFalse(documents.isEmpty()); + assertEquals(3, documents.size()); + } + + @Test + public void listResults() { + query.where(year.between(1800, 2000)); + query.restrict(new QueryModifiers(2L, 1L)); + query.orderBy(year.asc()); + final QueryResults<Document> results = query.fetchResults(); + assertFalse(results.isEmpty()); + assertEquals("1954", results.getResults().get(0).get("year")); + assertEquals("1990", results.getResults().get(1).get("year")); + assertEquals(2, results.getLimit()); + assertEquals(1, results.getOffset()); + assertEquals(4, results.getTotal()); + } + + @Test(expected = UnsupportedOperationException.class) + public void listDistinctResults() { + query.where(year.between(1800, 2000).or( + title.eq("The Lord of the Rings"))); + query.restrict(new QueryModifiers(1L, 1L)); + query.orderBy(year.asc()); + final QueryResults<Document> results = query.distinct().fetchResults(); + assertFalse(results.isEmpty()); + assertEquals("1954", results.getResults().get(0).get("year")); + assertEquals(1, results.getLimit()); + assertEquals(1, results.getOffset()); + assertEquals(4, results.getTotal()); + } + + @Test + public void list_all() { + final List<Document> results = query.where(title.like("*")).orderBy( + title.asc(), year.desc()).fetch(); + assertEquals(4, results.size()); + } + + @Test(expected = IllegalArgumentException.class) + public void list_sorted_ascending_limit_negative() { + query.where(year.between(1800, 2000)); + query.limit(-1); + query.orderBy(year.asc()); + query.fetch(); + } + + @Test(expected = IllegalArgumentException.class) + public void list_not_sorted_limit_negative() { + query.where(year.between(1800, 2000)); + query.limit(-1); + query.fetch(); + } + + @Test(expected = IllegalArgumentException.class) + public void list_sorted_ascending_limit_0() { + query.where(year.between(1800, 2000)); + query.limit(0); + query.orderBy(year.asc()); + query.fetch(); + } + + @Test(expected = IllegalArgumentException.class) + public void list_not_sorted_limit_0() { + query.where(year.between(1800, 2000)); + query.limit(0); + query.fetch(); + } + + @Test(expected = IllegalArgumentException.class) + public void list_sorted_ascending_offset_negative() { + query.where(year.between(1800, 2000)); + query.offset(-1); + query.orderBy(year.asc()); + query.fetch(); + } + + @Test(expected = IllegalArgumentException.class) + public void list_not_sorted_offset_negative() { + query.where(year.between(1800, 2000)); + query.offset(-1); + query.fetch(); + } + + @Test + public void list_sorted_ascending_offset_0() { + query.where(year.between(1800, 2000)); + query.offset(0); + query.orderBy(year.asc()); + final List<Document> documents = query.fetch(); + assertFalse(documents.isEmpty()); + assertEquals(4, documents.size()); + } + + @Test + public void list_not_sorted_offset_0() { + query.where(year.between(1800, 2000)); + query.offset(0); + final List<Document> documents = query.fetch(); + assertFalse(documents.isEmpty()); + assertEquals(4, documents.size()); + } + + @Test + public void iterate() { + query.where(year.between(1800, 2000)); + final Iterator<Document> iterator = query.iterate(); + int count = 0; + while (iterator.hasNext()) { + iterator.next(); + ++count; + } + assertEquals(4, count); + } + + @Test + public void all_by_excluding_where() { + assertEquals(4, query.fetch().size()); + } + + @Test + public void empty_index_should_return_empty_list() throws Exception { + idx = new RAMDirectory(); + + writer = createWriter(idx); + writer.close(); + IndexReader reader = IndexReader.open(idx); + searcher = new IndexSearcher(reader); + query = new LuceneQuery(new LuceneSerializer(true, true), searcher); + assertTrue(query.fetch().isEmpty()); + } + + @Test(expected = QueryException.class) + public void list_results_throws_an_illegal_argument_exception_when_sum_of_limit_and_offset_is_negative() { + query.limit(1).offset(Integer.MAX_VALUE).fetchResults(); + } + + @Test + public void limit_max_value() { + assertEquals(4, query.limit(Long.MAX_VALUE).fetch().size()); + } +} diff --git a/querydsl-lucene4/src/test/java/com/querydsl/lucene4/LuceneSerializerNotTokenizedTest.java b/querydsl-lucene4/src/test/java/com/querydsl/lucene4/LuceneSerializerNotTokenizedTest.java new file mode 100644 index 0000000000..65c9ef17aa --- /dev/null +++ b/querydsl-lucene4/src/test/java/com/querydsl/lucene4/LuceneSerializerNotTokenizedTest.java @@ -0,0 +1,209 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.lucene4; + +import static com.querydsl.lucene4.QPerson.person; +import static org.junit.Assert.assertEquals; + +import java.util.Arrays; + +import org.apache.lucene.analysis.standard.StandardAnalyzer; +import org.apache.lucene.document.Document; +import org.apache.lucene.document.Field; +import org.apache.lucene.document.Field.Index; +import org.apache.lucene.document.Field.Store; +import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexWriter; +import org.apache.lucene.index.IndexWriterConfig; +import org.apache.lucene.search.IndexSearcher; +import org.apache.lucene.search.Query; +import org.apache.lucene.search.TopDocs; +import org.apache.lucene.store.RAMDirectory; +import org.apache.lucene.util.Version; +import org.joda.time.LocalDate; +import org.junit.Before; +import org.junit.Test; + +import com.querydsl.core.DefaultQueryMetadata; +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.StringPath; + +public class LuceneSerializerNotTokenizedTest { + private RAMDirectory idx; + private IndexWriter writer; + private IndexSearcher searcher; + private LuceneSerializer serializer; + + private final QueryMetadata metadata = new DefaultQueryMetadata(); + + private final Person clooney = new Person("actor_1", "George Clooney", new LocalDate(1961, 4, 6)); + private final Person pitt = new Person("actor_2", "Brad Pitt", new LocalDate(1963, 12, 18)); + + private void testQuery(Expression<?> expr, String expectedQuery, int expectedHits) throws Exception { + Query query = serializer.toQuery(expr, metadata); + TopDocs docs = searcher.search(query, 100); + assertEquals(expectedHits, docs.totalHits); + assertEquals(expectedQuery, query.toString()); + } + + private Document createDocument(Person person) { + Document doc = new Document(); + doc.add(new Field("id", person.getId(), Store.YES, Index.NOT_ANALYZED)); + doc.add(new Field("name", person.getName(), Store.YES, Index.NOT_ANALYZED)); + doc.add(new Field("birthDate", person.getBirthDate().toString(), Store.YES, Index.NOT_ANALYZED)); + return doc; + } + + @Before + public void before() throws Exception { + serializer = new LuceneSerializer(false, false); + idx = new RAMDirectory(); + IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_31, + new StandardAnalyzer(Version.LUCENE_30)) + .setOpenMode(IndexWriterConfig.OpenMode.CREATE); + writer = new IndexWriter(idx, config); + + writer.addDocument(createDocument(clooney)); + writer.addDocument(createDocument(pitt)); + + Document document = new Document(); + for (String movie : Arrays.asList("Interview with the Vampire", + "Up in the Air")) { + document.add(new Field("movie", movie, Store.YES, Index.NOT_ANALYZED)); + } + writer.addDocument(document); + + writer.close(); + + IndexReader reader = IndexReader.open(idx); + searcher = new IndexSearcher(reader); + } + + @Test + public void equals_by_id_matches() throws Exception { + testQuery(person.id.eq("actor_1"), "id:actor_1", 1); + } + + @Test + public void equals_by_id_does_not_match() throws Exception { + testQuery(person.id.eq("actor_8"), "id:actor_8", 0); + } + + @Test + public void equals_by_name_matches() throws Exception { + testQuery(person.name.eq("George Clooney"), "name:George Clooney", 1); + } + + @Test(expected = UnsupportedOperationException.class) + public void equals_by_name_ignoring_case_does_not_match() throws Exception { + testQuery(person.name.equalsIgnoreCase("george clooney"), "name:george clooney", 0); + } + + @Test + public void equals_by_name_does_not_match() throws Exception { + testQuery(person.name.eq("George Looney"), "name:George Looney", 0); + } + + @Test + public void starts_with_name_should_match() throws Exception { + testQuery(person.name.startsWith("George C"), "name:George C*", 1); + } + + @Test + public void starts_with_name_should_not_match() throws Exception { + testQuery(person.name.startsWith("George L"), "name:George L*", 0); + } + + @Test + public void ends_with_name_should_match() throws Exception { + testQuery(person.name.endsWith("e Clooney"), "name:*e Clooney", 1); + } + + @Test + public void ends_with_name_should_not_match() throws Exception { + testQuery(person.name.endsWith("e Looney"), "name:*e Looney", 0); + } + + @Test + public void contains_name_should_match() throws Exception { + testQuery(person.name.contains("oney"), "name:*oney*", 1); + } + + @Test + public void contains_name_should_not_match() throws Exception { + testQuery(person.name.contains("bloney"), "name:*bloney*", 0); + } + + @Test + public void in_names_should_match_2() throws Exception { + testQuery(person.name.in("Brad Pitt", "George Clooney"), "name:Brad Pitt name:George Clooney", 2); + } + + @Test + public void or_by_name_should_match_2() throws Exception { + testQuery(person.name.eq("Brad Pitt") + .or(person.name.eq("George Clooney")), "name:Brad Pitt name:George Clooney", 2); + } + + @Test + public void equals_by_birth_date() throws Exception { + testQuery(person.birthDate.eq(clooney.getBirthDate()), "birthDate:1961-04-06", 1); + } + + @Test + public void between_phrase() throws Exception { + testQuery(person.name.between("Brad Pitt","George Clooney"), "name:[Brad Pitt TO George Clooney]", 2); + } + + @Test + public void not_equals_finds_the_actors_and_movies() throws Exception { + testQuery(person.name.ne("Michael Douglas"), "-name:Michael Douglas +*:*", 3); + } + + @Test + public void not_equals_finds_only_clooney_and_movies() throws Exception { + testQuery(person.name.ne("Brad Pitt"), "-name:Brad Pitt +*:*", 2); + } + + @Test + public void and_with_two_not_equals_doesnt_find_the_actors() throws Exception { + testQuery(person.name.ne("Brad Pitt") + .and(person.name.ne("George Clooney")), "+(-name:Brad Pitt +*:*) +(-name:George Clooney +*:*)", 1); + } + + @Test + public void or_with_two_not_equals_finds_movies_and_actors() throws Exception { + testQuery(person.name.ne("Brad Pitt") + .or(person.name.ne("George Clooney")), "(-name:Brad Pitt +*:*) (-name:George Clooney +*:*)", 3); + } + + @Test + public void negation_of_equals_finds_movies_and_actors() throws Exception { + testQuery(person.name.eq("Michael Douglas").not(), "-name:Michael Douglas +*:*", 3); + } + + @Test + public void negation_of_equals_finds_pitt_and_movies() throws Exception { + testQuery(person.name.eq("Brad Pitt").not(), "-name:Brad Pitt +*:*", 2); + } + + @Test + public void multiple_field_search_from_movies() throws Exception { + StringPath movie = Expressions.stringPath("movie"); + testQuery(movie.in("Interview with the Vampire"), "movie:Interview with the Vampire", 1); + testQuery(movie.eq("Up in the Air"), "movie:Up in the Air", 1); + } +} diff --git a/querydsl-lucene4/src/test/java/com/querydsl/lucene4/LuceneSerializerTest.java b/querydsl-lucene4/src/test/java/com/querydsl/lucene4/LuceneSerializerTest.java new file mode 100644 index 0000000000..9ff1653d8d --- /dev/null +++ b/querydsl-lucene4/src/test/java/com/querydsl/lucene4/LuceneSerializerTest.java @@ -0,0 +1,674 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.lucene4; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import java.io.StringReader; +import java.util.Arrays; +import java.util.Collections; +import java.util.EnumSet; +import java.util.Set; + +import org.apache.lucene.analysis.standard.StandardAnalyzer; +import org.apache.lucene.document.*; +import org.apache.lucene.document.Field.Index; +import org.apache.lucene.document.Field.Store; +import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexWriter; +import org.apache.lucene.index.IndexWriterConfig; +import org.apache.lucene.search.IndexSearcher; +import org.apache.lucene.search.Query; +import org.apache.lucene.search.TopDocs; +import org.apache.lucene.store.RAMDirectory; +import org.apache.lucene.util.Version; +import org.junit.After; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; + +import com.querydsl.core.*; +import com.querydsl.core.types.*; +import com.querydsl.core.types.dsl.*; + +/** + * Tests for LuceneSerializer + * + * @author vema + * + */ +public class LuceneSerializerTest { + private LuceneSerializer serializer; + private PathBuilder<Object> entityPath; + private StringPath title; + private StringPath author; + private StringPath text; + private StringPath rating; + private StringPath publisher; + private NumberPath<Integer> year; + private NumberPath<Double> gross; + private CollectionPath<String, StringPath> titles; + + private NumberPath<Long> longField; + private NumberPath<Short> shortField; + private NumberPath<Byte> byteField; + private NumberPath<Float> floatField; + + private static final String YEAR_PREFIX_CODED = ""; + private static final String GROSS_PREFIX_CODED = ""; + private static final String LONG_PREFIX_CODED = ""; + private static final String SHORT_PREFIX_CODED = ""; + private static final String BYTE_PREFIX_CODED = ""; + private static final String FLOAT_PREFIX_CODED = ""; + + private IndexWriterConfig config; + private RAMDirectory idx; + private IndexWriter writer; + private IndexSearcher searcher; + + private static final Set<? extends Operator> UNSUPPORTED_OPERATORS = Collections.unmodifiableSet(EnumSet.of(Ops.STARTS_WITH_IC, + Ops.EQ_IGNORE_CASE, Ops.ENDS_WITH_IC, Ops.STRING_CONTAINS_IC)); + + private final QueryMetadata metadata = new DefaultQueryMetadata(); + + private Document createDocument() { + Document doc = new Document(); + + doc.add(new Field("title", new StringReader("Jurassic Park"))); + doc.add(new Field("author", new StringReader("Michael Crichton"))); + doc.add(new Field("text", new StringReader("It's a UNIX system! I know this!"))); + doc.add(new Field("rating", new StringReader("Good"))); + doc.add(new Field("publisher", "", Store.YES, Index.ANALYZED)); + doc.add(new IntField("year", 1990, Store.YES)); + doc.add(new DoubleField("gross", 900.0, Store.YES)); + + doc.add(new LongField("longField", 1, Store.YES)); + doc.add(new IntField("shortField", 1, Store.YES)); + doc.add(new IntField("byteField", 1, Store.YES)); + doc.add(new FloatField("floatField", 1, Store.YES)); + + return doc; + } + + @Before + public void setUp() throws Exception { + serializer = new LuceneSerializer(true,true); + entityPath = new PathBuilder<Object>(Object.class, "obj"); + title = entityPath.getString("title"); + author = entityPath.getString("author"); + text = entityPath.getString("text"); + publisher = entityPath.getString("publisher"); + year = entityPath.getNumber("year", Integer.class); + rating = entityPath.getString("rating"); + gross = entityPath.getNumber("gross", Double.class); + titles = entityPath.getCollection("title", String.class, StringPath.class); + + longField = entityPath.getNumber("longField", Long.class); + shortField = entityPath.getNumber("shortField", Short.class); + byteField = entityPath.getNumber("byteField", Byte.class); + floatField = entityPath.getNumber("floatField", Float.class); + + idx = new RAMDirectory(); + config = new IndexWriterConfig(Version.LUCENE_42, + new StandardAnalyzer(Version.LUCENE_42)) + .setOpenMode(IndexWriterConfig.OpenMode.CREATE); + writer = new IndexWriter(idx, config); + + writer.addDocument(createDocument()); + + writer.close(); + + IndexReader reader = IndexReader.open(idx); + searcher = new IndexSearcher(reader); + } + + @After + public void tearDown() throws Exception { + searcher.getIndexReader().close(); + } + + private void testQuery(Expression<?> expr, int expectedHits) throws Exception { + Query query = serializer.toQuery(expr, metadata); + TopDocs docs = searcher.search(query, 100); + assertEquals(expectedHits, docs.totalHits); + } + + private void testQuery(Expression<?> expr, String expectedQuery, int expectedHits) throws Exception { + Query query = serializer.toQuery(expr, metadata); + TopDocs docs = searcher.search(query, 100); + assertEquals(expectedHits, docs.totalHits); + assertEquals(expectedQuery, query.toString()); + } + + @Test + public void queryElement() throws Exception { + Query query1 = serializer.toQuery(author.like("Michael"), metadata); + Query query2 = serializer.toQuery(text.like("Text"), metadata); + + BooleanExpression query = Expressions.anyOf( + new QueryElement(query1), + new QueryElement(query2) + ); + testQuery(query, "author:michael text:text", 1); + } + + @Test + public void like() throws Exception { + testQuery(author.like("*ichael*"), "author:*ichael*", 1); + } + + @Test + public void like_custom_wildcard_single_character() throws Exception { + testQuery(author.like("Mi?hael"), "author:mi?hael", 1); + } + + @Test + public void like_custom_wildcard_multiple_character() throws Exception { + testQuery(text.like("*U*X*"), "text:*u*x*", 1); + } + + @Test + public void like_phrase() throws Exception { + testQuery(title.like("*rassic Par*"), "+title:**rassic* +title:*par**", 1); + } + + @Test + public void like_or_like() throws Exception { + testQuery(title.like("House").or(author.like("*ichae*")), "title:house author:*ichae*", 1); + } + + @Test + public void like_and_like() throws Exception { + testQuery(title.like("*assic*").and(rating.like("G?od")), "+title:*assic* +rating:g?od", 1); + } + + @Test + public void eq() throws Exception { + testQuery(rating.eq("good"), "rating:good", 1); + } + + @Test + public void eq_with_deep_path() throws Exception { + StringPath deepPath = entityPath.get("property1", Object.class).getString("property2"); + testQuery(deepPath.eq("good"), "property1.property2:good", 0); + } + + @Test + public void fuzzyLike() throws Exception { + testQuery(LuceneExpressions.fuzzyLike(rating, "Good"), "rating:Good~2", 1); + } + + @Test + public void fuzzyLike_with_similarity() throws Exception { + testQuery(LuceneExpressions.fuzzyLike(rating, "Good", 2), "rating:Good~2", 1); + } + + @Test + public void fuzzyLike_with_similarity_and_prefix() throws Exception { + testQuery(LuceneExpressions.fuzzyLike(rating, "Good", 2, 0), "rating:Good~2", 1); + } + + @Test + @Ignore + public void eq_numeric_integer() throws Exception { + testQuery(year.eq(1990), "year:" + YEAR_PREFIX_CODED, 1); + } + + @Test + @Ignore + public void eq_numeric_double() throws Exception { + testQuery(gross.eq(900.00), "gross:" + GROSS_PREFIX_CODED, 1); + } + + @Test + @Ignore + public void eq_numeric() throws Exception { + testQuery(longField.eq(1L), "longField:" + LONG_PREFIX_CODED, 1); + testQuery(shortField.eq((short) 1), "shortField:" + SHORT_PREFIX_CODED, 1); + testQuery(byteField.eq((byte) 1), "byteField:" + BYTE_PREFIX_CODED, 1); + testQuery(floatField.eq((float) 1.0), "floatField:" + FLOAT_PREFIX_CODED, 1); + } + + @Test + public void equals_ignores_case() throws Exception { + testQuery(title.eq("Jurassic"), "title:jurassic", 1); + } + + @Test(expected = UnsupportedOperationException.class) + public void title_equals_ignore_case_or_year_equals() throws Exception { + testQuery(title.equalsIgnoreCase("House").or(year.eq(1990)), "title:house year:" + YEAR_PREFIX_CODED, 1); + } + + @Test + @Ignore + public void eq_and_eq() throws Exception { + testQuery(title.eq("Jurassic Park").and(year.eq(1990)), "+title:\"jurassic park\" +year:" + YEAR_PREFIX_CODED, 1); + } + + @Test + @Ignore + public void eq_and_eq_and_eq() throws Exception { + testQuery(title.eq("Jurassic Park").and(year.eq(1990)).and(author.eq("Michael Crichton")), "+(+title:\"jurassic park\" +year:" + YEAR_PREFIX_CODED + ") +author:\"michael crichton\"", 1); + } + + @Test(expected = UnsupportedOperationException.class) + public void equals_ignore_case_and_or() throws Exception { + testQuery(title.equalsIgnoreCase("Jurassic Park").and(rating.equalsIgnoreCase("Bad")).or(author.equalsIgnoreCase("Michael Crichton")), "(+title:\"jurassic park\" +rating:bad) author:\"michael crichton\"", 1); + } + + @Test + public void eq_or_eq_and_eq_does_not_find_results() throws Exception { + testQuery(title.eq("jeeves").or(rating.eq("superb")).and(author.eq("michael crichton")), "+(title:jeeves rating:superb) +author:\"michael crichton\"", 0); + } + + @Test + public void eq_phrase() throws Exception { + testQuery(title.eq("Jurassic Park"), "title:\"jurassic park\"", 1); + } + + @Test + @Ignore("Not easily done in Lucene!") + public void publisher_equals_empty_string() throws Exception { + testQuery(publisher.eq(""), "publisher:", 1); + } + + @Test + public void eq_phrase_should_not_find_results_but_luceNe_semantics_differs_from_querydsls() throws Exception { + testQuery(text.eq("UNIX System"), "text:\"unix system\"", 1); + } + + @Test + public void eq_phrase_does_not_find_results_because_word_in_middle() throws Exception { + testQuery(title.eq("Jurassic Amusement Park"), "title:\"jurassic amusement park\"", 0); + } + + @Test + public void like_not_does_not_find_results() throws Exception { + testQuery(title.like("*H*e*").not(), "-title:*h*e* +*:*", 1); + } + + @Test(expected = UnsupportedOperationException.class) + public void title_equals_ignore_case_negation_or_rating_equals_ignore_case() throws Exception { + testQuery(title.equalsIgnoreCase("House").not().or(rating.equalsIgnoreCase("Good")), "-title:house rating:good", 1); + } + + @Test + public void eq_not_does_not_find_results() throws Exception { + testQuery(title.eq("Jurassic Park").not(), "-title:\"jurassic park\" +*:*", 0); + } + + @Test + public void title_equals_not_house() throws Exception { + testQuery(title.eq("house").not(), "-title:house +*:*", 1); + } + + @Test + public void eq_and_eq_not_does_not_find_results_because_second_expression_finds_nothing() throws Exception { + testQuery(rating.eq("superb").and(title.eq("house").not()), "+rating:superb +(-title:house +*:*)", 0); + } + + @Test + public void not_equals_finds_one() throws Exception { + testQuery(title.ne("house"), "-title:house +*:*", 1); + } + + @Test + public void not_equals_finds_none() throws Exception { + testQuery(title.ne("Jurassic Park"), "-title:\"jurassic park\" +*:*", 0); + } + + @Test + public void nothing_found_with_not_equals_or_equals() throws Exception { + testQuery(title.ne("jurassic park").or(rating.eq("lousy")), "(-title:\"jurassic park\" +*:*) rating:lousy", 0); + } + + @Test + public void ne_and_eq() throws Exception { + testQuery(title.ne("house").and(rating.eq("good")), "+(-title:house +*:*) +rating:good", 1); + } + + @Test + public void startsWith() throws Exception { + testQuery(title.startsWith("Jurassi"), "title:jurassi*", 1); + } + + @Test + public void startsWith_phrase() throws Exception { + testQuery(title.startsWith("jurassic par"), "+title:jurassic* +title:*par*", 1); + } + + @Test(expected = UnsupportedOperationException.class) + public void starts_with_ignore_case_phrase_does_not_find_results() throws Exception { + testQuery(title.startsWithIgnoreCase("urassic Par"), "+title:urassic* +title:*par*", 0); + } + + @Test + public void endsWith() throws Exception { + testQuery(title.endsWith("ark"), "title:*ark", 1); + } + + @Test(expected = UnsupportedOperationException.class) + public void ends_with_ignore_case_phrase() throws Exception { + testQuery(title.endsWithIgnoreCase("sic Park"), "+title:*sic* +title:*park", 1); + } + + @Test(expected = UnsupportedOperationException.class) + public void ends_with_ignore_case_phrase_does_not_find_results() throws Exception { + testQuery(title.endsWithIgnoreCase("sic Par"), "+title:*sic* +title:*par", 0); + } + + @Test + public void contains() throws Exception { + testQuery(title.contains("rassi"), "title:*rassi*", 1); + } + + @Test(expected = UnsupportedOperationException.class) + public void contains_ignore_case_phrase() throws Exception { + testQuery(title.containsIgnoreCase("rassi Pa"), "+title:*rassi* +title:*pa*", 1); + } + + @Test + public void contains_user_inputted_wildcards_dont_work() throws Exception { + testQuery(title.contains("r*i"), "title:*r\\*i*", 0); + } + + @Test + public void between() throws Exception { + testQuery(title.between("Indiana", "Kundun"), "title:[indiana TO kundun]", 1); + } + + @Test + public void between_numeric_integer() throws Exception { + testQuery(year.between(1980, 2000), "year:[1980 TO 2000]", 1); + } + + @Test + public void between_numeric_double() throws Exception { + testQuery(gross.between(10.00, 19030.00), "gross:[10.0 TO 19030.0]", 1); + } + + @Test + public void between_numeric() throws Exception { + testQuery(longField.between(0L,2L), "longField:[0 TO 2]", 1); + testQuery(shortField.between((short) 0,(short) 2), "shortField:[0 TO 2]", 1); + testQuery(byteField.between((byte) 0,(byte) 2), "byteField:[0 TO 2]", 1); + testQuery(floatField.between((float) 0.0,(float) 2.0), "floatField:[0.0 TO 2.0]", 1); + } + + @Test + public void between_is_inclusive_from_start() throws Exception { + testQuery(title.between("Jurassic", "Kundun"), "title:[jurassic TO kundun]", 1); + } + + @Test + public void between_is_inclusive_to_end() throws Exception { + testQuery(title.between("Indiana", "Jurassic"), "title:[indiana TO jurassic]", 1); + } + + @Test + public void between_does_not_find_results() throws Exception { + testQuery(title.between("Indiana", "Jurassib"), "title:[indiana TO jurassib]", 0); + } + + @Test + public void in() throws Exception { + testQuery(title.in(Arrays.asList("jurassic", "park")), "title:jurassic title:park", 1); + testQuery(title.in("jurassic","park"), "title:jurassic title:park", 1); + testQuery(title.eq("jurassic").or(title.eq("park")), "title:jurassic title:park", 1); + } + + @Test + public void lt() throws Exception { + testQuery(rating.lt("Superb"), "rating:{* TO superb}", 1); + } + + @Test + public void lt_numeric_integer() throws Exception { + testQuery(year.lt(1991), "year:{* TO 1991}", 1); + } + + @Test + public void lt_numeric_double() throws Exception { + testQuery(gross.lt(10000.0), "gross:{* TO 10000.0}", 1); + } + + @Test + public void lt_not_in_range_because_equal() throws Exception { + testQuery(rating.lt("Good"), "rating:{* TO good}", 0); + } + + @Test + public void lt_numeric_integer_not_in_range_because_equal() throws Exception { + testQuery(year.lt(1990), "year:{* TO 1990}", 0); + } + + @Test + public void lt_numeric_double_not_in_range_because_equal() throws Exception { + testQuery(gross.lt(900.0), "gross:{* TO 900.0}", 0); + } + + @Test + public void loe() throws Exception { + testQuery(rating.loe("Superb"), "rating:[* TO superb]", 1); + } + + @Test + public void loe_numeric_integer() throws Exception { + testQuery(year.loe(1991), "year:[* TO 1991]", 1); + } + + @Test + public void loe_numeric_double() throws Exception { + testQuery(gross.loe(903.0), "gross:[* TO 903.0]", 1); + } + + @Test + public void loe_equal() throws Exception { + testQuery(rating.loe("Good"), "rating:[* TO good]", 1); + } + + @Test + public void loe_numeric_integer_equal() throws Exception { + testQuery(year.loe(1990), "year:[* TO 1990]", 1); + } + + @Test + public void loe_numeric_double_equal() throws Exception { + testQuery(gross.loe(900.0), "gross:[* TO 900.0]", 1); + } + + @Test + public void loe_not_found() throws Exception { + testQuery(rating.loe("Bad"), "rating:[* TO bad]", 0); + } + + @Test + public void loe_numeric_integer_not_found() throws Exception { + testQuery(year.loe(1989), "year:[* TO 1989]", 0); + } + + @Test + public void loe_numeric_double_not_found() throws Exception { + testQuery(gross.loe(899.9), "gross:[* TO 899.9]", 0); + } + + @Test + public void gt() throws Exception { + testQuery(rating.gt("Bad"), "rating:{bad TO *}", 1); + } + + @Test + public void gt_numeric_integer() throws Exception { + testQuery(year.gt(1989), "year:{1989 TO *}", 1); + } + + @Test + public void gt_numeric_double() throws Exception { + testQuery(gross.gt(100.00), "gross:{100.0 TO *}", 1); + } + + @Test + public void gt_not_in_range_because_equal() throws Exception { + testQuery(rating.gt("Good"), "rating:{good TO *}", 0); + } + + @Test + public void gt_numeric_integer_not_in_range_because_equal() throws Exception { + testQuery(year.gt(1990), "year:{1990 TO *}", 0); + } + + @Test + public void gt_numeric_double_not_in_range_because_equal() throws Exception { + testQuery(gross.gt(900.00), "gross:{900.0 TO *}", 0); + } + + @Test + public void goe() throws Exception { + testQuery(rating.goe("Bad"), "rating:[bad TO *]", 1); + } + + @Test + public void goe_numeric_integer() throws Exception { + testQuery(year.goe(1989), "year:[1989 TO *]", 1); + } + + @Test + public void goe_numeric_double() throws Exception { + testQuery(gross.goe(320.50), "gross:[320.5 TO *]", 1); + } + + @Test + public void goe_equal() throws Exception { + testQuery(rating.goe("Good"), "rating:[good TO *]", 1); + } + + @Test + public void goe_numeric_integer_equal() throws Exception { + testQuery(year.goe(1990), "year:[1990 TO *]", 1); + } + + @Test + public void goe_numeric_double_equal() throws Exception { + testQuery(gross.goe(900.00), "gross:[900.0 TO *]", 1); + } + + @Test + public void goe_not_found() throws Exception { + testQuery(rating.goe("Hood"), "rating:[hood TO *]", 0); + } + + @Test + public void goe_numeric_integer_not_found() throws Exception { + testQuery(year.goe(1991), "year:[1991 TO *]", 0); + } + + @Test + public void goe_numeric_double_not_found() throws Exception { + testQuery(gross.goe(900.10), "gross:[900.1 TO *]", 0); + } + + @Test + public void equals_empty_string() throws Exception { + testQuery(title.eq(""), "title:", 0); + } + + @Test + public void not_equals_empty_string() throws Exception { + testQuery(title.ne(""), "-title: +*:*", 1); + } + + @Test + public void contains_empty_string() throws Exception { + testQuery(title.contains(""), "title:**", 1); + } + + @Test + public void like_empty_string() throws Exception { + testQuery(title.like(""), "title:", 0); + } + + @Test + public void starts_with_empty_string() throws Exception { + testQuery(title.startsWith(""), "title:*", 1); + } + + @Test + public void ends_with_empty_string() throws Exception { + testQuery(title.endsWith(""), "title:*", 1); + } + + @Test + public void between_empty_strings() throws Exception { + testQuery(title.between("", ""), "title:[ TO ]", 0); + } + + @Test + public void booleanBuilder() throws Exception { + testQuery(new BooleanBuilder(gross.goe(900.10)), "gross:[900.1 TO *]", 0); + } + + @Test + @Ignore + public void fuzzy() throws Exception { + fail("Not yet implemented!"); + } + + @Test + @Ignore + public void proximity() throws Exception { + fail("Not yet implemented!"); + } + + @Test + @Ignore + public void boost() throws Exception { + fail("Not yet implemented!"); + } + + @Test + public void pathAny() throws Exception { + testQuery(titles.any().eq("Jurassic"), "title:jurassic", 1); + } + + private boolean unsupportedOperation(Predicate filter) { + return UNSUPPORTED_OPERATORS.contains(((Operation<?>) filter).getOperator()); + } + + @Test + public void various() throws Exception { + MatchingFiltersFactory filters = new MatchingFiltersFactory(QuerydslModule.LUCENE, Target.LUCENE); + for (Predicate filter : filters.string(title, StringConstant.create("jurassic park"))) { + if (unsupportedOperation(filter)) { + continue; + } + testQuery(filter, 1); + } + + for (Predicate filter : filters.string(author, StringConstant.create("michael crichton"))) { + if (unsupportedOperation(filter)) { + continue; + } + testQuery(filter, 1); + } + + for (Predicate filter : filters.string(title, StringConstant.create("1990"))) { + if (unsupportedOperation(filter)) { + continue; + } + testQuery(filter, 0); + } + } + +} diff --git a/querydsl-lucene4/src/test/java/com/querydsl/lucene4/Person.java b/querydsl-lucene4/src/test/java/com/querydsl/lucene4/Person.java new file mode 100644 index 0000000000..51f59edd6e --- /dev/null +++ b/querydsl-lucene4/src/test/java/com/querydsl/lucene4/Person.java @@ -0,0 +1,45 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.lucene4; + +import org.joda.time.LocalDate; + +import com.querydsl.core.annotations.QueryEntity; + +@QueryEntity +public class Person { + private final String id; + private final String name; + private final LocalDate birthDate; + + public Person(String id, String name, LocalDate birthDate) { + this.id = id; + this.name = name; + this.birthDate = birthDate; + } + + public String getId() { + return id; + } + + public LocalDate getBirthDate() { + return birthDate; + } + + public String getName() { + return name; + } +} + + diff --git a/querydsl-lucene4/src/test/java/com/querydsl/lucene4/PhraseElementTest.java b/querydsl-lucene4/src/test/java/com/querydsl/lucene4/PhraseElementTest.java new file mode 100644 index 0000000000..303d4dfb93 --- /dev/null +++ b/querydsl-lucene4/src/test/java/com/querydsl/lucene4/PhraseElementTest.java @@ -0,0 +1,50 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.lucene4; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; + +import org.junit.Test; + +import com.querydsl.core.DefaultQueryMetadata; +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.StringPath; + +public class PhraseElementTest { + + @Test + public void test() { + StringPath title = Expressions.stringPath("title"); + LuceneSerializer serializer = new LuceneSerializer(false,false); + QueryMetadata metadata = new DefaultQueryMetadata(); + assertEquals("title:Hello World", serializer.toQuery(title.eq("Hello World"), metadata).toString()); + assertEquals("title:\"Hello World\"", serializer.toQuery(title.eq(new PhraseElement("Hello World")), metadata).toString()); + } + + @Test + public void equals() { + PhraseElement el1 = new PhraseElement("x"), el2 = new PhraseElement("x"), el3 = new PhraseElement("y"); + assertEquals(el1, el2); + assertFalse(el1.equals(el3)); + } + + @Test + public void hashCode_() { + PhraseElement el1 = new PhraseElement("x"), el2 = new PhraseElement("x"); + assertEquals(el1.hashCode(), el2.hashCode()); + } + +} diff --git a/querydsl-lucene4/src/test/java/com/querydsl/lucene4/QDocument.java b/querydsl-lucene4/src/test/java/com/querydsl/lucene4/QDocument.java new file mode 100644 index 0000000000..8d4d31f5e8 --- /dev/null +++ b/querydsl-lucene4/src/test/java/com/querydsl/lucene4/QDocument.java @@ -0,0 +1,37 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.lucene4; + +import org.apache.lucene.document.Document; + +import com.querydsl.core.types.PathMetadataFactory; +import com.querydsl.core.types.dsl.EntityPathBase; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.StringPath; + +public class QDocument extends EntityPathBase<Document> { + + private static final long serialVersionUID = -4872833626508344081L; + + public QDocument(final String var) { + super(Document.class, PathMetadataFactory.forVariable(var)); + } + + public final NumberPath<Integer> year = createNumber("year", Integer.class); + + public final StringPath title = createString("title"); + + public final NumberPath<Double> gross = createNumber("gross", Double.class); + +} \ No newline at end of file diff --git a/querydsl-lucene4/src/test/java/com/querydsl/lucene4/QueryElementTest.java b/querydsl-lucene4/src/test/java/com/querydsl/lucene4/QueryElementTest.java new file mode 100644 index 0000000000..cf3c3e7b1a --- /dev/null +++ b/querydsl-lucene4/src/test/java/com/querydsl/lucene4/QueryElementTest.java @@ -0,0 +1,35 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.lucene4; + +import static org.junit.Assert.assertEquals; + +import org.apache.lucene.index.Term; +import org.apache.lucene.search.TermQuery; +import org.junit.Ignore; +import org.junit.Test; + +public class QueryElementTest { + + @Test + @Ignore + public void test() { + QueryElement element = new QueryElement(new TermQuery(new Term("str","text"))); + assertEquals("str:text",element.toString()); + //assertEquals(element.getQuery().hashCode(), element.hashCode()); + + QueryElement element2 = new QueryElement(new TermQuery(new Term("str","text"))); + assertEquals(element2, element); + } +} diff --git a/querydsl-lucene4/src/test/java/com/querydsl/lucene4/TermElementTest.java b/querydsl-lucene4/src/test/java/com/querydsl/lucene4/TermElementTest.java new file mode 100644 index 0000000000..0f1d4e1e11 --- /dev/null +++ b/querydsl-lucene4/src/test/java/com/querydsl/lucene4/TermElementTest.java @@ -0,0 +1,45 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.lucene4; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; + +import org.junit.Test; + +import com.querydsl.core.DefaultQueryMetadata; +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.StringPath; + +public class TermElementTest { + + @Test + public void test() { + StringPath title = Expressions.stringPath("title"); + LuceneSerializer serializer = new LuceneSerializer(false,true); + QueryMetadata metadata = new DefaultQueryMetadata(); + assertEquals("title:\"Hello World\"", serializer.toQuery(title.eq("Hello World"), metadata).toString()); + assertEquals("title:Hello World", serializer.toQuery(title.eq(new TermElement("Hello World")), metadata).toString()); + } + + @Test + public void testEqualsAndHashCode() { + TermElement el1 = new TermElement("x"), el2 = new TermElement("x"), el3 = new TermElement("y"); + assertEquals(el1, el2); + assertFalse(el1.equals(el3)); + assertEquals(el1.hashCode(), el2.hashCode()); + } + +} diff --git a/querydsl-lucene4/src/test/resources/log4j.properties.example b/querydsl-lucene4/src/test/resources/log4j.properties.example index 2f9467c280..50eef686c1 100644 --- a/querydsl-lucene4/src/test/resources/log4j.properties.example +++ b/querydsl-lucene4/src/test/resources/log4j.properties.example @@ -1,9 +1,9 @@ -# Configure an appender that logs to console -log4j.rootLogger=info, A1 -log4j.threshold=debug -log4j.appender.A1=org.apache.log4j.ConsoleAppender -log4j.appender.A1.layout=org.apache.log4j.PatternLayout -log4j.appender.A1.layout.ConversionPattern=%d [%t] %-5p %c{1} - %m%n - -# Configuration of logging levels for different packages -log4j.logger.com.mysema.query.lucene=DEBUG +# Configure an appender that logs to console +log4j.rootLogger=info, A1 +log4j.threshold=debug +log4j.appender.A1=org.apache.log4j.ConsoleAppender +log4j.appender.A1.layout=org.apache.log4j.PatternLayout +log4j.appender.A1.layout.ConversionPattern=%d [%t] %-5p %c{1} - %m%n + +# Configuration of logging levels for different packages +log4j.logger.com.querydsl.lucene4=DEBUG diff --git a/querydsl-lucene4/template.mf b/querydsl-lucene4/template.mf deleted file mode 100644 index faad6033e1..0000000000 --- a/querydsl-lucene4/template.mf +++ /dev/null @@ -1,11 +0,0 @@ -Bundle-SymbolicName: com.mysema.querydsl.lucene -Bundle-Name: Querydsl Lucene -Bundle-Vendor: Mysema -Bundle-ManifestVersion: 2 -Import-Template: - com.mysema.commons.lang.*;version="${mysema.lang.version}", - com.mysema.query.*;version="${project.version}", - javax.annotation.*;version="0", - com.google.common.*;version="${guava.version}", - org.apache.lucene.*;version="[4.0.0,5.0.0)", - org.slf4j.*;version="${slf4j.version}" \ No newline at end of file diff --git a/querydsl-lucene5/README.md b/querydsl-lucene5/README.md new file mode 100644 index 0000000000..5420d6690c --- /dev/null +++ b/querydsl-lucene5/README.md @@ -0,0 +1,57 @@ +## Querydsl Lucene 5 + +The Lucene module provides integration with the Lucene 5 indexing library. + +**Maven integration** + + Add the following dependencies to your Maven project : +```XML +<dependency> + <groupId>com.querydsl</groupId> + <artifactId>querydsl-lucene5</artifactId> + <version>${querydsl.version}</version> +</dependency> +``` + +**Creating the query types** + +With fields year and title a manually created query type could look something like this: + +```JAVA +public class QDocument extends EntityPathBase<Document>{ + private static final long serialVersionUID = -4872833626508344081L; + + public QDocument(String var) { + super(Document.class, PathMetadataFactory.forVariable(var)); + } + + public final StringPath year = createString("year"); + + public final StringPath title = createString("title"); +} +``` + +QDocument represents a Lucene document with the fields year and title. + +Code generation is not available for Lucene, since no schema data is available. + +**Querying** + +Querying with Querydsl Lucene is as simple as this: + +```JAVA +QDocument doc = new QDocument("doc"); + +IndexSearcher searcher = new IndexSearcher(index); +LuceneQuery query = new LuceneQuery(true, searcher); +List<Document> documents = query + .where(doc.year.between("1800", "2000").and(doc.title.startsWith("Huckle")) + .fetch(); +``` + +which is transformed into the following Lucene query : +``` ++year:[1800 TO 2000] +title:huckle* +``` + +For more information on the Querydsl Lucene module visit the reference documentation http://www.querydsl.com/static/querydsl/latest/reference/html/ch02s05.html diff --git a/querydsl-lucene5/pom.xml b/querydsl-lucene5/pom.xml new file mode 100644 index 0000000000..a35f1ea0ee --- /dev/null +++ b/querydsl-lucene5/pom.xml @@ -0,0 +1,130 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>com.querydsl</groupId> + <artifactId>querydsl-root</artifactId> + <version>5.1.0</version> + <relativePath>../pom.xml</relativePath> + </parent> + + <groupId>com.querydsl</groupId> + <artifactId>querydsl-lucene5</artifactId> + <name>Querydsl - Lucene 5 support</name> + <description>Lucene support for Querydsl</description> + <url>${project.homepage}</url> + <packaging>jar</packaging> + + <scm> + <connection>${project.checkout}</connection> + <developerConnection>${project.checkout}</developerConnection> + <url>${project.githubpage}</url> + </scm> + + <properties> + <lucene.version>5.1.0</lucene.version> + <osgi.import.package> + org.apache.lucene.*;version="[5.1.0)", + ${osgi.import.package.root} + </osgi.import.package> + </properties> + + <dependencies> + <dependency> + <groupId>org.jetbrains</groupId> + <artifactId>annotations</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.apache.lucene</groupId> + <artifactId>lucene-core</artifactId> + <version>${lucene.version}</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.apache.lucene</groupId> + <artifactId>lucene-analyzers-common</artifactId> + <version>${lucene.version}</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.apache.lucene</groupId> + <artifactId>lucene-queryparser</artifactId> + <version>${lucene.version}</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.apache.lucene</groupId> + <artifactId>lucene-queries</artifactId> + <version>${lucene.version}</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>com.querydsl</groupId> + <artifactId>querydsl-core</artifactId> + <version>${project.version}</version> + </dependency> + + <!-- test --> + <dependency> + <groupId>com.querydsl</groupId> + <artifactId>querydsl-core</artifactId> + <version>${project.version}</version> + <scope>test</scope> + <type>test-jar</type> + </dependency> + + <dependency> + <groupId>joda-time</groupId> + <artifactId>joda-time</artifactId> + <version>${jodatime.version}</version> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>com.querydsl</groupId> + <artifactId>querydsl-apt</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-jar-plugin</artifactId> + <configuration> + <archive> + <manifestEntries> + <Automatic-Module-Name>com.querydsl.lucene5</Automatic-Module-Name> + </manifestEntries> + </archive> + </configuration> + </plugin> + + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + </plugin> + + <plugin> + <groupId>com.mysema.maven</groupId> + <artifactId>apt-maven-plugin</artifactId> + <executions> + <execution> + <goals> + <goal>test-process</goal> + <goal>add-test-sources</goal> + </goals> + <configuration> + <outputDirectory>target/generated-test-sources/java</outputDirectory> + <processor>com.querydsl.apt.QuerydslAnnotationProcessor</processor> + <showWarnings>true</showWarnings> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> +</project> diff --git a/querydsl-lucene5/src/main/java/com/querydsl/lucene5/AbstractLuceneQuery.java b/querydsl-lucene5/src/main/java/com/querydsl/lucene5/AbstractLuceneQuery.java new file mode 100644 index 0000000000..906968ca4e --- /dev/null +++ b/querydsl-lucene5/src/main/java/com/querydsl/lucene5/AbstractLuceneQuery.java @@ -0,0 +1,403 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.lucene5; + +import com.mysema.commons.lang.CloseableIterator; +import com.mysema.commons.lang.EmptyCloseableIterator; +import com.mysema.commons.lang.IteratorAdapter; +import com.querydsl.core.DefaultQueryMetadata; +import com.querydsl.core.Fetchable; +import com.querydsl.core.NonUniqueResultException; +import com.querydsl.core.QueryException; +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.QueryModifiers; +import com.querydsl.core.QueryResults; +import com.querydsl.core.SimpleQuery; +import com.querydsl.core.support.QueryMixin; +import com.querydsl.core.types.OrderSpecifier; +import com.querydsl.core.types.ParamExpression; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.Predicate; +import org.apache.lucene.document.Document; +import org.apache.lucene.sandbox.queries.DuplicateFilter; +import org.apache.lucene.search.BooleanClause.Occur; +import org.apache.lucene.search.BooleanQuery; +import org.apache.lucene.search.Filter; +import org.apache.lucene.search.IndexSearcher; +import org.apache.lucene.search.MatchAllDocsQuery; +import org.apache.lucene.search.Query; +import org.apache.lucene.search.QueryWrapperFilter; +import org.apache.lucene.search.ScoreDoc; +import org.apache.lucene.search.Sort; +import org.apache.lucene.search.TotalHitCountCollector; +import org.jetbrains.annotations.Nullable; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.function.Function; + +/** + * AbstractLuceneQuery is an abstract super class for Lucene query + * implementations + * + * @author tiwe + * + * @param <T> + * projection type + * @param <Q> + * concrete subtype of querydsl + */ +public abstract class AbstractLuceneQuery<T, Q extends AbstractLuceneQuery<T, Q>> + implements SimpleQuery<Q>, Fetchable<T> { + + private static final String JAVA_ISO_CONTROL = "[\\p{Cntrl}&&[^\r\n\t]]"; + + private final QueryMixin<Q> queryMixin; + + private final IndexSearcher searcher; + + private final LuceneSerializer serializer; + + private final Function<Document, T> transformer; + + @Nullable + private Set<String> fieldsToLoad; + + private List<Filter> filters = Collections.emptyList(); + + @Nullable + private Filter filter; + + @Nullable + private Sort querySort; + + @SuppressWarnings("unchecked") + public AbstractLuceneQuery(LuceneSerializer serializer, + IndexSearcher searcher, Function<Document, T> transformer) { + queryMixin = new QueryMixin<Q>((Q) this, new DefaultQueryMetadata()); + this.serializer = serializer; + this.searcher = searcher; + this.transformer = transformer; + } + + public AbstractLuceneQuery(IndexSearcher searcher, + Function<Document, T> transformer) { + this(LuceneSerializer.DEFAULT, searcher, transformer); + } + + private long innerCount() { + try { + final int maxDoc = searcher.getIndexReader().maxDoc(); + if (maxDoc == 0) { + return 0; + } + TotalHitCountCollector collector = new TotalHitCountCollector(); + searcher.search(createQuery(), getFilter(), collector); + return collector.getTotalHits(); + } catch (IOException | IllegalArgumentException e) { + throw new QueryException(e); + } + } + + @Override + public long fetchCount() { + return innerCount(); + } + + protected Query createQuery() { + Query returnedQuery = null; + Query originalQuery = null; + if (queryMixin.getMetadata().getWhere() == null) { + originalQuery = new MatchAllDocsQuery(); + } else { + originalQuery = serializer.toQuery(queryMixin.getMetadata() + .getWhere(), queryMixin.getMetadata()); + } + Filter filter = getFilter(); + if (filter != null) { + BooleanQuery booleanQuery = new BooleanQuery(); + booleanQuery.add(originalQuery, Occur.MUST); + booleanQuery.add(filter, Occur.FILTER); + returnedQuery = booleanQuery; + } else { + returnedQuery = originalQuery; + } + + return returnedQuery; + } + + /** + * Create a filter for constraints defined in this querydsl + * + * @return filter + */ + public Filter asFilter() { + return new QueryWrapperFilter(createQuery()); + } + + @Override + public Q distinct() { + throw new UnsupportedOperationException("use distinct(path) instead"); + } + + /** + * Add a DuplicateFilter for the field of the given property path + * + * @param property + * distinct property + * @return the current object + */ + public Q distinct(Path<?> property) { + return filter(new DuplicateFilter(serializer.toField(property))); + } + + /** + * Apply the given Lucene filter to the search results + * + * @param filter + * filter + * @return the current object + */ + @SuppressWarnings("unchecked") + public Q filter(Filter filter) { + if (filters.isEmpty()) { + this.filter = filter; + filters = Collections.singletonList(filter); + } else { + this.filter = null; + if (filters.size() == 1) { + filters = new ArrayList<Filter>(); + } + filters.add(filter); + } + return (Q) this; + } + + private Filter getFilter() { + if (filter == null && !filters.isEmpty()) { + BooleanQuery filterQuery = new BooleanQuery(); + for (Filter filter : filters) { + filterQuery.add(filter, Occur.SHOULD); + } + filter = new QueryWrapperFilter(filterQuery); + } + return filter; + } + + @Override + public Q limit(long limit) { + return queryMixin.limit(limit); + } + + @Override + public CloseableIterator<T> iterate() { + final QueryMetadata metadata = queryMixin.getMetadata(); + final List<OrderSpecifier<?>> orderBys = metadata.getOrderBy(); + final Integer queryLimit = metadata.getModifiers().getLimitAsInteger(); + final Integer queryOffset = metadata.getModifiers() + .getOffsetAsInteger(); + Sort sort = querySort; + int limit; + final int offset = queryOffset != null ? queryOffset : 0; + try { + limit = maxDoc(); + if (limit == 0) { + return new EmptyCloseableIterator<T>(); + } + } catch (IOException | IllegalArgumentException e) { + throw new QueryException(e); + } + if (queryLimit != null && queryLimit < limit) { + limit = queryLimit; + } + if (sort == null && !orderBys.isEmpty()) { + sort = serializer.toSort(orderBys); + } + + try { + ScoreDoc[] scoreDocs; + int sumOfLimitAndOffset = limit + offset; + if (sumOfLimitAndOffset < 1) { + throw new QueryException("The given limit (" + limit + + ") and offset (" + offset + + ") cause an integer overflow."); + } + if (sort != null) { + scoreDocs = searcher.search(createQuery(), + // sumOfLimitAndOffset).scoreDocs; + sumOfLimitAndOffset, sort, false, false).scoreDocs; + } else { + scoreDocs = searcher.search(createQuery(), + sumOfLimitAndOffset, Sort.INDEXORDER, false, false).scoreDocs; + } + if (offset < scoreDocs.length) { + return new ResultIterator<T>(scoreDocs, offset, searcher, + fieldsToLoad, transformer); + } + return new EmptyCloseableIterator<T>(); + } catch (final IOException e) { + throw new QueryException(e); + } + } + + private List<T> innerList() { + return new IteratorAdapter<T>(iterate()).asList(); + } + + @Override + public List<T> fetch() { + return innerList(); + } + + /** + * Set the given fields to load + * + * @param fieldsToLoad + * fields to load + * @return the current object + */ + @SuppressWarnings("unchecked") + public Q load(Set<String> fieldsToLoad) { + this.fieldsToLoad = fieldsToLoad; + return (Q) this; + } + + /** + * Load only the fields of the given paths + * + * @param paths + * fields to load + * @return the current object + */ + @SuppressWarnings("unchecked") + public Q load(Path<?>... paths) { + Set<String> fields = new HashSet<String>(); + for (Path<?> path : paths) { + fields.add(serializer.toField(path)); + } + this.fieldsToLoad = fields; + return (Q) this; + } + + @Override + public QueryResults<T> fetchResults() { + List<T> documents = innerList(); + /* + * TODO Get rid of fetchCount(). It could be implemented by iterating + * the fetch results in fetch* from n to m. + */ + return new QueryResults<T>(documents, queryMixin.getMetadata() + .getModifiers(), innerCount()); + } + + @Override + public Q offset(long offset) { + return queryMixin.offset(offset); + } + + public Q orderBy(OrderSpecifier<?> o) { + return queryMixin.orderBy(o); + } + + @Override + public Q orderBy(OrderSpecifier<?>... o) { + return queryMixin.orderBy(o); + } + + @Override + public Q restrict(QueryModifiers modifiers) { + return queryMixin.restrict(modifiers); + } + + @Override + public <P> Q set(ParamExpression<P> param, P value) { + return queryMixin.set(param, value); + } + + @SuppressWarnings("unchecked") + public Q sort(Sort sort) { + this.querySort = sort; + return (Q) this; + } + + @Nullable + private T oneResult(boolean unique) { + try { + int maxDoc = maxDoc(); + if (maxDoc == 0) { + return null; + } + final ScoreDoc[] scoreDocs = searcher.search(createQuery(), + maxDoc, Sort.INDEXORDER, false, false).scoreDocs; + int index = 0; + QueryModifiers modifiers = queryMixin.getMetadata().getModifiers(); + Long offset = modifiers.getOffset(); + if (offset != null) { + index = offset.intValue(); + } + Long limit = modifiers.getLimit(); + if (unique + && (limit == null ? scoreDocs.length - index > 1 + : limit > 1 && scoreDocs.length > 1)) { + throw new NonUniqueResultException( + "Unique result requested, but " + scoreDocs.length + + " found."); + } else if (scoreDocs.length > index) { + Document document; + if (fieldsToLoad != null) { + document = searcher.doc(scoreDocs[index].doc, fieldsToLoad); + } else { + document = searcher.doc(scoreDocs[index].doc); + } + return transformer.apply(document); + } else { + return null; + } + } catch (IOException | IllegalArgumentException e) { + throw new QueryException(e); + } + } + + @Override + public T fetchFirst() { + return oneResult(false); + } + + @Override + public T fetchOne() throws NonUniqueResultException { + return oneResult(true); + } + + public Q where(Predicate e) { + return queryMixin.where(e); + } + + @Override + public Q where(Predicate... e) { + return queryMixin.where(e); + } + + @Override + public String toString() { + return createQuery().toString().replaceAll(JAVA_ISO_CONTROL, "_"); + } + + private int maxDoc() throws IOException { + return searcher.getIndexReader().maxDoc(); + } +} diff --git a/querydsl-lucene5/src/main/java/com/querydsl/lucene5/IgnoreCaseUnsupportedException.java b/querydsl-lucene5/src/main/java/com/querydsl/lucene5/IgnoreCaseUnsupportedException.java new file mode 100644 index 0000000000..6f778e02a5 --- /dev/null +++ b/querydsl-lucene5/src/main/java/com/querydsl/lucene5/IgnoreCaseUnsupportedException.java @@ -0,0 +1,31 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.lucene5; + +/** + * Thrown for case ignore usage + * + * @author tiwe + * + */ +public class IgnoreCaseUnsupportedException extends + UnsupportedOperationException { + + private static final long serialVersionUID = 412913389929530788L; + + public IgnoreCaseUnsupportedException() { + super("Ignore case queries are not supported with Lucene"); + } + +} diff --git a/querydsl-lucene5/src/main/java/com/querydsl/lucene5/LuceneExpressions.java b/querydsl-lucene5/src/main/java/com/querydsl/lucene5/LuceneExpressions.java new file mode 100644 index 0000000000..7e3fae4df7 --- /dev/null +++ b/querydsl-lucene5/src/main/java/com/querydsl/lucene5/LuceneExpressions.java @@ -0,0 +1,87 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.lucene5; + +import org.apache.lucene.index.Term; +import org.apache.lucene.search.FuzzyQuery; +import org.apache.lucene.util.automaton.LevenshteinAutomata; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.dsl.BooleanExpression; + +/** + * Utility methods to create filter expressions for Lucene queries that are not + * covered by the Querydsl standard expression model + * + * @author tiwe + * + */ +public final class LuceneExpressions { + + /** + * Create a fuzzy query + * + * @param path + * path + * @param value + * value to match + * @return condition + */ + public static BooleanExpression fuzzyLike(Path<String> path, String value) { + Term term = new Term(path.getMetadata().getName(), value); + return new QueryElement(new FuzzyQuery(term)); + } + + /** + * Create a fuzzy query + * + * @param path + * path + * @param value + * value to match + * @param maxEdits + * must be >= 0 and <= + * {@link LevenshteinAutomata#MAXIMUM_SUPPORTED_DISTANCE}. + * @return condition + */ + public static BooleanExpression fuzzyLike(Path<String> path, String value, + int maxEdits) { + Term term = new Term(path.getMetadata().getName(), value); + return new QueryElement(new FuzzyQuery(term, maxEdits)); + } + + /** + * Create a fuzzy query + * + * @param path + * path + * @param value + * value to match + * @param maxEdits + * must be >= 0 and <= + * {@link LevenshteinAutomata#MAXIMUM_SUPPORTED_DISTANCE}. + * @param prefixLength + * length of common (non-fuzzy) prefix + * @return condition + */ + public static BooleanExpression fuzzyLike(Path<String> path, String value, + int maxEdits, int prefixLength) { + Term term = new Term(path.getMetadata().getName(), value); + return new QueryElement(new FuzzyQuery(term, maxEdits, prefixLength)); + } + + private LuceneExpressions() { + } + +} diff --git a/querydsl-lucene5/src/main/java/com/querydsl/lucene5/LuceneOps.java b/querydsl-lucene5/src/main/java/com/querydsl/lucene5/LuceneOps.java new file mode 100644 index 0000000000..c53f4f4718 --- /dev/null +++ b/querydsl-lucene5/src/main/java/com/querydsl/lucene5/LuceneOps.java @@ -0,0 +1,37 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.lucene5; + +import com.querydsl.core.types.Operator; + +/** + * Lucene specific operators + * + * @author tiwe + * + */ +public enum LuceneOps implements Operator { + LUCENE_QUERY(Object.class), PHRASE(String.class), TERM(String.class); + + private final Class<?> type; + + LuceneOps(Class<?> type) { + this.type = type; + } + + @Override + public Class<?> getType() { + return type; + } +} diff --git a/querydsl-lucene5/src/main/java/com/querydsl/lucene5/LuceneQuery.java b/querydsl-lucene5/src/main/java/com/querydsl/lucene5/LuceneQuery.java new file mode 100644 index 0000000000..dbf9129243 --- /dev/null +++ b/querydsl-lucene5/src/main/java/com/querydsl/lucene5/LuceneQuery.java @@ -0,0 +1,57 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.lucene5; + +import org.apache.lucene.document.Document; +import org.apache.lucene.search.IndexSearcher; + +import java.util.function.Function; + +/** + * {@code LuceneQuery} is a Querydsl query implementation for Lucene queries. + * <p> + * Example: + * </p> + * + * <pre> + * {@code + * QDocument doc = new QDocument("doc"); + * IndexSearcher searcher = new IndexSearcher(index); + * LuceneQuery query = new LuceneQuery(true, searcher); + * List<Document> documents = query + * .where(doc.year.between("1800", "2000").and(doc.title.startsWith("Huckle")) + * .fetch(); + * } + * </pre> + * + * @author vema + */ +public class LuceneQuery extends AbstractLuceneQuery<Document, LuceneQuery> { + + private static final Function<Document, Document> TRANSFORMER = new Function<Document, Document>() { + @Override + public Document apply(Document input) { + return input; + } + }; + + public LuceneQuery(IndexSearcher searcher) { + super(searcher, TRANSFORMER); + } + + public LuceneQuery(LuceneSerializer luceneSerializer, IndexSearcher searcher) { + super(luceneSerializer, searcher, TRANSFORMER); + } + +} diff --git a/querydsl-lucene5/src/main/java/com/querydsl/lucene5/LuceneSerializer.java b/querydsl-lucene5/src/main/java/com/querydsl/lucene5/LuceneSerializer.java new file mode 100644 index 0000000000..433b8bad35 --- /dev/null +++ b/querydsl-lucene5/src/main/java/com/querydsl/lucene5/LuceneSerializer.java @@ -0,0 +1,608 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.lucene5; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; + +import org.jetbrains.annotations.Nullable; + +import org.apache.lucene.index.Term; +import org.apache.lucene.queryparser.classic.QueryParser; +import org.apache.lucene.search.BooleanClause; +import org.apache.lucene.search.BooleanClause.Occur; +import org.apache.lucene.search.BooleanQuery; +import org.apache.lucene.search.MatchAllDocsQuery; +import org.apache.lucene.search.NumericRangeQuery; +import org.apache.lucene.search.PhraseQuery; +import org.apache.lucene.search.PrefixQuery; +import org.apache.lucene.search.Query; +import org.apache.lucene.search.Sort; +import org.apache.lucene.search.SortField; +import org.apache.lucene.search.SortedNumericSortField; +import org.apache.lucene.search.TermQuery; +import org.apache.lucene.search.TermRangeQuery; +import org.apache.lucene.search.WildcardQuery; +import org.apache.lucene.util.BytesRef; +import org.apache.lucene.util.BytesRefBuilder; +import org.apache.lucene.util.NumericUtils; + +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.types.Constant; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.ExpressionUtils; +import com.querydsl.core.types.Operation; +import com.querydsl.core.types.Operator; +import com.querydsl.core.types.Ops; +import com.querydsl.core.types.OrderSpecifier; +import com.querydsl.core.types.ParamExpression; +import com.querydsl.core.types.ParamNotSetException; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.PathType; + +/** + * Serializes Querydsl queries to Lucene queries. + * + * @author vema + * + */ +public class LuceneSerializer { + private static final Map<Class<?>, SortField.Type> sortFields = new HashMap<Class<?>, SortField.Type>(); + + static { + sortFields.put(Integer.class, SortField.Type.INT); + sortFields.put(Float.class, SortField.Type.FLOAT); + sortFields.put(Long.class, SortField.Type.LONG); + sortFields.put(Double.class, SortField.Type.DOUBLE); + sortFields.put(BigDecimal.class, SortField.Type.DOUBLE); + sortFields.put(BigInteger.class, SortField.Type.LONG); + } + + public static final LuceneSerializer DEFAULT = new LuceneSerializer(false, + true); + + private final boolean lowerCase; + + private final boolean splitTerms; + + private final Locale sortLocale; + + public LuceneSerializer(boolean lowerCase, boolean splitTerms) { + this(lowerCase, splitTerms, Locale.getDefault()); + } + + public LuceneSerializer(boolean lowerCase, boolean splitTerms, + Locale sortLocale) { + this.lowerCase = lowerCase; + this.splitTerms = splitTerms; + this.sortLocale = sortLocale; + } + + private Query toQuery(Operation<?> operation, QueryMetadata metadata) { + Operator op = operation.getOperator(); + if (op == Ops.OR) { + return toTwoHandSidedQuery(operation, Occur.SHOULD, metadata); + } else if (op == Ops.AND) { + return toTwoHandSidedQuery(operation, Occur.MUST, metadata); + } else if (op == Ops.NOT) { + BooleanQuery bq = new BooleanQuery(); + bq.add(new BooleanClause(toQuery(operation.getArg(0), metadata), + Occur.MUST_NOT)); + bq.add(new BooleanClause(new MatchAllDocsQuery(), Occur.MUST)); + return bq; + } else if (op == Ops.LIKE) { + return like(operation, metadata); + } else if (op == Ops.LIKE_IC) { + throw new IgnoreCaseUnsupportedException(); + } else if (op == Ops.EQ) { + return eq(operation, metadata, false); + } else if (op == Ops.EQ_IGNORE_CASE) { + throw new IgnoreCaseUnsupportedException(); + } else if (op == Ops.NE) { + return ne(operation, metadata, false); + } else if (op == Ops.STARTS_WITH) { + return startsWith(metadata, operation, false); + } else if (op == Ops.STARTS_WITH_IC) { + throw new IgnoreCaseUnsupportedException(); + } else if (op == Ops.ENDS_WITH) { + return endsWith(operation, metadata, false); + } else if (op == Ops.ENDS_WITH_IC) { + throw new IgnoreCaseUnsupportedException(); + } else if (op == Ops.STRING_CONTAINS) { + return stringContains(operation, metadata, false); + } else if (op == Ops.STRING_CONTAINS_IC) { + throw new IgnoreCaseUnsupportedException(); + } else if (op == Ops.BETWEEN) { + return between(operation, metadata); + } else if (op == Ops.IN) { + return in(operation, metadata, false); + } else if (op == Ops.NOT_IN) { + return notIn(operation, metadata, false); + } else if (op == Ops.LT) { + return lt(operation, metadata); + } else if (op == Ops.GT) { + return gt(operation, metadata); + } else if (op == Ops.LOE) { + return le(operation, metadata); + } else if (op == Ops.GOE) { + return ge(operation, metadata); + } else if (op == LuceneOps.LUCENE_QUERY) { + @SuppressWarnings("unchecked") + // this is the expected type + Constant<Query> expectedConstant = (Constant<Query>) operation + .getArg(0); + return expectedConstant.getConstant(); + } + throw new UnsupportedOperationException("Illegal operation " + + operation); + } + + private Query toTwoHandSidedQuery(Operation<?> operation, Occur occur, + QueryMetadata metadata) { + Query lhs = toQuery(operation.getArg(0), metadata); + Query rhs = toQuery(operation.getArg(1), metadata); + BooleanQuery bq = new BooleanQuery(); + bq.add(createBooleanClause(lhs, occur)); + bq.add(createBooleanClause(rhs, occur)); + return bq; + } + + /** + * If the query is a BooleanQuery and it contains a single Occur.MUST_NOT + * clause it will be returned as is. Otherwise it will be wrapped in a + * BooleanClause with the given Occur. + */ + private BooleanClause createBooleanClause(Query query, Occur occur) { + if (query instanceof BooleanQuery) { + BooleanClause[] clauses = ((BooleanQuery) query).getClauses(); + if (clauses.length == 1 + && clauses[0].getOccur().equals(Occur.MUST_NOT)) { + return clauses[0]; + } + } + return new BooleanClause(query, occur); + } + + protected Query like(Operation<?> operation, QueryMetadata metadata) { + verifyArguments(operation); + Path<?> path = getPath(operation.getArg(0)); + String field = toField(path); + String[] terms = convert(path, operation.getArg(1)); + if (terms.length > 1) { + BooleanQuery bq = new BooleanQuery(); + for (String s : terms) { + bq.add(new WildcardQuery(new Term(field, "*" + s + "*")), + Occur.MUST); + } + return bq; + } + return new WildcardQuery(new Term(field, terms[0])); + } + + protected Query eq(Operation<?> operation, QueryMetadata metadata, + boolean ignoreCase) { + verifyArguments(operation); + Path<?> path = getPath(operation.getArg(0)); + String field = toField(path); + + if (Number.class.isAssignableFrom(operation.getArg(1).getType())) { + @SuppressWarnings("unchecked") + // guarded by previous check + Constant<? extends Number> rightArg = (Constant<? extends Number>) operation + .getArg(1); + return new TermQuery(new Term(field, + convertNumber(rightArg.getConstant()))); + } + + return eq(field, convert(path, operation.getArg(1), metadata), + ignoreCase); + } + + private BytesRef convertNumber(Number number) { + if (Integer.class.isInstance(number) || Byte.class.isInstance(number) + || Short.class.isInstance(number)) { + BytesRefBuilder ref = new BytesRefBuilder(); + NumericUtils.intToPrefixCoded(number.intValue(), 0, ref); + return ref.get(); + } else if (Double.class.isInstance(number) + || BigDecimal.class.isInstance(number)) { + BytesRefBuilder ref = new BytesRefBuilder(); + long l = NumericUtils.doubleToSortableLong(number.doubleValue()); + NumericUtils.longToPrefixCoded(l, 0, ref); + return ref.get(); + } else if (Long.class.isInstance(number) + || BigInteger.class.isInstance(number)) { + BytesRefBuilder ref = new BytesRefBuilder(); + NumericUtils.longToPrefixCoded(number.longValue(), 0, ref); + return ref.get(); + } else if (Float.class.isInstance(number)) { + BytesRefBuilder ref = new BytesRefBuilder(); + int i = NumericUtils.floatToSortableInt(number.floatValue()); + NumericUtils.intToPrefixCoded(i, 0, ref); + return ref.get(); + } else { + throw new IllegalArgumentException("Unsupported numeric type " + + number.getClass().getName()); + } + } + + protected Query eq(String field, String[] terms, boolean ignoreCase) { + if (terms.length > 1) { + PhraseQuery pq = new PhraseQuery(); + for (String s : terms) { + pq.add(new Term(field, s)); + } + return pq; + } + return new TermQuery(new Term(field, terms[0])); + } + + protected Query in(Operation<?> operation, QueryMetadata metadata, + boolean ignoreCase) { + Path<?> path = getPath(operation.getArg(0)); + String field = toField(path); + @SuppressWarnings("unchecked") + // this is the expected type + Constant<Collection<?>> expectedConstant = (Constant<Collection<?>>) operation + .getArg(1); + Collection<?> values = expectedConstant.getConstant(); + BooleanQuery bq = new BooleanQuery(); + if (Number.class.isAssignableFrom(path.getType())) { + for (Object value : values) { + TermQuery eq = new TermQuery(new Term(field, convertNumber((Number) value))); + bq.add(eq, Occur.SHOULD); + } + } else { + for (Object value : values) { + String[] str = convert(path, value); + bq.add(eq(field, str, ignoreCase), Occur.SHOULD); + } + } + return bq; + } + + protected Query notIn(Operation<?> operation, QueryMetadata metadata, + boolean ignoreCase) { + BooleanQuery bq = new BooleanQuery(); + bq.add(new BooleanClause(in(operation, metadata, false), Occur.MUST_NOT)); + bq.add(new BooleanClause(new MatchAllDocsQuery(), Occur.MUST)); + return bq; + } + + protected Query ne(Operation<?> operation, QueryMetadata metadata, + boolean ignoreCase) { + BooleanQuery bq = new BooleanQuery(); + bq.add(new BooleanClause(eq(operation, metadata, ignoreCase), + Occur.MUST_NOT)); + bq.add(new BooleanClause(new MatchAllDocsQuery(), Occur.MUST)); + return bq; + } + + protected Query startsWith(QueryMetadata metadata, Operation<?> operation, + boolean ignoreCase) { + verifyArguments(operation); + Path<?> path = getPath(operation.getArg(0)); + String field = toField(path); + String[] terms = convertEscaped(path, operation.getArg(1), metadata); + if (terms.length > 1) { + BooleanQuery bq = new BooleanQuery(); + for (int i = 0; i < terms.length; ++i) { + String s = i == 0 ? terms[i] + "*" : "*" + terms[i] + "*"; + bq.add(new WildcardQuery(new Term(field, s)), Occur.MUST); + } + return bq; + } + return new PrefixQuery(new Term(field, terms[0])); + } + + protected Query stringContains(Operation<?> operation, + QueryMetadata metadata, boolean ignoreCase) { + verifyArguments(operation); + Path<?> path = getPath(operation.getArg(0)); + String field = toField(path); + String[] terms = convertEscaped(path, operation.getArg(1), metadata); + if (terms.length > 1) { + BooleanQuery bq = new BooleanQuery(); + for (String s : terms) { + bq.add(new WildcardQuery(new Term(field, "*" + s + "*")), + Occur.MUST); + } + return bq; + } + return new WildcardQuery(new Term(field, "*" + terms[0] + "*")); + } + + protected Query endsWith(Operation<?> operation, QueryMetadata metadata, + boolean ignoreCase) { + verifyArguments(operation); + Path<?> path = getPath(operation.getArg(0)); + String field = toField(path); + String[] terms = convertEscaped(path, operation.getArg(1), metadata); + if (terms.length > 1) { + BooleanQuery bq = new BooleanQuery(); + for (int i = 0; i < terms.length; ++i) { + String s = i == terms.length - 1 ? "*" + terms[i] : "*" + + terms[i] + "*"; + bq.add(new WildcardQuery(new Term(field, s)), Occur.MUST); + } + return bq; + } + return new WildcardQuery(new Term(field, "*" + terms[0])); + } + + protected Query between(Operation<?> operation, QueryMetadata metadata) { + verifyArguments(operation); + Path<?> path = getPath(operation.getArg(0)); + // TODO Phrase not properly supported + return range(path, toField(path), operation.getArg(1), + operation.getArg(2), true, true, metadata); + } + + protected Query lt(Operation<?> operation, QueryMetadata metadata) { + verifyArguments(operation); + Path<?> path = getPath(operation.getArg(0)); + return range(path, toField(path), null, operation.getArg(1), false, + false, metadata); + } + + protected Query gt(Operation<?> operation, QueryMetadata metadata) { + verifyArguments(operation); + Path<?> path = getPath(operation.getArg(0)); + return range(path, toField(path), operation.getArg(1), null, false, + false, metadata); + } + + protected Query le(Operation<?> operation, QueryMetadata metadata) { + verifyArguments(operation); + Path<?> path = getPath(operation.getArg(0)); + return range(path, toField(path), null, operation.getArg(1), true, + true, metadata); + } + + protected Query ge(Operation<?> operation, QueryMetadata metadata) { + verifyArguments(operation); + Path<?> path = getPath(operation.getArg(0)); + return range(path, toField(path), operation.getArg(1), null, true, + true, metadata); + } + + protected Query range(Path<?> leftHandSide, String field, + @Nullable Expression<?> min, @Nullable Expression<?> max, + boolean minInc, boolean maxInc, QueryMetadata metadata) { + if (min != null && Number.class.isAssignableFrom(min.getType()) + || max != null && Number.class.isAssignableFrom(max.getType())) { + @SuppressWarnings("unchecked") + // guarded by previous check + Constant<? extends Number> minConstant = (Constant<? extends Number>) min; + @SuppressWarnings("unchecked") + // guarded by previous check + Constant<? extends Number> maxConstant = (Constant<? extends Number>) max; + + Class<? extends Number> numType = minConstant != null ? minConstant + .getType() : maxConstant.getType(); + // this is not necessarily safe, but compile time checking + // on the user side mandates these types to be interchangeable + @SuppressWarnings("unchecked") + Class<Number> unboundedNumType = (Class<Number>) numType; + return numericRange(unboundedNumType, field, + minConstant == null ? null : minConstant.getConstant(), + maxConstant == null ? null : maxConstant.getConstant(), + minInc, maxInc); + } + return stringRange(leftHandSide, field, min, max, minInc, maxInc, + metadata); + } + + protected <N extends Number> NumericRangeQuery<?> numericRange( + Class<N> clazz, String field, @Nullable N min, @Nullable N max, + boolean minInc, boolean maxInc) { + if (clazz.equals(Integer.class)) { + return NumericRangeQuery.newIntRange(field, (Integer) min, + (Integer) max, minInc, maxInc); + } else if (clazz.equals(Double.class)) { + return NumericRangeQuery.newDoubleRange(field, (Double) min, + (Double) max, minInc, minInc); + } else if (clazz.equals(Float.class)) { + return NumericRangeQuery.newFloatRange(field, (Float) min, + (Float) max, minInc, minInc); + } else if (clazz.equals(Long.class)) { + return NumericRangeQuery.newLongRange(field, (Long) min, + (Long) max, minInc, minInc); + } else if (clazz.equals(Byte.class) || clazz.equals(Short.class)) { + return NumericRangeQuery.newIntRange(field, + min != null ? min.intValue() : null, + max != null ? max.intValue() : null, minInc, maxInc); + } else { + throw new IllegalArgumentException("Unsupported numeric type " + + clazz.getName()); + } + } + + protected Query stringRange(Path<?> leftHandSide, String field, + @Nullable Expression<?> min, @Nullable Expression<?> max, + boolean minInc, boolean maxInc, QueryMetadata metadata) { + + if (min == null) { + return TermRangeQuery.newStringRange(field, null, + convert(leftHandSide, max, metadata)[0], minInc, maxInc); + } else if (max == null) { + return TermRangeQuery.newStringRange(field, + convert(leftHandSide, min, metadata)[0], null, minInc, + maxInc); + } else { + return TermRangeQuery.newStringRange(field, + convert(leftHandSide, min, metadata)[0], + convert(leftHandSide, max, metadata)[0], minInc, maxInc); + } + } + + private Path<?> getPath(Expression<?> leftHandSide) { + if (leftHandSide instanceof Path<?>) { + return (Path<?>) leftHandSide; + } else if (leftHandSide instanceof Operation<?>) { + Operation<?> operation = (Operation<?>) leftHandSide; + if (operation.getOperator() == Ops.LOWER + || operation.getOperator() == Ops.UPPER) { + return (Path<?>) operation.getArg(0); + } + } + throw new IllegalArgumentException("Unable to transform " + + leftHandSide + " to path"); + } + + /** + * template method, override to customize + * + * @param path + * path + * @return field name + */ + protected String toField(Path<?> path) { + PathMetadata md = path.getMetadata(); + if (md.getPathType() == PathType.COLLECTION_ANY) { + return toField(md.getParent()); + } else { + String rv = md.getName(); + if (md.getParent() != null) { + Path<?> parent = md.getParent(); + if (parent.getMetadata().getPathType() != PathType.VARIABLE) { + rv = toField(parent) + "." + rv; + } + } + return rv; + } + } + + private void verifyArguments(Operation<?> operation) { + List<Expression<?>> arguments = operation.getArgs(); + for (int i = 1; i < arguments.size(); ++i) { + if (!(arguments.get(i) instanceof Constant<?>) + && !(arguments.get(i) instanceof ParamExpression<?>) + && !(arguments.get(i) instanceof PhraseElement) + && !(arguments.get(i) instanceof TermElement)) { + throw new IllegalArgumentException( + "operand was of unsupported type " + + arguments.get(i).getClass().getName()); + } + } + } + + /** + * template method + * + * @param leftHandSide + * left hand side + * @param rightHandSide + * right hand side + * @return results + */ + protected String[] convert(Path<?> leftHandSide, + Expression<?> rightHandSide, QueryMetadata metadata) { + if (rightHandSide instanceof Operation) { + Operation<?> operation = (Operation<?>) rightHandSide; + if (operation.getOperator() == LuceneOps.PHRASE) { + return operation.getArg(0).toString().split("\\s+"); + } else if (operation.getOperator() == LuceneOps.TERM) { + return new String[] {operation.getArg(0).toString() }; + } else { + throw new IllegalArgumentException(rightHandSide.toString()); + } + } else if (rightHandSide instanceof ParamExpression<?>) { + Object value = metadata.getParams().get(rightHandSide); + if (value == null) { + throw new ParamNotSetException( + (ParamExpression<?>) rightHandSide); + } + return convert(leftHandSide, value); + + } else if (rightHandSide instanceof Constant<?>) { + return convert(leftHandSide, + ((Constant<?>) rightHandSide).getConstant()); + } else { + throw new IllegalArgumentException(rightHandSide.toString()); + } + } + + /** + * template method + * + * @param leftHandSide + * left hand side + * @param rightHandSide + * right hand side + * @return results + */ + protected String[] convert(Path<?> leftHandSide, Object rightHandSide) { + String str = rightHandSide.toString(); + if (lowerCase) { + str = str.toLowerCase(); + } + if (splitTerms) { + if (str.equals("")) { + return new String[] {str }; + } else { + return str.split("\\s+"); + } + } else { + return new String[] {str }; + } + } + + private String[] convertEscaped(Path<?> leftHandSide, + Expression<?> rightHandSide, QueryMetadata metadata) { + String[] str = convert(leftHandSide, rightHandSide, metadata); + for (int i = 0; i < str.length; i++) { + str[i] = QueryParser.escape(str[i]); + } + return str; + } + + public Query toQuery(Expression<?> expr, QueryMetadata metadata) { + if (expr instanceof Operation<?>) { + return toQuery((Operation<?>) expr, metadata); + } else { + return toQuery(ExpressionUtils.extract(expr), metadata); + } + } + + public Sort toSort(List<? extends OrderSpecifier<?>> orderBys) { + List<SortField> sorts = new ArrayList<SortField>(orderBys.size()); + for (OrderSpecifier<?> order : orderBys) { + if (!(order.getTarget() instanceof Path<?>)) { + throw new IllegalArgumentException( + "argument was not of type Path."); + } + Class<?> type = order.getTarget().getType(); + boolean reverse = !order.isAscending(); + Path<?> path = getPath(order.getTarget()); + if (Number.class.isAssignableFrom(type)) { + sorts.add(new SortedNumericSortField(toField(path), sortFields.get(type), + reverse)); + } else { + sorts.add(new SortField(toField(path), SortField.Type.STRING, + reverse)); + } + } + Sort sort = new Sort(); + sort.setSort(sorts.toArray(new SortField[0])); + return sort; + } +} diff --git a/querydsl-lucene5/src/main/java/com/querydsl/lucene5/PhraseElement.java b/querydsl-lucene5/src/main/java/com/querydsl/lucene5/PhraseElement.java new file mode 100644 index 0000000000..d3f9f6c49a --- /dev/null +++ b/querydsl-lucene5/src/main/java/com/querydsl/lucene5/PhraseElement.java @@ -0,0 +1,33 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.lucene5; + +import com.querydsl.core.types.ConstantImpl; +import com.querydsl.core.types.dsl.StringOperation; + +/** + * {@code PhraseElement} represents the embedded String as a phrase + * + * @author tiwe + * + */ +public class PhraseElement extends StringOperation { + + private static final long serialVersionUID = 2350215644019186076L; + + public PhraseElement(String str) { + super(LuceneOps.PHRASE, ConstantImpl.create(str)); + } + +} diff --git a/querydsl-lucene5/src/main/java/com/querydsl/lucene5/QueryElement.java b/querydsl-lucene5/src/main/java/com/querydsl/lucene5/QueryElement.java new file mode 100644 index 0000000000..c7583c5f70 --- /dev/null +++ b/querydsl-lucene5/src/main/java/com/querydsl/lucene5/QueryElement.java @@ -0,0 +1,35 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.lucene5; + +import org.apache.lucene.search.Query; + +import com.querydsl.core.types.ConstantImpl; +import com.querydsl.core.types.dsl.BooleanOperation; + +/** + * {@code QueryElement} wraps a Lucene Query + * + * @author tiwe + * + */ +public class QueryElement extends BooleanOperation { + + private static final long serialVersionUID = 470868107363840155L; + + public QueryElement(Query query) { + super(LuceneOps.LUCENE_QUERY, ConstantImpl.create(query)); + } + +} diff --git a/querydsl-lucene5/src/main/java/com/querydsl/lucene5/ResultIterator.java b/querydsl-lucene5/src/main/java/com/querydsl/lucene5/ResultIterator.java new file mode 100644 index 0000000000..3c6d8ec6bb --- /dev/null +++ b/querydsl-lucene5/src/main/java/com/querydsl/lucene5/ResultIterator.java @@ -0,0 +1,88 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.lucene5; + +import com.mysema.commons.lang.CloseableIterator; +import com.querydsl.core.QueryException; +import org.apache.lucene.document.Document; +import org.apache.lucene.search.IndexSearcher; +import org.apache.lucene.search.ScoreDoc; +import org.jetbrains.annotations.Nullable; + +import java.io.IOException; +import java.util.Set; +import java.util.function.Function; + +/** + * {@code ResultIterator} is a {@link CloseableIterator} implementation for + * Lucene query results + * + * @author tiwe + * + * @param <T> + */ +public final class ResultIterator<T> implements CloseableIterator<T> { + + private final ScoreDoc[] scoreDocs; + + private int cursor; + + private final IndexSearcher searcher; + + @Nullable + private final Set<String> fieldsToLoad; + + private final Function<Document, T> transformer; + + public ResultIterator(ScoreDoc[] scoreDocs, int offset, + IndexSearcher searcher, @Nullable Set<String> fieldsToLoad, + Function<Document, T> transformer) { + this.scoreDocs = scoreDocs.clone(); + this.cursor = offset; + this.searcher = searcher; + this.fieldsToLoad = fieldsToLoad; + this.transformer = transformer; + } + + @Override + public boolean hasNext() { + return cursor != scoreDocs.length; + } + + @Override + public T next() { + try { + Document document; + if (fieldsToLoad != null) { + document = searcher.doc(scoreDocs[cursor++].doc, fieldsToLoad); + } else { + document = searcher.doc(scoreDocs[cursor++].doc); + } + return transformer.apply(document); + } catch (IOException e) { + throw new QueryException(e); + } + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + + @Override + public void close() { + + } + +} \ No newline at end of file diff --git a/querydsl-lucene5/src/main/java/com/querydsl/lucene5/TermElement.java b/querydsl-lucene5/src/main/java/com/querydsl/lucene5/TermElement.java new file mode 100644 index 0000000000..ccd6e28bed --- /dev/null +++ b/querydsl-lucene5/src/main/java/com/querydsl/lucene5/TermElement.java @@ -0,0 +1,33 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.lucene5; + +import com.querydsl.core.types.ConstantImpl; +import com.querydsl.core.types.dsl.StringOperation; + +/** + * {@code TermElement} represents the embedded String as a term + * + * @author tiwe + * + */ +public class TermElement extends StringOperation { + + private static final long serialVersionUID = 2350215644019186076L; + + public TermElement(String str) { + super(LuceneOps.TERM, ConstantImpl.create(str)); + } + +} diff --git a/querydsl-lucene5/src/main/java/com/querydsl/lucene5/TypedQuery.java b/querydsl-lucene5/src/main/java/com/querydsl/lucene5/TypedQuery.java new file mode 100644 index 0000000000..cc72eb1e1b --- /dev/null +++ b/querydsl-lucene5/src/main/java/com/querydsl/lucene5/TypedQuery.java @@ -0,0 +1,63 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.lucene5; + +import org.apache.lucene.document.Document; +import org.apache.lucene.search.IndexSearcher; + +import java.util.function.Function; + +/** + * {@code TypedQuery} is a typed query implementation for Lucene queries. + * + * <p> + * Converts Lucene documents to typed results via a constructor supplied + * transformer + * </p> + * + * @param <T> result type + * + * @author laim + * @author tiwe + */ +public class TypedQuery<T> extends AbstractLuceneQuery<T, TypedQuery<T>> { + + /** + * Create a new TypedQuery instance + * + * @param searcher + * index searcher + * @param transformer + * transformer to transform Lucene documents to result objects + */ + public TypedQuery(IndexSearcher searcher, Function<Document, T> transformer) { + super(searcher, transformer); + } + + /** + * Create a new TypedQuery instance + * + * @param serializer + * serializer + * @param searcher + * index searcher + * @param transformer + * transformer to transform Lucene documents to result objects + */ + public TypedQuery(LuceneSerializer serializer, IndexSearcher searcher, + Function<Document, T> transformer) { + super(serializer, searcher, transformer); + } + +} diff --git a/querydsl-lucene5/src/main/java/com/querydsl/lucene5/package-info.java b/querydsl-lucene5/src/main/java/com/querydsl/lucene5/package-info.java new file mode 100644 index 0000000000..0d4c10ad02 --- /dev/null +++ b/querydsl-lucene5/src/main/java/com/querydsl/lucene5/package-info.java @@ -0,0 +1,19 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ + +/** + * Lucene 5 support + */ +package com.querydsl.lucene5; + diff --git a/querydsl-lucene5/src/test/java/com/querydsl/lucene5/LuceneQueryTest.java b/querydsl-lucene5/src/test/java/com/querydsl/lucene5/LuceneQueryTest.java new file mode 100644 index 0000000000..6dc9697722 --- /dev/null +++ b/querydsl-lucene5/src/test/java/com/querydsl/lucene5/LuceneQueryTest.java @@ -0,0 +1,838 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.lucene5; + +import static org.easymock.EasyMock.createMockBuilder; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.verify; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; + +import org.apache.lucene.analysis.standard.StandardAnalyzer; +import org.apache.lucene.document.Document; +import org.apache.lucene.document.DoubleDocValuesField; +import org.apache.lucene.document.DoubleField; +import org.apache.lucene.document.Field; +import org.apache.lucene.document.Field.Store; +import org.apache.lucene.document.IntField; +import org.apache.lucene.document.NumericDocValuesField; +import org.apache.lucene.document.SortedDocValuesField; +import org.apache.lucene.document.TextField; +import org.apache.lucene.index.DirectoryReader; +import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexWriter; +import org.apache.lucene.index.IndexWriterConfig; +import org.apache.lucene.sandbox.queries.DuplicateFilter; +import org.apache.lucene.search.Filter; +import org.apache.lucene.search.IndexSearcher; +import org.apache.lucene.search.Sort; +import org.apache.lucene.store.RAMDirectory; +import org.apache.lucene.util.BytesRef; +import org.junit.After; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; + +import com.querydsl.core.NonUniqueResultException; +import com.querydsl.core.QueryException; +import com.querydsl.core.QueryModifiers; +import com.querydsl.core.QueryResults; +import com.querydsl.core.types.ParamNotSetException; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.Param; +import com.querydsl.core.types.dsl.StringPath; + +/** + * Tests for LuceneQuery + * + * @author vema + * + */ +public class LuceneQueryTest { + + private LuceneQuery query; + private StringPath title; + private NumberPath<Integer> year; + private NumberPath<Double> gross; + + private final StringPath sort = Expressions.stringPath("sort"); + + private RAMDirectory idx; + private IndexWriter writer; + private IndexSearcher searcher; + private Field titleField = null; + private SortedDocValuesField titleSortedField; + private TextField authorField = null; + private SortedDocValuesField authorSortedField; + private TextField textField = null; + private IntField yearField = null; + private DoubleField grossField = null; + private SortedDocValuesField textSortedField; + private NumericDocValuesField yearSortedField; + private DoubleDocValuesField grossSortedField; + + private Document createDocument(final String docTitle, + final String docAuthor, final String docText, final int docYear, + final double docGross) { + Document doc = new Document(); + // Reusing field for performance + if (titleField == null) { + titleField = new TextField("title", docTitle, Store.YES); + doc.add(titleField); + titleSortedField = new SortedDocValuesField("title", new BytesRef( + docTitle)); + doc.add(titleSortedField); + } else { + titleField.setStringValue(docTitle); + titleSortedField.setBytesValue(new BytesRef(docTitle)); + doc.add(titleField); + doc.add(titleSortedField); + } + if (authorField == null) { + authorField = new TextField("author", docAuthor, Store.YES); + doc.add(authorField); + authorSortedField = new SortedDocValuesField("author", + new BytesRef(docAuthor)); + doc.add(authorSortedField); + + } else { + authorField.setStringValue(docAuthor); + authorSortedField.setBytesValue(new BytesRef(docAuthor)); + doc.add(authorField); + doc.add(authorSortedField); + } + if (textField == null) { + textField = new TextField("text", docText, Store.YES); + doc.add(textField); + textSortedField = new SortedDocValuesField("text", new BytesRef( + docText)); + doc.add(textSortedField); + } else { + textField.setStringValue(docText); + textSortedField.setBytesValue(new BytesRef(docText)); + doc.add(textField); + doc.add(textSortedField); + } + if (yearField == null) { + yearField = new IntField("year", docYear, Store.YES); + doc.add(yearField); + yearSortedField = new NumericDocValuesField("year", docYear); + doc.add(yearSortedField); + } else { + yearField.setIntValue(docYear); + yearSortedField.setLongValue(docYear); + doc.add(yearField); + doc.add(yearSortedField); + } + + if (grossField == null) { + grossField = new DoubleField("gross", docGross, Store.YES); + doc.add(grossField); + grossSortedField = new DoubleDocValuesField("gross", docGross); + doc.add(grossSortedField); + } else { + grossField.setDoubleValue(docGross); + grossSortedField.setDoubleValue(docGross); + doc.add(grossField); + doc.add(grossSortedField); + } + + return doc; + } + + @Before + public void setUp() throws Exception { + final QDocument entityPath = new QDocument("doc"); + title = entityPath.title; + year = entityPath.year; + gross = entityPath.gross; + + idx = new RAMDirectory(); + writer = createWriter(idx); + + writer.addDocument(createDocument("Jurassic Park", "Michael Crichton", + "It's a UNIX system! I know this!", 1990, 90.00)); + writer.addDocument(createDocument("Nummisuutarit", "Aleksis Kivi", + "ESKO. Ja iloitset ja riemuitset?", 1864, 10.00)); + writer.addDocument(createDocument( + "The Lord of the Rings", + "John R. R. Tolkien", + "One Ring to rule them all, One Ring to find them, One Ring to bring them all and in the darkness bind them", + 1954, 89.00)); + writer.addDocument(createDocument( + "Introduction to Algorithms", + "Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein", + "Bubble sort", 1990, 30.50)); + + writer.close(); + + IndexReader reader = DirectoryReader.open(idx); + searcher = new IndexSearcher(reader); + query = new LuceneQuery(new LuceneSerializer(true, true), searcher); + } + + private IndexWriter createWriter(RAMDirectory idx) throws Exception { + IndexWriterConfig config = new IndexWriterConfig(new StandardAnalyzer()) + .setOpenMode(IndexWriterConfig.OpenMode.CREATE); + return new IndexWriter(idx, config); + } + + @After + public void tearDown() throws Exception { + searcher.getIndexReader().close(); + } + + @Test + public void between() { + assertEquals(3, query.where(year.between(1950, 1990)).fetchCount()); + } + + @Test + public void count_empty_where_clause() { + assertEquals(4, query.fetchCount()); + } + + @Test + public void exists() { + assertTrue(query.where(title.eq("Jurassic Park")).fetchCount() > 0); + assertFalse(query.where(title.eq("Jurassic Park X")).fetchCount() > 0); + } + + @Test + public void notExists() { + assertFalse(query.where(title.eq("Jurassic Park")).fetchCount() == 0); + assertTrue(query.where(title.eq("Jurassic Park X")).fetchCount() == 0); + } + + @Test + public void count() { + query.where(title.eq("Jurassic Park")); + assertEquals(1, query.fetchCount()); + } + + @Test(expected = QueryException.class) + @Ignore + public void count_index_problem() throws IOException { + searcher = createMockBuilder(IndexSearcher.class).addMockedMethod( + "maxDoc").createMock(); + query = new LuceneQuery(new LuceneSerializer(true, true), searcher); + expect(searcher.getIndexReader().maxDoc()).andThrow( + new IllegalArgumentException()); + replay(searcher); + query.where(title.eq("Jurassic Park")); + query.fetchCount(); + verify(searcher); + } + + @Test(expected = UnsupportedOperationException.class) + public void countDistinct() { + query.where(year.between(1900, 3000)); + assertEquals(3, query.distinct().fetchCount()); + } + + @Test + public void in() { + assertEquals(2, query.where(title.in("Jurassic Park", "Nummisuutarit")).fetchCount()); + } + + @Test + public void in2() { + assertEquals(3, query.where(year.in(1990, 1864)).fetchCount()); + } + + @Test + public void in_toString() { + assertEquals("year:`____F year:`____H", query.where(year.in(1990, 1864)).toString()); + } + + @Test + public void list_sorted_by_year_ascending() { + query.where(year.between(1800, 2000)); + query.orderBy(year.asc()); + final List<Document> documents = query.fetch(); + assertFalse(documents.isEmpty()); + assertEquals(4, documents.size()); + } + + @Test + public void list_not_sorted() { + query.where(year.between(1800, 2000)); + final List<Document> documents = query.fetch(); + assertFalse(documents.isEmpty()); + assertEquals(4, documents.size()); + } + + @Test + @Ignore + // FIXME + public void sorted_by_different_locales() throws Exception { + Document d1 = new Document(); + Document d2 = new Document(); + Document d3 = new Document(); + d1.add(new TextField("sort", "a\u00c4", Store.YES)); + d2.add(new TextField("sort", "ab", Store.YES)); + d3.add(new TextField("sort", "aa", Store.YES)); + writer = createWriter(idx); + writer.addDocument(d1); + writer.addDocument(d2); + writer.addDocument(d3); + writer.close(); + + IndexReader reader = DirectoryReader.open(writer, true); + searcher = new IndexSearcher(reader); + query = new LuceneQuery( + new LuceneSerializer(true, true, Locale.ENGLISH), searcher); + assertEquals(3, query.fetch().size()); + List<Document> results = query.where(sort.startsWith("a")) + .orderBy(sort.asc()).fetch(); + assertEquals(3, results.size()); + assertEquals("aa", results.get(0).getField("sort").stringValue()); + assertEquals("a\u00c4", results.get(1).getField("sort").stringValue()); + assertEquals("ab", results.get(2).getField("sort").stringValue()); + + query = new LuceneQuery(new LuceneSerializer(true, true, new Locale( + "fi", "FI")), searcher); + results = query.where(sort.startsWith("a")).orderBy(sort.asc()).fetch(); + assertEquals("aa", results.get(0).getField("sort").stringValue()); + assertEquals("ab", results.get(1).getField("sort").stringValue()); + assertEquals("a\u00c4", results.get(2).getField("sort").stringValue()); + } + + @Test + public void list_not_sorted_limit_2() { + query.where(year.between(1800, 2000)); + query.limit(2); + final List<Document> documents = query.fetch(); + assertFalse(documents.isEmpty()); + assertEquals(2, documents.size()); + } + + @Test + public void list_sorted_by_year_limit_1() { + query.where(year.between(1800, 2000)); + query.limit(1); + query.orderBy(year.asc()); + final List<Document> documents = query.fetch(); + assertFalse(documents.isEmpty()); + assertEquals(1, documents.size()); + } + + @Test + public void list_not_sorted_offset_2() { + query.where(year.between(1800, 2000)); + query.offset(2); + final List<Document> documents = query.fetch(); + assertFalse(documents.isEmpty()); + assertEquals(2, documents.size()); + } + + @Test + public void list_sorted_ascending_by_year_offset_2() { + query.where(year.between(1800, 2000)); + query.offset(2); + query.orderBy(year.asc()); + final List<Document> documents = query.fetch(); + assertFalse(documents.isEmpty()); + assertEquals(2, documents.size()); + assertEquals("1990", documents.get(0).get("year")); + assertEquals("1990", documents.get(1).get("year")); + } + + @Test + public void list_sorted_ascending_by_year_restrict_limit_2_offset_1() { + query.where(year.between(1800, 2000)); + query.restrict(new QueryModifiers(2L, 1L)); + query.orderBy(year.asc()); + final List<Document> documents = query.fetch(); + assertFalse(documents.isEmpty()); + assertEquals(2, documents.size()); + assertEquals("1954", documents.get(0).get("year")); + assertEquals("1990", documents.get(1).get("year")); + } + + @Test + public void list_sorted_ascending_by_year() { + query.where(year.between(1800, 2000)); + query.orderBy(year.asc()); + final List<Document> documents = query.fetch(); + assertFalse(documents.isEmpty()); + assertEquals(4, documents.size()); + assertEquals("1864", documents.get(0).get("year")); + assertEquals("1954", documents.get(1).get("year")); + assertEquals("1990", documents.get(2).get("year")); + assertEquals("1990", documents.get(3).get("year")); + } + + @Test + public void list_sort() { + Sort sort = LuceneSerializer.DEFAULT.toSort(Collections + .singletonList(year.asc())); + + query.where(year.between(1800, 2000)); + // query.orderBy(year.asc()); + query.sort(sort); + final List<Document> documents = query.fetch(); + assertFalse(documents.isEmpty()); + assertEquals(4, documents.size()); + assertEquals("1864", documents.get(0).get("year")); + assertEquals("1954", documents.get(1).get("year")); + assertEquals("1990", documents.get(2).get("year")); + assertEquals("1990", documents.get(3).get("year")); + } + + @Test + public void list_distinct_property() { + assertEquals(4, query.fetch().size()); + assertEquals(3, query.distinct(year).fetch().size()); + } + + @Test + public void list_with_filter() { + Filter filter = new DuplicateFilter("year"); + assertEquals(4, query.fetch().size()); + assertEquals(3, query.filter(filter).fetch().size()); + } + + @Test + public void count_distinct_property() { + assertEquals(4L, query.fetchCount()); + assertEquals(3L, query.distinct(year).fetchCount()); + } + + @Test + public void list_sorted_descending_by_year() { + query.where(year.between(1800, 2000)); + query.orderBy(year.desc()); + final List<Document> documents = query.fetch(); + assertFalse(documents.isEmpty()); + assertEquals(4, documents.size()); + assertEquals("1990", documents.get(0).get("year")); + assertEquals("1990", documents.get(1).get("year")); + assertEquals("1954", documents.get(2).get("year")); + assertEquals("1864", documents.get(3).get("year")); + } + + @Test + public void list_sorted_descending_by_gross() { + query.where(gross.between(0.0, 1000.00)); + query.orderBy(gross.desc()); + final List<Document> documents = query.fetch(); + assertFalse(documents.isEmpty()); + assertEquals(4, documents.size()); + assertEquals("90.0", documents.get(0).get("gross")); + assertEquals("89.0", documents.get(1).get("gross")); + assertEquals("30.5", documents.get(2).get("gross")); + assertEquals("10.0", documents.get(3).get("gross")); + } + + @Test + public void list_sorted_descending_by_year_and_ascending_by_title() { + query.where(year.between(1800, 2000)); + query.orderBy(year.desc()); + query.orderBy(title.asc()); + final List<Document> documents = query.fetch(); + assertFalse(documents.isEmpty()); + assertEquals(4, documents.size()); + assertEquals("1990", documents.get(0).get("year")); + assertEquals("1990", documents.get(1).get("year")); + assertEquals("Introduction to Algorithms", documents.get(0) + .get("title")); + assertEquals("Jurassic Park", documents.get(1).get("title")); + } + + @Test + public void list_sorted_descending_by_year_and_descending_by_title() { + query.where(year.between(1800, 2000)); + query.orderBy(year.desc()); + query.orderBy(title.desc()); + final List<Document> documents = query.fetch(); + assertFalse(documents.isEmpty()); + assertEquals(4, documents.size()); + assertEquals("1990", documents.get(0).get("year")); + assertEquals("1990", documents.get(1).get("year")); + assertEquals("Jurassic Park", documents.get(0).get("title")); + assertEquals("Introduction to Algorithms", documents.get(1) + .get("title")); + } + + @Ignore + @Test(expected = QueryException.class) + public void list_index_problem_in_max_doc() throws IOException { + searcher = createMockBuilder(IndexSearcher.class).addMockedMethod( + "maxDoc").createMock(); + query = new LuceneQuery(new LuceneSerializer(true, true), searcher); + expect(searcher.getIndexReader().maxDoc()).andThrow(new IOException()); + replay(searcher); + query.where(title.eq("Jurassic Park")); + query.fetch(); + verify(searcher); + } + + @Ignore + @Test(expected = QueryException.class) + public void list_sorted_index_problem_in_max_doc() throws IOException { + searcher = createMockBuilder(IndexSearcher.class).addMockedMethod( + "maxDoc").createMock(); + query = new LuceneQuery(new LuceneSerializer(true, true), searcher); + expect(searcher.getIndexReader().maxDoc()).andThrow(new IOException()); + replay(searcher); + query.where(title.eq("Jurassic Park")); + query.orderBy(title.asc()); + query.fetch(); + verify(searcher); + } + + @Test + public void offset() { + assertTrue(query.where(title.eq("Jurassic Park")).offset(30).fetch() + .isEmpty()); + } + + @Test + public void load_list() { + Document document = query.where(title.ne("")).load(title).fetch() + .get(0); + assertNotNull(document.get("title")); + assertNull(document.get("year")); + } + + @Test + public void load_list_fieldSelector() { + Document document = query.where(title.ne("")) + .load(Collections.singleton("title")).fetch().get(0); + assertNotNull(document.get("title")); + assertNull(document.get("year")); + } + + @Test + public void load_singleResult() { + Document document = query.where(title.ne("")).load(title).fetchFirst(); + assertNotNull(document.get("title")); + assertNull(document.get("year")); + } + + @Test + public void load_singleResult_fieldSelector() { + Document document = query.where(title.ne("")) + .load(Collections.singleton("title")).fetchFirst(); + assertNotNull(document.get("title")); + assertNull(document.get("year")); + } + + @Test + public void singleResult() { + assertNotNull(query.where(title.ne("")).fetchFirst()); + } + + @Test + public void single_result_takes_limit() { + assertEquals("Jurassic Park", query.where(title.ne("")).limit(1) + .fetchFirst().get("title")); + } + + @Test + public void single_result_considers_limit_and_actual_result_size() { + query.where(title.startsWith("Nummi")); + final Document document = query.limit(3).fetchFirst(); + assertEquals("Nummisuutarit", document.get("title")); + } + + @Test + public void single_result_returns_null_if_nothing_is_in_range() { + query.where(title.startsWith("Nummi")); + assertNull(query.offset(10).fetchFirst()); + } + + @Test + public void single_result_considers_offset() { + assertEquals("Introduction to Algorithms", query.where(title.ne("")) + .offset(3).fetchFirst().get("title")); + } + + @Test + public void single_result_considers_limit_and_offset() { + assertEquals("The Lord of the Rings", query.where(title.ne("")) + .limit(1).offset(2).fetchFirst().get("title")); + } + + @Test(expected = NonUniqueResultException.class) + public void uniqueResult_contract() { + query.where(title.ne("")).fetchOne(); + } + + @Test + public void unique_result_takes_limit() { + assertEquals("Jurassic Park", query.where(title.ne("")).limit(1) + .fetchOne().get("title")); + } + + @Test + public void unique_result_considers_limit_and_actual_result_size() { + query.where(title.startsWith("Nummi")); + final Document document = query.limit(3).fetchOne(); + assertEquals("Nummisuutarit", document.get("title")); + } + + @Test + public void unique_result_returns_null_if_nothing_is_in_range() { + query.where(title.startsWith("Nummi")); + assertNull(query.offset(10).fetchOne()); + } + + @Test + public void unique_result_considers_offset() { + assertEquals("Introduction to Algorithms", query.where(title.ne("")) + .offset(3).fetchOne().get("title")); + } + + @Test + public void unique_result_considers_limit_and_offset() { + assertEquals("The Lord of the Rings", query.where(title.ne("")) + .limit(1).offset(2).fetchOne().get("title")); + } + + @Test + public void uniqueResult() { + query.where(title.startsWith("Nummi")); + final Document document = query.fetchOne(); + assertEquals("Nummisuutarit", document.get("title")); + } + + @Test + public void uniqueResult_with_param() { + final Param<String> param = new Param<String>(String.class, "title"); + query.set(param, "Nummi"); + query.where(title.startsWith(param)); + final Document document = query.fetchOne(); + assertEquals("Nummisuutarit", document.get("title")); + } + + @Test(expected = ParamNotSetException.class) + public void uniqueResult_param_not_set() { + final Param<String> param = new Param<String>(String.class, "title"); + query.where(title.startsWith(param)); + query.fetchOne(); + } + + @Test(expected = QueryException.class) + public void uniqueResult_finds_more_than_one_result() { + query.where(year.eq(1990)); + query.fetchOne(); + } + + @Test + public void uniqueResult_finds_no_results() { + query.where(year.eq(2200)); + assertNull(query.fetchOne()); + } + + @Test + @Ignore + public void uniqueResult_finds_no_results_because_no_documents_in_index() + throws IOException { + searcher = createMockBuilder(IndexSearcher.class) + .addMockedMethod("maxDoc").createMock(); + query = new LuceneQuery(new LuceneSerializer(true, true), searcher); + expect(searcher.getIndexReader().maxDoc()).andReturn(0); + replay(searcher); + assertNull(query.where(year.eq(3000)).fetchOne()); + verify(searcher); + } + + @Test(expected = QueryException.class) + @Ignore + public void uniqueResult_sorted_index_problem_in_max_doc() + throws IOException { + searcher = createMockBuilder(IndexSearcher.class) + .addMockedMethod("maxDoc").createMock(); + query = new LuceneQuery(new LuceneSerializer(true, true), searcher); + expect(searcher.getIndexReader().maxDoc()).andThrow( + new IllegalArgumentException()); + replay(searcher); + query.where(title.eq("Jurassic Park")); + query.fetchOne(); + verify(searcher); + } + + @Test + @Ignore + public void count_returns_0_because_no_documents_in_index() + throws IOException { + searcher = createMockBuilder(IndexSearcher.class) + .addMockedMethod("maxDoc").createMock(); + query = new LuceneQuery(new LuceneSerializer(true, true), searcher); + expect(searcher.getIndexReader().maxDoc()).andReturn(0); + replay(searcher); + assertEquals(0, query.where(year.eq(3000)).fetchCount()); + verify(searcher); + } + + @Test(expected = UnsupportedOperationException.class) + public void listDistinct() { + query.where(year.between(1900, 2000).or(title.startsWith("Jura"))); + query.orderBy(year.asc()); + final List<Document> documents = query.distinct().fetch(); + assertFalse(documents.isEmpty()); + assertEquals(3, documents.size()); + } + + @Test + public void listResults() { + query.where(year.between(1800, 2000)); + query.restrict(new QueryModifiers(2L, 1L)); + query.orderBy(year.asc()); + final QueryResults<Document> results = query.fetchResults(); + assertFalse(results.isEmpty()); + assertEquals("1954", results.getResults().get(0).get("year")); + assertEquals("1990", results.getResults().get(1).get("year")); + assertEquals(2, results.getLimit()); + assertEquals(1, results.getOffset()); + assertEquals(4, results.getTotal()); + } + + @Test(expected = UnsupportedOperationException.class) + public void listDistinctResults() { + query.where(year.between(1800, 2000).or( + title.eq("The Lord of the Rings"))); + query.restrict(new QueryModifiers(1L, 1L)); + query.orderBy(year.asc()); + final QueryResults<Document> results = query.distinct().fetchResults(); + assertFalse(results.isEmpty()); + assertEquals("1954", results.getResults().get(0).get("year")); + assertEquals(1, results.getLimit()); + assertEquals(1, results.getOffset()); + assertEquals(4, results.getTotal()); + } + + @Test + public void list_all() { + final List<Document> results = query.where(title.like("*")) + .orderBy(title.asc(), year.desc()).fetch(); + assertEquals(4, results.size()); + } + + @Test(expected = IllegalArgumentException.class) + public void list_sorted_ascending_limit_negative() { + query.where(year.between(1800, 2000)); + query.limit(-1); + query.orderBy(year.asc()); + query.fetch(); + } + + @Test(expected = IllegalArgumentException.class) + public void list_not_sorted_limit_negative() { + query.where(year.between(1800, 2000)); + query.limit(-1); + query.fetch(); + } + + @Test(expected = IllegalArgumentException.class) + public void list_sorted_ascending_limit_0() { + query.where(year.between(1800, 2000)); + query.limit(0); + query.orderBy(year.asc()); + query.fetch(); + } + + @Test(expected = IllegalArgumentException.class) + public void list_not_sorted_limit_0() { + query.where(year.between(1800, 2000)); + query.limit(0); + query.fetch(); + } + + @Test(expected = IllegalArgumentException.class) + public void list_sorted_ascending_offset_negative() { + query.where(year.between(1800, 2000)); + query.offset(-1); + query.orderBy(year.asc()); + query.fetch(); + } + + @Test(expected = IllegalArgumentException.class) + public void list_not_sorted_offset_negative() { + query.where(year.between(1800, 2000)); + query.offset(-1); + query.fetch(); + } + + @Test + public void list_sorted_ascending_offset_0() { + query.where(year.between(1800, 2000)); + query.offset(0); + query.orderBy(year.asc()); + final List<Document> documents = query.fetch(); + assertFalse(documents.isEmpty()); + assertEquals(4, documents.size()); + } + + @Test + public void list_not_sorted_offset_0() { + query.where(year.between(1800, 2000)); + query.offset(0); + final List<Document> documents = query.fetch(); + assertFalse(documents.isEmpty()); + assertEquals(4, documents.size()); + } + + @Test + public void iterate() { + query.where(year.between(1800, 2000)); + final Iterator<Document> iterator = query.iterate(); + int count = 0; + while (iterator.hasNext()) { + iterator.next(); + ++count; + } + assertEquals(4, count); + } + + @Test + public void all_by_excluding_where() { + assertEquals(4, query.fetch().size()); + } + + @Test + public void empty_index_should_return_empty_list() throws Exception { + idx = new RAMDirectory(); + + writer = createWriter(idx); + writer.close(); + IndexReader reader = DirectoryReader.open(idx); + searcher = new IndexSearcher(reader); + query = new LuceneQuery(new LuceneSerializer(true, true), searcher); + assertTrue(query.fetch().isEmpty()); + } + + @Test(expected = QueryException.class) + public void list_results_throws_an_illegal_argument_exception_when_sum_of_limit_and_offset_is_negative() { + query.limit(1).offset(Integer.MAX_VALUE).fetchResults(); + } + + @Test + public void limit_max_value() { + assertEquals(4, query.limit(Long.MAX_VALUE).fetch().size()); + } +} diff --git a/querydsl-lucene5/src/test/java/com/querydsl/lucene5/LuceneSerializerNotTokenizedTest.java b/querydsl-lucene5/src/test/java/com/querydsl/lucene5/LuceneSerializerNotTokenizedTest.java new file mode 100644 index 0000000000..9cff57a372 --- /dev/null +++ b/querydsl-lucene5/src/test/java/com/querydsl/lucene5/LuceneSerializerNotTokenizedTest.java @@ -0,0 +1,229 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.lucene5; + +import static com.querydsl.lucene5.QPerson.person; +import static org.junit.Assert.assertEquals; + +import java.util.Arrays; + +import org.apache.lucene.analysis.standard.StandardAnalyzer; +import org.apache.lucene.document.Document; +import org.apache.lucene.document.Field; +import org.apache.lucene.document.Field.Index; +import org.apache.lucene.document.Field.Store; +import org.apache.lucene.index.DirectoryReader; +import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexWriter; +import org.apache.lucene.index.IndexWriterConfig; +import org.apache.lucene.search.IndexSearcher; +import org.apache.lucene.search.Query; +import org.apache.lucene.search.TopDocs; +import org.apache.lucene.store.RAMDirectory; +import org.joda.time.LocalDate; +import org.junit.Before; +import org.junit.Test; + +import com.querydsl.core.DefaultQueryMetadata; +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.StringPath; + +public class LuceneSerializerNotTokenizedTest { + private RAMDirectory idx; + private IndexWriter writer; + private IndexSearcher searcher; + private LuceneSerializer serializer; + + private final QueryMetadata metadata = new DefaultQueryMetadata(); + + private final Person clooney = new Person("actor_1", "George Clooney", + new LocalDate(1961, 4, 6)); + private final Person pitt = new Person("actor_2", "Brad Pitt", + new LocalDate(1963, 12, 18)); + + private void testQuery(Expression<?> expr, String expectedQuery, + int expectedHits) throws Exception { + Query query = serializer.toQuery(expr, metadata); + TopDocs docs = searcher.search(query, 100); + assertEquals(expectedHits, docs.totalHits); + assertEquals(expectedQuery, query.toString()); + } + + private Document createDocument(Person person) { + Document doc = new Document(); + doc.add(new Field("id", person.getId(), Store.YES, Index.NOT_ANALYZED)); + doc.add(new Field("name", person.getName(), Store.YES, + Index.NOT_ANALYZED)); + doc.add(new Field("birthDate", person.getBirthDate().toString(), + Store.YES, Index.NOT_ANALYZED)); + return doc; + } + + @Before + public void before() throws Exception { + serializer = new LuceneSerializer(false, false); + idx = new RAMDirectory(); + IndexWriterConfig config = new IndexWriterConfig(new StandardAnalyzer()) + .setOpenMode(IndexWriterConfig.OpenMode.CREATE); + writer = new IndexWriter(idx, config); + + writer.addDocument(createDocument(clooney)); + writer.addDocument(createDocument(pitt)); + + Document document = new Document(); + for (String movie : Arrays.asList("Interview with the Vampire", + "Up in the Air")) { + document.add(new Field("movie", movie, Store.YES, + Index.NOT_ANALYZED)); + } + writer.addDocument(document); + + writer.close(); + + IndexReader reader = DirectoryReader.open(idx); + searcher = new IndexSearcher(reader); + } + + @Test + public void equals_by_id_matches() throws Exception { + testQuery(person.id.eq("actor_1"), "id:actor_1", 1); + } + + @Test + public void equals_by_id_does_not_match() throws Exception { + testQuery(person.id.eq("actor_8"), "id:actor_8", 0); + } + + @Test + public void equals_by_name_matches() throws Exception { + testQuery(person.name.eq("George Clooney"), "name:George Clooney", 1); + } + + @Test(expected = UnsupportedOperationException.class) + public void equals_by_name_ignoring_case_does_not_match() throws Exception { + testQuery(person.name.equalsIgnoreCase("george clooney"), + "name:george clooney", 0); + } + + @Test + public void equals_by_name_does_not_match() throws Exception { + testQuery(person.name.eq("George Looney"), "name:George Looney", 0); + } + + @Test + public void starts_with_name_should_match() throws Exception { + testQuery(person.name.startsWith("George C"), "name:George C*", 1); + } + + @Test + public void starts_with_name_should_not_match() throws Exception { + testQuery(person.name.startsWith("George L"), "name:George L*", 0); + } + + @Test + public void ends_with_name_should_match() throws Exception { + testQuery(person.name.endsWith("e Clooney"), "name:*e Clooney", 1); + } + + @Test + public void ends_with_name_should_not_match() throws Exception { + testQuery(person.name.endsWith("e Looney"), "name:*e Looney", 0); + } + + @Test + public void contains_name_should_match() throws Exception { + testQuery(person.name.contains("oney"), "name:*oney*", 1); + } + + @Test + public void contains_name_should_not_match() throws Exception { + testQuery(person.name.contains("bloney"), "name:*bloney*", 0); + } + + @Test + public void in_names_should_match_2() throws Exception { + testQuery(person.name.in("Brad Pitt", "George Clooney"), + "name:Brad Pitt name:George Clooney", 2); + } + + @Test + public void or_by_name_should_match_2() throws Exception { + testQuery( + person.name.eq("Brad Pitt") + .or(person.name.eq("George Clooney")), + "name:Brad Pitt name:George Clooney", 2); + } + + @Test + public void equals_by_birth_date() throws Exception { + testQuery(person.birthDate.eq(clooney.getBirthDate()), + "birthDate:1961-04-06", 1); + } + + @Test + public void between_phrase() throws Exception { + testQuery(person.name.between("Brad Pitt", "George Clooney"), + "name:[Brad Pitt TO George Clooney]", 2); + } + + @Test + public void not_equals_finds_the_actors_and_movies() throws Exception { + testQuery(person.name.ne("Michael Douglas"), + "-name:Michael Douglas +*:*", 3); + } + + @Test + public void not_equals_finds_only_clooney_and_movies() throws Exception { + testQuery(person.name.ne("Brad Pitt"), "-name:Brad Pitt +*:*", 2); + } + + @Test + public void and_with_two_not_equals_doesnt_find_the_actors() + throws Exception { + testQuery( + person.name.ne("Brad Pitt").and( + person.name.ne("George Clooney")), + "+(-name:Brad Pitt +*:*) +(-name:George Clooney +*:*)", 1); + } + + @Test + public void or_with_two_not_equals_finds_movies_and_actors() + throws Exception { + testQuery( + person.name.ne("Brad Pitt") + .or(person.name.ne("George Clooney")), + "(-name:Brad Pitt +*:*) (-name:George Clooney +*:*)", 3); + } + + @Test + public void negation_of_equals_finds_movies_and_actors() throws Exception { + testQuery(person.name.eq("Michael Douglas").not(), + "-name:Michael Douglas +*:*", 3); + } + + @Test + public void negation_of_equals_finds_pitt_and_movies() throws Exception { + testQuery(person.name.eq("Brad Pitt").not(), "-name:Brad Pitt +*:*", 2); + } + + @Test + public void multiple_field_search_from_movies() throws Exception { + StringPath movie = Expressions.stringPath("movie"); + testQuery(movie.in("Interview with the Vampire"), + "movie:Interview with the Vampire", 1); + testQuery(movie.eq("Up in the Air"), "movie:Up in the Air", 1); + } +} diff --git a/querydsl-lucene5/src/test/java/com/querydsl/lucene5/LuceneSerializerTest.java b/querydsl-lucene5/src/test/java/com/querydsl/lucene5/LuceneSerializerTest.java new file mode 100644 index 0000000000..e3a984f416 --- /dev/null +++ b/querydsl-lucene5/src/test/java/com/querydsl/lucene5/LuceneSerializerTest.java @@ -0,0 +1,753 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.lucene5; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import java.io.StringReader; +import java.util.Arrays; +import java.util.Collections; +import java.util.EnumSet; +import java.util.Set; + +import org.apache.lucene.analysis.standard.StandardAnalyzer; +import org.apache.lucene.document.Document; +import org.apache.lucene.document.DoubleField; +import org.apache.lucene.document.Field; +import org.apache.lucene.document.Field.Index; +import org.apache.lucene.document.Field.Store; +import org.apache.lucene.document.FloatField; +import org.apache.lucene.document.IntField; +import org.apache.lucene.document.LongField; +import org.apache.lucene.index.DirectoryReader; +import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexWriter; +import org.apache.lucene.index.IndexWriterConfig; +import org.apache.lucene.search.IndexSearcher; +import org.apache.lucene.search.Query; +import org.apache.lucene.search.TopDocs; +import org.apache.lucene.store.RAMDirectory; +import org.junit.After; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; + +import com.querydsl.core.BooleanBuilder; +import com.querydsl.core.DefaultQueryMetadata; +import com.querydsl.core.MatchingFiltersFactory; +import com.querydsl.core.QuerydslModule; +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.StringConstant; +import com.querydsl.core.Target; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.Operation; +import com.querydsl.core.types.Operator; +import com.querydsl.core.types.Ops; +import com.querydsl.core.types.Predicate; +import com.querydsl.core.types.dsl.BooleanExpression; +import com.querydsl.core.types.dsl.CollectionPath; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.PathBuilder; +import com.querydsl.core.types.dsl.StringPath; + +/** + * Tests for LuceneSerializer + * + * @author vema + * + */ +public class LuceneSerializerTest { + private LuceneSerializer serializer; + private PathBuilder<Object> entityPath; + private StringPath title; + private StringPath author; + private StringPath text; + private StringPath rating; + private StringPath publisher; + private NumberPath<Integer> year; + private NumberPath<Double> gross; + private CollectionPath<String, StringPath> titles; + + private NumberPath<Long> longField; + private NumberPath<Short> shortField; + private NumberPath<Byte> byteField; + private NumberPath<Float> floatField; + + private static final String YEAR_PREFIX_CODED = ""; + private static final String GROSS_PREFIX_CODED = ""; + private static final String LONG_PREFIX_CODED = ""; + private static final String SHORT_PREFIX_CODED = ""; + private static final String BYTE_PREFIX_CODED = ""; + private static final String FLOAT_PREFIX_CODED = ""; + + private IndexWriterConfig config; + private RAMDirectory idx; + private IndexWriter writer; + private IndexSearcher searcher; + + private static final Set<? extends Operator> UNSUPPORTED_OPERATORS = Collections.unmodifiableSet(EnumSet.of(Ops.STARTS_WITH_IC, + Ops.EQ_IGNORE_CASE, Ops.ENDS_WITH_IC, Ops.STRING_CONTAINS_IC)); + + private final QueryMetadata metadata = new DefaultQueryMetadata(); + + private Document createDocument() { + Document doc = new Document(); + + doc.add(new Field("title", new StringReader("Jurassic Park"))); + doc.add(new Field("author", new StringReader("Michael Crichton"))); + doc.add(new Field("text", new StringReader( + "It's a UNIX system! I know this!"))); + doc.add(new Field("rating", new StringReader("Good"))); + doc.add(new Field("publisher", "", Store.YES, Index.ANALYZED)); + doc.add(new IntField("year", 1990, Store.YES)); + doc.add(new DoubleField("gross", 900.0, Store.YES)); + + doc.add(new LongField("longField", 1, Store.YES)); + doc.add(new IntField("shortField", 1, Store.YES)); + doc.add(new IntField("byteField", 1, Store.YES)); + doc.add(new FloatField("floatField", 1, Store.YES)); + + return doc; + } + + @Before + public void setUp() throws Exception { + serializer = new LuceneSerializer(true, true); + entityPath = new PathBuilder<Object>(Object.class, "obj"); + title = entityPath.getString("title"); + author = entityPath.getString("author"); + text = entityPath.getString("text"); + publisher = entityPath.getString("publisher"); + year = entityPath.getNumber("year", Integer.class); + rating = entityPath.getString("rating"); + gross = entityPath.getNumber("gross", Double.class); + titles = entityPath.getCollection("title", String.class, + StringPath.class); + + longField = entityPath.getNumber("longField", Long.class); + shortField = entityPath.getNumber("shortField", Short.class); + byteField = entityPath.getNumber("byteField", Byte.class); + floatField = entityPath.getNumber("floatField", Float.class); + + idx = new RAMDirectory(); + config = new IndexWriterConfig(new StandardAnalyzer()) + .setOpenMode(IndexWriterConfig.OpenMode.CREATE); + writer = new IndexWriter(idx, config); + + writer.addDocument(createDocument()); + + writer.close(); + + IndexReader reader = DirectoryReader.open(idx); + searcher = new IndexSearcher(reader); + } + + @After + public void tearDown() throws Exception { + searcher.getIndexReader().close(); + } + + private void testQuery(Expression<?> expr, int expectedHits) + throws Exception { + Query query = serializer.toQuery(expr, metadata); + TopDocs docs = searcher.search(query, 100); + assertEquals(expectedHits, docs.totalHits); + } + + private void testQuery(Expression<?> expr, String expectedQuery, + int expectedHits) throws Exception { + Query query = serializer.toQuery(expr, metadata); + TopDocs docs = searcher.search(query, 100); + assertEquals(expectedHits, docs.totalHits); + assertEquals(expectedQuery, query.toString()); + } + + @Test + public void queryElement() throws Exception { + Query query1 = serializer.toQuery(author.like("Michael"), metadata); + Query query2 = serializer.toQuery(text.like("Text"), metadata); + + BooleanExpression query = Expressions.anyOf(new QueryElement(query1), + new QueryElement(query2)); + testQuery(query, "author:michael text:text", 1); + } + + @Test + public void like() throws Exception { + testQuery(author.like("*ichael*"), "author:*ichael*", 1); + } + + @Test + public void like_custom_wildcard_single_character() throws Exception { + testQuery(author.like("Mi?hael"), "author:mi?hael", 1); + } + + @Test + public void like_custom_wildcard_multiple_character() throws Exception { + testQuery(text.like("*U*X*"), "text:*u*x*", 1); + } + + @Test + public void like_phrase() throws Exception { + testQuery(title.like("*rassic Par*"), "+title:**rassic* +title:*par**", + 1); + } + + @Test + public void like_or_like() throws Exception { + testQuery(title.like("House").or(author.like("*ichae*")), + "title:house author:*ichae*", 1); + } + + @Test + public void like_and_like() throws Exception { + testQuery(title.like("*assic*").and(rating.like("G?od")), + "+title:*assic* +rating:g?od", 1); + } + + @Test + public void eq() throws Exception { + testQuery(rating.eq("good"), "rating:good", 1); + } + + @Test + public void eq_with_deep_path() throws Exception { + StringPath deepPath = entityPath.get("property1", Object.class) + .getString("property2"); + testQuery(deepPath.eq("good"), "property1.property2:good", 0); + } + + @Test + public void fuzzyLike() throws Exception { + testQuery(LuceneExpressions.fuzzyLike(rating, "Good"), "rating:Good~2", + 1); + } + + @Test + public void fuzzyLike_with_similarity() throws Exception { + testQuery(LuceneExpressions.fuzzyLike(rating, "Good", 2), + "rating:Good~2", 1); + } + + @Test + public void fuzzyLike_with_similarity_and_prefix() throws Exception { + testQuery(LuceneExpressions.fuzzyLike(rating, "Good", 2, 0), + "rating:Good~2", 1); + } + + @Test + @Ignore + public void eq_numeric_integer() throws Exception { + testQuery(year.eq(1990), "year:" + YEAR_PREFIX_CODED, 1); + } + + @Test + @Ignore + public void eq_numeric_double() throws Exception { + testQuery(gross.eq(900.00), "gross:" + GROSS_PREFIX_CODED, 1); + } + + @Test + @Ignore + public void eq_numeric() throws Exception { + testQuery(longField.eq(1L), "longField:" + LONG_PREFIX_CODED, 1); + testQuery(shortField.eq((short) 1), "shortField:" + SHORT_PREFIX_CODED, + 1); + testQuery(byteField.eq((byte) 1), "byteField:" + BYTE_PREFIX_CODED, 1); + testQuery(floatField.eq((float) 1.0), "floatField:" + + FLOAT_PREFIX_CODED, 1); + } + + @Test + public void equals_ignores_case() throws Exception { + testQuery(title.eq("Jurassic"), "title:jurassic", 1); + } + + @Test(expected = UnsupportedOperationException.class) + public void title_equals_ignore_case_or_year_equals() throws Exception { + testQuery(title.equalsIgnoreCase("House").or(year.eq(1990)), + "title:house year:" + YEAR_PREFIX_CODED, 1); + } + + @Test + @Ignore + public void eq_and_eq() throws Exception { + testQuery(title.eq("Jurassic Park").and(year.eq(1990)), + "+title:\"jurassic park\" +year:" + YEAR_PREFIX_CODED, 1); + } + + @Test + @Ignore + public void eq_and_eq_and_eq() throws Exception { + testQuery( + title.eq("Jurassic Park").and(year.eq(1990)) + .and(author.eq("Michael Crichton")), + "+(+title:\"jurassic park\" +year:" + YEAR_PREFIX_CODED + + ") +author:\"michael crichton\"", 1); + } + + @Test(expected = UnsupportedOperationException.class) + public void equals_ignore_case_and_or() throws Exception { + testQuery( + title.equalsIgnoreCase("Jurassic Park") + .and(rating.equalsIgnoreCase("Bad")) + .or(author.equalsIgnoreCase("Michael Crichton")), + "(+title:\"jurassic park\" +rating:bad) author:\"michael crichton\"", + 1); + } + + @Test + public void eq_or_eq_and_eq_does_not_find_results() throws Exception { + testQuery( + title.eq("jeeves").or(rating.eq("superb")) + .and(author.eq("michael crichton")), + "+(title:jeeves rating:superb) +author:\"michael crichton\"", 0); + } + + @Test + public void eq_phrase() throws Exception { + testQuery(title.eq("Jurassic Park"), "title:\"jurassic park\"", 1); + } + + @Test + @Ignore("Not easily done in Lucene!") + public void publisher_equals_empty_string() throws Exception { + testQuery(publisher.eq(""), "publisher:", 1); + } + + @Test + public void eq_phrase_should_not_find_results_but_luceNe_semantics_differs_from_querydsls() + throws Exception { + testQuery(text.eq("UNIX System"), "text:\"unix system\"", 1); + } + + @Test + public void eq_phrase_does_not_find_results_because_word_in_middle() + throws Exception { + testQuery(title.eq("Jurassic Amusement Park"), + "title:\"jurassic amusement park\"", 0); + } + + @Test + public void like_not_does_not_find_results() throws Exception { + testQuery(title.like("*H*e*").not(), "-title:*h*e* +*:*", 1); + } + + @Test(expected = UnsupportedOperationException.class) + public void title_equals_ignore_case_negation_or_rating_equals_ignore_case() + throws Exception { + testQuery( + title.equalsIgnoreCase("House").not() + .or(rating.equalsIgnoreCase("Good")), + "-title:house rating:good", 1); + } + + @Test + public void eq_not_does_not_find_results() throws Exception { + testQuery(title.eq("Jurassic Park").not(), + "-title:\"jurassic park\" +*:*", 0); + } + + @Test + public void title_equals_not_house() throws Exception { + testQuery(title.eq("house").not(), "-title:house +*:*", 1); + } + + @Test + public void eq_and_eq_not_does_not_find_results_because_second_expression_finds_nothing() + throws Exception { + testQuery(rating.eq("superb").and(title.eq("house").not()), + "+rating:superb +(-title:house +*:*)", 0); + } + + @Test + public void not_equals_finds_one() throws Exception { + testQuery(title.ne("house"), "-title:house +*:*", 1); + } + + @Test + public void not_equals_finds_none() throws Exception { + testQuery(title.ne("Jurassic Park"), "-title:\"jurassic park\" +*:*", 0); + } + + @Test + public void nothing_found_with_not_equals_or_equals() throws Exception { + testQuery(title.ne("jurassic park").or(rating.eq("lousy")), + "(-title:\"jurassic park\" +*:*) rating:lousy", 0); + } + + @Test + public void ne_and_eq() throws Exception { + testQuery(title.ne("house").and(rating.eq("good")), + "+(-title:house +*:*) +rating:good", 1); + } + + @Test + public void startsWith() throws Exception { + testQuery(title.startsWith("Jurassi"), "title:jurassi*", 1); + } + + @Test + public void startsWith_phrase() throws Exception { + testQuery(title.startsWith("jurassic par"), + "+title:jurassic* +title:*par*", 1); + } + + @Test(expected = UnsupportedOperationException.class) + public void starts_with_ignore_case_phrase_does_not_find_results() + throws Exception { + testQuery(title.startsWithIgnoreCase("urassic Par"), + "+title:urassic* +title:*par*", 0); + } + + @Test + public void endsWith() throws Exception { + testQuery(title.endsWith("ark"), "title:*ark", 1); + } + + @Test(expected = UnsupportedOperationException.class) + public void ends_with_ignore_case_phrase() throws Exception { + testQuery(title.endsWithIgnoreCase("sic Park"), + "+title:*sic* +title:*park", 1); + } + + @Test(expected = UnsupportedOperationException.class) + public void ends_with_ignore_case_phrase_does_not_find_results() + throws Exception { + testQuery(title.endsWithIgnoreCase("sic Par"), + "+title:*sic* +title:*par", 0); + } + + @Test + public void contains() throws Exception { + testQuery(title.contains("rassi"), "title:*rassi*", 1); + } + + @Test(expected = UnsupportedOperationException.class) + public void contains_ignore_case_phrase() throws Exception { + testQuery(title.containsIgnoreCase("rassi Pa"), + "+title:*rassi* +title:*pa*", 1); + } + + @Test + public void contains_user_inputted_wildcards_dont_work() throws Exception { + testQuery(title.contains("r*i"), "title:*r\\*i*", 0); + } + + @Test + public void between() throws Exception { + testQuery(title.between("Indiana", "Kundun"), + "title:[indiana TO kundun]", 1); + } + + @Test + public void between_numeric_integer() throws Exception { + testQuery(year.between(1980, 2000), "year:[1980 TO 2000]", 1); + } + + @Test + public void between_numeric_double() throws Exception { + testQuery(gross.between(10.00, 19030.00), "gross:[10.0 TO 19030.0]", 1); + } + + @Test + public void between_numeric() throws Exception { + testQuery(longField.between(0L, 2L), "longField:[0 TO 2]", 1); + testQuery(shortField.between((short) 0, (short) 2), + "shortField:[0 TO 2]", 1); + testQuery(byteField.between((byte) 0, (byte) 2), "byteField:[0 TO 2]", + 1); + testQuery(floatField.between((float) 0.0, (float) 2.0), + "floatField:[0.0 TO 2.0]", 1); + } + + @Test + public void between_is_inclusive_from_start() throws Exception { + testQuery(title.between("Jurassic", "Kundun"), + "title:[jurassic TO kundun]", 1); + } + + @Test + public void between_is_inclusive_to_end() throws Exception { + testQuery(title.between("Indiana", "Jurassic"), + "title:[indiana TO jurassic]", 1); + } + + @Test + public void between_does_not_find_results() throws Exception { + testQuery(title.between("Indiana", "Jurassib"), + "title:[indiana TO jurassib]", 0); + } + + @Test + public void in() throws Exception { + testQuery(title.in(Arrays.asList("jurassic", "park")), + "title:jurassic title:park", 1); + testQuery(title.in("jurassic", "park"), "title:jurassic title:park", 1); + testQuery(title.eq("jurassic").or(title.eq("park")), + "title:jurassic title:park", 1); + } + + @Test + public void lt() throws Exception { + testQuery(rating.lt("Superb"), "rating:{* TO superb}", 1); + } + + @Test + public void lt_numeric_integer() throws Exception { + testQuery(year.lt(1991), "year:{* TO 1991}", 1); + } + + @Test + public void lt_numeric_double() throws Exception { + testQuery(gross.lt(10000.0), "gross:{* TO 10000.0}", 1); + } + + @Test + public void lt_not_in_range_because_equal() throws Exception { + testQuery(rating.lt("Good"), "rating:{* TO good}", 0); + } + + @Test + public void lt_numeric_integer_not_in_range_because_equal() + throws Exception { + testQuery(year.lt(1990), "year:{* TO 1990}", 0); + } + + @Test + public void lt_numeric_double_not_in_range_because_equal() throws Exception { + testQuery(gross.lt(900.0), "gross:{* TO 900.0}", 0); + } + + @Test + public void loe() throws Exception { + testQuery(rating.loe("Superb"), "rating:[* TO superb]", 1); + } + + @Test + public void loe_numeric_integer() throws Exception { + testQuery(year.loe(1991), "year:[* TO 1991]", 1); + } + + @Test + public void loe_numeric_double() throws Exception { + testQuery(gross.loe(903.0), "gross:[* TO 903.0]", 1); + } + + @Test + public void loe_equal() throws Exception { + testQuery(rating.loe("Good"), "rating:[* TO good]", 1); + } + + @Test + public void loe_numeric_integer_equal() throws Exception { + testQuery(year.loe(1990), "year:[* TO 1990]", 1); + } + + @Test + public void loe_numeric_double_equal() throws Exception { + testQuery(gross.loe(900.0), "gross:[* TO 900.0]", 1); + } + + @Test + public void loe_not_found() throws Exception { + testQuery(rating.loe("Bad"), "rating:[* TO bad]", 0); + } + + @Test + public void loe_numeric_integer_not_found() throws Exception { + testQuery(year.loe(1989), "year:[* TO 1989]", 0); + } + + @Test + public void loe_numeric_double_not_found() throws Exception { + testQuery(gross.loe(899.9), "gross:[* TO 899.9]", 0); + } + + @Test + public void gt() throws Exception { + testQuery(rating.gt("Bad"), "rating:{bad TO *}", 1); + } + + @Test + public void gt_numeric_integer() throws Exception { + testQuery(year.gt(1989), "year:{1989 TO *}", 1); + } + + @Test + public void gt_numeric_double() throws Exception { + testQuery(gross.gt(100.00), "gross:{100.0 TO *}", 1); + } + + @Test + public void gt_not_in_range_because_equal() throws Exception { + testQuery(rating.gt("Good"), "rating:{good TO *}", 0); + } + + @Test + public void gt_numeric_integer_not_in_range_because_equal() + throws Exception { + testQuery(year.gt(1990), "year:{1990 TO *}", 0); + } + + @Test + public void gt_numeric_double_not_in_range_because_equal() throws Exception { + testQuery(gross.gt(900.00), "gross:{900.0 TO *}", 0); + } + + @Test + public void goe() throws Exception { + testQuery(rating.goe("Bad"), "rating:[bad TO *]", 1); + } + + @Test + public void goe_numeric_integer() throws Exception { + testQuery(year.goe(1989), "year:[1989 TO *]", 1); + } + + @Test + public void goe_numeric_double() throws Exception { + testQuery(gross.goe(320.50), "gross:[320.5 TO *]", 1); + } + + @Test + public void goe_equal() throws Exception { + testQuery(rating.goe("Good"), "rating:[good TO *]", 1); + } + + @Test + public void goe_numeric_integer_equal() throws Exception { + testQuery(year.goe(1990), "year:[1990 TO *]", 1); + } + + @Test + public void goe_numeric_double_equal() throws Exception { + testQuery(gross.goe(900.00), "gross:[900.0 TO *]", 1); + } + + @Test + public void goe_not_found() throws Exception { + testQuery(rating.goe("Hood"), "rating:[hood TO *]", 0); + } + + @Test + public void goe_numeric_integer_not_found() throws Exception { + testQuery(year.goe(1991), "year:[1991 TO *]", 0); + } + + @Test + public void goe_numeric_double_not_found() throws Exception { + testQuery(gross.goe(900.10), "gross:[900.1 TO *]", 0); + } + + @Test + public void equals_empty_string() throws Exception { + testQuery(title.eq(""), "title:", 0); + } + + @Test + public void not_equals_empty_string() throws Exception { + testQuery(title.ne(""), "-title: +*:*", 1); + } + + @Test + public void contains_empty_string() throws Exception { + testQuery(title.contains(""), "title:**", 1); + } + + @Test + public void like_empty_string() throws Exception { + testQuery(title.like(""), "title:", 0); + } + + @Test + public void starts_with_empty_string() throws Exception { + testQuery(title.startsWith(""), "title:*", 1); + } + + @Test + public void ends_with_empty_string() throws Exception { + testQuery(title.endsWith(""), "title:*", 1); + } + + @Test + public void between_empty_strings() throws Exception { + testQuery(title.between("", ""), "title:[ TO ]", 0); + } + + @Test + public void booleanBuilder() throws Exception { + testQuery(new BooleanBuilder(gross.goe(900.10)), "gross:[900.1 TO *]", + 0); + } + + @Test + @Ignore + public void fuzzy() throws Exception { + fail("Not yet implemented!"); + } + + @Test + @Ignore + public void proximity() throws Exception { + fail("Not yet implemented!"); + } + + @Test + @Ignore + public void boost() throws Exception { + fail("Not yet implemented!"); + } + + @Test + public void pathAny() throws Exception { + testQuery(titles.any().eq("Jurassic"), "title:jurassic", 1); + } + + private boolean unsupportedOperation(Predicate filter) { + return UNSUPPORTED_OPERATORS.contains(((Operation<?>) filter).getOperator()); + } + + @Test + public void various() throws Exception { + MatchingFiltersFactory filters = new MatchingFiltersFactory( + QuerydslModule.LUCENE, Target.LUCENE); + for (Predicate filter : filters.string(title, + StringConstant.create("jurassic park"))) { + if (unsupportedOperation(filter)) { + continue; + } + testQuery(filter, 1); + } + + for (Predicate filter : filters.string(author, + StringConstant.create("michael crichton"))) { + if (unsupportedOperation(filter)) { + continue; + } + testQuery(filter, 1); + } + + for (Predicate filter : filters.string(title, + StringConstant.create("1990"))) { + if (unsupportedOperation(filter)) { + continue; + } + testQuery(filter, 0); + } + } + +} diff --git a/querydsl-lucene5/src/test/java/com/querydsl/lucene5/Person.java b/querydsl-lucene5/src/test/java/com/querydsl/lucene5/Person.java new file mode 100644 index 0000000000..c3f0bb1409 --- /dev/null +++ b/querydsl-lucene5/src/test/java/com/querydsl/lucene5/Person.java @@ -0,0 +1,43 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.lucene5; + +import org.joda.time.LocalDate; + +import com.querydsl.core.annotations.QueryEntity; + +@QueryEntity +public class Person { + private final String id; + private final String name; + private final LocalDate birthDate; + + public Person(String id, String name, LocalDate birthDate) { + this.id = id; + this.name = name; + this.birthDate = birthDate; + } + + public String getId() { + return id; + } + + public LocalDate getBirthDate() { + return birthDate; + } + + public String getName() { + return name; + } +} diff --git a/querydsl-lucene5/src/test/java/com/querydsl/lucene5/PhraseElementTest.java b/querydsl-lucene5/src/test/java/com/querydsl/lucene5/PhraseElementTest.java new file mode 100644 index 0000000000..0b6aebc57e --- /dev/null +++ b/querydsl-lucene5/src/test/java/com/querydsl/lucene5/PhraseElementTest.java @@ -0,0 +1,58 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.lucene5; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; + +import org.junit.Test; + +import com.querydsl.core.DefaultQueryMetadata; +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.StringPath; +import com.querydsl.lucene5.LuceneSerializer; +import com.querydsl.lucene5.PhraseElement; + +public class PhraseElementTest { + + @Test + public void test() { + StringPath title = Expressions.stringPath("title"); + LuceneSerializer serializer = new LuceneSerializer(false, false); + QueryMetadata metadata = new DefaultQueryMetadata(); + assertEquals("title:Hello World", + serializer.toQuery(title.eq("Hello World"), metadata) + .toString()); + assertEquals( + "title:\"Hello World\"", + serializer.toQuery(title.eq(new PhraseElement("Hello World")), + metadata).toString()); + } + + @Test + public void equals() { + PhraseElement el1 = new PhraseElement("x"), el2 = new PhraseElement("x"), el3 = new PhraseElement( + "y"); + assertEquals(el1, el2); + assertFalse(el1.equals(el3)); + } + + @Test + public void hashCode_() { + PhraseElement el1 = new PhraseElement("x"), el2 = new PhraseElement("x"); + assertEquals(el1.hashCode(), el2.hashCode()); + } + +} diff --git a/querydsl-lucene5/src/test/java/com/querydsl/lucene5/QDocument.java b/querydsl-lucene5/src/test/java/com/querydsl/lucene5/QDocument.java new file mode 100644 index 0000000000..da2b5e2af6 --- /dev/null +++ b/querydsl-lucene5/src/test/java/com/querydsl/lucene5/QDocument.java @@ -0,0 +1,37 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.lucene5; + +import org.apache.lucene.document.Document; + +import com.querydsl.core.types.PathMetadataFactory; +import com.querydsl.core.types.dsl.EntityPathBase; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.StringPath; + +public class QDocument extends EntityPathBase<Document> { + + private static final long serialVersionUID = -4872833626508344081L; + + public QDocument(final String var) { + super(Document.class, PathMetadataFactory.forVariable(var)); + } + + public final NumberPath<Integer> year = createNumber("year", Integer.class); + + public final StringPath title = createString("title"); + + public final NumberPath<Double> gross = createNumber("gross", Double.class); + +} \ No newline at end of file diff --git a/querydsl-lucene5/src/test/java/com/querydsl/lucene5/QueryElementTest.java b/querydsl-lucene5/src/test/java/com/querydsl/lucene5/QueryElementTest.java new file mode 100644 index 0000000000..b014f84776 --- /dev/null +++ b/querydsl-lucene5/src/test/java/com/querydsl/lucene5/QueryElementTest.java @@ -0,0 +1,39 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.lucene5; + +import static org.junit.Assert.assertEquals; + +import org.apache.lucene.index.Term; +import org.apache.lucene.search.TermQuery; +import org.junit.Ignore; +import org.junit.Test; + +import com.querydsl.lucene5.QueryElement; + +public class QueryElementTest { + + @Test + @Ignore + public void test() { + QueryElement element = new QueryElement(new TermQuery(new Term("str", + "text"))); + assertEquals("str:text", element.toString()); + // assertEquals(element.getQuery().hashCode(), element.hashCode()); + + QueryElement element2 = new QueryElement(new TermQuery(new Term("str", + "text"))); + assertEquals(element2, element); + } +} diff --git a/querydsl-lucene5/src/test/java/com/querydsl/lucene5/TermElementTest.java b/querydsl-lucene5/src/test/java/com/querydsl/lucene5/TermElementTest.java new file mode 100644 index 0000000000..73fd8bd2fd --- /dev/null +++ b/querydsl-lucene5/src/test/java/com/querydsl/lucene5/TermElementTest.java @@ -0,0 +1,53 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.lucene5; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; + +import org.junit.Test; + +import com.querydsl.core.DefaultQueryMetadata; +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.StringPath; +import com.querydsl.lucene5.LuceneSerializer; +import com.querydsl.lucene5.TermElement; + +public class TermElementTest { + + @Test + public void test() { + StringPath title = Expressions.stringPath("title"); + LuceneSerializer serializer = new LuceneSerializer(false, true); + QueryMetadata metadata = new DefaultQueryMetadata(); + assertEquals("title:\"Hello World\"", + serializer.toQuery(title.eq("Hello World"), metadata) + .toString()); + assertEquals( + "title:Hello World", + serializer.toQuery(title.eq(new TermElement("Hello World")), + metadata).toString()); + } + + @Test + public void testEqualsAndHashCode() { + TermElement el1 = new TermElement("x"), el2 = new TermElement("x"), el3 = new TermElement( + "y"); + assertEquals(el1, el2); + assertFalse(el1.equals(el3)); + assertEquals(el1.hashCode(), el2.hashCode()); + } + +} diff --git a/querydsl-lucene5/src/test/resources/log4j.properties.example b/querydsl-lucene5/src/test/resources/log4j.properties.example new file mode 100644 index 0000000000..0f193f333c --- /dev/null +++ b/querydsl-lucene5/src/test/resources/log4j.properties.example @@ -0,0 +1,9 @@ +# Configure an appender that logs to console +log4j.rootLogger=info, A1 +log4j.threshold=debug +log4j.appender.A1=org.apache.log4j.ConsoleAppender +log4j.appender.A1.layout=org.apache.log4j.PatternLayout +log4j.appender.A1.layout.ConversionPattern=%d [%t] %-5p %c{1} - %m%n + +# Configuration of logging levels for different packages +log4j.logger.com.querydsl.lucene5=DEBUG diff --git a/querydsl-maven-plugin/pom.xml b/querydsl-maven-plugin/pom.xml index acc609708f..29392fadfc 100644 --- a/querydsl-maven-plugin/pom.xml +++ b/querydsl-maven-plugin/pom.xml @@ -1,101 +1,144 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0" encoding="UTF-8"?> <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> - <modelVersion>4.0.0</modelVersion> - - <parent> - <groupId>com.mysema.querydsl</groupId> - <artifactId>querydsl-root</artifactId> - <version>3.4.1.BUILD-SNAPSHOT</version> - <relativePath>../querydsl-root/pom.xml</relativePath> - </parent> - - <groupId>com.mysema.querydsl</groupId> - <artifactId>querydsl-maven-plugin</artifactId> - <name>Querydsl - Maven plugin</name> - <description>Querydsl Maven plugin</description> - <url>${project.homepage}</url> - <packaging>maven-plugin</packaging> - - <scm> - <connection>${project.checkout}</connection> - <developerConnection>${project.checkout}</developerConnection> - <url>${project.githubpage}</url> - </scm> - - <properties> - <mvn.version>2.2.1</mvn.version> - <jdo.version>2.3-eb</jdo.version> - </properties> - - <dependencies> - <dependency> - <groupId>org.apache.maven</groupId> - <artifactId>maven-plugin-api</artifactId> - <version>${mvn.version}</version> - </dependency> - <dependency> - <groupId>org.apache.maven</groupId> - <artifactId>maven-model</artifactId> - <version>${mvn.version}</version> - </dependency> - <dependency> - <groupId>org.apache.maven</groupId> - <artifactId>maven-project</artifactId> - <version>${mvn.version}</version> - </dependency> - - <dependency> - <groupId>org.sonatype.plexus</groupId> - <artifactId>plexus-build-api</artifactId> - <version>0.0.7</version> - </dependency> - <dependency> - <groupId>org.codehaus.plexus</groupId> - <artifactId>plexus-utils</artifactId> - <version>1.5.8</version> - </dependency> - - <dependency> - <groupId>com.mysema.querydsl</groupId> - <artifactId>querydsl-sql-codegen</artifactId> - <version>${project.version}</version> - </dependency> - - <dependency> - <groupId>org.slf4j</groupId> - <artifactId>slf4j-log4j12</artifactId> - <version>1.6.1</version> - </dependency> - - <!-- annotations --> - <dependency> - <groupId>javax.jdo</groupId> - <artifactId>jdo2-api</artifactId> - <version>${jdo.version}</version> - </dependency> - <dependency> - <groupId>org.hibernate.javax.persistence</groupId> - <artifactId>hibernate-jpa-2.0-api</artifactId> - <version>1.0.0.Final</version> - </dependency> - - <!-- test --> - - <dependency> - <groupId>com.h2database</groupId> - <artifactId>h2</artifactId> - <version>1.2.133</version> - <scope>test</scope> - </dependency> - - <dependency> - <groupId>com.mysema.querydsl</groupId> - <artifactId>querydsl-core</artifactId> - <version>${project.version}</version> - <scope>test</scope> - <type>test-jar</type> - </dependency> - - </dependencies> - -</project> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>com.querydsl</groupId> + <artifactId>querydsl-root</artifactId> + <version>5.1.0</version> + <relativePath>../pom.xml</relativePath> + </parent> + + <groupId>com.querydsl</groupId> + <artifactId>querydsl-maven-plugin</artifactId> + <name>Querydsl - Maven plugin</name> + <description>Querydsl Maven plugin</description> + <url>${project.homepage}</url> + <packaging>maven-plugin</packaging> + + <scm> + <connection>${project.checkout}</connection> + <developerConnection>${project.checkout}</developerConnection> + <url>${project.githubpage}</url> + </scm> + + <properties> + <mvn.version>2.2.1</mvn.version> + <maven.javadoc.skip>true</maven.javadoc.skip> + </properties> + + <build> + <pluginManagement> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-plugin-plugin</artifactId> + <version>3.11.0</version> + </plugin> + </plugins> + </pluginManagement> + </build> + + <dependencyManagement> + <dependencies> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-utils</artifactId> + <version>3.4.1</version> + </dependency> + </dependencies> + </dependencyManagement> + + <dependencies> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-plugin-api</artifactId> + <version>${mvn.version}</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-model</artifactId> + <version>${mvn.version}</version> + </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-project</artifactId> + <version>${mvn.version}</version> + </dependency> + + <dependency> + <groupId>org.sonatype.plexus</groupId> + <artifactId>plexus-build-api</artifactId> + <version>0.0.7</version> + </dependency> + <dependency> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-utils</artifactId> + </dependency> + + <dependency> + <groupId>com.querydsl</groupId> + <artifactId>querydsl-sql-codegen</artifactId> + <version>${project.version}</version> + </dependency> + + <!-- annotations --> + <dependency> + <groupId>org.datanucleus</groupId> + <artifactId>javax.jdo</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>jakarta.persistence</groupId> + <artifactId>jakarta.persistence-api</artifactId> + <version>2.2.3</version> + <scope>provided</scope> + </dependency> + + <!-- test --> + + <dependency> + <groupId>joda-time</groupId> + <artifactId>joda-time</artifactId> + <version>${jodatime.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>com.h2database</groupId> + <artifactId>h2</artifactId> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>com.querydsl</groupId> + <artifactId>querydsl-core</artifactId> + <version>${project.version}</version> + <scope>test</scope> + <type>test-jar</type> + </dependency> + + </dependencies> + + <profiles> + <profile> + <!-- See http://stackoverflow.com/a/22296107/14731 --> + <id>doclint-java8-disable</id> + <activation> + <jdk>[1.8,)</jdk> + </activation> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-javadoc-plugin</artifactId> + <configuration> + <additionalparam>-Xdoclint:none</additionalparam> + </configuration> + </plugin> + </plugins> + </build> + </profile> + </profiles> + +</project> diff --git a/querydsl-maven-plugin/src/main/java/com/mysema/query/maven/AbstractExporterMojo.java b/querydsl-maven-plugin/src/main/java/com/mysema/query/maven/AbstractExporterMojo.java deleted file mode 100644 index ef7240e000..0000000000 --- a/querydsl-maven-plugin/src/main/java/com/mysema/query/maven/AbstractExporterMojo.java +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Copyright 2012, Mysema Ltd - * - * 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. - */ -package com.mysema.query.maven; - -import java.io.File; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLClassLoader; -import java.nio.charset.Charset; -import java.util.ArrayList; -import java.util.List; - -import org.apache.maven.artifact.DependencyResolutionRequiredException; -import org.apache.maven.plugin.AbstractMojo; -import org.apache.maven.plugin.MojoExecutionException; -import org.apache.maven.plugin.MojoFailureException; -import org.apache.maven.project.MavenProject; -import org.sonatype.plexus.build.incremental.BuildContext; - -import com.mysema.query.codegen.GenericExporter; -import com.mysema.query.codegen.Serializer; -import com.mysema.query.codegen.TypeMappings; - -/** - * AbstractExporterMojo calls the {@link GenericExporter} tool using the - * classpath of the module the plugin is invoked in. - * - */ -public abstract class AbstractExporterMojo extends AbstractMojo { - - /** - * @parameter required=true - */ - private File targetFolder; - - /** - * @parameter default-value=false - */ - private boolean scala; - - /** - * @parameter required=true - */ - private String[] packages; - - /** - * @parameter default-value=true - */ - private boolean handleFields = true; - - /** - * @parameter default-value=true - */ - private boolean handleMethods = true; - - /** - * @parameter expression="${project}" readonly=true required=true - */ - private MavenProject project; - - /** - * @parameter - */ - private String sourceEncoding; - - /** - * @parameter default-value=false - */ - private boolean testClasspath; - - /** - * @component - */ - private BuildContext buildContext; - - @SuppressWarnings("unchecked") - @Override - public void execute() throws MojoExecutionException, MojoFailureException { - if (testClasspath) { - project.addTestCompileSourceRoot(targetFolder.getAbsolutePath()); - } else { - project.addCompileSourceRoot(targetFolder.getAbsolutePath()); - } - if (!hasSourceChanges()) { - // Only run if something has changed on the source dirs. This will - // avoid m2e entering on a infinite build. - return; - } - - ClassLoader classLoader = null; - try { - classLoader = getProjectClassLoader(); - } catch (MalformedURLException e) { - throw new MojoFailureException(e.getMessage(), e); - } catch (DependencyResolutionRequiredException e) { - throw new MojoFailureException(e.getMessage(), e); - } - - Charset charset = sourceEncoding != null ? Charset.forName(sourceEncoding) : Charset.defaultCharset(); - GenericExporter exporter = new GenericExporter(classLoader, charset); - exporter.setTargetFolder(targetFolder); - - if (scala) { - try { - exporter.setSerializerClass((Class<? extends Serializer>) Class - .forName("com.mysema.query.scala.ScalaEntitySerializer")); - exporter.setTypeMappingsClass((Class<? extends TypeMappings>) Class - .forName("com.mysema.query.scala.ScalaTypeMappings")); - exporter.setCreateScalaSources(true); - } catch (ClassNotFoundException e) { - throw new MojoFailureException(e.getMessage(), e); - } - } - - configure(exporter); - exporter.export(packages); - } - - /** - * Configures the {@link GenericExporter}; subclasses may override if desired. - */ - protected void configure(GenericExporter exporter) { - exporter.setHandleFields(handleFields); - exporter.setHandleMethods(handleMethods); - } - - @SuppressWarnings("unchecked") - protected ClassLoader getProjectClassLoader() throws DependencyResolutionRequiredException, - MalformedURLException { - List<String> classpathElements; - if (testClasspath) { - classpathElements = project.getTestClasspathElements(); - } else { - classpathElements = project.getCompileClasspathElements(); - } - List<URL> urls = new ArrayList<URL>(classpathElements.size()); - for (String element : classpathElements) { - File file = new File(element); - if (file.exists()) { - urls.add(file.toURI().toURL()); - } - } - return new URLClassLoader(urls.toArray(new URL[urls.size()]), getClass().getClassLoader()); - } - - @SuppressWarnings("rawtypes") - private boolean hasSourceChanges() { - if (buildContext != null) { - List sourceRoots = testClasspath ? project.getTestCompileSourceRoots() : - project.getCompileSourceRoots(); - for (Object path : sourceRoots) { - if (buildContext.hasDelta(new File(path.toString()))) { - return true; - } - } - return false; - } else { - return true; - } - } - - public void setTargetFolder(File targetFolder) { - this.targetFolder = targetFolder; - } - - public void setScala(boolean scala) { - this.scala = scala; - } - - public void setPackages(String[] packages) { - this.packages = packages; - } - - public void setProject(MavenProject project) { - this.project = project; - } - - public void setSourceEncoding(String sourceEncoding) { - this.sourceEncoding = sourceEncoding; - } - - public void setTestClasspath(boolean testClasspath) { - this.testClasspath = testClasspath; - } - - public void setBuildContext(BuildContext buildContext) { - this.buildContext = buildContext; - } - - public void setHandleFields(boolean handleFields) { - this.handleFields = handleFields; - } - - public void setHandleMethods(boolean handleMethods) { - this.handleMethods = handleMethods; - } -} diff --git a/querydsl-maven-plugin/src/main/java/com/mysema/query/maven/AbstractMetaDataExportMojo.java b/querydsl-maven-plugin/src/main/java/com/mysema/query/maven/AbstractMetaDataExportMojo.java deleted file mode 100644 index b56f41c305..0000000000 --- a/querydsl-maven-plugin/src/main/java/com/mysema/query/maven/AbstractMetaDataExportMojo.java +++ /dev/null @@ -1,547 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.maven; - -import java.io.File; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.SQLException; -import java.util.Comparator; - -import com.mysema.codegen.model.SimpleType; -import com.mysema.query.codegen.BeanSerializer; -import com.mysema.query.sql.Configuration; -import com.mysema.query.sql.SQLTemplates; -import com.mysema.query.sql.codegen.DefaultNamingStrategy; -import com.mysema.query.sql.codegen.MetaDataExporter; -import com.mysema.query.sql.codegen.NamingStrategy; -import com.mysema.query.sql.types.Type; -import org.apache.maven.plugin.AbstractMojo; -import org.apache.maven.plugin.MojoExecutionException; -import org.apache.maven.plugin.MojoFailureException; -import org.apache.maven.project.MavenProject; - -/** - * MetaDataExportMojo is a goal for MetaDataExporter usage - * - * @author tiwe - */ -public class AbstractMetaDataExportMojo extends AbstractMojo{ - - /** - * @parameter expression="${project}" readonly=true required=true - */ - private MavenProject project; - - /** - * JDBC driver class name - * @parameter required=true - */ - private String jdbcDriver; - - /** - * JDBC connection url - * @parameter required=true - */ - private String jdbcUrl; - - /** - * JDBC connection username - * @parameter - */ - private String jdbcUser; - - /** - * JDBC connection password - * @parameter - */ - private String jdbcPassword; - - /** - * name prefix for query-types (default: "Q") - * @parameter default-value="Q" - */ - private String namePrefix; - - /** - * name prefix for query-types (default: "") - * @parameter default-value="" - */ - private String nameSuffix; - - /** - * name prefix for bean types (default: "") - * @parameter default-value="" - */ - private String beanPrefix; - - /** - * name prefix for bean types (default: "") - * @parameter default-value="" - */ - private String beanSuffix; - - /** - * package name for sources - * @parameter required=true - */ - private String packageName; - - /** - * package name for bean sources (default: packageName) - * @parameter - */ - private String beanPackageName; - - /** - * schemaPattern a schema name pattern; must match the schema name - * as it is stored in the database; "" retrieves those without a schema; - * <code>null</code> means that the schema name should not be used to narrow - * the search (default: null) - * - * @parameter - */ - private String schemaPattern; - - /** - * tableNamePattern a table name pattern; must match the - * table name as it is stored in the database (default: null) - * - * @parameter - */ - private String tableNamePattern; - - /** - * target source folder to create the sources into (e.g. target/generated-sources/java) - * - * @parameter required=true - */ - private String targetFolder; - - /** - * namingstrategy class to override (default: DefaultNamingStrategy) - * - * @parameter - */ - private String namingStrategyClass; - - /** - * @parameter - */ - private String beanSerializerClass; - - /** - * @parameter - */ - private String serializerClass; - - /** - * serialize beans as well - * - * @parameter default-value=false - */ - private boolean exportBeans; - - /** - * @parameter - */ - private String[] beanInterfaces; - - /** - * @parameter default-value=false - */ - private boolean beanAddToString; - - /** - * @parameter default-value=false - */ - private boolean beanAddFullConstructor; - - /** - * @parameter default-value=false - */ - private boolean beanPrintSupertype; - - /** - * wrap key properties into inner classes (default: false) - * - * @parameter default-value=false - */ - private boolean innerClassesForKeys; - - /** - * export validation annotations (default: false) - * - * @parameter default-value=false - */ - private boolean validationAnnotations; - - /** - * export column annotations (default: false) - * - * @parameter default-value=false - */ - private boolean columnAnnotations; - - /** - * @parameter - */ - private String[] customTypes; - - /** - * @parameter - */ - private TypeMapping[] typeMappings; - - /** - * @parameter - */ - private NumericMapping[] numericMappings; - - /** - * @parameter default-value=false - */ - private boolean createScalaSources; - - /** - * @parameter default-value=false - */ - private boolean schemaToPackage; - - /** - * @parameter default-value=false - */ - private boolean lowerCase; - - /** - * @parameter default-value=true - */ - private boolean exportTables; - - /** - * @parameter default-value=true - */ - private boolean exportViews; - - /** - * @parameter default-value=false - */ - private boolean exportAll; - - /** - * @parameter default-value=true - */ - private boolean exportPrimaryKeys; - - /** - * @parameter default-value=true - */ - private boolean exportForeignKeys; - - /** - * override default column order (default: alphabetical) - * - * @parameter - */ - private String columnComparatorClass; - - /** - * @parameter default-value=false - */ - private boolean spatial; - - /** - * java import added to generated query classes: - * com.bar for package (without .* notation) - * com.bar.Foo for class - * - * @parameter - */ - private String[] imports; - - @SuppressWarnings({ "unchecked", "rawtypes" }) - @Override - public void execute() throws MojoExecutionException, MojoFailureException { - if (isForTest()) { - project.addTestCompileSourceRoot(targetFolder); - } else { - project.addCompileSourceRoot(targetFolder); - } - - try { - Configuration configuration = new Configuration(SQLTemplates.DEFAULT); - NamingStrategy namingStrategy; - if (namingStrategyClass != null) { - namingStrategy = (NamingStrategy) Class.forName(namingStrategyClass).newInstance(); - } else { - namingStrategy = new DefaultNamingStrategy(); - } - - // defaults for Scala - if (createScalaSources) { - if (serializerClass == null) { - serializerClass = "com.mysema.query.scala.sql.ScalaMetaDataSerializer"; - } - if (exportBeans && beanSerializerClass == null) { - beanSerializerClass = "com.mysema.query.scala.ScalaBeanSerializer"; - } - } - - MetaDataExporter exporter = new MetaDataExporter(); - if (namePrefix != null) { - exporter.setNamePrefix(namePrefix); - } - if (nameSuffix != null) { - exporter.setNameSuffix(nameSuffix); - } - if (beanPrefix != null) { - exporter.setBeanPrefix(beanPrefix); - } - if (beanSuffix != null) { - exporter.setBeanSuffix(beanSuffix); - } - exporter.setCreateScalaSources(createScalaSources); - exporter.setPackageName(packageName); - exporter.setBeanPackageName(beanPackageName); - exporter.setInnerClassesForKeys(innerClassesForKeys); - exporter.setTargetFolder(new File(targetFolder)); - exporter.setNamingStrategy(namingStrategy); - exporter.setSchemaPattern(schemaPattern); - exporter.setTableNamePattern(tableNamePattern); - exporter.setColumnAnnotations(columnAnnotations); - exporter.setValidationAnnotations(validationAnnotations); - exporter.setSchemaToPackage(schemaToPackage); - exporter.setLowerCase(lowerCase); - exporter.setExportTables(exportTables); - exporter.setExportViews(exportViews); - exporter.setExportAll(exportAll); - exporter.setExportPrimaryKeys(exportPrimaryKeys); - exporter.setExportForeignKeys(exportForeignKeys); - exporter.setSpatial(spatial); - - if (imports != null && imports.length > 0) { - exporter.setImports(imports); - } - - if (serializerClass != null) { - try { - exporter.setSerializerClass((Class)Class.forName(serializerClass)); - } catch (ClassNotFoundException e) { - getLog().error(e); - throw new MojoExecutionException(e.getMessage(), e); - } - } - if (exportBeans) { - if (beanSerializerClass != null) { - exporter.setBeanSerializerClass((Class)Class.forName(beanSerializerClass)); - } else { - BeanSerializer serializer = new BeanSerializer(); - if (beanInterfaces != null) { - for (String iface : beanInterfaces) { - int sepIndex = iface.lastIndexOf('.'); - if (sepIndex < 0) { - serializer.addInterface(new SimpleType(iface)); - } else { - String packageName = iface.substring(0, sepIndex); - String simpleName = iface.substring(sepIndex + 1); - serializer.addInterface(new SimpleType(iface, packageName, simpleName)); - } - } - } - serializer.setAddFullConstructor(beanAddFullConstructor); - serializer.setAddToString(beanAddToString); - serializer.setPrintSupertype(beanPrintSupertype); - exporter.setBeanSerializer(serializer); - } - - } - String sourceEncoding = (String)project.getProperties().get("project.build.sourceEncoding"); - if (sourceEncoding != null) { - exporter.setSourceEncoding(sourceEncoding); - } - - if (customTypes != null) { - for (String cl : customTypes) { - configuration.register((Type<?>) Class.forName(cl).newInstance()); - } - } - if (typeMappings != null) { - for (TypeMapping mapping : typeMappings) { - Class<?> typeClass = Class.forName(mapping.type); - if (Type.class.isAssignableFrom(typeClass)) { - configuration.register(mapping.table, mapping.column, (Type<?>)typeClass.newInstance()); - } else { - configuration.register(mapping.table, mapping.column, typeClass); - } - } - } - if (numericMappings != null) { - for (NumericMapping mapping : numericMappings) { - int total = Math.max(mapping.size, mapping.total); - int decimal = Math.max(mapping.digits, mapping.decimal); - configuration.registerNumeric(total, decimal, Class.forName(mapping.javaType)); - } - } - if (columnComparatorClass != null) { - try { - exporter.setColumnComparatorClass( (Class) Class.forName(this.columnComparatorClass).asSubclass(Comparator.class)); - } catch (ClassNotFoundException e) { - getLog().error(e); - throw new MojoExecutionException(e.getMessage(), e); - } - } - - exporter.setConfiguration(configuration); - - Class.forName(jdbcDriver); - Connection conn = DriverManager.getConnection(jdbcUrl, jdbcUser, jdbcPassword); - try{ - exporter.export(conn.getMetaData()); - } finally { - if (conn != null) { - conn.close(); - } - } - } catch (ClassNotFoundException e) { - throw new MojoExecutionException(e.getMessage(), e); - } catch (SQLException e) { - throw new MojoExecutionException(e.getMessage(), e); - } catch (InstantiationException e) { - throw new MojoExecutionException(e.getMessage(), e); - } catch (IllegalAccessException e) { - throw new MojoExecutionException(e.getMessage(), e); - } - - } - - protected boolean isForTest() { - return false; - } - - public void setProject(MavenProject project) { - this.project = project; - } - - public void setJdbcDriver(String jdbcDriver) { - this.jdbcDriver = jdbcDriver; - } - - public void setJdbcUrl(String jdbcUrl) { - this.jdbcUrl = jdbcUrl; - } - - public void setJdbcUser(String jdbcUser) { - this.jdbcUser = jdbcUser; - } - - public void setJdbcPassword(String jdbcPassword) { - this.jdbcPassword = jdbcPassword; - } - - public void setNamePrefix(String namePrefix) { - this.namePrefix = namePrefix; - } - - public void setNameSuffix(String nameSuffix) { - this.nameSuffix = nameSuffix; - } - - public void setBeanInterfaces(String[] beanInterfaces) { - this.beanInterfaces = beanInterfaces; - } - - public void setBeanPrefix(String beanPrefix) { - this.beanPrefix = beanPrefix; - } - - public void setBeanSuffix(String beanSuffix) { - this.beanSuffix = beanSuffix; - } - - public void setPackageName(String packageName) { - this.packageName = packageName; - } - - public void setBeanPackageName(String beanPackageName) { - this.beanPackageName = beanPackageName; - } - - public void setSchemaPattern(String schemaPattern) { - this.schemaPattern = schemaPattern; - } - - public void setTableNamePattern(String tableNamePattern) { - this.tableNamePattern = tableNamePattern; - } - - public void setTargetFolder(String targetFolder) { - this.targetFolder = targetFolder; - } - - public void setNamingStrategyClass(String namingStrategyClass) { - this.namingStrategyClass = namingStrategyClass; - } - - public void setBeanSerializerClass(String beanSerializerClass) { - this.beanSerializerClass = beanSerializerClass; - } - - public void setSerializerClass(String serializerClass) { - this.serializerClass = serializerClass; - } - - public void setExportBeans(boolean exportBeans) { - this.exportBeans = exportBeans; - } - - public void setInnerClassesForKeys(boolean innerClassesForKeys) { - this.innerClassesForKeys = innerClassesForKeys; - } - - public void setValidationAnnotations(boolean validationAnnotations) { - this.validationAnnotations = validationAnnotations; - } - - public void setColumnAnnotations(boolean columnAnnotations) { - this.columnAnnotations = columnAnnotations; - } - - public void setCustomTypes(String[] customTypes) { - this.customTypes = customTypes; - } - - public void setCreateScalaSources(boolean createScalaSources) { - this.createScalaSources = createScalaSources; - } - - public void setSchemaToPackage(boolean schemaToPackage) { - this.schemaToPackage = schemaToPackage; - } - - public void setLowerCase(boolean lowerCase) { - this.lowerCase = lowerCase; - } - - public void setTypeMappings(TypeMapping[] typeMappings) { - this.typeMappings = typeMappings; - } - - public void setNumericMappings(NumericMapping[] numericMappings) { - this.numericMappings = numericMappings; - } - - public void setImports(String[] imports) { - this.imports = imports; - } -} diff --git a/querydsl-maven-plugin/src/main/java/com/mysema/query/maven/GenericExporterMojo.java b/querydsl-maven-plugin/src/main/java/com/mysema/query/maven/GenericExporterMojo.java deleted file mode 100644 index 56a335d83b..0000000000 --- a/querydsl-maven-plugin/src/main/java/com/mysema/query/maven/GenericExporterMojo.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2012, Mysema Ltd - * - * 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. - */ -package com.mysema.query.maven; - -/** - * GenericExporterMojo calls the GenericExporter tool using the classpath of the module - * - * @goal generic-export - * @requiresDependencyResolution test - */ -public class GenericExporterMojo extends AbstractExporterMojo { - -} diff --git a/querydsl-maven-plugin/src/main/java/com/mysema/query/maven/JPAExporterMojo.java b/querydsl-maven-plugin/src/main/java/com/mysema/query/maven/JPAExporterMojo.java deleted file mode 100644 index 9bd7b07437..0000000000 --- a/querydsl-maven-plugin/src/main/java/com/mysema/query/maven/JPAExporterMojo.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2012, Mysema Ltd - * - * 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. - */ -package com.mysema.query.maven; - -import javax.persistence.Embeddable; -import javax.persistence.Embedded; -import javax.persistence.Entity; -import javax.persistence.MappedSuperclass; -import javax.persistence.Transient; - -import com.mysema.query.codegen.GenericExporter; - -/** - * JPAExporterMojo calls the GenericExporter tool using the classpath of the module - * - * @goal jpa-export - * @requiresDependencyResolution test - * @author tiwe - */ -public class JPAExporterMojo extends AbstractExporterMojo { - - @Override - protected void configure(GenericExporter exporter) { - super.configure(exporter); - exporter.setEmbeddableAnnotation(Embeddable.class); - exporter.setEmbeddedAnnotation(Embedded.class); - exporter.setEntityAnnotation(Entity.class); - exporter.setSkipAnnotation(Transient.class); - exporter.setSupertypeAnnotation(MappedSuperclass.class); - } - -} diff --git a/querydsl-maven-plugin/src/main/java/com/mysema/query/maven/MetadataExportMojo.java b/querydsl-maven-plugin/src/main/java/com/mysema/query/maven/MetadataExportMojo.java deleted file mode 100644 index f942aacd45..0000000000 --- a/querydsl-maven-plugin/src/main/java/com/mysema/query/maven/MetadataExportMojo.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.maven; - -/** - * MetadataExportMojo is a goal for MetaDataExporter usage and is bound to the generate-sources phased - * - * @phase generate-sources - * @goal export - * - */ -public class MetadataExportMojo extends AbstractMetaDataExportMojo{ - - protected boolean isForTest() { - return false; - } -} diff --git a/querydsl-maven-plugin/src/main/java/com/mysema/query/maven/NumericMapping.java b/querydsl-maven-plugin/src/main/java/com/mysema/query/maven/NumericMapping.java deleted file mode 100644 index 44ac80a98d..0000000000 --- a/querydsl-maven-plugin/src/main/java/com/mysema/query/maven/NumericMapping.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2013, Mysema Ltd - * - * 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. - */ -package com.mysema.query.maven; - -/** - * @author tiwe - * - */ -public class NumericMapping { - - @Deprecated - public int size, digits; - - public int total, decimal; - - public String javaType; - -} diff --git a/querydsl-maven-plugin/src/main/java/com/mysema/query/maven/TestMetadataExportMojo.java b/querydsl-maven-plugin/src/main/java/com/mysema/query/maven/TestMetadataExportMojo.java deleted file mode 100644 index 00b323bd89..0000000000 --- a/querydsl-maven-plugin/src/main/java/com/mysema/query/maven/TestMetadataExportMojo.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.maven; - -/** - * TestMetadataExportMojo is a goal for MetaDataExporter usage and is bound to the generated-sources phase - * - * @phase generate-sources - * @goal test-export - * - */ -public class TestMetadataExportMojo extends AbstractMetaDataExportMojo{ - - protected boolean isForTest() { - return true; - } - -} diff --git a/querydsl-maven-plugin/src/main/java/com/mysema/query/maven/TypeMapping.java b/querydsl-maven-plugin/src/main/java/com/mysema/query/maven/TypeMapping.java deleted file mode 100644 index 4bbf3780a5..0000000000 --- a/querydsl-maven-plugin/src/main/java/com/mysema/query/maven/TypeMapping.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2013, Mysema Ltd - * - * 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. - */ -package com.mysema.query.maven; - -/** - * @author tiwe - * - */ -public class TypeMapping { - - public String table; - - public String column; - - public String type; - -} diff --git a/querydsl-maven-plugin/src/main/java/com/querydsl/maven/AbstractExporterMojo.java b/querydsl-maven-plugin/src/main/java/com/querydsl/maven/AbstractExporterMojo.java new file mode 100644 index 0000000000..fc7a18943d --- /dev/null +++ b/querydsl-maven-plugin/src/main/java/com/querydsl/maven/AbstractExporterMojo.java @@ -0,0 +1,264 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.maven; + +import java.io.File; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.List; + +import org.apache.maven.artifact.DependencyResolutionRequiredException; +import org.apache.maven.plugin.AbstractMojo; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.project.MavenProject; +import org.sonatype.plexus.build.incremental.BuildContext; + +import com.querydsl.codegen.GenericExporter; +import com.querydsl.codegen.Serializer; +import com.querydsl.codegen.TypeMappings; + +/** + * {@code AbstractExporterMojo} calls {@link GenericExporter} using the + * classpath of the module in which the plugin is invoked. + * + */ +public abstract class AbstractExporterMojo extends AbstractMojo { + + /** + * target folder for sources + * + * @parameter + * @required + */ + private File targetFolder; + + /** + * switch for scala source generation + * + * @parameter default-value=false + */ + private boolean scala; + + /** + * packages to be exported + * + * @parameter + * @required + */ + private String[] packages; + + /** + * switch for inspecting fields + * + * @parameter default-value=true + */ + private boolean handleFields = true; + + /** + * switch for inspecting getters + * + * @parameter default-value=true + */ + private boolean handleMethods = true; + + /** + * switch for usage of field types instead of getter types + * + * @parameter default-value=false + */ + private boolean useFieldTypes = false; + + /** + * maven project + * + * @parameter default-value="${project}" + * @readonly + */ + private MavenProject project; + + /** + * source file encoding + * + * @parameter + */ + private String sourceEncoding; + + /** + * test classpath usage switch + * + * @parameter default-value=false + */ + private boolean testClasspath; + + /** + * Whether to skip the exporting execution + * + * @parameter default-value=false property="maven.querydsl.skip" + */ + private boolean skip; + + /** + * The fully qualified class name of the <em>Single-Element Annotation</em> (with <code>String</code> element) to put on the generated sources. Defaults to + * <code>javax.annotation.Generated</code> or <code>javax.annotation.processing.Generated</code> depending on the java version. + * <em>See also</em> <a href="https://docs.oracle.com/javase/specs/jls/se8/html/jls-9.html#jls-9.7.3">Single-Element Annotation</a> + * + * @parameter + */ + private String generatedAnnotationClass; + + /** + * build context + * + * @component + */ + private BuildContext buildContext; + + @SuppressWarnings("unchecked") + @Override + public void execute() throws MojoExecutionException, MojoFailureException { + if (testClasspath) { + project.addTestCompileSourceRoot(targetFolder.getAbsolutePath()); + } else { + project.addCompileSourceRoot(targetFolder.getAbsolutePath()); + } + if (skip || !hasSourceChanges()) { + // Only run if something has changed in the source directories. This will + // prevent m2e from entering an infinite build cycle. + return; + } + + ClassLoader classLoader = null; + try { + classLoader = getProjectClassLoader(); + } catch (MalformedURLException | DependencyResolutionRequiredException e) { + throw new MojoFailureException(e.getMessage(), e); + } + + Charset charset = sourceEncoding != null ? Charset.forName(sourceEncoding) : Charset.defaultCharset(); + GenericExporter exporter = new GenericExporter(classLoader, charset); + exporter.setTargetFolder(targetFolder); + + if (scala) { + try { + exporter.setSerializerClass((Class<? extends Serializer>) Class + .forName("com.querydsl.scala.ScalaEntitySerializer")); + exporter.setTypeMappingsClass((Class<? extends TypeMappings>) Class + .forName("com.querydsl.scala.ScalaTypeMappings")); + exporter.setCreateScalaSources(true); + } catch (ClassNotFoundException e) { + throw new MojoFailureException(e.getMessage(), e); + } + } + + configure(exporter); + exporter.export(packages); + } + + /** + * Configures the {@link GenericExporter}; subclasses may override if desired. + */ + protected void configure(GenericExporter exporter) { + exporter.setHandleFields(handleFields); + exporter.setHandleMethods(handleMethods); + exporter.setUseFieldTypes(useFieldTypes); + exporter.setGeneratedAnnotationClass(generatedAnnotationClass); + } + + @SuppressWarnings("unchecked") + protected ClassLoader getProjectClassLoader() throws DependencyResolutionRequiredException, + MalformedURLException { + List<String> classpathElements; + if (testClasspath) { + classpathElements = project.getTestClasspathElements(); + } else { + classpathElements = project.getCompileClasspathElements(); + } + List<URL> urls = new ArrayList<URL>(classpathElements.size()); + for (String element : classpathElements) { + File file = new File(element); + if (file.exists()) { + urls.add(file.toURI().toURL()); + } + } + return new URLClassLoader(urls.toArray(new URL[0]), getClass().getClassLoader()); + } + + @SuppressWarnings("rawtypes") + private boolean hasSourceChanges() { + if (buildContext != null) { + List sourceRoots = testClasspath ? project.getTestCompileSourceRoots() : + project.getCompileSourceRoots(); + for (Object path : sourceRoots) { + if (buildContext.hasDelta(new File(path.toString()))) { + return true; + } + } + return false; + } else { + return true; + } + } + + public void setTargetFolder(File targetFolder) { + this.targetFolder = targetFolder; + } + + public void setScala(boolean scala) { + this.scala = scala; + } + + public void setPackages(String[] packages) { + this.packages = packages; + } + + public void setProject(MavenProject project) { + this.project = project; + } + + public void setSourceEncoding(String sourceEncoding) { + this.sourceEncoding = sourceEncoding; + } + + public void setTestClasspath(boolean testClasspath) { + this.testClasspath = testClasspath; + } + + public void setSkip(boolean skip) { + this.skip = skip; + } + + public void setBuildContext(BuildContext buildContext) { + this.buildContext = buildContext; + } + + public void setHandleFields(boolean handleFields) { + this.handleFields = handleFields; + } + + public void setHandleMethods(boolean handleMethods) { + this.handleMethods = handleMethods; + } + + public void setUseFieldTypes(boolean useFieldTypes) { + this.useFieldTypes = useFieldTypes; + } + + public void setGeneratedAnnotationClass(String generatedAnnotationClass) { + this.generatedAnnotationClass = generatedAnnotationClass; + } +} diff --git a/querydsl-maven-plugin/src/main/java/com/querydsl/maven/AbstractMetaDataExportMojo.java b/querydsl-maven-plugin/src/main/java/com/querydsl/maven/AbstractMetaDataExportMojo.java new file mode 100644 index 0000000000..495795e56d --- /dev/null +++ b/querydsl-maven-plugin/src/main/java/com/querydsl/maven/AbstractMetaDataExportMojo.java @@ -0,0 +1,719 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.maven; + +import com.querydsl.codegen.BeanSerializer; +import com.querydsl.codegen.utils.model.SimpleType; +import com.querydsl.core.util.StringUtils; +import com.querydsl.sql.Configuration; +import com.querydsl.sql.SQLTemplates; +import com.querydsl.sql.codegen.DefaultNamingStrategy; +import com.querydsl.sql.codegen.MetaDataExporter; +import com.querydsl.sql.codegen.NamingStrategy; +import com.querydsl.sql.codegen.support.NumericMapping; +import com.querydsl.sql.codegen.support.RenameMapping; +import com.querydsl.sql.codegen.support.TypeMapping; +import com.querydsl.sql.types.Type; +import org.apache.maven.artifact.manager.WagonManager; +import org.apache.maven.plugin.AbstractMojo; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.project.MavenProject; +import org.apache.maven.wagon.authentication.AuthenticationInfo; + +import java.io.File; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.util.Comparator; +import java.util.regex.Pattern; + +/** + * {@code AbstractMetaDataExportMojo} is the base class for {@link MetaDataExporter} usage + * + * @author tiwe + */ +public class AbstractMetaDataExportMojo extends AbstractMojo { + + /** + * maven project + * + * @parameter default-value="${project}" + * @readonly + */ + private MavenProject project; + + /** + * The Maven Wagon manager to use when obtaining server authentication details. + * @component + */ + private WagonManager wagonManager; + + /** + * The server id in settings.xml to use as an alternative to jdbcUser and jdbcPassword + * @parameter + */ + private String server; + + /** + * JDBC driver class name + * @parameter required=true + */ + private String jdbcDriver; + + /** + * JDBC connection url + * @parameter required=true + */ + private String jdbcUrl; + + /** + * JDBC connection username + * @parameter + */ + private String jdbcUser; + + /** + * JDBC connection password + * @parameter + */ + private String jdbcPassword; + + /** + * name prefix for querydsl-types (default: "Q") + * @parameter default-value="Q" + */ + private String namePrefix; + + /** + * name suffix for querydsl-types (default: "") + * @parameter default-value="" + */ + private String nameSuffix; + + /** + * name prefix for bean types (default: "") + * @parameter default-value="" + */ + private String beanPrefix; + + /** + * name suffix for bean types (default: "") + * @parameter default-value="" + */ + private String beanSuffix; + + /** + * package name for sources + * @parameter + * @required + */ + private String packageName; + + /** + * package name for bean sources (default: packageName) + * @parameter + */ + private String beanPackageName; + + /** + * schemaPattern a schema name pattern; must match the schema name + * as it is stored in the database; "" retrieves those without a schema; + * {@code null} means that the schema name should not be used to narrow + * the search (default: null) + * + * @parameter + */ + private String schemaPattern; + + /** + * a catalog name; must match the catalog name as it + * is stored in the database; "" retrieves those without a catalog; + * <code>null</code> means that the catalog name should not be used to narrow + * the search + * @parameter + */ + private String catalogPattern; + + /** + * tableNamePattern a table name pattern; must match the + * table name as it is stored in the database (default: null) + * + * @parameter + */ + private String tableNamePattern; + + /** + * target source folder to create the sources into (e.g. target/generated-sources/java) + * + * @parameter + * @required + */ + private String targetFolder; + + /** + * target source folder to create the bean sources into + * + * @parameter + */ + private String beansTargetFolder; + + /** + * namingstrategy class to override (default: DefaultNamingStrategy) + * + * @parameter + */ + private String namingStrategyClass; + + /** + * name for bean serializer class + * + * @parameter + */ + private String beanSerializerClass; + + /** + * name for serializer class + * + * @parameter + */ + private String serializerClass; + + /** + * serialize beans as well + * + * @parameter default-value=false + */ + private boolean exportBeans; + + /** + * additional interfaces to be implemented by beans + * + * @parameter + */ + private String[] beanInterfaces; + + /** + * switch for {@code toString} addition + * + * @parameter default-value=false + */ + private boolean beanAddToString; + + /** + * switch for full constructor addition + * + * @parameter default-value=false + */ + private boolean beanAddFullConstructor; + + /** + * switch to print supertype content + * + * @parameter default-value=false + */ + private boolean beanPrintSupertype; + + /** + * wrap key properties into inner classes (default: false) + * + * @parameter default-value=false + */ + private boolean innerClassesForKeys; + + /** + * export validation annotations (default: false) + * + * @parameter default-value=false + */ + private boolean validationAnnotations; + + /** + * export column annotations (default: false) + * + * @parameter default-value=false + */ + private boolean columnAnnotations; + + /** + * custom type classnames to use + * + * @parameter + */ + private String[] customTypes; + + /** + * custom type mappings to use + * + * @parameter + */ + private TypeMapping[] typeMappings; + + /** + * custom numeric mappings + * + * @parameter + */ + private NumericMapping[] numericMappings; + + /** + * custom rename mappings + * + * @parameter + */ + private RenameMapping[] renameMappings; + + /** + * switch for generating scala sources + * + * @parameter default-value=false + */ + private boolean createScalaSources; + + /** + * switch for using schema as suffix in package generation, full package name will be + * {@code ${packageName}.${schema}} + * + * @parameter default-value=false + */ + private boolean schemaToPackage; + + /** + * switch to normalize schema, table and column names to lowercase + * + * @parameter default-value=false + */ + private boolean lowerCase; + + /** + * switch to export tables + * + * @parameter default-value=true + */ + private boolean exportTables; + + /** + * switch to export views + * + * @parameter default-value=true + */ + private boolean exportViews; + + /** + * switch to export all types + * + * @parameter default-value=false + */ + private boolean exportAll; + + /** + * switch to export primary keys + * + * @parameter default-value=true + */ + private boolean exportPrimaryKeys; + + /** + * switch to export foreign keys + * + * @parameter default-value=true + */ + private boolean exportForeignKeys; + + /** + * switch to export direct foreign keys + * + * @parameter default-value=true + */ + private boolean exportDirectForeignKeys; + + /** + * switch to export inverse foreign keys + * + * @parameter default-value=true + */ + private boolean exportInverseForeignKeys; + + /** + * override default column order (default: alphabetical) + * + * @parameter + */ + private String columnComparatorClass; + + /** + * switch to enable spatial type support + * + * @parameter default-value=false + */ + private boolean spatial; + + /** + * Comma-separated list of table types to export (allowable values will + * depend on JDBC driver). Allows for arbitrary set of types to be exported, + * e.g.: "TABLE, MATERIALIZED VIEW". The exportTables and exportViews + * parameters will be ignored if this parameter is set. (default: none) + * + * @parameter + */ + private String tableTypesToExport; + + /** + * java import added to generated query classes: + * com.bar for package (without .* notation) + * com.bar.Foo for class + * + * @parameter + */ + private String[] imports; + + /** + * Whether to skip the exporting execution + * + * @parameter default-value=false property="maven.querydsl.skip" + */ + private boolean skip; + + /** + * The fully qualified class name of the <em>Single-Element Annotation</em> (with <code>String</code> element) to put on the generated sources.Defaults to + * <code>javax.annotation.Generated</code> or <code>javax.annotation.processing.Generated</code> depending on the java version. + * <em>See also</em> <a href="https://docs.oracle.com/javase/specs/jls/se8/html/jls-9.html#jls-9.7.3">Single-Element Annotation</a> + * + * @parameter + */ + private String generatedAnnotationClass; + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Override + public void execute() throws MojoExecutionException, MojoFailureException { + if (isForTest()) { + project.addTestCompileSourceRoot(targetFolder); + } else { + project.addCompileSourceRoot(targetFolder); + } + + if (skip) { + return; + } + + try { + Configuration configuration = new Configuration(SQLTemplates.DEFAULT); + NamingStrategy namingStrategy; + if (namingStrategyClass != null) { + namingStrategy = (NamingStrategy) Class.forName(namingStrategyClass).newInstance(); + } else { + namingStrategy = new DefaultNamingStrategy(); + } + + // defaults for Scala + if (createScalaSources) { + if (serializerClass == null) { + serializerClass = "com.querydsl.scala.sql.ScalaMetaDataSerializer"; + } + if (exportBeans && beanSerializerClass == null) { + beanSerializerClass = "com.querydsl.scala.ScalaBeanSerializer"; + } + } + + MetaDataExporter exporter = new MetaDataExporter(); + exporter.setNamePrefix(emptyIfSetToBlank(namePrefix)); + exporter.setNameSuffix(StringUtils.nullToEmpty(nameSuffix)); + exporter.setBeanPrefix(StringUtils.nullToEmpty(beanPrefix)); + exporter.setBeanSuffix(StringUtils.nullToEmpty(beanSuffix)); + if (beansTargetFolder != null) { + exporter.setBeansTargetFolder(new File(beansTargetFolder)); + } + exporter.setCreateScalaSources(createScalaSources); + exporter.setPackageName(packageName); + exporter.setBeanPackageName(beanPackageName); + exporter.setInnerClassesForKeys(innerClassesForKeys); + exporter.setTargetFolder(new File(targetFolder)); + exporter.setNamingStrategy(namingStrategy); + exporter.setCatalogPattern(catalogPattern); + exporter.setSchemaPattern(processBlankValues(schemaPattern)); + exporter.setTableNamePattern(tableNamePattern); + exporter.setColumnAnnotations(columnAnnotations); + exporter.setValidationAnnotations(validationAnnotations); + exporter.setSchemaToPackage(schemaToPackage); + exporter.setLowerCase(lowerCase); + exporter.setExportTables(exportTables); + exporter.setExportViews(exportViews); + exporter.setExportAll(exportAll); + exporter.setTableTypesToExport(tableTypesToExport); + exporter.setExportPrimaryKeys(exportPrimaryKeys); + exporter.setExportForeignKeys(exportForeignKeys); + exporter.setExportDirectForeignKeys(exportDirectForeignKeys); + exporter.setExportInverseForeignKeys(exportInverseForeignKeys); + exporter.setSpatial(spatial); + exporter.setGeneratedAnnotationClass(generatedAnnotationClass); + + if (imports != null && imports.length > 0) { + exporter.setImports(imports); + } + + if (serializerClass != null) { + try { + exporter.setSerializerClass((Class) Class.forName(serializerClass)); + } catch (ClassNotFoundException e) { + getLog().error(e); + throw new MojoExecutionException(e.getMessage(), e); + } + } + if (exportBeans) { + if (beanSerializerClass != null) { + exporter.setBeanSerializerClass((Class) Class.forName(beanSerializerClass)); + } else { + BeanSerializer serializer = new BeanSerializer(); + if (beanInterfaces != null) { + for (String iface : beanInterfaces) { + int sepIndex = iface.lastIndexOf('.'); + if (sepIndex < 0) { + serializer.addInterface(new SimpleType(iface)); + } else { + String packageName = iface.substring(0, sepIndex); + String simpleName = iface.substring(sepIndex + 1); + serializer.addInterface(new SimpleType(iface, packageName, simpleName)); + } + } + } + serializer.setAddFullConstructor(beanAddFullConstructor); + serializer.setAddToString(beanAddToString); + serializer.setPrintSupertype(beanPrintSupertype); + exporter.setBeanSerializer(serializer); + } + + } + String sourceEncoding = (String) project.getProperties().get("project.build.sourceEncoding"); + if (sourceEncoding != null) { + exporter.setSourceEncoding(sourceEncoding); + } + + if (customTypes != null) { + for (String cl : customTypes) { + configuration.register((Type<?>) Class.forName(cl).newInstance()); + } + } + if (typeMappings != null) { + for (TypeMapping mapping : typeMappings) { + mapping.apply(configuration); + } + } + if (numericMappings != null) { + for (NumericMapping mapping : numericMappings) { + mapping.apply(configuration); + } + } + if (renameMappings != null) { + for (RenameMapping mapping : renameMappings) { + mapping.apply(configuration); + } + } + + if (columnComparatorClass != null) { + try { + exporter.setColumnComparatorClass((Class) Class.forName(this.columnComparatorClass).asSubclass(Comparator.class)); + } catch (ClassNotFoundException e) { + getLog().error(e); + throw new MojoExecutionException(e.getMessage(), e); + } + } + + exporter.setConfiguration(configuration); + + Class.forName(jdbcDriver); + String user; + String password; + if (server == null) { + user = jdbcUser; + password = jdbcPassword; + } else { + AuthenticationInfo info = wagonManager.getAuthenticationInfo(server); + if (info == null) { + throw new MojoExecutionException("No authentication info for server " + server); + } + + user = info.getUserName(); + if (user == null) { + throw new MojoExecutionException("Missing username from server " + server); + } + + password = info.getPassword(); + if (password == null) { + throw new MojoExecutionException("Missing password from server " + server); + } + } + try (Connection conn = DriverManager.getConnection(jdbcUrl, user, password)) { + exporter.export(conn.getMetaData()); + } + } catch (ClassNotFoundException | IllegalAccessException | InstantiationException | SQLException e) { + throw new MojoExecutionException(e.getMessage(), e); + } + + } + + protected boolean isForTest() { + return false; + } + + public void setProject(MavenProject project) { + this.project = project; + } + + public void setServer(String server) { + this.server = server; + } + + public void setJdbcDriver(String jdbcDriver) { + this.jdbcDriver = jdbcDriver; + } + + public void setJdbcUrl(String jdbcUrl) { + this.jdbcUrl = jdbcUrl; + } + + public void setJdbcUser(String jdbcUser) { + this.jdbcUser = jdbcUser; + } + + public void setJdbcPassword(String jdbcPassword) { + this.jdbcPassword = jdbcPassword; + } + + public void setNamePrefix(String namePrefix) { + this.namePrefix = namePrefix; + } + + public void setNameSuffix(String nameSuffix) { + this.nameSuffix = nameSuffix; + } + + public void setBeanInterfaces(String[] beanInterfaces) { + this.beanInterfaces = beanInterfaces; + } + + public void setBeanPrefix(String beanPrefix) { + this.beanPrefix = beanPrefix; + } + + public void setBeanSuffix(String beanSuffix) { + this.beanSuffix = beanSuffix; + } + + public void setPackageName(String packageName) { + this.packageName = packageName; + } + + public void setBeanPackageName(String beanPackageName) { + this.beanPackageName = beanPackageName; + } + + public void setCatalogPattern(String catalogPattern) { + this.catalogPattern = catalogPattern; + } + + public void setSchemaPattern(String schemaPattern) { + this.schemaPattern = schemaPattern; + } + + public void setTableNamePattern(String tableNamePattern) { + this.tableNamePattern = tableNamePattern; + } + + public void setTargetFolder(String targetFolder) { + this.targetFolder = targetFolder; + } + + public void setNamingStrategyClass(String namingStrategyClass) { + this.namingStrategyClass = namingStrategyClass; + } + + public void setBeanSerializerClass(String beanSerializerClass) { + this.beanSerializerClass = beanSerializerClass; + } + + public void setSerializerClass(String serializerClass) { + this.serializerClass = serializerClass; + } + + public void setExportBeans(boolean exportBeans) { + this.exportBeans = exportBeans; + } + + public void setInnerClassesForKeys(boolean innerClassesForKeys) { + this.innerClassesForKeys = innerClassesForKeys; + } + + public void setValidationAnnotations(boolean validationAnnotations) { + this.validationAnnotations = validationAnnotations; + } + + public void setColumnAnnotations(boolean columnAnnotations) { + this.columnAnnotations = columnAnnotations; + } + + public void setCustomTypes(String[] customTypes) { + this.customTypes = customTypes; + } + + public void setCreateScalaSources(boolean createScalaSources) { + this.createScalaSources = createScalaSources; + } + + public void setSchemaToPackage(boolean schemaToPackage) { + this.schemaToPackage = schemaToPackage; + } + + public void setLowerCase(boolean lowerCase) { + this.lowerCase = lowerCase; + } + + public void setTypeMappings(TypeMapping[] typeMappings) { + this.typeMappings = typeMappings; + } + + public void setNumericMappings(NumericMapping[] numericMappings) { + this.numericMappings = numericMappings; + } + + public void setRenameMappings(RenameMapping[] renameMappings) { + this.renameMappings = renameMappings; + } + + public void setImports(String[] imports) { + this.imports = imports; + } + + public void setSkip(boolean skip) { + this.skip = skip; + } + + public void setGeneratedAnnotationClass(String generatedAnnotationClass) { + this.generatedAnnotationClass = generatedAnnotationClass; + } + + private static String emptyIfSetToBlank(String value) { + boolean setToBlank = value == null || value.equalsIgnoreCase("BLANK"); + return setToBlank ? "" : value; + } + + private static String processBlankValues(String value) { + if (value == null) { + return null; + } + return BLANK_VALUE_PATTERN.matcher(value).replaceAll(BLANK_VALUE_REPLACEMENT); + } + + private static final Pattern BLANK_VALUE_PATTERN = Pattern.compile("(^|,)BLANK(,|$)", Pattern.CASE_INSENSITIVE); + private static final String BLANK_VALUE_REPLACEMENT = "$1$2"; +} diff --git a/querydsl-maven-plugin/src/main/java/com/mysema/query/maven/CompileMojo.java b/querydsl-maven-plugin/src/main/java/com/querydsl/maven/CompileMojo.java similarity index 92% rename from querydsl-maven-plugin/src/main/java/com/mysema/query/maven/CompileMojo.java rename to querydsl-maven-plugin/src/main/java/com/querydsl/maven/CompileMojo.java index 3bd1097b50..0d6a417bb5 100644 --- a/querydsl-maven-plugin/src/main/java/com/mysema/query/maven/CompileMojo.java +++ b/querydsl-maven-plugin/src/main/java/com/querydsl/maven/CompileMojo.java @@ -1,5 +1,5 @@ /* - * Copyright 2013, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,16 +11,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.maven; +package com.querydsl.maven; import java.io.File; import java.io.IOException; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import javax.tools.JavaCompiler; import javax.tools.JavaFileObject; @@ -36,7 +31,7 @@ import org.sonatype.plexus.build.incremental.BuildContext; /** - * CompilerMojo compiles the sources generated in the other tasks + * {@code CompileMojo} compiles the sources generated by other tasks * * @goal compile * @requiresDependencyResolution test @@ -45,44 +40,62 @@ public class CompileMojo extends AbstractMojo { private static final String JAVA_FILE_FILTER = "/*.java"; - private static final String[] ALL_JAVA_FILES_FILTER = new String[] { "**" + JAVA_FILE_FILTER }; + private static final String[] ALL_JAVA_FILES_FILTER = new String[] {"**" + JAVA_FILE_FILTER}; /** - * @parameter expression="${project}" readonly=true required=true + * maven project + * + * @parameter default-value="${project}" + * @readonly */ private MavenProject project; /** - * @parameter required=true + * source folder + * + * @parameter + * @required */ private File sourceFolder; /** + * source encoding + * * @parameter */ private String sourceEncoding; /** + * source option + * * @parameter */ private String source; /** + * target option + * * @parameter */ private String target; /** + * test classpath + * * @parameter default-value=false */ private boolean testClasspath; /** + * compiler options + * * @parameter */ private Map<String, String> compilerOptions; /** + * build context + * * @component */ private BuildContext buildContext; diff --git a/querydsl-maven-plugin/src/main/java/com/querydsl/maven/GenericExporterMojo.java b/querydsl-maven-plugin/src/main/java/com/querydsl/maven/GenericExporterMojo.java new file mode 100644 index 0000000000..551310515c --- /dev/null +++ b/querydsl-maven-plugin/src/main/java/com/querydsl/maven/GenericExporterMojo.java @@ -0,0 +1,26 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.maven; + +import com.querydsl.codegen.GenericExporter; + +/** + * {@code GenericExporterMojo} calls {@link GenericExporter} using the classpath of the module + * + * @goal generic-export + * @requiresDependencyResolution test + */ +public class GenericExporterMojo extends AbstractExporterMojo { + +} diff --git a/querydsl-maven-plugin/src/main/java/com/mysema/query/maven/JDOExporterMojo.java b/querydsl-maven-plugin/src/main/java/com/querydsl/maven/JDOExporterMojo.java similarity index 78% rename from querydsl-maven-plugin/src/main/java/com/mysema/query/maven/JDOExporterMojo.java rename to querydsl-maven-plugin/src/main/java/com/querydsl/maven/JDOExporterMojo.java index 7d9dd7b645..9db87c7905 100644 --- a/querydsl-maven-plugin/src/main/java/com/mysema/query/maven/JDOExporterMojo.java +++ b/querydsl-maven-plugin/src/main/java/com/querydsl/maven/JDOExporterMojo.java @@ -1,6 +1,6 @@ /* - * Copyright 2012, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,18 +11,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.maven; +package com.querydsl.maven; import javax.jdo.annotations.EmbeddedOnly; import javax.jdo.annotations.NotPersistent; import javax.jdo.annotations.PersistenceCapable; import javax.persistence.Embedded; -import com.mysema.query.codegen.GenericExporter; +import com.querydsl.codegen.GenericExporter; +import com.querydsl.codegen.PropertyHandling; /** - * JDOExporterMojo calls the GenericExporter tool using the classpath of the module - * + * {@code JDOExporterMojo} calls {@link GenericExporter} using the classpath of the module + * * @goal jdo-export * @requiresDependencyResolution test * @author tiwe @@ -36,6 +37,7 @@ protected void configure(GenericExporter exporter) { exporter.setEmbeddedAnnotation(Embedded.class); exporter.setEntityAnnotation(PersistenceCapable.class); exporter.setSkipAnnotation(NotPersistent.class); + exporter.setPropertyHandling(PropertyHandling.JDO); } } diff --git a/querydsl-maven-plugin/src/main/java/com/querydsl/maven/JPAExporterMojo.java b/querydsl-maven-plugin/src/main/java/com/querydsl/maven/JPAExporterMojo.java new file mode 100644 index 0000000000..18c4626961 --- /dev/null +++ b/querydsl-maven-plugin/src/main/java/com/querydsl/maven/JPAExporterMojo.java @@ -0,0 +1,43 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.maven; + +import javax.persistence.*; + +import com.querydsl.codegen.GenericExporter; +import com.querydsl.codegen.PropertyHandling; + +/** + * {@code JPAExporterMojo} calls {@link GenericExporter} using the classpath of the module + * + * @goal jpa-export + * @requiresDependencyResolution test + * @author tiwe + */ +public class JPAExporterMojo extends AbstractExporterMojo { + + @Override + protected void configure(GenericExporter exporter) { + super.configure(exporter); + exporter.setEmbeddableAnnotation(Embeddable.class); + exporter.setEmbeddedAnnotation(Embedded.class); + exporter.setEntityAnnotation(Entity.class); + exporter.setSkipAnnotation(Transient.class); + exporter.setSupertypeAnnotation(MappedSuperclass.class); + exporter.setPropertyHandling(PropertyHandling.JPA); + + // AnnotationHelpers to process specific JPA annotations + exporter.addAnnotationHelper(JPATemporalAnnotationHelper.INSTANCE); + } +} diff --git a/querydsl-maven-plugin/src/main/java/com/querydsl/maven/JPATemporalAnnotationHelper.java b/querydsl-maven-plugin/src/main/java/com/querydsl/maven/JPATemporalAnnotationHelper.java new file mode 100644 index 0000000000..0a661c4ad8 --- /dev/null +++ b/querydsl-maven-plugin/src/main/java/com/querydsl/maven/JPATemporalAnnotationHelper.java @@ -0,0 +1,57 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.maven; + +import java.lang.annotation.Annotation; + +import javax.persistence.Temporal; + +import com.querydsl.codegen.utils.model.TypeCategory; +import com.querydsl.codegen.AnnotationHelper; + +/** + * An {@link AnnotationHelper} that handles JPA {@link Temporal} annotation. + * + * @author dyorgio + */ +public final class JPATemporalAnnotationHelper implements AnnotationHelper { + + public static final JPATemporalAnnotationHelper INSTANCE = new JPATemporalAnnotationHelper(); + + private JPATemporalAnnotationHelper() { + } + + @Override + public boolean isSupported(Class<? extends Annotation> annotationClass) { + return Temporal.class.isAssignableFrom(annotationClass); + } + + @Override + public Object getCustomKey(Annotation annotation) { + return ((Temporal) annotation).value(); + } + + @Override + public TypeCategory getTypeByAnnotation(Class<?> cl, Annotation annotation) { + switch (((Temporal) annotation).value()) { + case DATE: + return TypeCategory.DATE; + case TIME: + return TypeCategory.TIME; + case TIMESTAMP: + return TypeCategory.DATETIME; + } + return null; + } + } diff --git a/querydsl-maven-plugin/src/main/java/com/querydsl/maven/MetadataExportMojo.java b/querydsl-maven-plugin/src/main/java/com/querydsl/maven/MetadataExportMojo.java new file mode 100644 index 0000000000..bbaf813859 --- /dev/null +++ b/querydsl-maven-plugin/src/main/java/com/querydsl/maven/MetadataExportMojo.java @@ -0,0 +1,32 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.maven; + +import com.querydsl.sql.codegen.MetaDataExporter; + +/** + * {@code MetadataExportMojo} is a goal for {@link MetaDataExporter} execution. + * It is executed by default in the {@code generate-sources} phase. + * + * @phase generate-sources + * @goal export + * + */ +public class MetadataExportMojo extends AbstractMetaDataExportMojo { + + @Override + protected boolean isForTest() { + return false; + } +} diff --git a/querydsl-maven-plugin/src/main/java/com/querydsl/maven/TestMetadataExportMojo.java b/querydsl-maven-plugin/src/main/java/com/querydsl/maven/TestMetadataExportMojo.java new file mode 100644 index 0000000000..612c22d5aa --- /dev/null +++ b/querydsl-maven-plugin/src/main/java/com/querydsl/maven/TestMetadataExportMojo.java @@ -0,0 +1,32 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.maven; + +import com.querydsl.sql.codegen.MetaDataExporter; + +/** + * {@code TestMetadataExportMojo} is a goal for {@link MetaDataExporter} usage and is bound to the generated-sources phase + * + * @phase generate-sources + * @goal test-export + * + */ +public class TestMetadataExportMojo extends AbstractMetaDataExportMojo { + + @Override + protected boolean isForTest() { + return true; + } + +} diff --git a/querydsl-maven-plugin/src/main/java/com/querydsl/maven/package-info.java b/querydsl-maven-plugin/src/main/java/com/querydsl/maven/package-info.java new file mode 100644 index 0000000000..929eca7705 --- /dev/null +++ b/querydsl-maven-plugin/src/main/java/com/querydsl/maven/package-info.java @@ -0,0 +1,18 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ + +/** + * Maven plugins + */ +package com.querydsl.maven; diff --git a/querydsl-maven-plugin/src/test/java/com/mysema/query/maven/Entity.java b/querydsl-maven-plugin/src/test/java/com/mysema/query/maven/Entity.java deleted file mode 100644 index be1a11cc88..0000000000 --- a/querydsl-maven-plugin/src/test/java/com/mysema/query/maven/Entity.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.mysema.query.maven; - -import javax.jdo.annotations.PersistenceCapable; - -import com.mysema.query.annotations.QueryEntity; - -@PersistenceCapable -@javax.persistence.Entity -@QueryEntity -public class Entity { - - String property; - -} diff --git a/querydsl-maven-plugin/src/test/java/com/mysema/query/maven/GenericExporterMojoTest.java b/querydsl-maven-plugin/src/test/java/com/mysema/query/maven/GenericExporterMojoTest.java deleted file mode 100644 index 0736d686c7..0000000000 --- a/querydsl-maven-plugin/src/test/java/com/mysema/query/maven/GenericExporterMojoTest.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.mysema.query.maven; - -import static org.junit.Assert.assertTrue; - -import java.io.File; - -import org.apache.maven.project.MavenProject; -import org.junit.Test; - -public class GenericExporterMojoTest { - - @Test - public void Execute() throws Exception { - MavenProject mavenProject = new MavenProject(); - mavenProject.getBuild().setOutputDirectory("target/classes"); - - GenericExporterMojo mojo = new GenericExporterMojo(); - mojo.setTargetFolder(new File("target/generated-test-data")); - mojo.setPackages(new String[]{"com.mysema.query.maven"}); - mojo.setProject( mavenProject); - mojo.execute(); - - File file = new File("target/generated-test-data/com/mysema/query/maven/QEntity.java"); - assertTrue(file.exists()); - } - -} diff --git a/querydsl-maven-plugin/src/test/java/com/mysema/query/maven/JDOExporterMojoTest.java b/querydsl-maven-plugin/src/test/java/com/mysema/query/maven/JDOExporterMojoTest.java deleted file mode 100644 index 543f0ba346..0000000000 --- a/querydsl-maven-plugin/src/test/java/com/mysema/query/maven/JDOExporterMojoTest.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.mysema.query.maven; - -import static org.junit.Assert.assertTrue; - -import java.io.File; - -import org.apache.maven.project.MavenProject; -import org.junit.Test; - -public class JDOExporterMojoTest { - - @Test - public void Execute() throws Exception { - MavenProject mavenProject = new MavenProject(); - mavenProject.getBuild().setOutputDirectory("target/classes"); - - JDOExporterMojo mojo = new JDOExporterMojo(); - mojo.setTargetFolder(new File("target/generated-test-data3")); - mojo.setPackages(new String[]{"com.mysema.query.maven"}); - mojo.setProject( mavenProject); - mojo.execute(); - - File file = new File("target/generated-test-data3/com/mysema/query/maven/QEntity.java"); - assertTrue(file.exists()); - } - -} diff --git a/querydsl-maven-plugin/src/test/java/com/mysema/query/maven/JPAExporterMojoTest.java b/querydsl-maven-plugin/src/test/java/com/mysema/query/maven/JPAExporterMojoTest.java deleted file mode 100644 index cd54ea08dd..0000000000 --- a/querydsl-maven-plugin/src/test/java/com/mysema/query/maven/JPAExporterMojoTest.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.mysema.query.maven; - -import static org.junit.Assert.assertTrue; - -import java.io.File; - -import org.apache.maven.project.MavenProject; -import org.junit.Test; - -public class JPAExporterMojoTest { - - @Test - public void Execute() throws Exception { - MavenProject mavenProject = new MavenProject(); - mavenProject.getBuild().setOutputDirectory("target/classes"); - - JPAExporterMojo mojo = new JPAExporterMojo(); - mojo.setTargetFolder(new File("target/generated-test-data2")); - mojo.setPackages(new String[]{"com.mysema.query.maven"}); - mojo.setProject( mavenProject); - mojo.execute(); - - File file = new File("target/generated-test-data2/com/mysema/query/maven/QEntity.java"); - assertTrue(file.exists()); - } - -} diff --git a/querydsl-maven-plugin/src/test/java/com/mysema/query/maven/MetadataExportMojoTest.java b/querydsl-maven-plugin/src/test/java/com/mysema/query/maven/MetadataExportMojoTest.java deleted file mode 100644 index 0162e10842..0000000000 --- a/querydsl-maven-plugin/src/test/java/com/mysema/query/maven/MetadataExportMojoTest.java +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.maven; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import java.io.File; -import java.io.Serializable; -import java.util.Collections; - -import org.apache.maven.project.MavenProject; -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; - -import com.mysema.query.sql.codegen.ExtendedBeanSerializer; -import com.mysema.query.sql.codegen.OriginalNamingStrategy; -import com.mysema.query.sql.types.BytesType; -import com.mysema.query.sql.types.DateTimeType; -import com.mysema.query.sql.types.LocalDateType; -import com.mysema.query.sql.types.LocalTimeType; - -public class MetadataExportMojoTest { - - private final String url = "jdbc:h2:mem:testdb" + System.currentTimeMillis(); - - private final MavenProject project = new MavenProject(); - - private final MetadataExportMojo mojo = new MetadataExportMojo(); - - @Before - public void setUp() { - mojo.setProject(project); - mojo.setJdbcDriver("org.h2.Driver"); - mojo.setJdbcUrl(url); - mojo.setJdbcUser("sa"); - mojo.setNamePrefix("Q"); // default value - mojo.setPackageName("com.example"); - } - - @Test - public void Execute() throws Exception { - mojo.setTargetFolder("target/export"); - mojo.execute(); - - assertEquals(Collections.singletonList("target/export"), project.getCompileSourceRoots()); - assertTrue(new File("target/export").exists()); - } - - @Test - public void Execute_With_CustomTypes() throws Exception { - mojo.setTargetFolder("target/export2"); - mojo.setCustomTypes(new String[]{BytesType.class.getName()}); - mojo.execute(); - - assertEquals(Collections.singletonList("target/export2"), project.getCompileSourceRoots()); - assertTrue(new File("target/export2").exists()); - } - - @Test - public void Execute_With_JodaTypes() throws Exception { - mojo.setTargetFolder("target/export3"); - mojo.setCustomTypes(new String[]{LocalDateType.class.getName(), LocalTimeType.class.getName(), DateTimeType.class.getName()}); - - mojo.execute(); - - assertEquals(Collections.singletonList("target/export3"), project.getCompileSourceRoots()); - assertTrue(new File("target/export3").exists()); - } - - @Test - public void Execute_With_TypeMappings() throws Exception { - mojo.setTargetFolder("target/export4"); - TypeMapping mapping = new TypeMapping(); - mapping.table = "CATALOGS"; - mapping.column = "CATALOG_NAME"; - mapping.type = Object.class.getName(); - mojo.setTypeMappings(new TypeMapping[]{mapping}); - - mojo.execute(); - - assertEquals(Collections.singletonList("target/export4"), project.getCompileSourceRoots()); - assertTrue(new File("target/export4").exists()); - } - - @Test - public void ExecuteWithNumericMappings() throws Exception { - mojo.setTargetFolder("target/export5"); - NumericMapping mapping = new NumericMapping(); - mapping.size = 1; - mapping.digits = 1; - mapping.javaType = Number.class.getName(); - mojo.setNumericMappings(new NumericMapping[]{mapping}); - - mojo.execute(); - - assertEquals(Collections.singletonList("target/export5"), project.getCompileSourceRoots()); - assertTrue(new File("target/export5").exists()); - } - - @Test - public void ExecuteWithBeans() throws Exception { - mojo.setTargetFolder("target/export6"); - mojo.setExportBeans(true); - mojo.execute(); - - assertTrue(new File("target/export6").exists()); - } - - @Test - @Ignore - public void ExecuteWithScalaSources() throws Exception { - mojo.setTargetFolder("target/export7"); - mojo.setCreateScalaSources(true); - mojo.execute(); - - assertTrue(new File("target/export7").exists()); - } - - @Test - public void ExecuteWithNamingStrategy() throws Exception { - mojo.setTargetFolder("target/export8"); - mojo.setNamingStrategyClass(OriginalNamingStrategy.class.getName()); - mojo.execute(); - - assertTrue(new File("target/export8").exists()); - } - - @Test - public void ExecuteWithBeans2() throws Exception { - mojo.setTargetFolder("target/export9"); - mojo.setExportBeans(true); - mojo.setBeanSerializerClass(ExtendedBeanSerializer.class.getName()); - mojo.execute(); - - assertTrue(new File("target/export9").exists()); - } - - @Test - public void ExecuteWithBeans3() throws Exception { - mojo.setTargetFolder("target/export10"); - mojo.setExportBeans(true); - mojo.setBeanInterfaces(new String[]{Serializable.class.getName()}); - mojo.execute(); - - assertTrue(new File("target/export10").exists()); - } - - @Test - public void ExecuteWithImport1() throws Exception { - mojo.setTargetFolder("target/export11"); - mojo.setImports(new String[]{"com.pck1" , "com.pck2" , "com.Q1" , "com.Q2"}); - mojo.execute(); - - assertTrue(new File("target/export11").exists()); - } - - @Test - public void ExecuteWithImportAndBeans1() throws Exception { - mojo.setTargetFolder("target/export12"); - mojo.setImports(new String[]{"com.pck1" , "com.pck2" , "com.Q1" , "com.Q2"}); - mojo.setExportBeans(true); - mojo.execute(); - - assertTrue(new File("target/export12").exists()); - } -} diff --git a/querydsl-maven-plugin/src/test/java/com/mysema/query/maven/TestMetadataExportMojoTest.java b/querydsl-maven-plugin/src/test/java/com/mysema/query/maven/TestMetadataExportMojoTest.java deleted file mode 100644 index 3f59e59c13..0000000000 --- a/querydsl-maven-plugin/src/test/java/com/mysema/query/maven/TestMetadataExportMojoTest.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.maven; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import java.io.File; -import java.util.Collections; - -import org.apache.maven.project.MavenProject; -import org.junit.Test; - - -public class TestMetadataExportMojoTest { - - private final String url = "jdbc:h2:mem:testdb" + System.currentTimeMillis(); - - @Test - public void Execute() throws Exception { - MavenProject project = new MavenProject(); - TestMetadataExportMojo mojo = new TestMetadataExportMojo(); - mojo.setProject(project); - mojo.setJdbcDriver("org.h2.Driver"); - mojo.setJdbcUrl(url); - mojo.setJdbcUser("sa"); - mojo.setNamePrefix("Q"); // default value - mojo.setNameSuffix(""); - mojo.setBeanPrefix(""); - mojo.setBeanSuffix("Bean"); - mojo.setPackageName("com.example"); - mojo.setTargetFolder("target/export4"); - mojo.setImports(new String[]{"com.pck1" , "com.pck2" , "com.Q1" , "com.Q2"}); - mojo.execute(); - - //'target/export4' seems to conflict with MetadataExportMojoTest.Execute_With_TypeMappings - assertEquals(Collections.singletonList("target/export4"), project.getTestCompileSourceRoots()); - assertTrue(new File("target/export4").exists()); - } - -} diff --git a/querydsl-maven-plugin/src/test/java/com/mysema/query/maven/CompileMojoTest.java b/querydsl-maven-plugin/src/test/java/com/querydsl/maven/CompileMojoTest.java similarity index 95% rename from querydsl-maven-plugin/src/test/java/com/mysema/query/maven/CompileMojoTest.java rename to querydsl-maven-plugin/src/test/java/com/querydsl/maven/CompileMojoTest.java index e9bb3af35d..684b26b5e0 100644 --- a/querydsl-maven-plugin/src/test/java/com/mysema/query/maven/CompileMojoTest.java +++ b/querydsl-maven-plugin/src/test/java/com/querydsl/maven/CompileMojoTest.java @@ -1,4 +1,4 @@ -package com.mysema.query.maven; +package com.querydsl.maven; import java.io.File; diff --git a/querydsl-maven-plugin/src/test/java/com/querydsl/maven/Entity.java b/querydsl-maven-plugin/src/test/java/com/querydsl/maven/Entity.java new file mode 100644 index 0000000000..39d318eb83 --- /dev/null +++ b/querydsl-maven-plugin/src/test/java/com/querydsl/maven/Entity.java @@ -0,0 +1,20 @@ +package com.querydsl.maven; + +import java.util.Date; + +import javax.jdo.annotations.PersistenceCapable; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; + +import com.querydsl.core.annotations.QueryEntity; + +@PersistenceCapable +@javax.persistence.Entity +@QueryEntity +public class Entity { + + String property; + + @Temporal(TemporalType.TIMESTAMP) + Date annotatedProperty; +} diff --git a/querydsl-maven-plugin/src/test/java/com/querydsl/maven/GenericExporterMojoTest.java b/querydsl-maven-plugin/src/test/java/com/querydsl/maven/GenericExporterMojoTest.java new file mode 100644 index 0000000000..d378efcc70 --- /dev/null +++ b/querydsl-maven-plugin/src/test/java/com/querydsl/maven/GenericExporterMojoTest.java @@ -0,0 +1,63 @@ +package com.querydsl.maven; + +import static org.hamcrest.Matchers.containsString; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.lang.annotation.Annotation; + +import org.apache.maven.project.MavenProject; +import org.codehaus.plexus.util.FileUtils; +import org.junit.Test; + +import com.querydsl.codegen.GeneratedAnnotationResolver; + +public class GenericExporterMojoTest { + + public static final File Q_ENTITY_SOURCE_FILE = new File("target/generated-test-data/com/querydsl/maven/QEntity.java"); + + private GenericExporterMojo prepareMojo() { + MavenProject mavenProject = new MavenProject(); + mavenProject.getBuild().setOutputDirectory("target/classes"); + mavenProject.getBuild().setTestOutputDirectory("target/test-classes"); + + GenericExporterMojo mojo = new GenericExporterMojo(); + mojo.setTargetFolder(new File("target/generated-test-data")); + mojo.setPackages(new String[] {"com.querydsl.maven"}); + mojo.setProject(mavenProject); + mojo.setTestClasspath(true); + return mojo; + } + + @Test + public void execute() throws Exception { + GenericExporterMojo mojo = prepareMojo(); + mojo.execute(); + + assertTrue(Q_ENTITY_SOURCE_FILE.exists()); + } + + @Test + public void defaultGeneratedAnnotation() throws Exception { + GenericExporterMojo mojo = prepareMojo(); + mojo.execute(); + + File file = Q_ENTITY_SOURCE_FILE; + String source = FileUtils.fileRead(file); + assertThat(source, containsString("@" + GeneratedAnnotationResolver.resolveDefault().getSimpleName())); + } + + @Test + public void providedGeneratedAnnotation() throws Exception { + Class<? extends Annotation> annotationClass = com.querydsl.core.annotations.Generated.class; + GenericExporterMojo mojo = prepareMojo(); + mojo.setGeneratedAnnotationClass(annotationClass.getName()); + mojo.execute(); + + File file = Q_ENTITY_SOURCE_FILE; + String source = FileUtils.fileRead(file); + assertThat(source, containsString("@" + annotationClass.getSimpleName())); + } + +} diff --git a/querydsl-maven-plugin/src/test/java/com/querydsl/maven/JDOExporterMojoTest.java b/querydsl-maven-plugin/src/test/java/com/querydsl/maven/JDOExporterMojoTest.java new file mode 100644 index 0000000000..f2252327ba --- /dev/null +++ b/querydsl-maven-plugin/src/test/java/com/querydsl/maven/JDOExporterMojoTest.java @@ -0,0 +1,29 @@ +package com.querydsl.maven; + +import static org.junit.Assert.assertTrue; + +import java.io.File; + +import org.apache.maven.project.MavenProject; +import org.junit.Test; + +public class JDOExporterMojoTest { + + @Test + public void execute() throws Exception { + MavenProject mavenProject = new MavenProject(); + mavenProject.getBuild().setOutputDirectory("target/classes"); + mavenProject.getBuild().setTestOutputDirectory("target/test-classes"); + + JDOExporterMojo mojo = new JDOExporterMojo(); + mojo.setTargetFolder(new File("target/generated-test-data3")); + mojo.setPackages(new String[]{"com.querydsl.maven"}); + mojo.setProject(mavenProject); + mojo.setTestClasspath(true); + mojo.execute(); + + File file = new File("target/generated-test-data3/com/querydsl/maven/QEntity.java"); + assertTrue(file.exists()); + } + +} diff --git a/querydsl-maven-plugin/src/test/java/com/querydsl/maven/JPAExporterMojoTest.java b/querydsl-maven-plugin/src/test/java/com/querydsl/maven/JPAExporterMojoTest.java new file mode 100644 index 0000000000..78125a88a9 --- /dev/null +++ b/querydsl-maven-plugin/src/test/java/com/querydsl/maven/JPAExporterMojoTest.java @@ -0,0 +1,29 @@ +package com.querydsl.maven; + +import static org.junit.Assert.assertTrue; + +import java.io.File; + +import org.apache.maven.project.MavenProject; +import org.junit.Test; + +public class JPAExporterMojoTest { + + @Test + public void execute() throws Exception { + MavenProject mavenProject = new MavenProject(); + mavenProject.getBuild().setOutputDirectory("target/classes"); + mavenProject.getBuild().setTestOutputDirectory("target/test-classes"); + + JPAExporterMojo mojo = new JPAExporterMojo(); + mojo.setTargetFolder(new File("target/generated-test-data2")); + mojo.setPackages(new String[]{"com.querydsl.maven"}); + mojo.setProject(mavenProject); + mojo.setTestClasspath(true); + mojo.execute(); + + File file = new File("target/generated-test-data2/com/querydsl/maven/QEntity.java"); + assertTrue(file.exists()); + } + +} diff --git a/querydsl-maven-plugin/src/test/java/com/querydsl/maven/MetadataExportMojoTest.java b/querydsl-maven-plugin/src/test/java/com/querydsl/maven/MetadataExportMojoTest.java new file mode 100644 index 0000000000..24726333d4 --- /dev/null +++ b/querydsl-maven-plugin/src/test/java/com/querydsl/maven/MetadataExportMojoTest.java @@ -0,0 +1,440 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.maven; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.io.Serializable; +import java.util.Collections; + +import org.apache.maven.project.MavenProject; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestName; + +import com.querydsl.sql.codegen.ExtendedBeanSerializer; +import com.querydsl.sql.codegen.OriginalNamingStrategy; +import com.querydsl.sql.codegen.support.NumericMapping; +import com.querydsl.sql.codegen.support.RenameMapping; +import com.querydsl.sql.codegen.support.TypeMapping; +import com.querydsl.sql.types.BytesType; +import com.querydsl.sql.types.DateTimeType; +import com.querydsl.sql.types.LocalDateType; +import com.querydsl.sql.types.LocalTimeType; + +public class MetadataExportMojoTest { + + private final String url = "jdbc:h2:mem:testdb" + System.currentTimeMillis() + ";INIT=" + + "CREATE TABLE NO_SCHEMA_TABLE (COL1 INT) \\;" + + "CREATE SCHEMA SCHEMA1 \\;" + + "CREATE TABLE SCHEMA1.SCHEMA1_TABLE (COL1 INT) \\;" + + "CREATE SCHEMA SCHEMA2 \\;" + + "CREATE TABLE SCHEMA2.SCHEMA2_TABLE (COL1 INT) \\;"; + + private final MavenProject project = new MavenProject(); + + private final MetadataExportMojo mojo = new MetadataExportMojo(); + + @Rule + public TestName testName = new TestName(); + + @Before + public void setUp() { + mojo.setProject(project); + mojo.setJdbcDriver("org.h2.Driver"); + mojo.setJdbcUrl(url); + mojo.setJdbcUser("sa"); + mojo.setNamePrefix("Q"); // default value + mojo.setPackageName("com.example"); + } + + @Test + public void execute() throws Exception { + mojo.setTargetFolder("target/export"); + mojo.execute(); + + assertEquals(Collections.singletonList("target/export"), project.getCompileSourceRoots()); + assertTrue(new File("target/export").exists()); + } + + @Test + public void execute_with_customTypes() throws Exception { + mojo.setTargetFolder("target/export2"); + mojo.setCustomTypes(new String[]{BytesType.class.getName()}); + mojo.execute(); + + assertEquals(Collections.singletonList("target/export2"), project.getCompileSourceRoots()); + assertTrue(new File("target/export2").exists()); + } + + @Test + public void execute_with_jodaTypes() throws Exception { + mojo.setTargetFolder("target/export3"); + mojo.setCustomTypes(new String[]{LocalDateType.class.getName(), LocalTimeType.class.getName(), DateTimeType.class.getName()}); + + mojo.execute(); + + assertEquals(Collections.singletonList("target/export3"), project.getCompileSourceRoots()); + assertTrue(new File("target/export3").exists()); + } + + @Test + public void execute_with_typeMappings() throws Exception { + mojo.setTargetFolder("target/export4"); + TypeMapping mapping = new TypeMapping(); + mapping.setTable("CATALOGS"); + mapping.setColumn("CATALOG_NAME"); + mapping.setType(Object.class.getName()); + mojo.setTypeMappings(new TypeMapping[]{mapping}); + + mojo.execute(); + + assertEquals(Collections.singletonList("target/export4"), project.getCompileSourceRoots()); + assertTrue(new File("target/export4").exists()); + } + + @Test + public void executeWithNumericMappings() throws Exception { + mojo.setTargetFolder("target/export5"); + NumericMapping mapping = new NumericMapping(); + mapping.setTotal(1); + mapping.setDecimal(1); + mapping.setJavaType(Number.class.getName()); + mojo.setNumericMappings(new NumericMapping[]{mapping}); + + mojo.execute(); + + assertEquals(Collections.singletonList("target/export5"), project.getCompileSourceRoots()); + assertTrue(new File("target/export5").exists()); + } + + @Test + public void executeWithBeans() throws Exception { + mojo.setTargetFolder("target/export6"); + mojo.setExportBeans(true); + mojo.execute(); + + assertTrue(new File("target/export6").exists()); + } + + @Test + @Ignore + public void executeWithScalaSources() throws Exception { + mojo.setTargetFolder("target/export7"); + mojo.setCreateScalaSources(true); + mojo.execute(); + + assertTrue(new File("target/export7").exists()); + } + + @Test + public void executeWithNamingStrategy() throws Exception { + mojo.setTargetFolder("target/export8"); + mojo.setNamingStrategyClass(OriginalNamingStrategy.class.getName()); + mojo.execute(); + + assertTrue(new File("target/export8").exists()); + } + + @Test + public void executeWithBeans2() throws Exception { + mojo.setTargetFolder("target/export9"); + mojo.setExportBeans(true); + mojo.setBeanSerializerClass(ExtendedBeanSerializer.class.getName()); + mojo.execute(); + + assertTrue(new File("target/export9").exists()); + } + + @Test + public void executeWithBeans3() throws Exception { + mojo.setTargetFolder("target/export10"); + mojo.setExportBeans(true); + mojo.setBeanInterfaces(new String[]{Serializable.class.getName()}); + mojo.execute(); + + assertTrue(new File("target/export10").exists()); + } + + @Test + public void executeWithImport1() throws Exception { + mojo.setTargetFolder("target/export11"); + mojo.setImports(new String[]{"com.pck1", "com.pck2", "com.Q1", "com.Q2"}); + mojo.execute(); + + assertTrue(new File("target/export11").exists()); + } + + @Test + public void executeWithImportAndBeans1() throws Exception { + mojo.setTargetFolder("target/export12"); + mojo.setImports(new String[]{"com.pck1", "com.pck2", "com.Q1", "com.Q2"}); + mojo.setExportBeans(true); + mojo.execute(); + + assertTrue(new File("target/export12").exists()); + } + + @Test + public void executeWithRenames() throws Exception { + RenameMapping mapping = new RenameMapping(); + mapping.setFromSchema("ABC"); + mapping.setToSchema("DEF"); + + mojo.setTargetFolder("target/export13"); + mojo.setRenameMappings(new RenameMapping[]{mapping}); + mojo.execute(); + + assertEquals(Collections.singletonList("target/export13"), project.getCompileSourceRoots()); + assertTrue(new File("target/export13").exists()); + } + + // region Schema Pattern Matching + + @Test + public void executeWithUnsetSchemaPattern() throws Exception { + String targetFolder = "target/" + testName.getMethodName(); + + mojo.setTargetFolder(targetFolder); + mojo.setSchemaPattern(null); + mojo.execute(); + + assertTrue(new File(targetFolder + "/com/example/QNoSchemaTable.java").exists()); + assertTrue(new File(targetFolder + "/com/example/QSchema1Table.java").exists()); + assertTrue(new File(targetFolder + "/com/example/QSchema2Table.java").exists()); + } + + @Test + public void executeWithExactSchemaPattern() throws Exception { + String targetFolder = "target/" + testName.getMethodName(); + + mojo.setTargetFolder(targetFolder); + mojo.setSchemaPattern("SCHEMA1"); + mojo.execute(); + + assertTrue(new File(targetFolder + "/com/example/QSchema1Table.java").exists()); + + assertFalse(new File(targetFolder + "/com/example/QNoSchemaTable.java").exists()); + assertFalse(new File(targetFolder + "/com/example/QSchema2Table.java").exists()); + } + + @Test + public void executeWithSimilarSchemaPattern() throws Exception { + String targetFolder = "target/" + testName.getMethodName(); + + mojo.setTargetFolder(targetFolder); + mojo.setSchemaPattern("%EMA1"); + mojo.execute(); + + assertTrue(new File(targetFolder + "/com/example/QSchema1Table.java").exists()); + + assertFalse(new File(targetFolder + "/com/example/QNoSchemaTable.java").exists()); + assertFalse(new File(targetFolder + "/com/example/QSchema2Table.java").exists()); + } + + @Test + public void executeWithMismatchedSchemaPattern() throws Exception { + String targetFolder = "target/" + testName.getMethodName(); + + mojo.setTargetFolder(targetFolder); + mojo.setSchemaPattern("NON_EXISTENT_SCHEMA"); + mojo.execute(); + + assertFalse(new File(targetFolder + "/com/example/QNoSchemaTable.java").exists()); + assertFalse(new File(targetFolder + "/com/example/QSchema1Table.java").exists()); + assertFalse(new File(targetFolder + "/com/example/QSchema2Table.java").exists()); + } + + @Test + public void executeWithMultipleSchemaPatterns() throws Exception { + String targetFolder = "target/" + testName.getMethodName(); + + mojo.setTargetFolder(targetFolder); + mojo.setSchemaPattern("SCHEMA1,SCHEMA2"); + mojo.execute(); + + assertTrue(new File(targetFolder + "/com/example/QSchema1Table.java").exists()); + assertTrue(new File(targetFolder + "/com/example/QSchema2Table.java").exists()); + + assertFalse(new File(targetFolder + "/com/example/QNoSchemaTable.java").exists()); + } + + // endregion Schema Pattern Matching + + // region Schema Pattern Matching - Empty Values + + @Test + public void executeWithEmptySchemaPattern() throws Exception { + String targetFolder = "target/" + testName.getMethodName(); + + mojo.setTargetFolder(targetFolder); + mojo.setSchemaPattern(""); + mojo.execute(); + + assertTrue(new File(targetFolder + "/com/example/QNoSchemaTable.java").exists()); + + assertFalse(new File(targetFolder + "/com/example/QSchema1Table.java").exists()); + assertFalse(new File(targetFolder + "/com/example/QSchema2Table.java").exists()); + } + + @Test + public void executeWithMultipleSchemaPatternsAndInterleavedEmpty() throws Exception { + String targetFolder = "target/" + testName.getMethodName(); + + mojo.setTargetFolder(targetFolder); + mojo.setSchemaPattern("SCHEMA1,,SCHEMA2"); + mojo.execute(); + + assertTrue(new File(targetFolder + "/com/example/QNoSchemaTable.java").exists()); + assertTrue(new File(targetFolder + "/com/example/QSchema1Table.java").exists()); + assertTrue(new File(targetFolder + "/com/example/QSchema2Table.java").exists()); + } + + @Test + public void executeWithMultipleSchemaPatternsAndLeadingEmpty() throws Exception { + String targetFolder = "target/" + testName.getMethodName(); + + mojo.setTargetFolder(targetFolder); + mojo.setSchemaPattern(",SCHEMA2"); + mojo.execute(); + + assertTrue(new File(targetFolder + "/com/example/QNoSchemaTable.java").exists()); + assertTrue(new File(targetFolder + "/com/example/QSchema2Table.java").exists()); + + assertFalse(new File(targetFolder + "/com/example/QSchema1Table.java").exists()); + } + + @Test + @Ignore("Trailing empty strings are not handled correctly by the MetaDataExporter") + public void executeWithMultipleSchemaPatternsAndTrailingEmpty() throws Exception { + String targetFolder = "target/" + testName.getMethodName(); + + mojo.setTargetFolder(targetFolder); + mojo.setSchemaPattern("SCHEMA1,"); + mojo.execute(); + + assertTrue(new File(targetFolder + "/com/example/QNoSchemaTable.java").exists()); + assertTrue(new File(targetFolder + "/com/example/QSchema1Table.java").exists()); + + assertFalse(new File(targetFolder + "/com/example/QSchema2Table.java").exists()); + } + + // endregion Schema Pattern Matching - Empty Values + + // region Schema Pattern Matching - BLANK Values + + @Test + public void executeWithBlankUppercaseSchemaPattern() throws Exception { + String targetFolder = "target/" + testName.getMethodName(); + + mojo.setTargetFolder(targetFolder); + mojo.setSchemaPattern("BLANK"); + mojo.execute(); + + assertTrue(new File(targetFolder + "/com/example/QNoSchemaTable.java").exists()); + + assertFalse(new File(targetFolder + "/com/example/QSchema1Table.java").exists()); + assertFalse(new File(targetFolder + "/com/example/QSchema2Table.java").exists()); + } + + @Test + public void executeWithBlankLowercaseSchemaPattern() throws Exception { + String targetFolder = "target/" + testName.getMethodName(); + + mojo.setTargetFolder(targetFolder); + mojo.setSchemaPattern("blank"); + mojo.execute(); + + assertTrue(new File(targetFolder + "/com/example/QNoSchemaTable.java").exists()); + + assertFalse(new File(targetFolder + "/com/example/QSchema1Table.java").exists()); + assertFalse(new File(targetFolder + "/com/example/QSchema2Table.java").exists()); + } + + + @Test + public void executeWithSchemaPatternContainingBlank() throws Exception { + String targetFolder = "target/" + testName.getMethodName(); + + mojo.setTargetFolder(targetFolder); + mojo.setSchemaPattern("SCHEMA1BLANK"); + mojo.execute(); + + assertFalse(new File(targetFolder + "/com/example/QNoSchemaTable.java").exists()); + assertFalse(new File(targetFolder + "/com/example/QSchema1Table.java").exists()); + assertFalse(new File(targetFolder + "/com/example/QSchema2Table.java").exists()); + } + @Test + public void executeWithMultipleSchemaPatternsAndInterleavedBlank() throws Exception { + String targetFolder = "target/" + testName.getMethodName(); + + mojo.setTargetFolder(targetFolder); + mojo.setSchemaPattern("SCHEMA1,BLANK,SCHEMA2"); + mojo.execute(); + + assertTrue(new File(targetFolder + "/com/example/QNoSchemaTable.java").exists()); + assertTrue(new File(targetFolder + "/com/example/QSchema1Table.java").exists()); + assertTrue(new File(targetFolder + "/com/example/QSchema2Table.java").exists()); + } + + @Test + public void executeWithMultipleSchemaPatternsAndLeadingBlank() throws Exception { + String targetFolder = "target/" + testName.getMethodName(); + + mojo.setTargetFolder(targetFolder); + mojo.setSchemaPattern("BLANK,SCHEMA2"); + mojo.execute(); + + assertTrue(new File(targetFolder + "/com/example/QNoSchemaTable.java").exists()); + assertTrue(new File(targetFolder + "/com/example/QSchema2Table.java").exists()); + + assertFalse(new File(targetFolder + "/com/example/QSchema1Table.java").exists()); + } + + @Test + @Ignore("Trailing empty strings are not handled correctly by the MetaDataExporter") + public void executeWithMultipleSchemaPatternsAndTrailingBlank() throws Exception { + String targetFolder = "target/" + testName.getMethodName(); + + mojo.setTargetFolder(targetFolder); + mojo.setSchemaPattern("SCHEMA1,BLANK"); + mojo.execute(); + + assertTrue(new File(targetFolder + "/com/example/QNoSchemaTable.java").exists()); + assertTrue(new File(targetFolder + "/com/example/QSchema1Table.java").exists()); + + assertFalse(new File(targetFolder + "/com/example/QSchema2Table.java").exists()); + } + + @Test + public void executeWithMultipleSchemaPatternsAndContainingBlank() throws Exception { + String targetFolder = "target/" + testName.getMethodName(); + + mojo.setTargetFolder(targetFolder); + mojo.setSchemaPattern("SCHEMA1,SCHEMA2BLANK"); + mojo.execute(); + + assertTrue(new File(targetFolder + "/com/example/QSchema1Table.java").exists()); + + assertFalse(new File(targetFolder + "/com/example/QNoSchemaTable.java").exists()); + assertFalse(new File(targetFolder + "/com/example/QSchema2Table.java").exists()); + } + + // endregion Schema Pattern Matching - BLANK Values +} diff --git a/querydsl-maven-plugin/src/test/java/com/querydsl/maven/TestMetadataExportMojoTest.java b/querydsl-maven-plugin/src/test/java/com/querydsl/maven/TestMetadataExportMojoTest.java new file mode 100644 index 0000000000..baaedfcc76 --- /dev/null +++ b/querydsl-maven-plugin/src/test/java/com/querydsl/maven/TestMetadataExportMojoTest.java @@ -0,0 +1,85 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.maven; + +import com.querydsl.codegen.GeneratedAnnotationResolver; +import org.apache.maven.project.MavenProject; +import org.codehaus.plexus.util.FileUtils; +import org.junit.Test; + +import java.io.File; +import java.lang.annotation.Annotation; +import java.util.Collections; + +import static org.hamcrest.Matchers.containsString; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; + +public class TestMetadataExportMojoTest { + + private final String url = "jdbc:h2:mem:testdb" + System.currentTimeMillis(); + + private TestMetadataExportMojo setupMojoWith(MavenProject project) { + TestMetadataExportMojo mojo = new TestMetadataExportMojo(); + mojo.setProject(project); + mojo.setJdbcDriver("org.h2.Driver"); + mojo.setJdbcUrl(url); + mojo.setJdbcUser("sa"); + mojo.setNamePrefix("Q"); // default value + mojo.setNameSuffix(""); + mojo.setBeanPrefix(""); + mojo.setBeanSuffix("Bean"); + mojo.setPackageName("com.example"); + mojo.setTargetFolder("target/export4"); + mojo.setImports(new String[] {"com.pck1", "com.pck2", "com.Q1", "com.Q2"}); + return mojo; + } + + @Test + public void execute() throws Exception { + MavenProject project = new MavenProject(); + TestMetadataExportMojo mojo = setupMojoWith(project); + mojo.execute(); + + //'target/export4' seems to conflict with MetadataExportMojoTest.Execute_With_TypeMappings + assertEquals(Collections.singletonList("target/export4"), project.getTestCompileSourceRoots()); + assertTrue(new File("target/export4").exists()); + } + + @Test + public void defaultGeneratedAnnotation() throws Exception { + MavenProject project = new MavenProject(); + TestMetadataExportMojo mojo = setupMojoWith(project); + mojo.execute(); + + File sourceFile = new File("target/export4/com/example/QCatalogs.java"); + String sourceFileContent = FileUtils.fileRead(sourceFile); + assertThat(sourceFileContent, containsString("@" + GeneratedAnnotationResolver.resolveDefault().getSimpleName())); + } + + @Test + public void providedGeneratedAnnotation() throws Exception { + Class<? extends Annotation> annotationClass = com.querydsl.core.annotations.Generated.class; + MavenProject project = new MavenProject(); + TestMetadataExportMojo mojo = setupMojoWith(project); + mojo.setGeneratedAnnotationClass(annotationClass.getName()); + mojo.execute(); + + File sourceFile = new File("target/export4/com/example/QCatalogs.java"); + String sourceFileContent = FileUtils.fileRead(sourceFile); + assertThat(sourceFileContent, containsString("@" + annotationClass.getSimpleName())); + } + +} diff --git a/querydsl-mongodb/README.md b/querydsl-mongodb/README.md index 6625c74d63..3feb9e2d19 100644 --- a/querydsl-mongodb/README.md +++ b/querydsl-mongodb/README.md @@ -6,42 +6,48 @@ The Mongodb module provides integration with the Mongodb API. Add the following dependencies to your Maven project : - <dependency> - <groupId>com.mysema.querydsl</groupId> - <artifactId>querydsl-mongodb</artifactId> - <version>${querydsl.version}</version> - </dependency> - - <dependency> - <groupId>org.slf4j</groupId> - <artifactId>slf4j-log4j12</artifactId> - <version>1.6.1</version> - </dependency> +```XML +<dependency> + <groupId>com.querydsl</groupId> + <artifactId>querydsl-mongodb</artifactId> + <version>${querydsl.version}</version> +</dependency> +``` And now, configure the Maven APT plugin which generates the query types used by Querydsl : - <plugin> - <groupId>com.mysema.maven</groupId> - <artifactId>apt-maven-plugin</artifactId> - <version>1.0.6</version> - <executions> - <execution> - <goals> - <goal>process</goal> - </goals> - <configuration> - <outputDirectory>target/generated-sources/java</outputDirectory> - <processor>com.mysema.query.mongodb.morphia.MorphiaAnnotationProcessor</processor> - </configuration> - </execution> - </executions> - </plugin> +```XML +<project> + <build> + <plugins> + ... + <plugin> + <groupId>com.mysema.maven</groupId> + <artifactId>apt-maven-plugin</artifactId> + <version>1.1.3</version> + <executions> + <execution> + <goals> + <goal>process</goal> + </goals> + <configuration> + <outputDirectory>target/generated-sources/java</outputDirectory> + <processor>com.querydsl.mongodb.morphia.MorphiaAnnotationProcessor</processor> + </configuration> + </execution> + </executions> + </plugin> + ... + </plugins> + </build> +</project> +``` The MorphiaAnnotationProcessor finds domain types annotated with the com.google.code.morphia.annotations.Entity annotation and generates Querydsl query types for them. -Run clean install and you will get your Query types generated into target/generated-sources/java. +Run `mvn clean install` and you will get your Query types generated into target/generated-sources/java. -If you use Eclipse, run mvn eclipse:eclipse to update your Eclipse project to include target/generated-sources/java as a source folder. +If you use Eclipse, run `mvn eclipse:eclipse` to update your Eclipse project to include target/generated-sources/java as a source folder. Now you are able to construct Mongodb queries and instances of the query domain model. @@ -49,14 +55,16 @@ Now you are able to construct Mongodb queries and instances of the query domain Querying with Querydsl Mongodb with Morphia is as simple as this : - Morphia morphia; - Datastore datastore; - // ... - QUser user = new QUser("user"); - MorphiaQuery<User> query = new MorphiaQuery<User>(morphia, datastore, user); - List<User> list = query - .where(user.firstName.eq("Bob")) - .list(); +```JAVA +Morphia morphia; +Datastore datastore; +// ... +QUser user = new QUser("user"); +MorphiaQuery<User> query = new MorphiaQuery<User>(morphia, datastore, user); +List<User> list = query + .where(user.firstName.eq("Bob")) + .fetch(); +``` -For more information on the Querydsl Mongodb module visit the reference documentation http://www.querydsl.com/static/querydsl/latest/reference/html/ch02s06.html \ No newline at end of file +For more information on the Querydsl Mongodb module visit the reference documentation http://www.querydsl.com/static/querydsl/latest/reference/html/ch02s07.html diff --git a/querydsl-mongodb/doc/README.txt b/querydsl-mongodb/doc/README.txt deleted file mode 100644 index 8ad95360fc..0000000000 --- a/querydsl-mongodb/doc/README.txt +++ /dev/null @@ -1,6 +0,0 @@ - -- Download and install Mongodb -- run: mongod --dbpath put/your/path - -Now the tests should be runnable - diff --git a/querydsl-mongodb/pom.xml b/querydsl-mongodb/pom.xml index ba74139769..43e5448670 100644 --- a/querydsl-mongodb/pom.xml +++ b/querydsl-mongodb/pom.xml @@ -1,26 +1,36 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0" encoding="UTF-8"?> <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <modelVersion>4.0.0</modelVersion> <parent> - <groupId>com.mysema.querydsl</groupId> + <groupId>com.querydsl</groupId> <artifactId>querydsl-root</artifactId> - <version>3.4.1.BUILD-SNAPSHOT</version> - <relativePath>../querydsl-root/pom.xml</relativePath> + <version>5.1.0</version> + <relativePath>../pom.xml</relativePath> </parent> - <groupId>com.mysema.querydsl</groupId> + <groupId>com.querydsl</groupId> <artifactId>querydsl-mongodb</artifactId> <name>Querydsl - Mongodb support</name> <description>Mongodb support for Querydsl</description> <packaging>jar</packaging> <properties> - <mongodb.version>2.10.0</mongodb.version> - <morphia.version>0.105</morphia.version> + <mongodb.version>3.12.11</mongodb.version> + <osgi.import.package> + com.mongodb;version="0.0.0", + org.mongodb.morphia.*;version="1.3.2", + org.bson.*;version="0.0.0", + ${osgi.import.package.root} + </osgi.import.package> </properties> <dependencies> + <dependency> + <groupId>org.jetbrains</groupId> + <artifactId>annotations</artifactId> + <scope>provided</scope> + </dependency> <dependency> <groupId>org.mongodb</groupId> <artifactId>mongo-java-driver</artifactId> @@ -30,7 +40,14 @@ <groupId>org.mongodb.morphia</groupId> <artifactId>morphia</artifactId> <version>${morphia.version}</version> + <exclusions> + <exclusion> + <artifactId>mongo-java-driver</artifactId> + <groupId>org.mongodb</groupId> + </exclusion> + </exclusions> <optional>true</optional> + <scope>provided</scope> </dependency> <dependency> <groupId>com.thoughtworks.proxytoys</groupId> @@ -41,29 +58,20 @@ </dependency> <dependency> - <groupId>com.mysema.querydsl</groupId> + <groupId>com.querydsl</groupId> <artifactId>querydsl-core</artifactId> <version>${project.version}</version> </dependency> <dependency> - <groupId>com.mysema.querydsl</groupId> + <groupId>com.querydsl</groupId> <artifactId>querydsl-apt</artifactId> <version>${project.version}</version> <scope>provided</scope> </dependency> - <dependency> - <groupId>org.slf4j</groupId> - <artifactId>slf4j-api</artifactId> - </dependency> - <dependency> - <groupId>org.slf4j</groupId> - <artifactId>slf4j-log4j12</artifactId> - </dependency> - <!-- test --> <dependency> - <groupId>com.mysema.querydsl</groupId> + <groupId>com.querydsl</groupId> <artifactId>querydsl-core</artifactId> <version>${project.version}</version> <scope>test</scope> @@ -74,8 +82,20 @@ <build> <plugins> <plugin> - <groupId>com.springsource.bundlor</groupId> - <artifactId>com.springsource.bundlor.maven</artifactId> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-jar-plugin</artifactId> + <configuration> + <archive> + <manifestEntries> + <Automatic-Module-Name>com.querydsl.mongodb</Automatic-Module-Name> + </manifestEntries> + </archive> + </configuration> + </plugin> + + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> </plugin> <plugin> @@ -89,7 +109,7 @@ </goals> <configuration> <outputDirectory>target/generated-test-sources/java</outputDirectory> - <processor>com.mysema.query.apt.morphia.MorphiaAnnotationProcessor</processor> + <processor>com.querydsl.apt.morphia.MorphiaAnnotationProcessor</processor> <logOnlyOnError>true</logOnlyOnError> <options> <defaultOverwrite>true</defaultOverwrite> @@ -137,7 +157,7 @@ </property> </systemProperties> <includes> - <include>com/mysema/query/PackageVerification.java</include> + <include>com/querydsl/jpa/PackageVerification.java</include> </includes> </configuration> </execution> @@ -148,4 +168,4 @@ </build> -</project> +</project> diff --git a/querydsl-mongodb/src/apt/META-INF/services/javax.annotation.processing.Processor b/querydsl-mongodb/src/apt/META-INF/services/javax.annotation.processing.Processor index 7a4886bc1e..d0b82f8576 100644 --- a/querydsl-mongodb/src/apt/META-INF/services/javax.annotation.processing.Processor +++ b/querydsl-mongodb/src/apt/META-INF/services/javax.annotation.processing.Processor @@ -1 +1 @@ -com.mysema.query.apt.morphia.MorphiaAnnotationProcessor \ No newline at end of file +com.querydsl.apt.morphia.MorphiaAnnotationProcessor \ No newline at end of file diff --git a/querydsl-mongodb/src/main/apt.xml b/querydsl-mongodb/src/main/apt.xml index a8b530cb0b..5f792b563f 100644 --- a/querydsl-mongodb/src/main/apt.xml +++ b/querydsl-mongodb/src/main/apt.xml @@ -8,12 +8,12 @@ <includeBaseDirectory>false</includeBaseDirectory> <fileSets> <fileSet> - <directory>src/apt</directory> - <outputDirectory>/</outputDirectory> - </fileSet> + <directory>src/apt</directory> + <outputDirectory>/</outputDirectory> + </fileSet> <fileSet> - <directory>${project.build.outputDirectory}</directory> - <outputDirectory>/</outputDirectory> - </fileSet> + <directory>${project.build.outputDirectory}</directory> + <outputDirectory>/</outputDirectory> + </fileSet> </fileSets> </assembly> \ No newline at end of file diff --git a/querydsl-mongodb/src/main/assembly.xml b/querydsl-mongodb/src/main/assembly.xml index 1c14abc7f4..f663fb239c 100644 --- a/querydsl-mongodb/src/main/assembly.xml +++ b/querydsl-mongodb/src/main/assembly.xml @@ -8,14 +8,14 @@ <includeBaseDirectory>false</includeBaseDirectory> <fileSets> <fileSet> - <directory>src/apt</directory> - <outputDirectory>/</outputDirectory> - </fileSet> + <directory>src/apt</directory> + <outputDirectory>/</outputDirectory> + </fileSet> <fileSet> - <directory>src/license</directory> - <outputDirectory>/license</outputDirectory> - </fileSet> - </fileSets> + <directory>src/license</directory> + <outputDirectory>/license</outputDirectory> + </fileSet> + </fileSets> <dependencySets> <dependencySet> <unpack>true</unpack> diff --git a/querydsl-mongodb/src/main/java/com/mysema/query/mongodb/AnyEmbeddedBuilder.java b/querydsl-mongodb/src/main/java/com/mysema/query/mongodb/AnyEmbeddedBuilder.java deleted file mode 100644 index 6e8dfa7fe9..0000000000 --- a/querydsl-mongodb/src/main/java/com/mysema/query/mongodb/AnyEmbeddedBuilder.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2012, Mysema Ltd - * - * 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. - */ -package com.mysema.query.mongodb; - -import java.util.Collection; - -import com.mysema.query.support.QueryMixin; -import com.mysema.query.types.ExpressionUtils; -import com.mysema.query.types.Path; -import com.mysema.query.types.Predicate; -import com.mysema.query.types.PredicateOperation; - -/** - * AnyEmbeddedBuilder is a builder for constraints on embedded objects - * - * @author tiwe - * - * @param <K> - */ -public class AnyEmbeddedBuilder<K> { - - private final QueryMixin<MongodbQuery<K>> queryMixin; - - private final Path<? extends Collection<?>> collection; - - public AnyEmbeddedBuilder(QueryMixin<MongodbQuery<K>> queryMixin, - Path<? extends Collection<?>> collection) { - this.queryMixin = queryMixin; - this.collection = collection; - } - - public MongodbQuery<K> on(Predicate... conditions) { - return queryMixin.where(PredicateOperation.create( - MongodbOps.ELEM_MATCH, collection, ExpressionUtils.allOf(conditions))); - } - -} diff --git a/querydsl-mongodb/src/main/java/com/mysema/query/mongodb/JoinBuilder.java b/querydsl-mongodb/src/main/java/com/mysema/query/mongodb/JoinBuilder.java deleted file mode 100644 index 5254655d2e..0000000000 --- a/querydsl-mongodb/src/main/java/com/mysema/query/mongodb/JoinBuilder.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2012, Mysema Ltd - * - * 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. - */ -package com.mysema.query.mongodb; - -import com.mysema.query.JoinType; -import com.mysema.query.support.QueryMixin; -import com.mysema.query.types.ExpressionUtils; -import com.mysema.query.types.Path; -import com.mysema.query.types.Predicate; - -/** - * JoinBuilder is a builder for join constraints - * - * @author tiwe - * - * @param <K> - * @param <T> - */ -public class JoinBuilder<K, T> { - - private final QueryMixin<MongodbQuery<K>> queryMixin; - - private final Path<?> ref; - - private final Path<T> target; - - public JoinBuilder(QueryMixin<MongodbQuery<K>> queryMixin, Path<?> ref, Path<T> target) { - this.queryMixin = queryMixin; - this.ref = ref; - this.target = target; - } - - public MongodbQuery<K> on(Predicate... conditions) { - queryMixin.addJoin(JoinType.JOIN, ExpressionUtils.as((Path)ref, target)); - queryMixin.on(conditions); - return queryMixin.getSelf(); - } - -} diff --git a/querydsl-mongodb/src/main/java/com/mysema/query/mongodb/MongodbExpressions.java b/querydsl-mongodb/src/main/java/com/mysema/query/mongodb/MongodbExpressions.java deleted file mode 100644 index a41e06800a..0000000000 --- a/querydsl-mongodb/src/main/java/com/mysema/query/mongodb/MongodbExpressions.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.mongodb; - -import com.mysema.query.types.ConstantImpl; -import com.mysema.query.types.Expression; -import com.mysema.query.types.expr.BooleanExpression; -import com.mysema.query.types.expr.BooleanOperation; - -/** - * Mongodb specific operations - * - * @author tiwe - * - */ -public final class MongodbExpressions { - - private MongodbExpressions() {} - - /** - * Finds the closest points relative to the given location and orders the results with decreasing promimity - * - * @param expr - * @param latVal latitude - * @param longVal longitude - * @return - */ - public static BooleanExpression near(Expression<Double[]> expr, double latVal, double longVal) { - return BooleanOperation.create(MongodbOps.NEAR, expr, ConstantImpl.create(new Double[]{latVal, longVal})); - } - -} diff --git a/querydsl-mongodb/src/main/java/com/mysema/query/mongodb/MongodbOps.java b/querydsl-mongodb/src/main/java/com/mysema/query/mongodb/MongodbOps.java deleted file mode 100644 index f4fb8c728a..0000000000 --- a/querydsl-mongodb/src/main/java/com/mysema/query/mongodb/MongodbOps.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2013, Mysema Ltd - * - * 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. - */ -package com.mysema.query.mongodb; - -import com.mysema.query.types.Operator; -import com.mysema.query.types.OperatorImpl; - -/** - * @author tiwe - * - */ -public final class MongodbOps { - - private static final String NS = MongodbOps.class.getName(); - - public static final Operator<Boolean> NEAR = new OperatorImpl<Boolean>(NS, "NEAR"); - - public static final Operator<Boolean> ELEM_MATCH = new OperatorImpl<Boolean>(NS, "ELEM_MATCH"); - - private MongodbOps() {} - -} diff --git a/querydsl-mongodb/src/main/java/com/mysema/query/mongodb/MongodbQuery.java b/querydsl-mongodb/src/main/java/com/mysema/query/mongodb/MongodbQuery.java deleted file mode 100644 index 6f761457f9..0000000000 --- a/querydsl-mongodb/src/main/java/com/mysema/query/mongodb/MongodbQuery.java +++ /dev/null @@ -1,410 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.mongodb; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; - -import javax.annotation.Nullable; - -import com.google.common.base.Function; -import com.google.common.collect.HashMultimap; -import com.google.common.collect.Multimap; -import com.mongodb.BasicDBObject; -import com.mongodb.DBCollection; -import com.mongodb.DBCursor; -import com.mongodb.DBObject; -import com.mongodb.ReadPreference; -import com.mysema.commons.lang.CloseableIterator; -import com.mysema.query.DefaultQueryMetadata; -import com.mysema.query.JoinExpression; -import com.mysema.query.NonUniqueResultException; -import com.mysema.query.QueryMetadata; -import com.mysema.query.QueryModifiers; -import com.mysema.query.SearchResults; -import com.mysema.query.SimpleProjectable; -import com.mysema.query.SimpleQuery; -import com.mysema.query.support.QueryMixin; -import com.mysema.query.types.Expression; -import com.mysema.query.types.ExpressionUtils; -import com.mysema.query.types.Operation; -import com.mysema.query.types.OrderSpecifier; -import com.mysema.query.types.ParamExpression; -import com.mysema.query.types.Path; -import com.mysema.query.types.PathImpl; -import com.mysema.query.types.Predicate; -import com.mysema.query.types.path.CollectionPathBase; - -/** - * MongodbQuery provides a general Querydsl query implementation with a pluggable DBObject to Bean transformation - * - * @author laimw - * - * @param <K> - */ -public abstract class MongodbQuery<K> implements SimpleQuery<MongodbQuery<K>>, SimpleProjectable<K> { - - @SuppressWarnings("serial") - private static class NoResults extends RuntimeException {} - - private final MongodbSerializer serializer; - - private final QueryMixin<MongodbQuery<K>> queryMixin; - - private final DBCollection collection; - - private final Function<DBObject, K> transformer; - - private ReadPreference readPreference; - - /** - * Create a new MongodbQuery instance - * - * @param collection - * @param transformer - * @param serializer - */ - public MongodbQuery(DBCollection collection, Function<DBObject, K> transformer, MongodbSerializer serializer) { - this.queryMixin = new QueryMixin<MongodbQuery<K>>(this, new DefaultQueryMetadata().noValidate(), false); - this.transformer = transformer; - this.collection = collection; - this.serializer = serializer; - } - - /** - * Define a join - * - * @param ref - * @param target - * @return - */ - public <T> JoinBuilder<K,T> join(Path<T> ref, Path<T> target) { - return new JoinBuilder<K,T>(queryMixin, ref, target); - } - - /** - * Define a join - * - * @param ref - * @param target - * @return - */ - public <T> JoinBuilder<K,T> join(CollectionPathBase<?,T,?> ref, Path<T> target) { - return new JoinBuilder<K,T>(queryMixin, ref, target); - } - - /** - * Define a constraint for an embedded object - * - * @param collection - * @param target - * @return - */ - public <T> AnyEmbeddedBuilder<K> anyEmbedded(Path<? extends Collection<T>> collection, Path<T> target) { - return new AnyEmbeddedBuilder<K>(queryMixin, collection); - } - - protected abstract DBCollection getCollection(Class<?> type); - - @Override - public boolean exists() { - try { - QueryMetadata metadata = queryMixin.getMetadata(); - Predicate filter = createFilter(metadata); - return collection.findOne(createQuery(filter)) != null; - } catch (NoResults ex) { - return false; - } - } - - @Nullable - protected Predicate createFilter(QueryMetadata metadata) { - Predicate filter; - if (!metadata.getJoins().isEmpty()) { - filter = ExpressionUtils.allOf(metadata.getWhere(), createJoinFilter(metadata)); - } else { - filter = metadata.getWhere(); - } - return filter; - } - - @Nullable - protected Predicate createJoinFilter(QueryMetadata metadata) { - Multimap<Expression<?>, Predicate> predicates = HashMultimap.<Expression<?>, Predicate>create(); - List<JoinExpression> joins = metadata.getJoins(); - for (int i = joins.size() - 1; i >= 0; i--) { - JoinExpression join = joins.get(i); - Path source = (Path)((Operation<?>)join.getTarget()).getArg(0); - Path target = (Path)((Operation<?>)join.getTarget()).getArg(1); - Collection<Predicate> extraFilters = predicates.get(target.getRoot()); - Predicate filter = ExpressionUtils.allOf(join.getCondition(), allOf(extraFilters)); - List<Object> ids = getIds(target.getType(), filter); - if (ids.isEmpty()) { - throw new NoResults(); - } - Path path = new PathImpl<String>(String.class, source, "$id"); - predicates.put(source.getRoot(), ExpressionUtils.in(path, ids)); - } - Path source = (Path)((Operation)joins.get(0).getTarget()).getArg(0); - return allOf(predicates.get(source.getRoot())); - } - - private Predicate allOf(Collection<Predicate> predicates) { - return predicates != null ? ExpressionUtils.allOf(predicates) : null; - } - - protected List<Object> getIds(Class<?> targetType, Predicate condition) { - DBCollection collection = getCollection(targetType); - // TODO : fetch only ids - DBCursor cursor = createCursor(collection, condition, Collections.<Expression<?>>emptyList(), - QueryModifiers.EMPTY, Collections.<OrderSpecifier<?>>emptyList()); - if (cursor.hasNext()) { - List<Object> ids = new ArrayList<Object>(cursor.count()); - for (DBObject obj : cursor) { - ids.add(obj.get("_id")); - } - return ids; - } else { - return Collections.emptyList(); - } - } - - @Override - public boolean notExists() { - return !exists(); - } - - @Override - public MongodbQuery<K> distinct() { - return queryMixin.distinct(); - } - - public MongodbQuery<K> where(Predicate e) { - return queryMixin.where(e); - } - - @Override - public MongodbQuery<K> where(Predicate... e) { - return queryMixin.where(e); - } - - @Override - public MongodbQuery<K> limit(long limit) { - return queryMixin.limit(limit); - } - - @Override - public MongodbQuery<K> offset(long offset) { - return queryMixin.offset(offset); - } - - @Override - public MongodbQuery<K> restrict(QueryModifiers modifiers) { - return queryMixin.restrict(modifiers); - } - - public MongodbQuery<K> orderBy(OrderSpecifier<?> o) { - return queryMixin.orderBy(o); - } - - @Override - public MongodbQuery<K> orderBy(OrderSpecifier<?>... o) { - return queryMixin.orderBy(o); - } - - @Override - public <T> MongodbQuery<K> set(ParamExpression<T> param, T value) { - return queryMixin.set(param, value); - } - - public CloseableIterator<K> iterate(Path<?>... paths) { - queryMixin.addProjection(paths); - return iterate(); - } - - @Override - public CloseableIterator<K> iterate() { - final DBCursor cursor = createCursor(); - return new CloseableIterator<K>() { - @Override - public boolean hasNext() { - return cursor.hasNext(); - } - - @Override - public K next() { - return transformer.apply(cursor.next()); - } - - @Override - public void remove() { - } - - @Override - public void close() { - } - }; - } - - public List<K> list(Path<?>... paths) { - queryMixin.addProjection(paths); - return list(); - } - - @Override - public List<K> list() { - try { - DBCursor cursor = createCursor(); - List<K> results = new ArrayList<K>(cursor.size()); - for (DBObject dbObject : cursor) { - results.add(transformer.apply(dbObject)); - } - return results; - } catch (NoResults ex) { - return Collections.emptyList(); - } - } - - protected DBCursor createCursor() { - QueryMetadata metadata = queryMixin.getMetadata(); - Predicate filter = createFilter(metadata); - return createCursor(collection, filter, metadata.getProjection(), metadata.getModifiers(), metadata.getOrderBy()); - } - - protected DBCursor createCursor(DBCollection collection, @Nullable Predicate where, List<Expression<?>> projection, - QueryModifiers modifiers, List<OrderSpecifier<?>> orderBy) { - DBCursor cursor = collection.find(createQuery(where), createProjection(projection)); - Integer limit = modifiers.getLimitAsInteger(); - Integer offset = modifiers.getOffsetAsInteger(); - if (limit != null) { - cursor.limit(limit.intValue()); - } - if (offset != null) { - cursor.skip(offset.intValue()); - } - if (orderBy.size() > 0) { - cursor.sort(serializer.toSort(orderBy)); - } - if (readPreference != null) { - cursor.setReadPreference(readPreference); - } - return cursor; - } - - private DBObject createProjection(List<Expression<?>> projection) { - if (!projection.isEmpty()) { - DBObject obj = new BasicDBObject(); - for (Expression<?> expr : projection) { - obj.put((String)serializer.handle(expr), 1); - } - return obj; - } - return null; - } - - public K singleResult(Path<?>...paths) { - queryMixin.addProjection(paths); - return singleResult(); - } - - @Override - public K singleResult() { - try { - DBCursor c = createCursor().limit(1); - if (c.hasNext()) { - return transformer.apply(c.next()); - } else { - return null; - } - } catch (NoResults ex) { - return null; - } - } - - public K uniqueResult(Path<?>... paths) { - queryMixin.addProjection(paths); - return uniqueResult(); - } - - @Override - public K uniqueResult() { - try { - Long limit = queryMixin.getMetadata().getModifiers().getLimit(); - if (limit == null) { - limit = 2l; - } - DBCursor c = createCursor().limit(limit.intValue()); - if (c.hasNext()) { - K rv = transformer.apply(c.next()); - if (c.hasNext()) { - throw new NonUniqueResultException(); - } - return rv; - } else { - return null; - } - } catch (NoResults ex) { - return null; - } - } - - public SearchResults<K> listResults(Path<?>... paths) { - queryMixin.addProjection(paths); - return listResults(); - } - - @Override - public SearchResults<K> listResults() { - try { - long total = count(); - if (total > 0l) { - return new SearchResults<K>(list(), queryMixin.getMetadata().getModifiers(), total); - } else { - return SearchResults.emptyResults(); - } - } catch (NoResults ex) { - return SearchResults.emptyResults(); - } - } - - @Override - public long count() { - try { - Predicate filter = createFilter(queryMixin.getMetadata()); - return collection.count(createQuery(filter)); - } catch (NoResults ex) { - return 0l; - } - } - - private DBObject createQuery(@Nullable Predicate predicate) { - if (predicate != null) { - return (DBObject) serializer.handle(predicate); - } else { - return new BasicDBObject(); - } - } - - public void setReadPreference(ReadPreference readPreference) { - this.readPreference = readPreference; - } - - @Override - public String toString() { - return createQuery(queryMixin.getMetadata().getWhere()).toString(); - } - -} \ No newline at end of file diff --git a/querydsl-mongodb/src/main/java/com/mysema/query/mongodb/MongodbSerializer.java b/querydsl-mongodb/src/main/java/com/mysema/query/mongodb/MongodbSerializer.java deleted file mode 100644 index 7ed493f1d1..0000000000 --- a/querydsl-mongodb/src/main/java/com/mysema/query/mongodb/MongodbSerializer.java +++ /dev/null @@ -1,340 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.mongodb; - -import java.util.Collection; -import java.util.List; -import java.util.regex.Pattern; - -import org.bson.BSONObject; -import org.bson.types.ObjectId; - -import com.google.common.collect.Sets; -import com.mongodb.BasicDBList; -import com.mongodb.BasicDBObject; -import com.mongodb.DBObject; -import com.mongodb.DBRef; -import com.mysema.query.types.Constant; -import com.mysema.query.types.Expression; -import com.mysema.query.types.ExpressionUtils; -import com.mysema.query.types.FactoryExpression; -import com.mysema.query.types.Operation; -import com.mysema.query.types.OperationImpl; -import com.mysema.query.types.Operator; -import com.mysema.query.types.Ops; -import com.mysema.query.types.Order; -import com.mysema.query.types.OrderSpecifier; -import com.mysema.query.types.ParamExpression; -import com.mysema.query.types.Path; -import com.mysema.query.types.PathMetadata; -import com.mysema.query.types.PathType; -import com.mysema.query.types.SubQueryExpression; -import com.mysema.query.types.TemplateExpression; -import com.mysema.query.types.Visitor; - -/** - * Serializes the given Querydsl query to a DBObject query for MongoDB - * - * @author laimw - * - */ -public abstract class MongodbSerializer implements Visitor<Object, Void> { - - public Object handle(Expression<?> expression) { - return expression.accept(this, null); - } - - public DBObject toSort(List<OrderSpecifier<?>> orderBys) { - BasicDBObject sort = new BasicDBObject(); - for (OrderSpecifier<?> orderBy : orderBys) { - Object key = orderBy.getTarget().accept(this, null); - sort.append(key.toString(), orderBy.getOrder() == Order.ASC ? 1 : -1); - } - return sort; - } - - @Override - public Object visit(Constant<?> expr, Void context) { - if (Enum.class.isAssignableFrom(expr.getType())) { - return ((Enum<?>)expr.getConstant()).name(); - } else { - return expr.getConstant(); - } - } - - @Override - public Object visit(TemplateExpression<?> expr, Void context) { - throw new UnsupportedOperationException(); - } - - @Override - public Object visit(FactoryExpression<?> expr, Void context) { - throw new UnsupportedOperationException(); - } - - private String asDBKey(Operation<?> expr, int index) { - return (String) asDBValue(expr, index); - } - - private Object asDBValue(Operation<?> expr, int index) { - return expr.getArg(index).accept(this, null); - } - - private String regexValue(Operation<?> expr, int index) { - return Pattern.quote(expr.getArg(index).accept(this, null).toString()); - } - - protected DBObject asDBObject(String key, Object value) { - return new BasicDBObject(key, value); - } - - @Override - public Object visit(Operation<?> expr, Void context) { - Operator<?> op = expr.getOperator(); - if (op == Ops.EQ) { - if (expr.getArg(0) instanceof Operation) { - Operation<?> lhs = (Operation<?>) expr.getArg(0); - if (lhs.getOperator() == Ops.COL_SIZE || lhs.getOperator() == Ops.ARRAY_SIZE) { - return asDBObject(asDBKey(lhs, 0), asDBObject("$size", asDBValue(expr, 1))); - } else { - throw new UnsupportedOperationException("Illegal operation " + expr); - } - } else if (isReference(expr, 0)) { - return asDBObject(asDBKey(expr, 0), asReference(expr, 1)); - } else { - return asDBObject(asDBKey(expr, 0), asDBValue(expr, 1)); - } - - } else if (op == Ops.STRING_IS_EMPTY) { - return asDBObject(asDBKey(expr, 0), ""); - - } else if (op == Ops.AND) { - BSONObject lhs = (BSONObject) handle(expr.getArg(0)); - BSONObject rhs = (BSONObject) handle(expr.getArg(1)); - if (Sets.intersection(lhs.keySet(), rhs.keySet()).isEmpty()) { - lhs.putAll(rhs); - return lhs; - } else { - BasicDBList list = new BasicDBList(); - list.add(handle(expr.getArg(0))); - list.add(handle(expr.getArg(1))); - return asDBObject("$and", list); - } - - } else if (op == Ops.NOT) { - //Handle the not's child - BasicDBObject arg = (BasicDBObject) handle(expr.getArg(0)); - - //Only support the first key, let's see if there - //is cases where this will get broken - String key = arg.keySet().iterator().next(); - Operation<?> subOperation = (Operation<?>) expr.getArg(0); - Operator<?> subOp = subOperation.getOperator(); - if (subOp == Ops.IN) { - return visit(OperationImpl.create(Boolean.class, Ops.NOT_IN, subOperation.getArg(0), - subOperation.getArg(1)), context); - } else if (subOp != Ops.EQ && subOp != Ops.STRING_IS_EMPTY) { - return asDBObject(key, asDBObject("$not", arg.get(key))); - } else { - return asDBObject(key, asDBObject("$ne", arg.get(key))); - } - - } else if (op == Ops.OR) { - BasicDBList list = new BasicDBList(); - list.add(handle(expr.getArg(0))); - list.add(handle(expr.getArg(1))); - return asDBObject("$or", list); - - } else if (op == Ops.NE) { - if (isReference(expr, 0)) { - return asDBObject(asDBKey(expr, 0), asDBObject("$ne", asReference(expr, 1))); - } else { - return asDBObject(asDBKey(expr, 0), asDBObject("$ne", asDBValue(expr, 1))); - } - - } else if (op == Ops.STARTS_WITH) { - return asDBObject(asDBKey(expr, 0), - Pattern.compile("^" + regexValue(expr, 1))); - - } else if (op == Ops.STARTS_WITH_IC) { - return asDBObject(asDBKey(expr, 0), - Pattern.compile("^" + regexValue(expr, 1), Pattern.CASE_INSENSITIVE)); - - } else if (op == Ops.ENDS_WITH) { - return asDBObject(asDBKey(expr, 0), Pattern.compile(regexValue(expr, 1) + "$")); - - } else if (op == Ops.ENDS_WITH_IC) { - return asDBObject(asDBKey(expr, 0), - Pattern.compile(regexValue(expr, 1) + "$", Pattern.CASE_INSENSITIVE)); - - } else if (op == Ops.EQ_IGNORE_CASE) { - return asDBObject(asDBKey(expr, 0), - Pattern.compile("^" + regexValue(expr, 1) + "$", Pattern.CASE_INSENSITIVE)); - - } else if (op == Ops.STRING_CONTAINS) { - return asDBObject(asDBKey(expr, 0), Pattern.compile(".*" + regexValue(expr, 1) + ".*")); - - } else if (op == Ops.STRING_CONTAINS_IC) { - return asDBObject(asDBKey(expr, 0), - Pattern.compile(".*" + regexValue(expr, 1) + ".*", Pattern.CASE_INSENSITIVE)); - - } else if (op == Ops.MATCHES) { - return asDBObject(asDBKey(expr, 0), Pattern.compile(asDBValue(expr, 1).toString())); - - } else if (op == Ops.MATCHES_IC) { - return asDBObject(asDBKey(expr, 0), Pattern.compile(asDBValue(expr, 1).toString(), Pattern.CASE_INSENSITIVE)); - - } else if (op == Ops.LIKE) { - String regex = ExpressionUtils.likeToRegex((Expression)expr.getArg(1)).toString(); - return asDBObject(asDBKey(expr, 0), Pattern.compile(regex)); - - } else if (op == Ops.BETWEEN) { - BasicDBObject value = new BasicDBObject("$gte", asDBValue(expr, 1)); - value.append("$lte", asDBValue(expr, 2)); - return asDBObject(asDBKey(expr, 0), value); - - } else if (op == Ops.IN) { - int constIndex = 0; - int exprIndex = 1; - if (expr.getArg(1) instanceof Constant<?>) { - constIndex = 1; - exprIndex = 0; - } - if (Collection.class.isAssignableFrom(expr.getArg(constIndex).getType())) { - Collection<?> values = (Collection<?>) ((Constant<?>) expr.getArg(constIndex)).getConstant(); - return asDBObject(asDBKey(expr, exprIndex), asDBObject("$in", values.toArray())); - } else { - if (isReference(expr, exprIndex)) { - return asDBObject(asDBKey(expr, exprIndex), asReference(expr, constIndex)); - } else { - return asDBObject(asDBKey(expr, exprIndex), asDBValue(expr, constIndex)); - } - } - - } else if (op == Ops.NOT_IN) { - int constIndex = 0; - int exprIndex = 1; - if (expr.getArg(1) instanceof Constant<?>) { - constIndex = 1; - exprIndex = 0; - } - if (Collection.class.isAssignableFrom(expr.getArg(constIndex).getType())) { - Collection<?> values = (Collection<?>) ((Constant<?>) expr.getArg(constIndex)).getConstant(); - return asDBObject(asDBKey(expr, exprIndex), asDBObject("$nin", values.toArray())); - } else { - if (isReference(expr, exprIndex)) { - return asDBObject(asDBKey(expr, exprIndex), - asDBObject("$ne", asReference(expr, constIndex))); - } else { - return asDBObject(asDBKey(expr, exprIndex), - asDBObject("$ne", asDBValue(expr, constIndex))); - } - } - - } else if (op == Ops.COL_IS_EMPTY) { - BasicDBList list = new BasicDBList(); - list.add(asDBObject(asDBKey(expr, 0), new BasicDBList())); - list.add(asDBObject(asDBKey(expr, 0), asDBObject("$exists", false))); - return asDBObject("$or", list); - - } else if (op == Ops.LT) { - return asDBObject(asDBKey(expr, 0), asDBObject("$lt", asDBValue(expr, 1))); - - } else if (op == Ops.GT) { - return asDBObject(asDBKey(expr, 0), asDBObject("$gt", asDBValue(expr, 1))); - - } else if (op == Ops.LOE) { - return asDBObject(asDBKey(expr, 0), asDBObject("$lte", asDBValue(expr, 1))); - - } else if (op == Ops.GOE) { - return asDBObject(asDBKey(expr, 0), asDBObject("$gte", asDBValue(expr, 1))); - - } else if (op == Ops.IS_NULL) { - return asDBObject(asDBKey(expr, 0), asDBObject("$exists", false)); - - } else if (op == Ops.IS_NOT_NULL) { - return asDBObject(asDBKey(expr, 0), asDBObject("$exists", true)); - - } else if (op == Ops.CONTAINS_KEY) { - Path<?> path = (Path<?>) expr.getArg(0); - Expression<?> key = expr.getArg(1); - return asDBObject(visit(path, context) + "." + key.toString(), asDBObject("$exists", true)); - - } else if (op == MongodbOps.NEAR) { - return asDBObject(asDBKey(expr, 0), asDBObject("$near", asDBValue(expr, 1))); - - } else if (op == MongodbOps.ELEM_MATCH) { - return asDBObject(asDBKey(expr, 0), asDBObject("$elemMatch", asDBValue(expr, 1))); - } - - throw new UnsupportedOperationException("Illegal operation " + expr); - } - - protected DBRef asReference(Operation<?> expr, int constIndex) { - return asReference(((Constant<?>)expr.getArg(constIndex)).getConstant()); - } - - protected DBRef asReference(Object constant) { - // override in subclass - throw new UnsupportedOperationException(); - } - - protected boolean isReference(Operation<?> expr, int exprIndex) { - Expression<?> arg = expr.getArg(exprIndex); - if (arg instanceof Path) { - return isReference((Path<?>) arg); - } else { - return false; - } - } - - protected boolean isReference(Path<?> arg) { - // override in subclass - return false; - } - - - @Override - public String visit(Path<?> expr, Void context) { - PathMetadata<?> metadata = expr.getMetadata(); - if (metadata.getParent() != null) { - if (metadata.getPathType() == PathType.COLLECTION_ANY) { - return visit(metadata.getParent(), context); - } else if (metadata.getParent().getMetadata().getPathType() != PathType.VARIABLE) { - String rv = getKeyForPath(expr, metadata); - return visit(metadata.getParent(), context) + "." + rv; - } - } - return getKeyForPath(expr, metadata); - } - - protected String getKeyForPath(Path<?> expr, PathMetadata<?> metadata) { - if (expr.getType().equals(ObjectId.class)) { - return "_id"; - } else { - return metadata.getElement().toString(); - } - } - - @Override - public Object visit(SubQueryExpression<?> expr, Void context) { - throw new UnsupportedOperationException(); - } - - @Override - public Object visit(ParamExpression<?> expr, Void context) { - throw new UnsupportedOperationException(); - } - -} \ No newline at end of file diff --git a/querydsl-mongodb/src/main/java/com/mysema/query/mongodb/Point.java b/querydsl-mongodb/src/main/java/com/mysema/query/mongodb/Point.java deleted file mode 100644 index 82ba097768..0000000000 --- a/querydsl-mongodb/src/main/java/com/mysema/query/mongodb/Point.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.mongodb; - -import com.mysema.query.types.Path; -import com.mysema.query.types.PathMetadata; -import com.mysema.query.types.expr.BooleanExpression; -import com.mysema.query.types.path.ArrayPath; - -/** - * Point is an adapter type for Double[] arrays to use geo spatial querying features of Mongodb - * - * @author tiwe - * - */ -public class Point extends ArrayPath<Double[], Double> { - - private static final long serialVersionUID = 1776628530121566388L; - - public Point(String variable) { - super(Double[].class, variable); - } - - public Point(Path<?> parent, String property) { - super(Double[].class, parent, property); - } - - public Point(PathMetadata<?> metadata) { - super(Double[].class, metadata); - } - - /** - * Finds the closest points relative to the given location and orders the results with decreasing promimity - * - * @param latVal latitude - * @param longVal longitude - * @return - */ - public BooleanExpression near(double latVal, double longVal) { - return MongodbExpressions.near(this, latVal, longVal); - } - -} diff --git a/querydsl-mongodb/src/main/java/com/mysema/query/mongodb/morphia/MorphiaQuery.java b/querydsl-mongodb/src/main/java/com/mysema/query/mongodb/morphia/MorphiaQuery.java deleted file mode 100644 index be3186bf83..0000000000 --- a/querydsl-mongodb/src/main/java/com/mysema/query/mongodb/morphia/MorphiaQuery.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.mongodb.morphia; - -import org.mongodb.morphia.Datastore; -import org.mongodb.morphia.Morphia; -import org.mongodb.morphia.mapping.cache.DefaultEntityCache; -import org.mongodb.morphia.mapping.cache.EntityCache; - -import com.google.common.base.Function; -import com.mongodb.DBCollection; -import com.mongodb.DBCursor; -import com.mongodb.DBObject; -import com.mysema.query.mongodb.MongodbQuery; -import com.mysema.query.types.EntityPath; - -/** - * MorphiaQuery extends {@link MongodbQuery} with Morphia specific transformations - * - * @author laimw - * @author tiwe - * - */ -public final class MorphiaQuery<K> extends MongodbQuery<K> { - - private final EntityCache cache; - - private final Datastore datastore; - - public MorphiaQuery(Morphia morphia, Datastore datastore, EntityPath<K> entityPath) { - this(morphia, datastore, new DefaultEntityCache(), entityPath); - } - - public MorphiaQuery(final Morphia morphia, final Datastore datastore, - final EntityCache cache, final EntityPath<K> entityPath) { - super(datastore.getCollection(entityPath.getType()), new Function<DBObject, K>() { - @Override - public K apply(DBObject dbObject) { - return morphia.fromDBObject(entityPath.getType(), dbObject, cache); - } - }, new MorphiaSerializer(morphia)); - this.datastore = datastore; - this.cache = cache; - } - - @Override - protected DBCursor createCursor() { - cache.flush(); - return super.createCursor(); - } - - @Override - protected DBCollection getCollection(Class<?> type) { - return datastore.getCollection(type); - } - -} \ No newline at end of file diff --git a/querydsl-mongodb/src/main/java/com/mysema/query/mongodb/morphia/MorphiaSerializer.java b/querydsl-mongodb/src/main/java/com/mysema/query/mongodb/morphia/MorphiaSerializer.java deleted file mode 100644 index 633d034688..0000000000 --- a/querydsl-mongodb/src/main/java/com/mysema/query/mongodb/morphia/MorphiaSerializer.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.mongodb.morphia; - -import org.mongodb.morphia.Key; -import org.mongodb.morphia.Morphia; -import org.mongodb.morphia.annotations.Property; -import org.mongodb.morphia.annotations.Reference; - -import com.mongodb.DBRef; -import com.mysema.query.mongodb.MongodbSerializer; -import com.mysema.query.types.Path; -import com.mysema.query.types.PathMetadata; -import com.mysema.query.types.PathType; - -/** - * MorphiaSerializer extends {@link MongodbSerializer} with Morphia specific annotation handling - * - * @author tiwe - * - */ -public class MorphiaSerializer extends MongodbSerializer { - - private final Morphia morphia; - - public MorphiaSerializer(Morphia morphia) { - this.morphia = morphia; - } - - @Override - protected String getKeyForPath(Path<?> expr, PathMetadata<?> metadata) { - if (metadata.getPathType() == PathType.PROPERTY && expr.getAnnotatedElement().isAnnotationPresent(Property.class)) { - return expr.getAnnotatedElement().getAnnotation(Property.class).value(); - } else { - return super.getKeyForPath(expr, metadata); - } - } - - @Override - protected boolean isReference(Path<?> arg) { - return arg.getAnnotatedElement().getAnnotation(Reference.class) != null; - } - - @Override - protected DBRef asReference(Object constant) { - Key<?> key = morphia.getMapper().getKey(constant); - return morphia.getMapper().keyToRef(key); - } - -} diff --git a/querydsl-mongodb/src/main/java/com/mysema/query/mongodb/morphia/package-info.java b/querydsl-mongodb/src/main/java/com/mysema/query/mongodb/morphia/package-info.java deleted file mode 100644 index 55170f6ec0..0000000000 --- a/querydsl-mongodb/src/main/java/com/mysema/query/mongodb/morphia/package-info.java +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ - -package com.mysema.query.mongodb.morphia; diff --git a/querydsl-mongodb/src/main/java/com/mysema/query/mongodb/package-info.java b/querydsl-mongodb/src/main/java/com/mysema/query/mongodb/package-info.java deleted file mode 100644 index 78e059447b..0000000000 --- a/querydsl-mongodb/src/main/java/com/mysema/query/mongodb/package-info.java +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ - -package com.mysema.query.mongodb; diff --git a/querydsl-mongodb/src/main/java/com/querydsl/mongodb/AbstractMongodbQuery.java b/querydsl-mongodb/src/main/java/com/querydsl/mongodb/AbstractMongodbQuery.java new file mode 100644 index 0000000000..4b082a9d1f --- /dev/null +++ b/querydsl-mongodb/src/main/java/com/querydsl/mongodb/AbstractMongodbQuery.java @@ -0,0 +1,425 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.mongodb; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; + +import org.jetbrains.annotations.Nullable; + +import java.util.Map; +import java.util.function.Function; +import com.mongodb.*; +import com.mysema.commons.lang.CloseableIterator; +import com.querydsl.core.*; +import com.querydsl.core.support.QueryMixin; +import com.querydsl.core.types.*; +import com.querydsl.core.types.dsl.CollectionPathBase; + +/** + * {@code AbstractMongodbQuery} provides a base class for general Querydsl query implementation with a + * pluggable DBObject to Bean transformation + * + * @author laimw + * + * @param <K> result type + * @param <Q> concrete subtype + */ +public abstract class AbstractMongodbQuery<K, Q extends AbstractMongodbQuery<K, Q>> implements SimpleQuery<Q>, Fetchable<K> { + + @SuppressWarnings("serial") + private static class NoResults extends RuntimeException { } + + private final MongodbSerializer serializer; + + private final QueryMixin<Q> queryMixin; + + private final DBCollection collection; + + private final Function<DBObject, K> transformer; + + private ReadPreference readPreference; + + /** + * Create a new MongodbQuery instance + * + * @param collection collection + * @param transformer result transformer + * @param serializer serializer + */ + @SuppressWarnings("unchecked") + public AbstractMongodbQuery(DBCollection collection, Function<DBObject, K> transformer, MongodbSerializer serializer) { + @SuppressWarnings("unchecked") // Q is this plus subclass + Q query = (Q) this; + this.queryMixin = new QueryMixin<Q>(query, new DefaultQueryMetadata(), false); + this.transformer = transformer; + this.collection = collection; + this.serializer = serializer; + } + + /** + * Define a join + * + * @param ref reference + * @param target join target + * @return join builder + */ + public <T> JoinBuilder<Q, K,T> join(Path<T> ref, Path<T> target) { + return new JoinBuilder<Q, K,T>(queryMixin, ref, target); + } + + /** + * Define a join + * + * @param ref reference + * @param target join target + * @return join builder + */ + public <T> JoinBuilder<Q, K,T> join(CollectionPathBase<?,T,?> ref, Path<T> target) { + return new JoinBuilder<Q, K,T>(queryMixin, ref, target); + } + + /** + * Define a constraint for an embedded object + * + * @param collection collection + * @param target target + * @return builder + */ + public <T> AnyEmbeddedBuilder<Q, K> anyEmbedded(Path<? extends Collection<T>> collection, Path<T> target) { + return new AnyEmbeddedBuilder<Q, K>(queryMixin, collection); + } + + protected abstract DBCollection getCollection(Class<?> type); + + @Nullable + protected Predicate createFilter(QueryMetadata metadata) { + Predicate filter; + if (!metadata.getJoins().isEmpty()) { + filter = ExpressionUtils.allOf(metadata.getWhere(), createJoinFilter(metadata)); + } else { + filter = metadata.getWhere(); + } + return filter; + } + + @SuppressWarnings("unchecked") + @Nullable + protected Predicate createJoinFilter(QueryMetadata metadata) { + Map<Expression<?>, Predicate> predicates = new HashMap<>(); + List<JoinExpression> joins = metadata.getJoins(); + for (int i = joins.size() - 1; i >= 0; i--) { + JoinExpression join = joins.get(i); + Path<?> source = (Path) ((Operation<?>) join.getTarget()).getArg(0); + Path<?> target = (Path) ((Operation<?>) join.getTarget()).getArg(1); + + final Predicate extraFilters = predicates.get(target.getRoot()); + Predicate filter = ExpressionUtils.allOf(join.getCondition(), extraFilters); + List<? extends Object> ids = getIds(target.getType(), filter); + if (ids.isEmpty()) { + throw new NoResults(); + } + Path<?> path = ExpressionUtils.path(String.class, source, "$id"); + predicates.merge(source.getRoot(), ExpressionUtils.in((Path<Object>) path, ids), ExpressionUtils::and); + } + Path<?> source = (Path) ((Operation) joins.get(0).getTarget()).getArg(0); + return predicates.get(source.getRoot()); + } + + protected List<Object> getIds(Class<?> targetType, Predicate condition) { + DBCollection collection = getCollection(targetType); + // TODO : fetch only ids + DBCursor cursor = createCursor(collection, condition, null, + QueryModifiers.EMPTY, Collections.<OrderSpecifier<?>>emptyList()); + if (cursor.hasNext()) { + List<Object> ids = new ArrayList<Object>(cursor.count()); + for (DBObject obj : cursor) { + ids.add(obj.get("_id")); + } + return ids; + } else { + return Collections.emptyList(); + } + } + + @Override + public Q distinct() { + return queryMixin.distinct(); + } + + public Q where(Predicate e) { + return queryMixin.where(e); + } + + @Override + public Q where(Predicate... e) { + return queryMixin.where(e); + } + + @Override + public Q limit(long limit) { + return queryMixin.limit(limit); + } + + @Override + public Q offset(long offset) { + return queryMixin.offset(offset); + } + + @Override + public Q restrict(QueryModifiers modifiers) { + return queryMixin.restrict(modifiers); + } + + public Q orderBy(OrderSpecifier<?> o) { + return queryMixin.orderBy(o); + } + + @Override + public Q orderBy(OrderSpecifier<?>... o) { + return queryMixin.orderBy(o); + } + + @Override + public <T> Q set(ParamExpression<T> param, T value) { + return queryMixin.set(param, value); + } + + /** + * Iterate with the specific fields + * + * @param paths fields to return + * @return iterator + */ + public CloseableIterator<K> iterate(Path<?>... paths) { + queryMixin.setProjection(paths); + return iterate(); + } + + @Override + public CloseableIterator<K> iterate() { + final DBCursor cursor = createCursor(); + return new CloseableIterator<K>() { + @Override + public boolean hasNext() { + return cursor.hasNext(); + } + + @Override + public K next() { + return transformer.apply(cursor.next()); + } + + @Override + public void remove() { + } + + @Override + public void close() { + } + }; + } + + /** + * Fetch with the specific fields + * + * @param paths fields to return + * @return results + */ + public List<K> fetch(Path<?>... paths) { + queryMixin.setProjection(paths); + return fetch(); + } + + @Override + public List<K> fetch() { + try { + DBCursor cursor = createCursor(); + List<K> results = new ArrayList<K>(); + for (DBObject dbObject : cursor) { + results.add(transformer.apply(dbObject)); + } + return results; + } catch (NoResults ex) { + return Collections.emptyList(); + } + } + + protected DBCursor createCursor() { + QueryMetadata metadata = queryMixin.getMetadata(); + Predicate filter = createFilter(metadata); + return createCursor(collection, filter, metadata.getProjection(), metadata.getModifiers(), metadata.getOrderBy()); + } + + protected DBCursor createCursor(DBCollection collection, @Nullable Predicate where, Expression<?> projection, + QueryModifiers modifiers, List<OrderSpecifier<?>> orderBy) { + DBCursor cursor = collection.find(createQuery(where), createProjection(projection)); + Integer limit = modifiers.getLimitAsInteger(); + Integer offset = modifiers.getOffsetAsInteger(); + if (limit != null) { + cursor.limit(limit); + } + if (offset != null) { + cursor.skip(offset); + } + if (orderBy.size() > 0) { + cursor.sort(serializer.toSort(orderBy)); + } + if (readPreference != null) { + cursor.setReadPreference(readPreference); + } + return cursor; + } + + private DBObject createProjection(Expression<?> projection) { + if (projection instanceof FactoryExpression) { + DBObject obj = new BasicDBObject(); + for (Object expr : ((FactoryExpression) projection).getArgs()) { + if (expr instanceof Expression) { + obj.put((String) serializer.handle((Expression) expr), 1); + } + } + return obj; + } + return null; + } + + /** + * Fetch first with the specific fields + * + * @param paths fields to return + * @return first result + */ + public K fetchFirst(Path<?>...paths) { + queryMixin.setProjection(paths); + return fetchFirst(); + } + + @Override + public K fetchFirst() { + try { + DBCursor c = createCursor().limit(1); + if (c.hasNext()) { + return transformer.apply(c.next()); + } else { + return null; + } + } catch (NoResults ex) { + return null; + } + } + + /** + * Fetch one with the specific fields + * + * @param paths fields to return + * @return first result + */ + public K fetchOne(Path<?>... paths) { + queryMixin.setProjection(paths); + return fetchOne(); + } + + @Override + public K fetchOne() throws NonUniqueResultException { + try { + Long limit = queryMixin.getMetadata().getModifiers().getLimit(); + if (limit == null) { + limit = 2L; + } + DBCursor c = createCursor().limit(limit.intValue()); + if (c.hasNext()) { + K rv = transformer.apply(c.next()); + if (c.hasNext()) { + throw new NonUniqueResultException(); + } + return rv; + } else { + return null; + } + } catch (NoResults ex) { + return null; + } + } + + /** + * Fetch results with the specific fields + * + * @param paths fields to return + * @return results + */ + public QueryResults<K> fetchResults(Path<?>... paths) { + queryMixin.setProjection(paths); + return fetchResults(); + } + + @Override + public QueryResults<K> fetchResults() { + try { + long total = fetchCount(); + if (total > 0L) { + return new QueryResults<K>(fetch(), queryMixin.getMetadata().getModifiers(), total); + } else { + return QueryResults.emptyResults(); + } + } catch (NoResults ex) { + return QueryResults.emptyResults(); + } + } + + @Override + public long fetchCount() { + try { + Predicate filter = createFilter(queryMixin.getMetadata()); + return collection.count(createQuery(filter)); + } catch (NoResults ex) { + return 0L; + } + } + + private DBObject createQuery(@Nullable Predicate predicate) { + if (predicate != null) { + return (DBObject) serializer.handle(predicate); + } else { + return new BasicDBObject(); + } + } + + /** + * Sets the read preference for this query + * + * @param readPreference read preference + */ + public void setReadPreference(ReadPreference readPreference) { + this.readPreference = readPreference; + } + + /** + * Get the where definition as a DBObject instance + * + * @return + */ + public DBObject asDBObject() { + return createQuery(queryMixin.getMetadata().getWhere()); + } + + @Override + public String toString() { + return asDBObject().toString(); + } + +} \ No newline at end of file diff --git a/querydsl-mongodb/src/main/java/com/querydsl/mongodb/AnyEmbeddedBuilder.java b/querydsl-mongodb/src/main/java/com/querydsl/mongodb/AnyEmbeddedBuilder.java new file mode 100644 index 0000000000..a09df28223 --- /dev/null +++ b/querydsl-mongodb/src/main/java/com/querydsl/mongodb/AnyEmbeddedBuilder.java @@ -0,0 +1,48 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.mongodb; + +import java.util.Collection; + +import com.querydsl.core.support.QueryMixin; +import com.querydsl.core.types.ExpressionUtils; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.Predicate; + +/** + * {@code AnyEmbeddedBuilder} is a builder for constraints on embedded objects + * + * @param <Q> query type + * @param <K> result type + * + * @author tiwe + */ +public class AnyEmbeddedBuilder<Q extends AbstractMongodbQuery<K, Q>, K> { + + private final QueryMixin<Q> queryMixin; + + private final Path<? extends Collection<?>> collection; + + public AnyEmbeddedBuilder(QueryMixin<Q> queryMixin, + Path<? extends Collection<?>> collection) { + this.queryMixin = queryMixin; + this.collection = collection; + } + + public Q on(Predicate... conditions) { + return queryMixin.where(ExpressionUtils.predicate( + MongodbOps.ELEM_MATCH, collection, ExpressionUtils.allOf(conditions))); + } + +} diff --git a/querydsl-mongodb/src/main/java/com/querydsl/mongodb/JoinBuilder.java b/querydsl-mongodb/src/main/java/com/querydsl/mongodb/JoinBuilder.java new file mode 100644 index 0000000000..5d7d13e771 --- /dev/null +++ b/querydsl-mongodb/src/main/java/com/querydsl/mongodb/JoinBuilder.java @@ -0,0 +1,52 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.mongodb; + +import com.querydsl.core.JoinType; +import com.querydsl.core.support.QueryMixin; +import com.querydsl.core.types.ExpressionUtils; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.Predicate; + +/** + * {@code JoinBuilder} is a builder for join constraints + * + * @author tiwe + * + * @param <Q> + * @param <K> + * @param <T> + */ +public class JoinBuilder<Q extends AbstractMongodbQuery<K, Q>, K, T> { + + private final QueryMixin<Q> queryMixin; + + private final Path<?> ref; + + private final Path<T> target; + + public JoinBuilder(QueryMixin<Q> queryMixin, Path<?> ref, Path<T> target) { + this.queryMixin = queryMixin; + this.ref = ref; + this.target = target; + } + + @SuppressWarnings("unchecked") + public Q on(Predicate... conditions) { + queryMixin.addJoin(JoinType.JOIN, ExpressionUtils.as((Path) ref, target)); + queryMixin.on(conditions); + return queryMixin.getSelf(); + } + +} diff --git a/querydsl-mongodb/src/main/java/com/querydsl/mongodb/MongodbExpressions.java b/querydsl-mongodb/src/main/java/com/querydsl/mongodb/MongodbExpressions.java new file mode 100644 index 0000000000..6025a3a771 --- /dev/null +++ b/querydsl-mongodb/src/main/java/com/querydsl/mongodb/MongodbExpressions.java @@ -0,0 +1,98 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.mongodb; + +import com.querydsl.core.types.ConstantImpl; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.dsl.BooleanExpression; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.ListPath; +import com.querydsl.core.types.dsl.SimpleExpression; + +import java.util.Collection; + +/** + * Mongodb specific operations + * + * @author tiwe + * @author sangyong choi + */ +public final class MongodbExpressions { + + private MongodbExpressions() { } + + /** + * Finds the closest points relative to the given location and orders the results with decreasing proximity + * + * @param expr location + * @param latVal latitude + * @param longVal longitude + * @return predicate + */ + public static BooleanExpression near(Expression<Double[]> expr, double latVal, double longVal) { + return Expressions.booleanOperation(MongodbOps.NEAR, expr, ConstantImpl.create(new Double[]{latVal, longVal})); + } + + /** + * Finds the closest points relative to the given location on a sphere and orders the results with decreasing proximity + * + * @param expr location + * @param latVal latitude + * @param longVal longitude + * @return predicate + */ + public static BooleanExpression nearSphere(Expression<Double[]> expr, double latVal, double longVal) { + return Expressions.booleanOperation(MongodbOps.NEAR_SPHERE, expr, ConstantImpl.create(new Double[]{latVal, longVal})); + } + + /** + * Finds points within bounds of the rectangle + * + * @param blLatVal bottom left latitude + * @param blLongVal bottom left longitude + * @param urLatVal upper right latitude + * @param urLongVal upper right longitude + * @return predicate + */ + public static BooleanExpression withinBox(Expression<Double[]> expr, double blLongVal, double blLatVal, double urLongVal, double urLatVal) { + return Expressions.booleanOperation( + MongodbOps.GEO_WITHIN_BOX, + expr, + ConstantImpl.create(new Double[]{blLongVal, blLatVal}), + ConstantImpl.create(new Double[]{urLongVal, urLatVal}) + ); + } + + /** + * Finds documents whose geospatial data intersects + * + * @param expr location + * @param latVal latitude + * @param longVal longitude + * @return predicate + */ + public static BooleanExpression geoIntersects(Expression<Double[]> expr, double latVal, double longVal) { + return Expressions.booleanOperation(MongodbOps.GEO_INTERSECTS, expr, ConstantImpl.create(new Double[]{latVal, longVal})); + } + + /** + * Find documents where the value of a field is an array that contains all the specific elements. + * + * @param expr expression + * @param params params + */ + public static <T, Q extends SimpleExpression<? super T>> BooleanExpression all(ListPath<T, Q> expr, Collection<T> params) { + return Expressions.booleanOperation(MongodbOps.ALL, expr, ConstantImpl.create(params)); + } +} diff --git a/querydsl-mongodb/src/main/java/com/querydsl/mongodb/MongodbOps.java b/querydsl-mongodb/src/main/java/com/querydsl/mongodb/MongodbOps.java new file mode 100644 index 0000000000..d80833dcf1 --- /dev/null +++ b/querydsl-mongodb/src/main/java/com/querydsl/mongodb/MongodbOps.java @@ -0,0 +1,43 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.mongodb; + +import com.querydsl.core.types.Operator; + +/** + * MongoDB specific operators + * + * @author tiwe + * @author sangyong choi + */ +public enum MongodbOps implements Operator { + NEAR(Boolean.class), + GEO_WITHIN_BOX(Boolean.class), + ELEM_MATCH(Boolean.class), + NO_MATCH(Boolean.class), + NEAR_SPHERE(Boolean.class), + GEO_INTERSECTS(Boolean.class), + ALL(Boolean.class); + + private final Class<?> type; + + MongodbOps(Class<?> type) { + this.type = type; + } + + @Override + public Class<?> getType() { + return type; + } +} diff --git a/querydsl-mongodb/src/main/java/com/querydsl/mongodb/MongodbSerializer.java b/querydsl-mongodb/src/main/java/com/querydsl/mongodb/MongodbSerializer.java new file mode 100644 index 0000000000..a2514b4bbc --- /dev/null +++ b/querydsl-mongodb/src/main/java/com/querydsl/mongodb/MongodbSerializer.java @@ -0,0 +1,383 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.mongodb; + +import com.mongodb.BasicDBList; +import com.mongodb.BasicDBObject; +import com.mongodb.DBObject; +import com.mongodb.DBRef; +import com.querydsl.core.types.*; +import org.bson.BSONObject; +import org.bson.types.ObjectId; + +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.regex.Pattern; + +/** + * Serializes the given Querydsl query to a DBObject query for MongoDB + * + * @author laimw + * @author sangyong choi + */ +public abstract class MongodbSerializer implements Visitor<Object, Void> { + + public Object handle(Expression<?> expression) { + return expression.accept(this, null); + } + + public DBObject toSort(List<OrderSpecifier<?>> orderBys) { + BasicDBObject sort = new BasicDBObject(); + for (OrderSpecifier<?> orderBy : orderBys) { + Object key = orderBy.getTarget().accept(this, null); + sort.append(key.toString(), orderBy.getOrder() == Order.ASC ? 1 : -1); + } + return sort; + } + + @Override + public Object visit(Constant<?> expr, Void context) { + if (Enum.class.isAssignableFrom(expr.getType())) { + @SuppressWarnings("unchecked") //Guarded by previous check + Constant<? extends Enum<?>> expectedExpr = (Constant<? extends Enum<?>>) expr; + return expectedExpr.getConstant().name(); + } else { + return expr.getConstant(); + } + } + + @Override + public Object visit(TemplateExpression<?> expr, Void context) { + throw new UnsupportedOperationException(); + } + + @Override + public Object visit(FactoryExpression<?> expr, Void context) { + throw new UnsupportedOperationException(); + } + + protected String asDBKey(Operation<?> expr, int index) { + return (String) asDBValue(expr, index); + } + + protected Object asDBValue(Operation<?> expr, int index) { + return expr.getArg(index).accept(this, null); + } + + private String regexValue(Operation<?> expr, int index) { + return Pattern.quote(expr.getArg(index).accept(this, null).toString()); + } + + protected DBObject asDBObject(String key, Object value) { + return new BasicDBObject(key, value); + } + + @SuppressWarnings("unchecked") + @Override + public Object visit(Operation<?> expr, Void context) { + Operator op = expr.getOperator(); + if (op == Ops.EQ) { + if (expr.getArg(0) instanceof Operation) { + Operation<?> lhs = (Operation<?>) expr.getArg(0); + if (lhs.getOperator() == Ops.COL_SIZE || lhs.getOperator() == Ops.ARRAY_SIZE) { + return asDBObject(asDBKey(lhs, 0), asDBObject("$size", asDBValue(expr, 1))); + } else { + throw new UnsupportedOperationException("Illegal operation " + expr); + } + } else if (expr.getArg(0) instanceof Path) { + Path<?> path = (Path<?>) expr.getArg(0); + Constant<?> constant = (Constant<?>) expr.getArg(1); + return asDBObject(asDBKey(expr, 0), convert(path, constant)); + } + } else if (op == Ops.STRING_IS_EMPTY) { + return asDBObject(asDBKey(expr, 0), ""); + + } else if (op == Ops.AND) { + BSONObject lhs = (BSONObject) handle(expr.getArg(0)); + BSONObject rhs = (BSONObject) handle(expr.getArg(1)); + if (lhs.keySet().stream().noneMatch(rhs.keySet()::contains)) { + lhs.putAll(rhs); + return lhs; + } else { + BasicDBList list = new BasicDBList(); + list.add(handle(expr.getArg(0))); + list.add(handle(expr.getArg(1))); + return asDBObject("$and", list); + } + + } else if (op == Ops.NOT) { + //Handle the not's child + Operation<?> subOperation = (Operation<?>) expr.getArg(0); + Operator subOp = subOperation.getOperator(); + if (subOp == Ops.IN) { + return visit(ExpressionUtils.operation(Boolean.class, Ops.NOT_IN, subOperation.getArg(0), + subOperation.getArg(1)), context); + } else { + BasicDBObject arg = (BasicDBObject) handle(expr.getArg(0)); + return negate(arg); + } + + } else if (op == Ops.OR) { + BasicDBList list = new BasicDBList(); + list.add(handle(expr.getArg(0))); + list.add(handle(expr.getArg(1))); + return asDBObject("$or", list); + + } else if (op == Ops.NE) { + Path<?> path = (Path<?>) expr.getArg(0); + Constant<?> constant = (Constant<?>) expr.getArg(1); + return asDBObject(asDBKey(expr, 0), asDBObject("$ne", convert(path, constant))); + + } else if (op == Ops.STARTS_WITH) { + return asDBObject(asDBKey(expr, 0), + Pattern.compile("^" + regexValue(expr, 1))); + + } else if (op == Ops.STARTS_WITH_IC) { + return asDBObject(asDBKey(expr, 0), + Pattern.compile("^" + regexValue(expr, 1), Pattern.CASE_INSENSITIVE)); + + } else if (op == Ops.ENDS_WITH) { + return asDBObject(asDBKey(expr, 0), Pattern.compile(regexValue(expr, 1) + "$")); + + } else if (op == Ops.ENDS_WITH_IC) { + return asDBObject(asDBKey(expr, 0), + Pattern.compile(regexValue(expr, 1) + "$", Pattern.CASE_INSENSITIVE)); + + } else if (op == Ops.EQ_IGNORE_CASE) { + return asDBObject(asDBKey(expr, 0), + Pattern.compile("^" + regexValue(expr, 1) + "$", Pattern.CASE_INSENSITIVE)); + + } else if (op == Ops.STRING_CONTAINS) { + return asDBObject(asDBKey(expr, 0), Pattern.compile(".*" + regexValue(expr, 1) + ".*")); + + } else if (op == Ops.STRING_CONTAINS_IC) { + return asDBObject(asDBKey(expr, 0), + Pattern.compile(".*" + regexValue(expr, 1) + ".*", Pattern.CASE_INSENSITIVE)); + + } else if (op == Ops.MATCHES) { + return asDBObject(asDBKey(expr, 0), Pattern.compile(asDBValue(expr, 1).toString())); + + } else if (op == Ops.MATCHES_IC) { + return asDBObject(asDBKey(expr, 0), Pattern.compile(asDBValue(expr, 1).toString(), Pattern.CASE_INSENSITIVE)); + + } else if (op == Ops.LIKE) { + String regex = ExpressionUtils.likeToRegex((Expression) expr.getArg(1)).toString(); + return asDBObject(asDBKey(expr, 0), Pattern.compile(regex)); + + } else if (op == Ops.LIKE_IC) { + String regex = ExpressionUtils.likeToRegex((Expression) expr.getArg(1)).toString(); + return asDBObject(asDBKey(expr, 0), Pattern.compile(regex, Pattern.CASE_INSENSITIVE)); + + } else if (op == Ops.BETWEEN) { + BasicDBObject value = new BasicDBObject("$gte", asDBValue(expr, 1)); + value.append("$lte", asDBValue(expr, 2)); + return asDBObject(asDBKey(expr, 0), value); + + } else if (op == Ops.IN) { + int constIndex = 0; + int exprIndex = 1; + if (expr.getArg(1) instanceof Constant<?>) { + constIndex = 1; + exprIndex = 0; + } + if (Collection.class.isAssignableFrom(expr.getArg(constIndex).getType())) { + @SuppressWarnings("unchecked") //guarded by previous check + Collection<?> values = ((Constant<? extends Collection<?>>) expr.getArg(constIndex)).getConstant(); + return asDBObject(asDBKey(expr, exprIndex), asDBObject("$in", values.toArray())); + } else { + Path<?> path = (Path<?>) expr.getArg(exprIndex); + Constant<?> constant = (Constant<?>) expr.getArg(constIndex); + return asDBObject(asDBKey(expr, exprIndex), convert(path, constant)); + } + + } else if (op == Ops.NOT_IN) { + int constIndex = 0; + int exprIndex = 1; + if (expr.getArg(1) instanceof Constant<?>) { + constIndex = 1; + exprIndex = 0; + } + if (Collection.class.isAssignableFrom(expr.getArg(constIndex).getType())) { + @SuppressWarnings("unchecked") //guarded by previous check + Collection<?> values = ((Constant<? extends Collection<?>>) expr.getArg(constIndex)).getConstant(); + return asDBObject(asDBKey(expr, exprIndex), asDBObject("$nin", values.toArray())); + } else { + Path<?> path = (Path<?>) expr.getArg(exprIndex); + Constant<?> constant = (Constant<?>) expr.getArg(constIndex); + return asDBObject(asDBKey(expr, exprIndex), asDBObject("$ne", convert(path, constant))); + } + + } else if (op == Ops.COL_IS_EMPTY) { + BasicDBList list = new BasicDBList(); + list.add(asDBObject(asDBKey(expr, 0), new BasicDBList())); + list.add(asDBObject(asDBKey(expr, 0), asDBObject("$exists", false))); + return asDBObject("$or", list); + + } else if (op == Ops.LT) { + return asDBObject(asDBKey(expr, 0), asDBObject("$lt", asDBValue(expr, 1))); + + } else if (op == Ops.GT) { + return asDBObject(asDBKey(expr, 0), asDBObject("$gt", asDBValue(expr, 1))); + + } else if (op == Ops.LOE) { + return asDBObject(asDBKey(expr, 0), asDBObject("$lte", asDBValue(expr, 1))); + + } else if (op == Ops.GOE) { + return asDBObject(asDBKey(expr, 0), asDBObject("$gte", asDBValue(expr, 1))); + + } else if (op == Ops.IS_NULL) { + return asDBObject(asDBKey(expr, 0), asDBObject("$exists", false)); + + } else if (op == Ops.IS_NOT_NULL) { + return asDBObject(asDBKey(expr, 0), asDBObject("$exists", true)); + + } else if (op == Ops.CONTAINS_KEY) { + Path<?> path = (Path<?>) expr.getArg(0); + Expression<?> key = expr.getArg(1); + return asDBObject(visit(path, context) + "." + key.toString(), asDBObject("$exists", true)); + + } else if (op == MongodbOps.NEAR) { + return asDBObject(asDBKey(expr, 0), asDBObject("$near", asDBValue(expr, 1))); + + } else if (op == MongodbOps.GEO_WITHIN_BOX) { + return asDBObject(asDBKey(expr, 0), asDBObject( + "$geoWithin", + asDBObject("$box", Arrays.asList(asDBValue(expr, 1), asDBValue(expr, 2))) + )); + + } else if (op == MongodbOps.NEAR_SPHERE) { + return asDBObject(asDBKey(expr, 0), asDBObject("$nearSphere", asDBValue(expr, 1))); + + } else if (op == MongodbOps.GEO_INTERSECTS) { + return asDBObject(asDBKey(expr, 0), asDBObject( + "$geoIntersects", + asDBObject("$geometry", asDBValue(expr, 1)) + )); + } else if (op == MongodbOps.ALL) { + return asDBObject(asDBKey(expr, 0), asDBObject("$all", asDBValue(expr, 1))); + } else if (op == MongodbOps.ELEM_MATCH) { + return asDBObject(asDBKey(expr, 0), asDBObject("$elemMatch", asDBValue(expr, 1))); + } + + throw new UnsupportedOperationException("Illegal operation " + expr); + } + + private Object negate(BasicDBObject arg) { + BasicDBList list = new BasicDBList(); + for (Map.Entry<String, Object> entry : arg.entrySet()) { + if (entry.getKey().equals("$or")) { + list.add(asDBObject("$nor", entry.getValue())); + + } else if (entry.getKey().equals("$and")) { + BasicDBList list2 = new BasicDBList(); + for (Object o : ((BasicDBList) entry.getValue())) { + list2.add(negate((BasicDBObject) o)); + } + list.add(asDBObject("$or", list2)); + + } else if (entry.getValue() instanceof Pattern) { + list.add(asDBObject(entry.getKey(), asDBObject("$not", entry.getValue()))); + + } else if (entry.getValue() instanceof BasicDBObject) { + list.add(negate(entry.getKey(), (BasicDBObject) entry.getValue())); + + } else { + list.add(asDBObject(entry.getKey(), asDBObject("$ne", entry.getValue()))); + } + } + return list.size() == 1 ? list.get(0) : asDBObject("$or", list); + } + + private Object negate(String key, BasicDBObject value) { + if (value.size() == 1) { + return asDBObject(key, asDBObject("$not", value)); + + } else { + BasicDBList list2 = new BasicDBList(); + for (Map.Entry<String, Object> entry2 : value.entrySet()) { + list2.add(asDBObject(key, + asDBObject("$not", asDBObject(entry2.getKey(), entry2.getValue())))); + } + return asDBObject("$or", list2); + } + } + + protected Object convert(Path<?> property, Constant<?> constant) { + if (isReference(property)) { + return asReference(constant.getConstant()); + } else if (isId(property)) { + if (isReference(property.getMetadata().getParent())) { + return asReferenceKey(property.getMetadata().getParent().getType(), constant.getConstant()); + } else if (constant.getType().equals(String.class) && isImplicitObjectIdConversion()) { + String id = (String) constant.getConstant(); + return ObjectId.isValid(id) ? new ObjectId(id) : id; + } + } + return visit(constant, null); + } + + protected boolean isImplicitObjectIdConversion() { + return true; + } + + protected DBRef asReferenceKey(Class<?> entity, Object id) { + // TODO override in subclass + throw new UnsupportedOperationException(); + } + + protected abstract DBRef asReference(Object constant); + + protected abstract boolean isReference(Path<?> arg); + + protected boolean isId(Path<?> arg) { + // TODO override in subclass + return false; + } + + @Override + public String visit(Path<?> expr, Void context) { + PathMetadata metadata = expr.getMetadata(); + if (metadata.getParent() != null) { + Path<?> parent = metadata.getParent(); + if (parent.getMetadata().getPathType() == PathType.DELEGATE) { + parent = parent.getMetadata().getParent(); + } + if (metadata.getPathType() == PathType.COLLECTION_ANY) { + return visit(parent, context); + } else if (parent.getMetadata().getPathType() != PathType.VARIABLE) { + String rv = getKeyForPath(expr, metadata); + String parentStr = visit(parent, context); + return rv != null ? parentStr + "." + rv : parentStr; + } + } + return getKeyForPath(expr, metadata); + } + + protected String getKeyForPath(Path<?> expr, PathMetadata metadata) { + return metadata.getElement().toString(); + } + + @Override + public Object visit(SubQueryExpression<?> expr, Void context) { + throw new UnsupportedOperationException(); + } + + @Override + public Object visit(ParamExpression<?> expr, Void context) { + throw new UnsupportedOperationException(); + } + +} diff --git a/querydsl-mongodb/src/main/java/com/querydsl/mongodb/Point.java b/querydsl-mongodb/src/main/java/com/querydsl/mongodb/Point.java new file mode 100644 index 0000000000..0263e326c9 --- /dev/null +++ b/querydsl-mongodb/src/main/java/com/querydsl/mongodb/Point.java @@ -0,0 +1,54 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.mongodb; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.ArrayPath; +import com.querydsl.core.types.dsl.BooleanExpression; + +/** + * {@code Point} is an adapter type for Double[] arrays to use geo spatial querying features of Mongodb + * + * @author tiwe + * + */ +public class Point extends ArrayPath<Double[], Double> { + + private static final long serialVersionUID = 1776628530121566388L; + + public Point(String variable) { + super(Double[].class, variable); + } + + public Point(Path<?> parent, String property) { + super(Double[].class, parent, property); + } + + public Point(PathMetadata metadata) { + super(Double[].class, metadata); + } + + /** + * Finds the closest points relative to the given location and orders the results with decreasing proximity + * + * @param latVal latitude + * @param longVal longitude + * @return predicate + */ + public BooleanExpression near(double latVal, double longVal) { + return MongodbExpressions.near(this, latVal, longVal); + } + +} diff --git a/querydsl-mongodb/src/main/java/com/querydsl/mongodb/document/AbstractFetchableMongodbQuery.java b/querydsl-mongodb/src/main/java/com/querydsl/mongodb/document/AbstractFetchableMongodbQuery.java new file mode 100644 index 0000000000..590760e7d9 --- /dev/null +++ b/querydsl-mongodb/src/main/java/com/querydsl/mongodb/document/AbstractFetchableMongodbQuery.java @@ -0,0 +1,288 @@ +/* + * Copyright 2020 the original author or 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. + */ +package com.querydsl.mongodb.document; + +import com.mongodb.ReadPreference; +import com.mongodb.client.FindIterable; +import com.mongodb.client.MongoCollection; +import com.mongodb.client.MongoCursor; +import com.mysema.commons.lang.CloseableIterator; +import com.querydsl.core.*; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.OrderSpecifier; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.Predicate; +import org.bson.Document; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.function.Function; + +/** + * {@link Fetchable} Mongodb query with a pluggable Document to Bean transformation. + * + * @param <K> result type + * @param <Q> concrete subtype + * @author Mark Paluch + */ +public abstract class AbstractFetchableMongodbQuery<K, Q extends AbstractFetchableMongodbQuery<K, Q>> + extends AbstractMongodbQuery<Q> implements Fetchable<K> { + + private final Function<Document, K> transformer; + + private final MongoCollection<Document> collection; + + /** + * Create a new MongodbQuery instance + * @param collection + * @param transformer result transformer + * @param serializer serializer + */ + public AbstractFetchableMongodbQuery(MongoCollection<Document> collection, Function<Document, K> transformer, MongodbDocumentSerializer serializer) { + super(serializer); + this.transformer = transformer; + this.collection = collection; + } + + /** + * Iterate with the specific fields + * + * @param paths fields to return + * @return iterator + */ + public CloseableIterator<K> iterate(Path<?>... paths) { + getQueryMixin().setProjection(paths); + return iterate(); + } + + @Override + public CloseableIterator<K> iterate() { + FindIterable<Document> cursor = createCursor(); + final MongoCursor<Document> iterator = cursor.iterator(); + + return new CloseableIterator<K>() { + @Override + public boolean hasNext() { + return iterator.hasNext(); + } + + @Override + public K next() { + return transformer.apply(iterator.next()); + } + + @Override + public void remove() { + + } + + @Override + public void close() { + iterator.close(); + } + }; + } + + /** + * Fetch with the specific fields + * + * @param paths fields to return + * @return results + */ + public List<K> fetch(Path<?>... paths) { + getQueryMixin().setProjection(paths); + return fetch(); + } + + @Override + public List<K> fetch() { + try { + FindIterable<Document> cursor = createCursor(); + List<K> results = new ArrayList<K>(); + for (Document document : cursor) { + results.add(transformer.apply(document)); + } + return results; + } catch (NoResults ex) { + return Collections.emptyList(); + } + } + + /** + * Fetch first with the specific fields + * + * @param paths fields to return + * @return first result + */ + public K fetchFirst(Path<?>... paths) { + getQueryMixin().setProjection(paths); + return fetchFirst(); + } + + @Override + public K fetchFirst() { + try { + FindIterable<Document> c = createCursor().limit(1); + MongoCursor<Document> iterator = c.iterator(); + try { + + if (iterator.hasNext()) { + return transformer.apply(iterator.next()); + } else { + return null; + } + } finally { + iterator.close(); + } + } catch (NoResults ex) { + return null; + } + } + + /** + * Fetch one with the specific fields + * + * @param paths fields to return + * @return first result + */ + public K fetchOne(Path<?>... paths) { + getQueryMixin().setProjection(paths); + return fetchOne(); + } + + @Override + public K fetchOne() { + try { + Long limit = getQueryMixin().getMetadata().getModifiers().getLimit(); + if (limit == null) { + limit = 2L; + } + + FindIterable<Document> c = createCursor().limit(limit.intValue()); + MongoCursor<Document> iterator = c.iterator(); + try { + + if (iterator.hasNext()) { + K rv = transformer.apply(iterator.next()); + if (iterator.hasNext()) { + throw new NonUniqueResultException(); + } + return rv; + } else { + return null; + } + } finally { + iterator.close(); + } + + + } catch (NoResults ex) { + return null; + } + } + + /** + * Fetch results with the specific fields + * + * @param paths fields to return + * @return results + */ + public QueryResults<K> fetchResults(Path<?>... paths) { + getQueryMixin().setProjection(paths); + return fetchResults(); + } + + @Override + public QueryResults<K> fetchResults() { + try { + long total = fetchCount(); + if (total > 0L) { + return new QueryResults<K>(fetch(), getQueryMixin().getMetadata().getModifiers(), total); + } else { + return QueryResults.emptyResults(); + } + } catch (NoResults ex) { + return QueryResults.emptyResults(); + } + } + + @Override + public long fetchCount() { + try { + Predicate filter = createFilter(getQueryMixin().getMetadata()); + return collection.count(createQuery(filter)); + } catch (NoResults ex) { + return 0L; + } + } + + protected FindIterable<Document> createCursor() { + QueryMetadata metadata = getQueryMixin().getMetadata(); + Predicate filter = createFilter(metadata); + return createCursor(collection, filter, metadata.getProjection(), metadata.getModifiers(), metadata.getOrderBy()); + } + + protected FindIterable<Document> createCursor(MongoCollection<Document> collection, @Nullable Predicate where, + Expression<?> projection, QueryModifiers modifiers, List<OrderSpecifier<?>> orderBy) { + + ReadPreference readPreference = getReadPreference(); + MongoCollection<Document> collectionToUse = readPreference != null ? collection + .withReadPreference(readPreference) : collection; + FindIterable<Document> cursor = collectionToUse.find(createQuery(where)) + .projection(createProjection(projection)); + Integer limit = modifiers.getLimitAsInteger(); + Integer offset = modifiers.getOffsetAsInteger(); + + if (limit != null) { + cursor = cursor.limit(limit); + } + if (offset != null) { + cursor = cursor.skip(offset); + } + if (orderBy.size() > 0) { + cursor = cursor.sort(getSerializer().toSort(orderBy)); + } + return cursor; + } + + protected abstract MongoCollection<Document> getCollection(Class<?> type); + + @Override + protected List<Object> getIds(Class<?> targetType, Predicate condition) { + MongoCollection<Document> collection = getCollection(targetType); + // TODO : fetch only ids + FindIterable<Document> cursor = createCursor(collection, condition, null, + QueryModifiers.EMPTY, Collections.<OrderSpecifier<?>>emptyList()); + + MongoCursor<Document> iterator = cursor.iterator(); + try { + + if (iterator.hasNext()) { + List<Object> ids = new ArrayList<Object>(); + for (Document obj : cursor) { + ids.add(obj.get("_id")); + } + return ids; + } else { + return Collections.emptyList(); + } + } finally { + iterator.close(); + } + } +} diff --git a/querydsl-mongodb/src/main/java/com/querydsl/mongodb/document/AbstractMongodbQuery.java b/querydsl-mongodb/src/main/java/com/querydsl/mongodb/document/AbstractMongodbQuery.java new file mode 100644 index 0000000000..37fb636ab7 --- /dev/null +++ b/querydsl-mongodb/src/main/java/com/querydsl/mongodb/document/AbstractMongodbQuery.java @@ -0,0 +1,247 @@ +/* + * Copyright 2020 the original author or 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. + */ +package com.querydsl.mongodb.document; + +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.bson.Document; + +import com.mongodb.ReadPreference; +import com.querydsl.core.DefaultQueryMetadata; +import com.querydsl.core.JoinExpression; +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.QueryModifiers; +import com.querydsl.core.SimpleQuery; +import com.querydsl.core.support.QueryMixin; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.ExpressionUtils; +import com.querydsl.core.types.FactoryExpression; +import com.querydsl.core.types.Operation; +import com.querydsl.core.types.OrderSpecifier; +import com.querydsl.core.types.ParamExpression; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.Predicate; +import com.querydsl.core.types.dsl.CollectionPathBase; +import org.jetbrains.annotations.Nullable; + +/** + * {@code AbstractMongodbQuery} provides a base class for general Querydsl query implementation. + * + * @author Mark Paluch + * + * @param <Q> concrete subtype + */ +public abstract class AbstractMongodbQuery<Q extends AbstractMongodbQuery<Q>> implements SimpleQuery<Q> { + + @SuppressWarnings("serial") + static class NoResults extends RuntimeException { } + + private final MongodbDocumentSerializer serializer; + + private final QueryMixin<Q> queryMixin; + + private ReadPreference readPreference; + + /** + * Create a new MongodbQuery instance + * + * @param serializer serializer + */ + @SuppressWarnings("unchecked") + public AbstractMongodbQuery(MongodbDocumentSerializer serializer) { + @SuppressWarnings("unchecked") // Q is this plus subclass + Q query = (Q) this; + this.queryMixin = new QueryMixin<Q>(query, new DefaultQueryMetadata(), false); + this.serializer = serializer; + } + + /** + * Define a join + * + * @param ref reference + * @param target join target + * @return join builder + */ + public <T> JoinBuilder<Q, T> join(Path<T> ref, Path<T> target) { + return new JoinBuilder<Q, T>(queryMixin, ref, target); + } + + /** + * Define a join + * + * @param ref reference + * @param target join target + * @return join builder + */ + public <T> JoinBuilder<Q, T> join(CollectionPathBase<?,T,?> ref, Path<T> target) { + return new JoinBuilder<Q, T>(queryMixin, ref, target); + } + + /** + * Define a constraint for an embedded object + * + * @param collection collection + * @param target target + * @return builder + */ + public <T> AnyEmbeddedBuilder<Q> anyEmbedded(Path<? extends Collection<T>> collection, Path<T> target) { + return new AnyEmbeddedBuilder<Q>(queryMixin, collection); + } + + @Nullable + protected Predicate createFilter(QueryMetadata metadata) { + Predicate filter; + if (!metadata.getJoins().isEmpty()) { + filter = ExpressionUtils.allOf(metadata.getWhere(), createJoinFilter(metadata)); + } else { + filter = metadata.getWhere(); + } + return filter; + } + + @SuppressWarnings("unchecked") + @Nullable + protected Predicate createJoinFilter(QueryMetadata metadata) { + Map<Expression<?>, Predicate> predicates = new HashMap<>(); + List<JoinExpression> joins = metadata.getJoins(); + for (int i = joins.size() - 1; i >= 0; i--) { + JoinExpression join = joins.get(i); + Path<?> source = (Path) ((Operation<?>) join.getTarget()).getArg(0); + Path<?> target = (Path) ((Operation<?>) join.getTarget()).getArg(1); + + final Predicate extraFilters = predicates.get(target.getRoot()); + Predicate filter = ExpressionUtils.allOf(join.getCondition(), extraFilters); + List<? extends Object> ids = getIds(target.getType(), filter); + if (ids.isEmpty()) { + throw new NoResults(); + } + Path<?> path = ExpressionUtils.path(String.class, source, "$id"); + predicates.merge(source.getRoot(), ExpressionUtils.in((Path<Object>) path, ids), ExpressionUtils::and); + } + Path<?> source = (Path) ((Operation) joins.get(0).getTarget()).getArg(0); + return predicates.get(source.getRoot()); + } + + private Predicate allOf(Collection<Predicate> predicates) { + return predicates != null ? ExpressionUtils.allOf(predicates) : null; + } + + protected abstract List<Object> getIds(Class<?> targetType, Predicate condition); + + @Override + public Q distinct() { + return queryMixin.distinct(); + } + + public Q where(Predicate e) { + return queryMixin.where(e); + } + + @Override + public Q where(Predicate... e) { + return queryMixin.where(e); + } + + @Override + public Q limit(long limit) { + return queryMixin.limit(limit); + } + + @Override + public Q offset(long offset) { + return queryMixin.offset(offset); + } + + @Override + public Q restrict(QueryModifiers modifiers) { + return queryMixin.restrict(modifiers); + } + + public Q orderBy(OrderSpecifier<?> o) { + return queryMixin.orderBy(o); + } + + @Override + public Q orderBy(OrderSpecifier<?>... o) { + return queryMixin.orderBy(o); + } + + @Override + public <T> Q set(ParamExpression<T> param, T value) { + return queryMixin.set(param, value); + } + + protected Document createProjection(Expression<?> projection) { + if (projection instanceof FactoryExpression) { + Document obj = new Document(); + for (Object expr : ((FactoryExpression) projection).getArgs()) { + if (expr instanceof Expression) { + obj.put((String) serializer.handle((Expression) expr), 1); + } + } + return obj; + } + return null; + } + + + protected Document createQuery(@Nullable Predicate predicate) { + if (predicate != null) { + return (Document) serializer.handle(predicate); + } else { + return new Document(); + } + } + + + /** + * Sets the read preference for this query + * + * @param readPreference read preference + */ + public void setReadPreference(ReadPreference readPreference) { + this.readPreference = readPreference; + } + + protected QueryMixin<Q> getQueryMixin() { + return queryMixin; + } + + protected MongodbDocumentSerializer getSerializer() { + return serializer; + } + + protected ReadPreference getReadPreference() { + return readPreference; + } + + /** + * Get the where definition as a Document instance + * + * @return + */ + public Document asDocument() { + return createQuery(queryMixin.getMetadata().getWhere()); + } + + @Override + public String toString() { + return asDocument().toString(); + } +} diff --git a/querydsl-mongodb/src/main/java/com/querydsl/mongodb/document/AnyEmbeddedBuilder.java b/querydsl-mongodb/src/main/java/com/querydsl/mongodb/document/AnyEmbeddedBuilder.java new file mode 100644 index 0000000000..a34eba6795 --- /dev/null +++ b/querydsl-mongodb/src/main/java/com/querydsl/mongodb/document/AnyEmbeddedBuilder.java @@ -0,0 +1,49 @@ +/* + * Copyright 2020 the original author or 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. + */ +package com.querydsl.mongodb.document; + +import java.util.Collection; + +import com.querydsl.core.support.QueryMixin; +import com.querydsl.core.types.ExpressionUtils; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.Predicate; +import com.querydsl.mongodb.MongodbOps; + +/** + * {@code AnyEmbeddedBuilder} is a builder for constraints on embedded objects + * + * @param <Q> query type + * + * @author Mark Paluch + */ +public class AnyEmbeddedBuilder<Q extends AbstractMongodbQuery<Q>> { + + private final QueryMixin<Q> queryMixin; + + private final Path<? extends Collection<?>> collection; + + public AnyEmbeddedBuilder(QueryMixin<Q> queryMixin, + Path<? extends Collection<?>> collection) { + this.queryMixin = queryMixin; + this.collection = collection; + } + + public Q on(Predicate... conditions) { + return queryMixin.where(ExpressionUtils.predicate( + MongodbOps.ELEM_MATCH, collection, ExpressionUtils.allOf(conditions))); + } +} diff --git a/querydsl-mongodb/src/main/java/com/querydsl/mongodb/document/JoinBuilder.java b/querydsl-mongodb/src/main/java/com/querydsl/mongodb/document/JoinBuilder.java new file mode 100644 index 0000000000..8443203867 --- /dev/null +++ b/querydsl-mongodb/src/main/java/com/querydsl/mongodb/document/JoinBuilder.java @@ -0,0 +1,52 @@ +/* + * Copyright 2020 the original author or 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. + */ +package com.querydsl.mongodb.document; + +import com.querydsl.core.JoinType; +import com.querydsl.core.support.QueryMixin; +import com.querydsl.core.types.ExpressionUtils; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.Predicate; + +/** + * {@code JoinBuilder} is a builder for join constraints + * + * @author Mark Paluch + * + * @param <Q> + * @param <T> + */ +public class JoinBuilder<Q extends AbstractMongodbQuery<Q>, T> { + + private final QueryMixin<Q> queryMixin; + + private final Path<?> ref; + + private final Path<T> target; + + public JoinBuilder(QueryMixin<Q> queryMixin, Path<?> ref, Path<T> target) { + this.queryMixin = queryMixin; + this.ref = ref; + this.target = target; + } + + @SuppressWarnings("unchecked") + public Q on(Predicate... conditions) { + queryMixin.addJoin(JoinType.JOIN, ExpressionUtils.as((Path) ref, target)); + queryMixin.on(conditions); + return queryMixin.getSelf(); + } +} diff --git a/querydsl-mongodb/src/main/java/com/querydsl/mongodb/document/MongodbDocumentSerializer.java b/querydsl-mongodb/src/main/java/com/querydsl/mongodb/document/MongodbDocumentSerializer.java new file mode 100644 index 0000000000..6cf373a32d --- /dev/null +++ b/querydsl-mongodb/src/main/java/com/querydsl/mongodb/document/MongodbDocumentSerializer.java @@ -0,0 +1,395 @@ +/* + * Copyright 2020 the original author or 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. + */ +package com.querydsl.mongodb.document; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.LinkedHashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Queue; +import java.util.Set; +import java.util.regex.Pattern; + +import com.mongodb.DBRef; +import com.querydsl.core.types.*; +import com.querydsl.mongodb.MongodbOps; +import org.bson.BsonJavaScript; +import org.bson.BsonRegularExpression; +import org.bson.Document; +import org.bson.types.ObjectId; + +/** + * Serializes the given Querydsl query to a Document query for MongoDB. + * + * @author Mark Paluch + */ +public abstract class MongodbDocumentSerializer implements Visitor<Object, Void> { + + public Object handle(Expression<?> expression) { + return expression.accept(this, null); + } + + public Document toSort(List<OrderSpecifier<?>> orderBys) { + Document sort = new Document(); + for (OrderSpecifier<?> orderBy : orderBys) { + Object key = orderBy.getTarget().accept(this, null); + sort.append(key.toString(), orderBy.getOrder() == Order.ASC ? 1 : -1); + } + return sort; + } + + @Override + public Object visit(Constant<?> expr, Void context) { + if (Enum.class.isAssignableFrom(expr.getType())) { + @SuppressWarnings("unchecked") //Guarded by previous check + Constant<? extends Enum<?>> expectedExpr = (Constant<? extends Enum<?>>) expr; + return expectedExpr.getConstant().name(); + } else { + return expr.getConstant(); + } + } + + @Override + public Object visit(TemplateExpression<?> expr, Void context) { + throw new UnsupportedOperationException(); + } + + @Override + public Object visit(FactoryExpression<?> expr, Void context) { + throw new UnsupportedOperationException(); + } + + protected String asDBKey(Operation<?> expr, int index) { + return (String) asDBValue(expr, index); + } + + protected Object asDBValue(Operation<?> expr, int index) { + return expr.getArg(index).accept(this, null); + } + + private String regexValue(Operation<?> expr, int index) { + return Pattern.quote(expr.getArg(index).accept(this, null).toString()); + } + + protected Document asDocument(String key, Object value) { + return new Document(key, value); + } + + @SuppressWarnings("unchecked") + @Override + public Object visit(Operation<?> expr, Void context) { + Operator op = expr.getOperator(); + if (op == Ops.EQ) { + if (expr.getArg(0) instanceof Operation) { + Operation<?> lhs = (Operation<?>) expr.getArg(0); + if (lhs.getOperator() == Ops.COL_SIZE || lhs.getOperator() == Ops.ARRAY_SIZE) { + return asDocument(asDBKey(lhs, 0), asDocument("$size", asDBValue(expr, 1))); + } else { + throw new UnsupportedOperationException("Illegal operation " + expr); + } + } else if (expr.getArg(0) instanceof Path) { + Path<?> path = (Path<?>) expr.getArg(0); + Constant<?> constant = (Constant<?>) expr.getArg(1); + return asDocument(asDBKey(expr, 0), convert(path, constant)); + } + } else if (op == Ops.STRING_IS_EMPTY) { + return asDocument(asDBKey(expr, 0), ""); + + } else if (op == Ops.AND) { + Queue<Map<Object, Object>> pendingDocuments = collectConnectorArgs("$and", expr); + List<Map<Object, Object>> unmergeableDocuments = new ArrayList<Map<Object, Object>>(); + List<Map<Object, Object>> generatedDocuments = new ArrayList<Map<Object, Object>>(); + + while (!pendingDocuments.isEmpty()) { + + Map<Object, Object> lhs = pendingDocuments.poll(); + + for (Map<Object, Object> rhs : pendingDocuments) { + Set<Object> lhs2 = new LinkedHashSet<Object>(lhs.keySet()); + lhs2.retainAll(rhs.keySet()); + if (lhs2.isEmpty()) { + lhs.putAll(rhs); + } else { + unmergeableDocuments.add(rhs); + } + } + + generatedDocuments.add(lhs); + pendingDocuments = new LinkedList<Map<Object, Object>>(unmergeableDocuments); + unmergeableDocuments = new LinkedList<Map<Object, Object>>(); + } + + return generatedDocuments.size() == 1 ? generatedDocuments.get(0) : asDocument("$and", generatedDocuments); + } else if (op == Ops.NOT) { + //Handle the not's child + Operation<?> subOperation = (Operation<?>) expr.getArg(0); + Operator subOp = subOperation.getOperator(); + if (subOp == Ops.IN) { + return visit(ExpressionUtils.operation(Boolean.class, Ops.NOT_IN, subOperation.getArg(0), + subOperation.getArg(1)), context); + } else { + Document arg = (Document) handle(expr.getArg(0)); + return negate(arg); + } + + } else if (op == Ops.OR) { + return asDocument("$or", collectConnectorArgs("$or", expr)); + + } else if (op == Ops.NE) { + Path<?> path = (Path<?>) expr.getArg(0); + Constant<?> constant = (Constant<?>) expr.getArg(1); + return asDocument(asDBKey(expr, 0), asDocument("$ne", convert(path, constant))); + + } else if (op == Ops.STARTS_WITH) { + return asDocument(asDBKey(expr, 0), new BsonRegularExpression("^" + regexValue(expr, 1))); + + } else if (op == Ops.STARTS_WITH_IC) { + return asDocument(asDBKey(expr, 0), new BsonRegularExpression("^" + regexValue(expr, 1), "i")); + + } else if (op == Ops.ENDS_WITH) { + return asDocument(asDBKey(expr, 0), new BsonRegularExpression(regexValue(expr, 1) + "$")); + + } else if (op == Ops.ENDS_WITH_IC) { + return asDocument(asDBKey(expr, 0), new BsonRegularExpression(regexValue(expr, 1) + "$", "i")); + + } else if (op == Ops.EQ_IGNORE_CASE) { + return asDocument(asDBKey(expr, 0), new BsonRegularExpression("^" + regexValue(expr, 1) + "$", "i")); + + } else if (op == Ops.STRING_CONTAINS) { + return asDocument(asDBKey(expr, 0), new BsonRegularExpression(".*" + regexValue(expr, 1) + ".*")); + + } else if (op == Ops.STRING_CONTAINS_IC) { + return asDocument(asDBKey(expr, 0), new BsonRegularExpression(".*" + regexValue(expr, 1) + ".*", "i")); + + } else if (op == Ops.MATCHES) { + return asDocument(asDBKey(expr, 0), new BsonRegularExpression(asDBValue(expr, 1).toString())); + + } else if (op == Ops.MATCHES_IC) { + return asDocument(asDBKey(expr, 0), new BsonRegularExpression(asDBValue(expr, 1).toString(), "i")); + + } else if (op == Ops.LIKE) { + String regex = ExpressionUtils.likeToRegex((Expression) expr.getArg(1)).toString(); + return asDocument(asDBKey(expr, 0), new BsonRegularExpression(regex)); + + } else if (op == Ops.LIKE_IC) { + String regex = ExpressionUtils.likeToRegex((Expression) expr.getArg(1)).toString(); + return asDocument(asDBKey(expr, 0), new BsonRegularExpression(regex, "i")); + + } else if (op == Ops.BETWEEN) { + Document value = new Document("$gte", asDBValue(expr, 1)); + value.append("$lte", asDBValue(expr, 2)); + return asDocument(asDBKey(expr, 0), value); + + } else if (op == Ops.IN) { + int constIndex = 0; + int exprIndex = 1; + if (expr.getArg(1) instanceof Constant<?>) { + constIndex = 1; + exprIndex = 0; + } + if (Collection.class.isAssignableFrom(expr.getArg(constIndex).getType())) { + @SuppressWarnings("unchecked") //guarded by previous check + Collection<?> values = ((Constant<? extends Collection<?>>) expr.getArg(constIndex)).getConstant(); + return asDocument(asDBKey(expr, exprIndex), asDocument("$in", values)); + } else { + Path<?> path = (Path<?>) expr.getArg(exprIndex); + Constant<?> constant = (Constant<?>) expr.getArg(constIndex); + return asDocument(asDBKey(expr, exprIndex), convert(path, constant)); + } + + } else if (op == Ops.NOT_IN) { + int constIndex = 0; + int exprIndex = 1; + if (expr.getArg(1) instanceof Constant<?>) { + constIndex = 1; + exprIndex = 0; + } + if (Collection.class.isAssignableFrom(expr.getArg(constIndex).getType())) { + @SuppressWarnings("unchecked") //guarded by previous check + Collection<?> values = ((Constant<? extends Collection<?>>) expr.getArg(constIndex)).getConstant(); + return asDocument(asDBKey(expr, exprIndex), asDocument("$nin", values)); + } else { + Path<?> path = (Path<?>) expr.getArg(exprIndex); + Constant<?> constant = (Constant<?>) expr.getArg(constIndex); + return asDocument(asDBKey(expr, exprIndex), asDocument("$ne", convert(path, constant))); + } + + } else if (op == Ops.COL_IS_EMPTY) { + List<Object> list = new ArrayList<Object>(2); + list.add(asDocument(asDBKey(expr, 0), new ArrayList<Object>())); + list.add(asDocument(asDBKey(expr, 0), asDocument("$exists", false))); + return asDocument("$or", list); + + } else if (op == Ops.LT) { + return asDocument(asDBKey(expr, 0), asDocument("$lt", asDBValue(expr, 1))); + + } else if (op == Ops.GT) { + return asDocument(asDBKey(expr, 0), asDocument("$gt", asDBValue(expr, 1))); + + } else if (op == Ops.LOE) { + return asDocument(asDBKey(expr, 0), asDocument("$lte", asDBValue(expr, 1))); + + } else if (op == Ops.GOE) { + return asDocument(asDBKey(expr, 0), asDocument("$gte", asDBValue(expr, 1))); + + } else if (op == Ops.IS_NULL) { + return asDocument(asDBKey(expr, 0), asDocument("$exists", false)); + + } else if (op == Ops.IS_NOT_NULL) { + return asDocument(asDBKey(expr, 0), asDocument("$exists", true)); + + } else if (op == Ops.CONTAINS_KEY) { + Path<?> path = (Path<?>) expr.getArg(0); + Expression<?> key = expr.getArg(1); + return asDocument(visit(path, context) + "." + key.toString(), asDocument("$exists", true)); + + } else if (op == MongodbOps.NEAR) { + return asDocument(asDBKey(expr, 0), asDocument("$near", asDBValue(expr, 1))); + + } else if (op == MongodbOps.NEAR_SPHERE) { + return asDocument(asDBKey(expr, 0), asDocument("$nearSphere", asDBValue(expr, 1))); + + } else if (op == MongodbOps.ELEM_MATCH) { + return asDocument(asDBKey(expr, 0), asDocument("$elemMatch", asDBValue(expr, 1))); + } else if (op == MongodbOps.NO_MATCH) { + return new Document("$where", new BsonJavaScript("function() { return false }")); + } + + throw new UnsupportedOperationException("Illegal operation " + expr); + } + + private Object negate(Document arg) { + List<Object> list = new ArrayList<Object>(); + for (Map.Entry<String, Object> entry : arg.entrySet()) { + if (entry.getKey().equals("$or")) { + list.add(asDocument("$nor", entry.getValue())); + + } else if (entry.getKey().equals("$and")) { + List<Object> list2 = new ArrayList<Object>(); + for (Object o : ((Collection) entry.getValue())) { + list2.add(negate((Document) o)); + } + list.add(asDocument("$or", list2)); + + } else if (entry.getValue() instanceof Pattern || entry.getValue() instanceof BsonRegularExpression) { + list.add(asDocument(entry.getKey(), asDocument("$not", entry.getValue()))); + + } else if (entry.getValue() instanceof Document) { + list.add(negate(entry.getKey(), (Document) entry.getValue())); + + } else { + list.add(asDocument(entry.getKey(), asDocument("$ne", entry.getValue()))); + } + } + return list.size() == 1 ? list.get(0) : asDocument("$or", list); + } + + private Object negate(String key, Document value) { + if (value.size() == 1) { + return asDocument(key, asDocument("$not", value)); + + } else { + List<Object> list2 = new ArrayList<Object>(); + for (Map.Entry<String, Object> entry2 : value.entrySet()) { + list2.add(asDocument(key, + asDocument("$not", asDocument(entry2.getKey(), entry2.getValue())))); + } + return asDocument("$or", list2); + } + } + + protected Object convert(Path<?> property, Constant<?> constant) { + if (isReference(property)) { + return asReference(constant.getConstant()); + } else if (isId(property)) { + if (isReference(property.getMetadata().getParent())) { + return asReferenceKey(property.getMetadata().getParent().getType(), constant.getConstant()); + } else if (constant.getType().equals(String.class) && isImplicitObjectIdConversion()) { + String id = (String) constant.getConstant(); + return ObjectId.isValid(id) ? new ObjectId(id) : id; + } + } + return visit(constant, null); + } + + protected boolean isImplicitObjectIdConversion() { + return true; + } + + protected DBRef asReferenceKey(Class<?> entity, Object id) { + // TODO override in subclass + throw new UnsupportedOperationException(); + } + + protected abstract DBRef asReference(Object constant); + + protected abstract boolean isReference(Path<?> arg); + + protected boolean isId(Path<?> arg) { + // TODO override in subclass + return false; + } + + @Override + public String visit(Path<?> expr, Void context) { + PathMetadata metadata = expr.getMetadata(); + if (metadata.getParent() != null) { + Path<?> parent = metadata.getParent(); + if (parent.getMetadata().getPathType() == PathType.DELEGATE) { + parent = parent.getMetadata().getParent(); + } + if (metadata.getPathType() == PathType.COLLECTION_ANY) { + return visit(parent, context); + } else if (parent.getMetadata().getPathType() != PathType.VARIABLE) { + String rv = getKeyForPath(expr, metadata); + String parentStr = visit(parent, context); + return rv != null ? parentStr + "." + rv : parentStr; + } + } + return getKeyForPath(expr, metadata); + } + + protected String getKeyForPath(Path<?> expr, PathMetadata metadata) { + return metadata.getElement().toString(); + } + + @Override + public Object visit(SubQueryExpression<?> expr, Void context) { + throw new UnsupportedOperationException(); + } + + @Override + public Object visit(ParamExpression<?> expr, Void context) { + throw new UnsupportedOperationException(); + } + + private Queue<Map<Object, Object>> collectConnectorArgs(String operator, Operation<?> operation) { + + Queue<Map<Object, Object>> pendingDocuments = new LinkedList<Map<Object, Object>>(); + for (Expression<?> exp : operation.getArgs()) { + Map<Object, Object> document = (Map<Object, Object>) handle(exp); + if (document.keySet().size() == 1 && document.containsKey(operator)) { + pendingDocuments + .addAll((Collection<Map<Object, Object>>) document.get(operator)); + } else { + pendingDocuments.add(document); + } + } + return pendingDocuments; + } +} diff --git a/querydsl-mongodb/src/main/java/com/querydsl/mongodb/document/MongodbExpressions.java b/querydsl-mongodb/src/main/java/com/querydsl/mongodb/document/MongodbExpressions.java new file mode 100644 index 0000000000..28ec72072c --- /dev/null +++ b/querydsl-mongodb/src/main/java/com/querydsl/mongodb/document/MongodbExpressions.java @@ -0,0 +1,60 @@ +/* + * Copyright 2020 the original author or 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. + */ +package com.querydsl.mongodb.document; + +import java.util.Arrays; + +import com.querydsl.core.types.ConstantImpl; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.dsl.BooleanExpression; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.mongodb.MongodbOps; + +/** + * Mongodb Document-API-specific operations. + * + * @author tiwe + * @author Mark Paluch + * + */ +public final class MongodbExpressions { + + private MongodbExpressions() { } + + /** + * Finds the closest points relative to the given location and orders the results with decreasing proximity + * + * @param expr location + * @param latVal latitude + * @param longVal longitude + * @return predicate + */ + public static BooleanExpression near(Expression<Double[]> expr, double latVal, double longVal) { + return Expressions.booleanOperation(MongodbOps.NEAR, expr, ConstantImpl.create(Arrays.asList(latVal, longVal))); + } + + /** + * Finds the closest points relative to the given location on a sphere and orders the results with decreasing proximity + * + * @param expr location + * @param latVal latitude + * @param longVal longitude + * @return predicate + */ + public static BooleanExpression nearSphere(Expression<Double[]> expr, double latVal, double longVal) { + return Expressions.booleanOperation(MongodbOps.NEAR_SPHERE, expr, ConstantImpl.create(Arrays.asList(latVal, longVal))); + } +} diff --git a/querydsl-mongodb/src/main/java/com/querydsl/mongodb/document/package-info.java b/querydsl-mongodb/src/main/java/com/querydsl/mongodb/document/package-info.java new file mode 100644 index 0000000000..62b25d0423 --- /dev/null +++ b/querydsl-mongodb/src/main/java/com/querydsl/mongodb/document/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2020 the original author or 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. + */ + +/** + * MongoDB Document API support. + */ +package com.querydsl.mongodb.document; diff --git a/querydsl-mongodb/src/main/java/com/querydsl/mongodb/morphia/MorphiaQuery.java b/querydsl-mongodb/src/main/java/com/querydsl/mongodb/morphia/MorphiaQuery.java new file mode 100644 index 0000000000..8c9ec2c821 --- /dev/null +++ b/querydsl-mongodb/src/main/java/com/querydsl/mongodb/morphia/MorphiaQuery.java @@ -0,0 +1,90 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.mongodb.morphia; + +import com.mongodb.DBCollection; +import com.mongodb.DBCursor; +import com.mongodb.DBObject; +import com.querydsl.core.types.EntityPath; +import com.querydsl.mongodb.AbstractMongodbQuery; +import org.mongodb.morphia.Datastore; +import org.mongodb.morphia.Morphia; +import org.mongodb.morphia.mapping.cache.DefaultEntityCache; +import org.mongodb.morphia.mapping.cache.EntityCache; + +import java.util.function.Function; + +/** + * {@code MorphiaQuery} extends {@link AbstractMongodbQuery} with Morphia specific transformations + * + * <p>Example</p> + * + * <pre>{@code + * QUser user = QUser.user; + * MorphiaQuery<User> query = new MorphiaQuery<User>(morphia, datastore, user); + * List<User> list = query + * .where(user.firstName.eq("Bob")) + * .fetch(); + * }</pre> + * + * @param <K> result type + * + * @author laimw + * @author tiwe + * + */ +public class MorphiaQuery<K> extends AbstractMongodbQuery<K, MorphiaQuery<K>> { + + private final EntityCache cache; + + private final Datastore datastore; + + public MorphiaQuery(Morphia morphia, Datastore datastore, EntityPath<K> entityPath) { + this(morphia, datastore, new DefaultEntityCache(), entityPath); + } + + public MorphiaQuery(Morphia morphia, Datastore datastore, Class<? extends K> entityType) { + this(morphia, datastore, new DefaultEntityCache(), entityType); + } + + public MorphiaQuery(Morphia morphia, Datastore datastore, + EntityCache cache, EntityPath<K> entityPath) { + this(morphia, datastore, cache, entityPath.getType()); + } + + public MorphiaQuery(final Morphia morphia, final Datastore datastore, + final EntityCache cache, final Class<? extends K> entityType) { + super(datastore.getCollection(entityType), new Function<DBObject, K>() { + @Override + public K apply(DBObject dbObject) { + return morphia.fromDBObject(datastore, entityType, dbObject, cache); + } + }, new MorphiaSerializer(morphia)); + this.datastore = datastore; + this.cache = cache; + } + + + @Override + protected DBCursor createCursor() { + cache.flush(); + return super.createCursor(); + } + + @Override + protected DBCollection getCollection(Class<?> type) { + return datastore.getCollection(type); + } + +} \ No newline at end of file diff --git a/querydsl-mongodb/src/main/java/com/querydsl/mongodb/morphia/MorphiaSerializer.java b/querydsl-mongodb/src/main/java/com/querydsl/mongodb/morphia/MorphiaSerializer.java new file mode 100644 index 0000000000..803aec320e --- /dev/null +++ b/querydsl-mongodb/src/main/java/com/querydsl/mongodb/morphia/MorphiaSerializer.java @@ -0,0 +1,103 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.mongodb.morphia; + +import java.lang.reflect.AnnotatedElement; + +import org.mongodb.morphia.Key; +import org.mongodb.morphia.Morphia; +import org.mongodb.morphia.annotations.Id; +import org.mongodb.morphia.annotations.Property; +import org.mongodb.morphia.annotations.Reference; +import org.mongodb.morphia.mapping.Mapper; + +import com.mongodb.DBRef; +import com.querydsl.core.types.Constant; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.mongodb.MongodbSerializer; + +/** + * {@code MorphiaSerializer} extends {@link MongodbSerializer} with Morphia specific annotation handling + * + * @author tiwe + * + */ +public class MorphiaSerializer extends MongodbSerializer { + + private final Morphia morphia; + + public MorphiaSerializer(Morphia morphia) { + this.morphia = morphia; + } + + @Override + public Object visit(Constant<?> expr, Void context) { + Object value = super.visit(expr, context); + return morphia.getMapper().toMongoObject(null, null, value); + } + + @Override + protected String getKeyForPath(Path<?> expr, PathMetadata metadata) { + AnnotatedElement annotations = expr.getAnnotatedElement(); + if (annotations.isAnnotationPresent(Id.class)) { + Path<?> parent = expr.getMetadata().getParent(); + if (parent.getAnnotatedElement().isAnnotationPresent(Reference.class)) { + return null; // go to parent + } else { + return "_id"; + } + } else if (annotations.isAnnotationPresent(Property.class)) { + Property property = annotations.getAnnotation(Property.class); + if (!property.value().equals(Mapper.IGNORED_FIELDNAME)) { + return property.value(); + } + } else if (annotations.isAnnotationPresent(Reference.class)) { + Reference reference = annotations.getAnnotation(Reference.class); + if (!reference.value().equals(Mapper.IGNORED_FIELDNAME)) { + return reference.value(); + } + } + return super.getKeyForPath(expr, metadata); + } + + @Override + protected boolean isReference(Path<?> arg) { + return arg.getAnnotatedElement().isAnnotationPresent(Reference.class); + } + + @Override + protected boolean isImplicitObjectIdConversion() { + // see https://github.com/mongodb/morphia/wiki/FrequentlyAskedQuestions + return false; + } + + @Override + protected boolean isId(Path<?> arg) { + return arg.getAnnotatedElement().isAnnotationPresent(Id.class); + } + + @Override + protected DBRef asReference(Object constant) { + Key<?> key = morphia.getMapper().getKey(constant); + return morphia.getMapper().keyToDBRef(key); + } + + @Override + protected DBRef asReferenceKey(Class<?> entity, Object id) { + String collection = morphia.getMapper().getCollectionName(entity); + Key<?> key = new Key<Object>(entity, collection, id); + return morphia.getMapper().keyToDBRef(key); + } +} diff --git a/querydsl-mongodb/src/main/java/com/querydsl/mongodb/morphia/package-info.java b/querydsl-mongodb/src/main/java/com/querydsl/mongodb/morphia/package-info.java new file mode 100644 index 0000000000..43b5a2f4ed --- /dev/null +++ b/querydsl-mongodb/src/main/java/com/querydsl/mongodb/morphia/package-info.java @@ -0,0 +1,18 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ + +/** + * Morphia bindings + */ +package com.querydsl.mongodb.morphia; diff --git a/querydsl-mongodb/src/main/java/com/querydsl/mongodb/package-info.java b/querydsl-mongodb/src/main/java/com/querydsl/mongodb/package-info.java new file mode 100644 index 0000000000..0204f2227f --- /dev/null +++ b/querydsl-mongodb/src/main/java/com/querydsl/mongodb/package-info.java @@ -0,0 +1,18 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ + +/** + * MongoDB support + */ +package com.querydsl.mongodb; diff --git a/querydsl-mongodb/src/test/java/com/mysema/query/PackageVerification.java b/querydsl-mongodb/src/test/java/com/mysema/query/PackageVerification.java deleted file mode 100644 index 587d5fe05d..0000000000 --- a/querydsl-mongodb/src/test/java/com/mysema/query/PackageVerification.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import java.io.File; -import java.net.URL; -import java.net.URLClassLoader; - -import org.junit.Test; - -import com.google.common.base.Charsets; -import com.google.common.io.Resources; -import com.mysema.codegen.CodeWriter; -import com.mysema.query.apt.morphia.MorphiaAnnotationProcessor; -import com.mysema.query.codegen.CodegenModule; -import com.mysema.query.types.Expression; - -public class PackageVerification { - - @Test - public void Verify_Package() throws Exception{ - String version = System.getProperty("version"); - verify(new File("target/querydsl-mongodb-"+version+"-apt-one-jar.jar")); - } - - private void verify(File oneJar) throws Exception { - assertTrue(oneJar.getPath() + " doesn't exist", oneJar.exists()); - // verify classLoader - URLClassLoader oneJarClassLoader = new URLClassLoader(new URL[]{oneJar.toURI().toURL()}); - oneJarClassLoader.loadClass(Expression.class.getName()); // querydsl-core - oneJarClassLoader.loadClass(CodeWriter.class.getName()); // codegen - oneJarClassLoader.loadClass(CodegenModule.class.getName()).newInstance(); - oneJarClassLoader.loadClass(Entity.class.getName()); // morphia - Class cl = oneJarClassLoader.loadClass(MorphiaAnnotationProcessor.class.getName()); // querydsl-apt - cl.newInstance(); - String resourceKey = "META-INF/services/javax.annotation.processing.Processor"; - assertEquals(MorphiaAnnotationProcessor.class.getName(), Resources.toString(oneJarClassLoader.findResource(resourceKey), Charsets.UTF_8)); - } - -} diff --git a/querydsl-mongodb/src/test/java/com/mysema/query/mongodb/GeoSpatialQueryTest.java b/querydsl-mongodb/src/test/java/com/mysema/query/mongodb/GeoSpatialQueryTest.java deleted file mode 100644 index fa3d0c1f75..0000000000 --- a/querydsl-mongodb/src/test/java/com/mysema/query/mongodb/GeoSpatialQueryTest.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.mongodb; - -import static org.junit.Assert.assertEquals; - -import java.net.UnknownHostException; -import java.util.List; - -import org.junit.Before; -import org.junit.Test; -import org.junit.experimental.categories.Category; -import org.mongodb.morphia.Datastore; -import org.mongodb.morphia.Morphia; - -import com.mongodb.BasicDBObject; -import com.mongodb.Mongo; -import com.mongodb.MongoException; -import com.mysema.query.mongodb.domain.GeoEntity; -import com.mysema.query.mongodb.domain.QGeoEntity; -import com.mysema.query.mongodb.morphia.MorphiaQuery; -import com.mysema.testutil.ExternalDB; - -@Category(ExternalDB.class) -public class GeoSpatialQueryTest { - - private final String dbname = "geodb"; - private final Mongo mongo; - private final Morphia morphia; - private final Datastore ds; - private final QGeoEntity geoEntity = new QGeoEntity("geoEntity"); - - public GeoSpatialQueryTest() throws UnknownHostException, MongoException { - mongo = new Mongo(); - morphia = new Morphia().map(GeoEntity.class); - ds = morphia.createDatastore(mongo, dbname); - } - - @Before - public void before() { - ds.delete(ds.createQuery(GeoEntity.class)); - ds.getCollection(GeoEntity.class).ensureIndex(new BasicDBObject("location","2d"));; - } - - @Test - public void Near() { - ds.save(new GeoEntity(10.0, 50.0)); - ds.save(new GeoEntity(20.0, 50.0)); - ds.save(new GeoEntity(30.0, 50.0)); - - List<GeoEntity> entities = query().where(geoEntity.location.near(50.0, 50.0)).list(); - assertEquals(30.0, entities.get(0).getLocation()[0].doubleValue(), 0.1); - assertEquals(20.0, entities.get(1).getLocation()[0].doubleValue(), 0.1); - assertEquals(10.0, entities.get(2).getLocation()[0].doubleValue(), 0.1); - } - - private MorphiaQuery<GeoEntity> query() { - return new MorphiaQuery<GeoEntity>(morphia, ds, geoEntity); - } - -} diff --git a/querydsl-mongodb/src/test/java/com/mysema/query/mongodb/JoinTest.java b/querydsl-mongodb/src/test/java/com/mysema/query/mongodb/JoinTest.java deleted file mode 100644 index 295bf2d649..0000000000 --- a/querydsl-mongodb/src/test/java/com/mysema/query/mongodb/JoinTest.java +++ /dev/null @@ -1,154 +0,0 @@ -package com.mysema.query.mongodb; - -import java.net.UnknownHostException; - -import com.mongodb.Mongo; -import com.mongodb.MongoException; -import com.mysema.query.mongodb.domain.Item; -import com.mysema.query.mongodb.domain.QUser; -import com.mysema.query.mongodb.domain.User; -import com.mysema.query.mongodb.morphia.MorphiaQuery; -import com.mysema.query.types.Predicate; -import com.mysema.testutil.ExternalDB; -import org.junit.Before; -import org.junit.Test; -import org.junit.experimental.categories.Category; -import org.mongodb.morphia.Datastore; -import org.mongodb.morphia.Morphia; -import static junit.framework.Assert.assertEquals; -import static org.junit.Assert.*; - -@Category(ExternalDB.class) -public class JoinTest { - - private final Mongo mongo; - private final Morphia morphia; - private final Datastore ds; - - private final String dbname = "testdb"; - private final QUser user = QUser.user; - private final QUser friend = new QUser("friend"); - private final QUser friend2 = new QUser("friend2"); - private final QUser enemy = new QUser("enemy"); - - public JoinTest() throws UnknownHostException, MongoException { - mongo = new Mongo(); - morphia = new Morphia().map(User.class).map(Item.class); - ds = morphia.createDatastore(mongo, dbname); - } - - @Before - public void before() throws UnknownHostException, MongoException { - ds.delete(ds.createQuery(User.class)); - - User friend1 = new User("Max", null); - User friend2 = new User("Jack", null); - User friend3 = new User("Bob", null); - ds.save(friend1, friend2, friend3); - - User user1 = new User("Jane", null, friend1); - User user2 = new User("Mary", null, user1); - User user3 = new User("Ann", null, friend3); - ds.save(user1, user2, user3); - - User user4 = new User("Mike", null); - user4.setFriend(user2); - user4.setEnemy(user3); - ds.save(user4); - - User user5 = new User("Bart", null); - user5.addFriend(user2); - user5.addFriend(user3); - ds.save(user5); - - } - - @Test - public void Count() { - assertEquals(1, where().join(user.friend(), friend).on(friend.firstName.eq("Max")).count()); - assertEquals(1, where(user.firstName.eq("Jane")).join(user.friend(), friend).on(friend.firstName.eq("Max")).count()); - assertEquals(0, where(user.firstName.eq("Mary")).join(user.friend(), friend).on(friend.firstName.eq("Max")).count()); - assertEquals(0, where(user.firstName.eq("Jane")).join(user.friend(), friend).on(friend.firstName.eq("Jack")).count()); - } - - @Test - public void Count_Collection() { - assertEquals(1, where().join(user.friends, friend).on(friend.firstName.eq("Mary")).count()); - assertEquals(1, where().join(user.friends, friend).on(friend.firstName.eq("Ann")).count()); - assertEquals(1, where().join(user.friends, friend).on(friend.firstName.eq("Ann").or(friend.firstName.eq("Mary"))).count()); - assertEquals(1, where(user.firstName.eq("Bart")).join(user.friends, friend).on(friend.firstName.eq("Mary")).count()); - assertEquals(0, where().join(user.friends, friend).on(friend.firstName.eq("Max")).count()); - } - - @Test - public void Exists() { - assertTrue(where().join(user.friend(), friend).on(friend.firstName.eq("Max")).exists()); - assertTrue(where(user.firstName.eq("Jane")).join(user.friend(), friend).on(friend.firstName.eq("Max")).exists()); - assertFalse(where(user.firstName.eq("Mary")).join(user.friend(), friend).on(friend.firstName.eq("Max")).exists()); - assertFalse(where(user.firstName.eq("Jane")).join(user.friend(), friend).on(friend.firstName.eq("Jack")).exists()); - } - - @Test - public void Exists_Collection() { - assertTrue(where().join(user.friends, friend).on(friend.firstName.eq("Mary")).exists()); - assertTrue(where(user.firstName.eq("Bart")).join(user.friends, friend).on(friend.firstName.eq("Mary")).exists()); - } - - @Test - public void List() { - assertEquals(1, where().join(user.friend(), friend).on(friend.firstName.eq("Max")).list().size()); - assertEquals(1, where(user.firstName.eq("Jane")).join(user.friend(), friend).on(friend.firstName.eq("Max")).list().size()); - assertEquals(0, where(user.firstName.eq("Mary")).join(user.friend(), friend).on(friend.firstName.eq("Max")).list().size()); - assertEquals(0, where(user.firstName.eq("Jane")).join(user.friend(), friend).on(friend.firstName.eq("Jack")).list().size()); - } - - public void List_Collection() { - assertEquals(1, where().join(user.friends, friend).on(friend.firstName.eq("Mary")).list().size()); - } - - @Test - public void Single() { - assertEquals("Jane", where().join(user.friend(), friend).on(friend.firstName.eq("Max")).singleResult().getFirstName()); - assertEquals("Jane", where(user.firstName.eq("Jane")).join(user.friend(), friend).on(friend.firstName.eq("Max")).singleResult().getFirstName()); - assertNull(where(user.firstName.eq("Mary")).join(user.friend(), friend).on(friend.firstName.eq("Max")).singleResult()); - assertNull(where(user.firstName.eq("Jane")).join(user.friend(), friend).on(friend.firstName.eq("Jack")).singleResult()); - } - - @Test - public void Single_Collection() { - assertEquals("Bart", where().join(user.friends, friend).on(friend.firstName.eq("Mary")).singleResult().getFirstName()); - } - - @Test - public void Double() { - assertEquals("Mike", where() - .join(user.friend(), friend).on(friend.firstName.isNotNull()) - .join(user.enemy(), enemy).on(enemy.firstName.isNotNull()) - .singleResult().getFirstName()); - } - - @Test - public void Double2() { - assertEquals("Mike", where() - .join(user.friend(), friend).on(friend.firstName.eq("Mary")) - .join(user.enemy(), enemy).on(enemy.firstName.eq("Ann")) - .singleResult().getFirstName()); - } - - @Test - public void Deep() { - // Mike -> Mary -> Jane - assertEquals("Mike", where() - .join(user.friend(), friend).on(friend.firstName.isNotNull()) - .join(friend.friend(), friend2).on(friend2.firstName.eq("Jane")) - .singleResult().getFirstName()); - } - - private MongodbQuery<User> query() { - return new MorphiaQuery<User>(morphia, ds, user); - } - - private MongodbQuery<User> where(Predicate ... e) { - return query().where(e); - } -} diff --git a/querydsl-mongodb/src/test/java/com/mysema/query/mongodb/MongodbQueryTest.java b/querydsl-mongodb/src/test/java/com/mysema/query/mongodb/MongodbQueryTest.java deleted file mode 100644 index ff12190127..0000000000 --- a/querydsl-mongodb/src/test/java/com/mysema/query/mongodb/MongodbQueryTest.java +++ /dev/null @@ -1,538 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.mongodb; - -import java.net.UnknownHostException; -import java.util.*; - -import com.google.common.collect.Lists; -import com.mongodb.Mongo; -import com.mongodb.MongoException; -import com.mongodb.ReadPreference; -import com.mysema.query.NonUniqueResultException; -import com.mysema.query.SearchResults; -import com.mysema.query.mongodb.domain.*; -import com.mysema.query.mongodb.domain.User.Gender; -import com.mysema.query.mongodb.morphia.MorphiaQuery; -import com.mysema.query.types.EntityPath; -import com.mysema.query.types.OrderSpecifier; -import com.mysema.query.types.Predicate; -import com.mysema.query.types.path.StringPath; -import com.mysema.testutil.ExternalDB; -import org.bson.types.ObjectId; -import org.junit.Before; -import org.junit.Test; -import org.junit.experimental.categories.Category; -import org.mongodb.morphia.Datastore; -import org.mongodb.morphia.Morphia; -import static java.util.Arrays.asList; -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertNotNull; -import static org.junit.Assert.*; - -@Category(ExternalDB.class) -public class MongodbQueryTest { - - private final Mongo mongo; - private final Morphia morphia; - private final Datastore ds; - - private final String dbname = "testdb"; - private final QUser user = QUser.user; - private final QItem item = QItem.item; - private final QAddress address = QAddress.address; - private final QMapEntity mapEntity = QMapEntity.mapEntity; - private final QDates dates = QDates.dates; - - List<User> users = Lists.newArrayList(); - User u1, u2, u3, u4; - City tampere, helsinki; - - public MongodbQueryTest() throws UnknownHostException, MongoException { - mongo = new Mongo(); - morphia = new Morphia().map(User.class).map(Item.class).map(MapEntity.class).map(Dates.class); - ds = morphia.createDatastore(mongo, dbname); - } - - @Before - public void before() throws UnknownHostException, MongoException { - ds.delete(ds.createQuery(Item.class)); - ds.delete(ds.createQuery(User.class)); - ds.delete(ds.createQuery(MapEntity.class)); - - tampere = new City("Tampere", 61.30, 23.50); - helsinki= new City("Helsinki", 60.15, 20.03); - - u1 = addUser("Jaakko", "Jantunen", 20, new Address("Aakatu", "00100", helsinki), - new Address("Aakatu1", "00100", helsinki), - new Address("Aakatu2", "00100", helsinki)); - u2 = addUser("Jaakki", "Jantunen", 30, new Address("Beekatu", "00200", helsinki)); - u3 = addUser("Jaana", "Aakkonen", 40, new Address("Ceekatu","00300", tampere)); - u4 = addUser("Jaana", "BeekkoNen", 50, new Address("Deekatu","00400",tampere)); - } - - @Test - public void List_Keys() { - User u = where(user.firstName.eq("Jaakko")).list(user.firstName, user.mainAddress().street).get(0); - assertEquals("Jaakko", u.getFirstName()); - assertNull(u.getLastName()); - assertEquals("Aakatu", u.getMainAddress().street); - assertNull(u.getMainAddress().postCode); - } - - @Test - public void SingleResult_Keys() { - User u = where(user.firstName.eq("Jaakko")).singleResult(user.firstName); - assertEquals("Jaakko", u.getFirstName()); - assertNull(u.getLastName()); - } - - @Test - public void UniqueResult_Keys() { - User u = where(user.firstName.eq("Jaakko")).uniqueResult(user.firstName); - assertEquals("Jaakko", u.getFirstName()); - assertNull(u.getLastName()); - } - - @Test - public void List_Deep_Keys() { - User u = where(user.firstName.eq("Jaakko")).singleResult(user.addresses.any().street); - for (Address a : u.getAddresses()) { - assertNotNull(a.street); - assertNull(a.city); - } - } - - @Test - public void Contains() { - assertQuery(user.friends.contains(u1), u3, u4, u2); - } - - @Test - public void Contains2() { - assertQuery(user.friends.contains(u4)); - } - - @Test - public void NotContains() { - assertQuery(user.friends.contains(u1).not(), u1); - } - - @Test - public void Contains_Key() { - MapEntity entity = new MapEntity(); - entity.getProperties().put("key", "value"); - ds.save(entity); - - assertTrue(query(mapEntity).where(mapEntity.properties.get("key").isNotNull()).exists()); - assertFalse(query(mapEntity).where(mapEntity.properties.get("key2").isNotNull()).exists()); - - assertTrue(query(mapEntity).where(mapEntity.properties.containsKey("key")).exists()); - assertFalse(query(mapEntity).where(mapEntity.properties.containsKey("key2")).exists()); - } - - @Test - public void Equals_Ignore_Case() { - assertTrue(where(user.firstName.equalsIgnoreCase("jAaKko")).exists()); - assertFalse(where(user.firstName.equalsIgnoreCase("AaKk")).exists()); - } - - @Test - public void Exists() { - assertTrue(where(user.firstName.eq("Jaakko")).exists()); - assertFalse(where(user.firstName.eq("JaakkoX")).exists()); - assertTrue(where(user.id.eq(u1.getId())).exists()); - } - - @Test - public void Find_By_Id() { - assertNotNull(where(user.id.eq(u1.getId())).singleResult() != null); - } - - @Test - public void NotExists() { - assertFalse(where(user.firstName.eq("Jaakko")).notExists()); - assertTrue(where(user.firstName.eq("JaakkoX")).notExists()); - } - - @Test - public void UniqueResult() { - assertEquals("Jantunen", where(user.firstName.eq("Jaakko")).uniqueResult().getLastName()); - } - - @Test(expected=NonUniqueResultException.class) - public void UniqueResultContract() { - where(user.firstName.isNotNull()).uniqueResult(); - } - - @Test - public void SingleResult() { - where(user.firstName.isNotNull()).singleResult(); - } - - @Test - public void LongPath() { - assertEquals(2, query().where(user.mainAddress().city().name.eq("Helsinki")).count()); - assertEquals(2, query().where(user.mainAddress().city().name.eq("Tampere")).count()); - } - - @Test - public void CollectionPath() { - assertEquals(1, query().where(user.addresses.any().street.eq("Aakatu1")).count()); - assertEquals(0, query().where(user.addresses.any().street.eq("akatu")).count()); - } - - @Test - public void Dates() { - long current = System.currentTimeMillis(); - int dayInMillis = 24 * 60 * 60 * 1000; - Date start = new Date(current); - ds.delete(ds.createQuery(Dates.class)); - Dates d = new Dates(); - d.setDate(new Date(current + dayInMillis)); - ds.save(d); - Date end = new Date(current + 2 * dayInMillis); - - assertEquals(d, query(dates).where(dates.date.between(start, end)).singleResult()); - assertEquals(0, query(dates).where(dates.date.between(new Date(0), start)).count()); - } - - @Test - public void ElemMatch() { -// { "addresses" : { "$elemMatch" : { "street" : "Aakatu1"}}} - assertEquals(1, query().anyEmbedded(user.addresses, address).on(address.street.eq("Aakatu1")).count()); -// { "addresses" : { "$elemMatch" : { "street" : "Aakatu1" , "postCode" : "00100"}}} - assertEquals(1, query().anyEmbedded(user.addresses, address).on(address.street.eq("Aakatu1"), address.postCode.eq("00100")).count()); -// { "addresses" : { "$elemMatch" : { "street" : "akatu"}}} - assertEquals(0, query().anyEmbedded(user.addresses, address).on(address.street.eq("akatu")).count()); -// { "addresses" : { "$elemMatch" : { "street" : "Aakatu1" , "postCode" : "00200"}}} - assertEquals(0, query().anyEmbedded(user.addresses, address).on(address.street.eq("Aakatu1"), address.postCode.eq("00200")).count()); - } - - @Test - public void IndexedAccess() { - assertEquals(1, query().where(user.addresses.get(0).street.eq("Aakatu1")).count()); - assertEquals(0, query().where(user.addresses.get(1).street.eq("Aakatu1")).count()); - } - - @Test - public void Count() { - assertEquals(4, query().count()); - } - - @Test - public void Order() { - List<User> users = query().orderBy(user.age.asc()).list(); - assertEquals(asList(u1, u2, u3, u4), users); - - users = query().orderBy(user.age.desc()).list(); - assertEquals(asList(u4, u3, u2, u1), users); - } - - @Test - public void Restrict() { - assertEquals(asList(u1, u2), query().limit(2).orderBy(user.age.asc()).list()); - assertEquals(asList(u2, u3), query().limit(2).offset(1).orderBy(user.age.asc()).list()); - } - - @Test - public void ListResults() { - SearchResults<User> results = query().limit(2).orderBy(user.age.asc()).listResults(); - assertEquals(4l, results.getTotal()); - assertEquals(2, results.getResults().size()); - - results = query().offset(2).orderBy(user.age.asc()).listResults(); - assertEquals(4l, results.getTotal()); - assertEquals(2, results.getResults().size()); - } - - @Test - public void EmptyResults() { - SearchResults<User> results = query().where(user.firstName.eq("XXX")).listResults(); - assertEquals(0l, results.getTotal()); - assertEquals(Collections.emptyList(), results.getResults()); - } - - @Test - public void EqInAndOrderByQueries() { - assertQuery(user.firstName.eq("Jaakko"), u1); - assertQuery(user.firstName.equalsIgnoreCase("jaakko"), u1); - assertQuery(user.lastName.eq("Aakkonen"), u3); - - assertQuery(user.firstName.in("Jaakko","Teppo"), u1); - assertQuery(user.lastName.in("Aakkonen","BeekkoNen"), u3, u4); - - assertQuery(user.firstName.eq("Jouko")); - - assertQuery(user.firstName.eq("Jaana"), user.lastName.asc(), u3, u4); - assertQuery(user.firstName.eq("Jaana"), user.lastName.desc(), u4, u3); - assertQuery(user.lastName.eq("Jantunen"), user.firstName.asc(), u2, u1); - assertQuery(user.lastName.eq("Jantunen"), user.firstName.desc(), u1, u2); - - assertQuery(user.firstName.eq("Jaana").and(user.lastName.eq("Aakkonen")), u3); - //This shoud produce 'and' also - assertQuery(where(user.firstName.eq("Jaana"), user.lastName.eq("Aakkonen")), u3); - - assertQuery(user.firstName.ne("Jaana"), u2, u1); - - } - - @Test - public void RegexQueries() { - assertQuery(user.firstName.startsWith("Jaan"), u3, u4); - assertQuery(user.firstName.startsWith("jaan")); - assertQuery(user.firstName.startsWithIgnoreCase("jaan"), u3, u4); - - assertQuery(user.lastName.endsWith("unen"), u2, u1); - - assertQuery(user.lastName.endsWithIgnoreCase("onen"), u3, u4); - - assertQuery(user.lastName.contains("oN"), u4); - assertQuery(user.lastName.containsIgnoreCase("on"), u3, u4); - - assertQuery(user.firstName.matches(".*aa.*[^i]$"), u3, u4, u1); - } - - @Test - public void Like() { - assertQuery(user.firstName.like("Jaan")); - assertQuery(user.firstName.like("Jaan%"), u3, u4); - assertQuery(user.firstName.like("jaan%")); - - assertQuery(user.lastName.like("%unen"), u2, u1); - } - - @Test - public void IsNotNull() { - assertQuery(user.firstName.isNotNull(), u3, u4, u2, u1); - } - - @Test - public void IsNull() { - assertQuery(user.firstName.isNull()); - } - - @Test - public void IsEmpty() { - assertQuery(user.firstName.isEmpty()); - } - - @Test - public void isEmpty2() { - assertQuery(user.friends.isEmpty(), u1); - } - - @Test - public void Not() { - assertQuery(user.firstName.eq("Jaakko").not(), u3, u4, u2); - assertQuery(user.firstName.ne("Jaakko").not(), u1); - assertQuery(user.firstName.matches("Jaakko").not(), u3, u4, u2); - } - - @Test - public void Or() { - assertQuery(user.lastName.eq("Aakkonen").or(user.lastName.eq("BeekkoNen")), u3, u4); - } - - //This is not supported yet -// @Test -// public void UniqueResult() { -// -// addUser("Dille", "Duplikaatti"); -// addUser("Dille", "Duplikaatti"); -// -// assertEquals(2, where(user.firstName.eq("Dille")).count()); -// assertEquals(1, where(user.firstName.eq("Dille")).countDistinct()); -// -// } - - @Test - public void Iterate() { - User a = addUser("A", "A"); - User b = addUser("A1", "B"); - User c = addUser("A2", "C"); - - Iterator<User> i = where(user.firstName.startsWith("A")) - .orderBy(user.firstName.asc()) - .iterate(); - - assertEquals(a, i.next()); - assertEquals(b, i.next()); - assertEquals(c, i.next()); - assertEquals(false, i.hasNext()); - } - - @Test - public void UniqueResultAndLimitAndOffset() { - MongodbQuery<User> q = query().where(user.firstName.startsWith("Ja")).orderBy(user.age.asc()); - assertEquals(4, q.list().size()); - assertEquals(u1, q.list().get(0)); - } - - @Test - public void References() { - for (User u : users) { - if (u.getFriend() != null) { - assertQuery(user.friend().eq(u.getFriend()), u); - where(user.friend().ne(u.getFriend())).list(); - } - } - } - - @Test - public void Various() { - StringPath str = user.lastName; - List<Predicate> predicates = new ArrayList<Predicate>(); - predicates.add(str.between("a", "b")); - predicates.add(str.contains("a")); - predicates.add(str.containsIgnoreCase("a")); - predicates.add(str.endsWith("a")); - predicates.add(str.endsWithIgnoreCase("a")); - predicates.add(str.eq("a")); - predicates.add(str.equalsIgnoreCase("a")); - predicates.add(str.goe("a")); - predicates.add(str.gt("a")); - predicates.add(str.in("a","b","c")); - predicates.add(str.isEmpty()); - predicates.add(str.isNotNull()); - predicates.add(str.isNull()); -// predicates.add(str.like("a")); - predicates.add(str.loe("a")); - predicates.add(str.lt("a")); - predicates.add(str.matches("a")); - predicates.add(str.ne("a")); - predicates.add(str.notBetween("a", "b")); - predicates.add(str.notIn("a","b","c")); - predicates.add(str.startsWith("a")); - predicates.add(str.startsWithIgnoreCase("a")); - - for (Predicate predicate : predicates) { - where(predicate).count(); - where(predicate.not()).count(); - } - } - - @Test - public void Enum_Eq() { - assertQuery(user.gender.eq(Gender.MALE), u3, u4, u2, u1); - } - - @Test - public void Enum_Ne() { - assertQuery(user.gender.ne(Gender.MALE)); - } - - @Test - public void In_ObjectIds() { - Item i = new Item(); - i.setCtds(Arrays.asList(ObjectId.get(), ObjectId.get(), ObjectId.get())); - ds.save(i); - - assertTrue(where(item, item.ctds.contains(i.getCtds().get(0))).count() > 0); - assertTrue(where(item, item.ctds.contains(ObjectId.get())).count() == 0); - } - - @Test - public void In_ObjectIds2() { - Item i = new Item(); - i.setCtds(Arrays.asList(ObjectId.get(), ObjectId.get(), ObjectId.get())); - ds.save(i); - - assertTrue(where(item, item.ctds.any().in(i.getCtds())).count() > 0); - assertTrue(where(item, item.ctds.any().in(Arrays.asList(ObjectId.get(), ObjectId.get()))).count() == 0); - } - - @Test - public void Size() { - assertQuery(user.addresses.size().eq(2), u1); - } - - @Test - public void ReadPreference() { - MorphiaQuery<User> query = query(); - query.setReadPreference(ReadPreference.primary()); - assertEquals(4, query.count()); - - } - - //TODO - // - test dates - // - test with empty values and nulls - // - test more complex ands - - private void assertQuery(Predicate e, User ... expected) { - assertQuery(where(e).orderBy(user.lastName.asc(), user.firstName.asc()), expected ); - } - - private void assertQuery(Predicate e, OrderSpecifier<?> orderBy, User ... expected ) { - assertQuery(where(e).orderBy(orderBy), expected); - } - - private <T> MongodbQuery<T> where(EntityPath<T> entity, Predicate... e) { - return new MorphiaQuery<T>(morphia, ds, entity).where(e); - } - - private MongodbQuery<User> where(Predicate ... e) { - return query().where(e); - } - - private MorphiaQuery<User> query() { - return new MorphiaQuery<User>(morphia, ds, user); - } - - private <T> MorphiaQuery<T> query(EntityPath<T> path) { - return new MorphiaQuery<T>(morphia, ds, path); - } - - private void assertQuery(MongodbQuery<User> query, User ... expected ) { - //System.out.println(query.toString()); - List<User> results = query.list(); - - assertNotNull(results); - if (expected == null ) { - assertEquals("Should get empty result", 0, results.size()); - return; - } - assertEquals(expected.length, results.size()); - int i = 0; - for (User u : expected) { - assertEquals(u, results.get(i++)); - } - } - - private User addUser(String first, String last) { - User user = new User(first, last); - ds.save(user); - return user; - } - - private User addUser(String first, String last, int age, Address mainAddress, Address... addresses) { - User user = new User(first, last, age, new Date()); - user.setGender(Gender.MALE); - user.setMainAddress(mainAddress); - for (Address address : addresses) { - user.addAddress(address); - } - for (User u : users) { - user.addFriend(u); - } - if (!users.isEmpty()) { - user.setFriend(users.get(users.size() - 1)); - } - ds.save(user); - users.add(user); - return user; - } - -} diff --git a/querydsl-mongodb/src/test/java/com/mysema/query/mongodb/MongodbSerializerTest.java b/querydsl-mongodb/src/test/java/com/mysema/query/mongodb/MongodbSerializerTest.java deleted file mode 100644 index 80e79f8091..0000000000 --- a/querydsl-mongodb/src/test/java/com/mysema/query/mongodb/MongodbSerializerTest.java +++ /dev/null @@ -1,249 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.mongodb; - -import static junit.framework.Assert.assertEquals; - -import java.sql.Timestamp; -import java.util.Arrays; -import java.util.Date; -import java.util.List; - -import org.junit.Before; -import org.junit.Test; - -import com.mongodb.BasicDBList; -import com.mongodb.BasicDBObject; -import com.mongodb.DBObject; -import com.mysema.query.mongodb.domain.QDummyEntity; -import com.mysema.query.mongodb.domain.QUser; -import com.mysema.query.mongodb.morphia.MorphiaSerializer; -import com.mysema.query.types.Expression; -import com.mysema.query.types.OrderSpecifier; -import com.mysema.query.types.path.DatePath; -import com.mysema.query.types.path.DateTimePath; -import com.mysema.query.types.path.NumberPath; -import com.mysema.query.types.path.PathBuilder; -import com.mysema.query.types.path.StringPath; - -public class MongodbSerializerTest { - - private PathBuilder<Object> entityPath; - private StringPath title; - private NumberPath<Integer> year; - private NumberPath<Double> gross; - - private NumberPath<Long> longField; - private NumberPath<Short> shortField; - private NumberPath<Byte> byteField; - private NumberPath<Float> floatField; - - private DatePath<Date> date; - private final Date dateVal = new Date(); - private DateTimePath<Timestamp> dateTime; - private final Timestamp dateTimeVal = new Timestamp(System.currentTimeMillis()); - - private MongodbSerializer serializer; - - @Before - public void before() { - serializer = new MorphiaSerializer(null); - entityPath = new PathBuilder<Object>(Object.class, "obj"); - title = entityPath.getString("title"); - year = entityPath.getNumber("year", Integer.class); - gross = entityPath.getNumber("gross", Double.class); - longField = entityPath.getNumber("longField", Long.class); - shortField = entityPath.getNumber("shortField", Short.class); - byteField = entityPath.getNumber("byteField", Byte.class); - floatField = entityPath.getNumber("floatField", Float.class); - date = entityPath.getDate("date", Date.class); - dateTime = entityPath.getDateTime("dateTime", Timestamp.class); - } - - @Test - public void Paths() { - QUser user = QUser.user; - assertEquals("user", serializer.visit(user, null)); - assertEquals("addresses", serializer.visit(user.addresses, null)); - assertEquals("addresses", serializer.visit(user.addresses.any(), null)); - assertEquals("addresses.street", serializer.visit(user.addresses.any().street, null)); - assertEquals("firstName", serializer.visit(user.firstName, null)); - } - - @Test - public void PropertyAnnotation() { - QDummyEntity entity = QDummyEntity.dummyEntity; - assertEquals("prop", serializer.visit(entity.property, null)); - } - - @Test - public void IndexedAccess() { - QUser user = QUser.user; - assertEquals("addresses.0.street", serializer.visit(user.addresses.get(0).street, null)); - } - - @Test - public void CollectionAny() { - QUser user = QUser.user; - assertQuery(user.addresses.any().street.eq("Aakatu"), dbo("addresses.street","Aakatu")); - } - - @Test - public void Equals() { - assertQuery(title.eq("A"), dbo("title","A")); - assertQuery(year.eq(1), dbo("year",1)); - assertQuery(gross.eq(1.0D), dbo("gross", 1.0D)); - assertQuery(longField.eq(1L), dbo("longField", 1L)); - assertQuery(shortField.eq((short)1), dbo("shortField", 1)); - assertQuery(byteField.eq((byte)1), dbo("byteField", 1L)); - assertQuery(floatField.eq(1.0F), dbo("floatField", 1.0F)); - - assertQuery(date.eq(dateVal), dbo("date", dateVal)); - assertQuery(dateTime.eq(dateTimeVal), dbo("dateTime", dateTimeVal)); - } - - @Test - public void EqAndEq() { - assertQuery( - title.eq("A").and(year.eq(1)), - dbo("title","A").append("year", 1) - ); - - assertQuery( - title.eq("A").and(year.eq(1).and(gross.eq(1.0D))), - dbo("title","A").append("year", 1).append("gross", 1.0D) - ); - } - - @Test - public void NotEq() { - assertQuery(title.ne("A"), dbo("title", dbo("$ne", "A"))); - } - - @Test - public void Between() { - System.err.println(dbo("year", dbo("$gte", 1).append("$lte", 10))); - assertQuery(year.between(1, 10), dbo("year", dbo("$gte", 1).append("$lte", 10))); - } - - @Test - public void LessAndGreaterAndBetween() { - assertQuery(title.lt("A"), dbo("title", dbo("$lt", "A"))); - assertQuery(year.gt(1), dbo("year", dbo("$gt", 1))); - - assertQuery(title.loe("A"), dbo("title", dbo("$lte", "A"))); - assertQuery(year.goe(1), dbo("year", dbo("$gte", 1))); - - assertQuery( - year.gt(1).and(year.lt(10)), - dbo("$and", dblist( - dbo("year", dbo("$gt", 1)), - dbo("year", dbo("$lt", 10)))) - ); - - assertQuery( - year.between(1, 10), - dbo("year", dbo("$gte", 1).append("$lte", 10)) - ); - } - - @Test - public void In() { - assertQuery(year.in(1,2,3), dbo("year", dbo("$in", 1,2,3))); - } - - @Test - public void OrderBy() { - DBObject orderBy = serializer.toSort(sortList(year.asc())); - assertEquals(dbo("year", 1), orderBy); - - orderBy = serializer.toSort(sortList(year.desc())); - assertEquals(dbo("year", -1), orderBy); - - orderBy = serializer.toSort(sortList(year.desc(), title.asc())); - assertEquals(dbo("year", -1).append("title", 1), orderBy); - } - - @Test - public void Regexcases() { - assertQuery(title.startsWith("A"), - dbo("title", dbo("$regex", "^\\QA\\E"))); - assertQuery(title.startsWithIgnoreCase("A"), - dbo("title", dbo("$regex", "^\\QA\\E").append("$options", "i"))); - - assertQuery(title.endsWith("A"), - dbo("title", dbo("$regex", "\\QA\\E$"))); - assertQuery(title.endsWithIgnoreCase("A"), - dbo("title", dbo("$regex", "\\QA\\E$").append("$options", "i"))); - - assertQuery(title.equalsIgnoreCase("A"), - dbo("title", dbo("$regex", "^\\QA\\E$").append("$options", "i"))); - - assertQuery(title.contains("A"), - dbo("title", dbo("$regex", ".*\\QA\\E.*"))); - assertQuery(title.containsIgnoreCase("A"), - dbo("title", dbo("$regex", ".*\\QA\\E.*").append("$options", "i"))); - - assertQuery(title.matches(".*A^"), - dbo("title", dbo("$regex", ".*A^"))); - - } - - @Test - public void And() { - assertQuery( - title.startsWithIgnoreCase("a").and(title.endsWithIgnoreCase("b")), - - dbo("$and", dblist( - dbo("title", dbo("$regex", "^\\Qa\\E").append("$options", "i")), - dbo("title", dbo("$regex", "\\Qb\\E$").append("$options", "i"))))); - - } - - @Test - public void Not() { - assertQuery(title.eq("A").not(), dbo("title", dbo("$ne","A"))); - - assertQuery(title.lt("A").not().and(year.ne(1800)), - dbo("title", dbo("$not", dbo("$lt","A"))). - append("year", dbo("$ne", 1800))); - } - - - private List<OrderSpecifier<?>> sortList(OrderSpecifier<?> ... order) { - return Arrays.asList(order); - } - - private void assertQuery(Expression<?> e, BasicDBObject expected) { - BasicDBObject result = (BasicDBObject) serializer.handle(e); - assertEquals(expected.toString(), result.toString()); - } - - public static BasicDBObject dbo(String key, Object... value) { - if (value.length == 1) { - return new BasicDBObject(key, value[0]); - } - return new BasicDBObject(key, value); - } - - public static BasicDBList dblist(Object... contents) { - BasicDBList list = new BasicDBList(); - for (Object o : contents) { - list.add(o); - } - return list; - } - - -} diff --git a/querydsl-mongodb/src/test/java/com/mysema/query/mongodb/domain/AbstractEntity.java b/querydsl-mongodb/src/test/java/com/mysema/query/mongodb/domain/AbstractEntity.java deleted file mode 100644 index dc50cede1d..0000000000 --- a/querydsl-mongodb/src/test/java/com/mysema/query/mongodb/domain/AbstractEntity.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.mysema.query.mongodb.domain; - -import com.mysema.query.annotations.QuerySupertype; -import org.bson.types.ObjectId; -import org.mongodb.morphia.annotations.Id; - -@QuerySupertype -public abstract class AbstractEntity { - - private @Id ObjectId id; - - public ObjectId getId() { - return id; - } - - public void setId(ObjectId id) { - this.id = id; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((id == null) ? 0 : id.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - AbstractEntity other = (AbstractEntity) obj; - if (id == null) { - if (other.id != null) - return false; - } else if (!id.equals(other.id)) - return false; - return true; - } - - -} diff --git a/querydsl-mongodb/src/test/java/com/mysema/query/mongodb/domain/Address.java b/querydsl-mongodb/src/test/java/com/mysema/query/mongodb/domain/Address.java deleted file mode 100644 index 2998992314..0000000000 --- a/querydsl-mongodb/src/test/java/com/mysema/query/mongodb/domain/Address.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.mongodb.domain; - -import org.mongodb.morphia.annotations.Embedded; - -public final class Address { - - public Address() { - - } - - public Address(String street, String postCode, City city) { - this.street = street; this.postCode = postCode; this.city = city; - } - - public String street; - - public String postCode; - - @Embedded - public City city; - -} diff --git a/querydsl-mongodb/src/test/java/com/mysema/query/mongodb/domain/City.java b/querydsl-mongodb/src/test/java/com/mysema/query/mongodb/domain/City.java deleted file mode 100644 index 483477d8f6..0000000000 --- a/querydsl-mongodb/src/test/java/com/mysema/query/mongodb/domain/City.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.mongodb.domain; - - -public final class City { - - public City() {} - - public City(String name, Double latitude, Double longitude) { - this.name = name; - this.latitude = latitude; - this.longitude = longitude; - } - - public String name; - - public Double latitude; - - public Double longitude; - -} diff --git a/querydsl-mongodb/src/test/java/com/mysema/query/mongodb/domain/DummyEntity.java b/querydsl-mongodb/src/test/java/com/mysema/query/mongodb/domain/DummyEntity.java deleted file mode 100644 index c7eb33602a..0000000000 --- a/querydsl-mongodb/src/test/java/com/mysema/query/mongodb/domain/DummyEntity.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.mongodb.domain; - -import org.mongodb.morphia.annotations.Entity; -import org.mongodb.morphia.annotations.Property; - -@Entity -public class DummyEntity extends AbstractEntity { - - @Property("prop") - private String property; - - public String getProperty() { - return property; - } - - public void setProperty(String property) { - this.property = property; - } - -} diff --git a/querydsl-mongodb/src/test/java/com/mysema/query/mongodb/domain/GeoEntity.java b/querydsl-mongodb/src/test/java/com/mysema/query/mongodb/domain/GeoEntity.java deleted file mode 100644 index 61ce5edc26..0000000000 --- a/querydsl-mongodb/src/test/java/com/mysema/query/mongodb/domain/GeoEntity.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.mongodb.domain; - -import org.mongodb.morphia.annotations.Entity; - -@Entity -public class GeoEntity extends AbstractEntity { - - private Double[] location; - - public GeoEntity(double l1, double l2) { - location = new Double[]{l1, l2}; - } - - public GeoEntity() {} - - public Double[] getLocation() { - return location; - } - - public void setLocation(Double[] location) { - this.location = location; - } - - -} diff --git a/querydsl-mongodb/src/test/java/com/mysema/query/mongodb/domain/Item.java b/querydsl-mongodb/src/test/java/com/mysema/query/mongodb/domain/Item.java deleted file mode 100644 index 35331f35e8..0000000000 --- a/querydsl-mongodb/src/test/java/com/mysema/query/mongodb/domain/Item.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.mongodb.domain; - -import java.util.List; - -import org.bson.types.ObjectId; -import org.mongodb.morphia.annotations.Entity; - -@Entity -public class Item extends AbstractEntity { - - private List<ObjectId> ctds; - - public List<ObjectId> getCtds() { - return ctds; - } - - public void setCtds(List<ObjectId> ctds) { - this.ctds = ctds; - } - -} diff --git a/querydsl-mongodb/src/test/java/com/mysema/query/mongodb/domain/User.java b/querydsl-mongodb/src/test/java/com/mysema/query/mongodb/domain/User.java deleted file mode 100644 index a039b90ab6..0000000000 --- a/querydsl-mongodb/src/test/java/com/mysema/query/mongodb/domain/User.java +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.mongodb.domain; - -import java.util.ArrayList; -import java.util.Date; -import java.util.List; - -import org.mongodb.morphia.annotations.Embedded; -import org.mongodb.morphia.annotations.Entity; -import org.mongodb.morphia.annotations.Reference; - -@Entity -public class User extends AbstractEntity { - - public enum Gender { MALE, FEMALE } - - private String firstName; - - private String lastName; - - private Date created; - - private Gender gender; - - @Embedded - private final List<Address> addresses = new ArrayList<Address>(); - - @Embedded - private Address mainAddress; - - @Reference - private final List<User> friends = new ArrayList<User>(); - - @Reference - private User friend; - - @Reference - private User enemy; - - private int age; - - public User() { - } - - public User(String firstName, String lastName, User friend) { - this(firstName, lastName); - this.friend = friend; - } - - public User(String firstName, String lastName) { - this.firstName = firstName; this.lastName = lastName; - this.created = new Date(); - } - - public User(String firstName, String lastName, int age, Date created) { - this.firstName = firstName; this.lastName = lastName; this.age = age; this.created = created; - } - - @Override - public String toString() { - return "TestUser [id=" + getId() + ", firstName=" + firstName + ", lastName=" + lastName - + "]"; - } - - public String getFirstName() { - return firstName; - } - - public void setFirstName(String firstName) { - this.firstName = firstName; - } - - public String getLastName() { - return lastName; - } - - public void setLastName(String lastName) { - this.lastName = lastName; - } - - public Date getCreated() { - return created; - } - - public void setCreated(Date created) { - this.created = created; - } - - public int getAge() { - return age; - } - - public void setAge(int age) { - this.age = age; - } - - public Address getMainAddress() { - return mainAddress; - } - - public void setMainAddress(Address mainAddress) { - this.mainAddress = mainAddress; - } - - public void setMainAddress(String street, String postCode, City city) { - this.mainAddress = new Address(street, postCode, city); - } - - public User addAddress(Address address) { - addresses.add(address); - return this; - } - - public User addAddress(String street, String postalCode, City city) { - addresses.add(new Address(street, postalCode, city)); - return this; - } - - public List<Address> getAddresses() { - return addresses; - } - - public User addFriend(User friend) { - friends.add(friend); - return this; - } - - public List<User> getFriends() { - return friends; - } - - public Gender getGender() { - return gender; - } - - public void setGender(Gender gender) { - this.gender = gender; - } - - public User getFriend() { - return friend; - } - - public void setFriend(User friend) { - this.friend = friend; - } - - public User getEnemy() { - return enemy; - } - - public void setEnemy(User enemy) { - this.enemy = enemy; - } - -} diff --git a/querydsl-mongodb/src/test/java/com/mysema/query/mongodb/domain/UserTest.java b/querydsl-mongodb/src/test/java/com/mysema/query/mongodb/domain/UserTest.java deleted file mode 100644 index 36f4c6d47f..0000000000 --- a/querydsl-mongodb/src/test/java/com/mysema/query/mongodb/domain/UserTest.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.mongodb.domain; - -import org.bson.types.ObjectId; -import org.junit.Test; -import org.mongodb.morphia.Morphia; - -public class UserTest { - - private static final Morphia morphia = new Morphia().map(User.class); - - @Test - public void Map() { - City tampere = new City("Tampere", 61.30, 23.50); - - User user = new User(); - user.setAge(12); - user.setFirstName("Jaakko"); - user.addAddress("Aakatu", "00300", tampere); - - System.out.println(morphia.toDBObject(user)); - } - - @Test - public void Friend() { - User friend = new User(); - friend.setId(new ObjectId(1,2,3)); - - User user = new User(); - user.setFriend(friend); - - System.out.println(morphia.toDBObject(user)); - } - - @Test - public void Friends() { - User friend = new User(); - friend.setId(new ObjectId(1,2,3)); - - User user = new User(); - user.addFriend(friend); - - System.out.println(morphia.toDBObject(user)); - } - -} diff --git a/querydsl-mongodb/src/test/java/com/mysema/query/mongodb/domain/package-info.java b/querydsl-mongodb/src/test/java/com/mysema/query/mongodb/domain/package-info.java deleted file mode 100644 index efe2a7fdc2..0000000000 --- a/querydsl-mongodb/src/test/java/com/mysema/query/mongodb/domain/package-info.java +++ /dev/null @@ -1,5 +0,0 @@ -@Config(entityAccessors=true) -package com.mysema.query.mongodb.domain; - -import com.mysema.query.annotations.Config; - diff --git a/querydsl-mongodb/src/test/java/com/mysema/query/mongodb/domain2/User.java b/querydsl-mongodb/src/test/java/com/mysema/query/mongodb/domain2/User.java deleted file mode 100644 index a8eed39373..0000000000 --- a/querydsl-mongodb/src/test/java/com/mysema/query/mongodb/domain2/User.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.mongodb.domain2; - -import java.util.Map; - -import org.mongodb.morphia.annotations.Embedded; -import org.mongodb.morphia.annotations.Entity; - -@Entity(value = "USER", noClassnameStored = true) -public class User { - - @Embedded - Map<String, UserAttribute> properties; - -} \ No newline at end of file diff --git a/querydsl-mongodb/src/test/java/com/querydsl/mongodb/GeoSpatialQueryTest.java b/querydsl-mongodb/src/test/java/com/querydsl/mongodb/GeoSpatialQueryTest.java new file mode 100644 index 0000000000..f7a582cbf6 --- /dev/null +++ b/querydsl-mongodb/src/test/java/com/querydsl/mongodb/GeoSpatialQueryTest.java @@ -0,0 +1,107 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.mongodb; + +import static org.junit.Assert.assertEquals; + +import java.net.UnknownHostException; +import java.util.List; + +import org.junit.Before; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.mongodb.morphia.Datastore; +import org.mongodb.morphia.Morphia; + +import com.mongodb.MongoClient; +import com.mongodb.MongoException; +import com.querydsl.core.testutil.MongoDB; +import com.querydsl.mongodb.domain.GeoEntity; +import com.querydsl.mongodb.domain.QGeoEntity; +import com.querydsl.mongodb.morphia.MorphiaQuery; + +@Category(MongoDB.class) +public class GeoSpatialQueryTest { + + private final String dbname = "geodb"; + private final MongoClient mongo; + private final Morphia morphia; + private final Datastore ds; + private final QGeoEntity geoEntity = new QGeoEntity("geoEntity"); + + public GeoSpatialQueryTest() throws UnknownHostException, MongoException { + mongo = new MongoClient(); + morphia = new Morphia().map(GeoEntity.class); + ds = morphia.createDatastore(mongo, dbname); + } + + @Before + public void before() { + ds.delete(ds.createQuery(GeoEntity.class)); + ds.ensureIndexes(GeoEntity.class); + } + + @Test + public void near() { + ds.save(new GeoEntity(10.0, 50.0)); + ds.save(new GeoEntity(20.0, 50.0)); + ds.save(new GeoEntity(30.0, 50.0)); + + List<GeoEntity> entities = query().where(geoEntity.location.near(50.0, 50.0)).fetch(); + assertEquals(30.0, entities.get(0).getLocation()[0], 0.1); + assertEquals(20.0, entities.get(1).getLocation()[0], 0.1); + assertEquals(10.0, entities.get(2).getLocation()[0], 0.1); + } + + @Test + public void near_sphere() { + ds.save(new GeoEntity(10.0, 50.0)); + ds.save(new GeoEntity(20.0, 50.0)); + ds.save(new GeoEntity(30.0, 50.0)); + + List<GeoEntity> entities = query().where(MongodbExpressions.nearSphere(geoEntity.location, 50.0, 50.0)).fetch(); + assertEquals(30.0, entities.get(0).getLocation()[0], 0.1); + assertEquals(20.0, entities.get(1).getLocation()[0], 0.1); + assertEquals(10.0, entities.get(2).getLocation()[0], 0.1); + } + + @Test + public void geo_within_box() { + ds.save(new GeoEntity(10.0, 50.0)); + ds.save(new GeoEntity(20.0, 50.0)); + ds.save(new GeoEntity(30.0, 50.0)); + + List<GeoEntity> entities = query().where(MongodbExpressions.withinBox(geoEntity.location, 0, 0, 20, 50)).fetch(); + assertEquals(2, entities.size()); + assertEquals(10.0, entities.get(0).getLocation()[0], 0.1); + assertEquals(20.0, entities.get(1).getLocation()[0], 0.1); + + } + + @Test + public void geo_intersects() { + ds.save(new GeoEntity(10.0, 50.0)); + ds.save(new GeoEntity(20.0, 50.0)); + ds.save(new GeoEntity(30.0, 50.0)); + + List<GeoEntity> entities = query().where(MongodbExpressions.geoIntersects(geoEntity.location, 20.0, 50.0)).fetch(); + assertEquals(1, entities.size()); + assertEquals(20.0, entities.get(0).getLocation()[0], 0.1); + } + + private MorphiaQuery<GeoEntity> query() { + return new MorphiaQuery<GeoEntity>(morphia, ds, geoEntity); + } + +} diff --git a/querydsl-mongodb/src/test/java/com/querydsl/mongodb/JoinTest.java b/querydsl-mongodb/src/test/java/com/querydsl/mongodb/JoinTest.java new file mode 100644 index 0000000000..5381fea086 --- /dev/null +++ b/querydsl-mongodb/src/test/java/com/querydsl/mongodb/JoinTest.java @@ -0,0 +1,155 @@ +package com.querydsl.mongodb; + +import static org.junit.Assert.*; + +import java.net.UnknownHostException; + +import org.junit.Before; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.mongodb.morphia.Datastore; +import org.mongodb.morphia.Morphia; + +import com.mongodb.MongoClient; +import com.mongodb.MongoException; +import com.querydsl.core.testutil.MongoDB; +import com.querydsl.core.types.Predicate; +import com.querydsl.mongodb.domain.Item; +import com.querydsl.mongodb.domain.QUser; +import com.querydsl.mongodb.domain.User; +import com.querydsl.mongodb.morphia.MorphiaQuery; + +@Category(MongoDB.class) +public class JoinTest { + + private final MongoClient mongo; + private final Morphia morphia; + private final Datastore ds; + + private final String dbname = "testdb"; + private final QUser user = QUser.user; + private final QUser friend = new QUser("friend"); + private final QUser friend2 = new QUser("friend2"); + private final QUser enemy = new QUser("enemy"); + + public JoinTest() throws UnknownHostException, MongoException { + mongo = new MongoClient(); + morphia = new Morphia().map(User.class).map(Item.class); + ds = morphia.createDatastore(mongo, dbname); + } + + @Before + public void before() throws UnknownHostException, MongoException { + ds.delete(ds.createQuery(User.class)); + + User friend1 = new User("Max", null); + User friend2 = new User("Jack", null); + User friend3 = new User("Bob", null); + ds.save(friend1, friend2, friend3); + + User user1 = new User("Jane", null, friend1); + User user2 = new User("Mary", null, user1); + User user3 = new User("Ann", null, friend3); + ds.save(user1, user2, user3); + + User user4 = new User("Mike", null); + user4.setFriend(user2); + user4.setEnemy(user3); + ds.save(user4); + + User user5 = new User("Bart", null); + user5.addFriend(user2); + user5.addFriend(user3); + ds.save(user5); + + } + + @Test + public void count() { + assertEquals(1, where().join(user.friend(), friend).on(friend.firstName.eq("Max")).fetchCount()); + assertEquals(1, where(user.firstName.eq("Jane")).join(user.friend(), friend).on(friend.firstName.eq("Max")).fetchCount()); + assertEquals(0, where(user.firstName.eq("Mary")).join(user.friend(), friend).on(friend.firstName.eq("Max")).fetchCount()); + assertEquals(0, where(user.firstName.eq("Jane")).join(user.friend(), friend).on(friend.firstName.eq("Jack")).fetchCount()); + } + + @Test + public void count_collection() { + assertEquals(1, where().join(user.friends, friend).on(friend.firstName.eq("Mary")).fetchCount()); + assertEquals(1, where().join(user.friends, friend).on(friend.firstName.eq("Ann")).fetchCount()); + assertEquals(1, where().join(user.friends, friend).on(friend.firstName.eq("Ann").or(friend.firstName.eq("Mary"))).fetchCount()); + assertEquals(1, where(user.firstName.eq("Bart")).join(user.friends, friend).on(friend.firstName.eq("Mary")).fetchCount()); + assertEquals(0, where().join(user.friends, friend).on(friend.firstName.eq("Max")).fetchCount()); + } + + @Test + public void exists() { + assertTrue(where().join(user.friend(), friend).on(friend.firstName.eq("Max")).fetchCount() > 0); + assertTrue(where(user.firstName.eq("Jane")).join(user.friend(), friend).on(friend.firstName.eq("Max")).fetchCount() > 0); + assertFalse(where(user.firstName.eq("Mary")).join(user.friend(), friend).on(friend.firstName.eq("Max")).fetchCount() > 0); + assertFalse(where(user.firstName.eq("Jane")).join(user.friend(), friend).on(friend.firstName.eq("Jack")).fetchCount() > 0); + } + + @Test + public void exists_collection() { + assertTrue(where().join(user.friends, friend).on(friend.firstName.eq("Mary")).fetchCount() > 0); + assertTrue(where(user.firstName.eq("Bart")).join(user.friends, friend).on(friend.firstName.eq("Mary")).fetchCount() > 0); + } + + @Test + public void list() { + assertEquals(1, where().join(user.friend(), friend).on(friend.firstName.eq("Max")).fetch().size()); + assertEquals(1, where(user.firstName.eq("Jane")).join(user.friend(), friend).on(friend.firstName.eq("Max")).fetch().size()); + assertEquals(0, where(user.firstName.eq("Mary")).join(user.friend(), friend).on(friend.firstName.eq("Max")).fetch().size()); + assertEquals(0, where(user.firstName.eq("Jane")).join(user.friend(), friend).on(friend.firstName.eq("Jack")).fetch().size()); + } + + public void list_collection() { + assertEquals(1, where().join(user.friends, friend).on(friend.firstName.eq("Mary")).fetch().size()); + } + + @Test + public void single() { + assertEquals("Jane", where().join(user.friend(), friend).on(friend.firstName.eq("Max")).fetchFirst().getFirstName()); + assertEquals("Jane", where(user.firstName.eq("Jane")).join(user.friend(), friend).on(friend.firstName.eq("Max")).fetchFirst().getFirstName()); + assertNull(where(user.firstName.eq("Mary")).join(user.friend(), friend).on(friend.firstName.eq("Max")).fetchFirst()); + assertNull(where(user.firstName.eq("Jane")).join(user.friend(), friend).on(friend.firstName.eq("Jack")).fetchFirst()); + } + + @Test + public void single_collection() { + assertEquals("Bart", where().join(user.friends, friend).on(friend.firstName.eq("Mary")).fetchFirst().getFirstName()); + } + + @Test + public void double1() { + assertEquals("Mike", where() + .join(user.friend(), friend).on(friend.firstName.isNotNull()) + .join(user.enemy(), enemy).on(enemy.firstName.isNotNull()) + .fetchFirst().getFirstName()); + } + + @Test + public void double2() { + assertEquals("Mike", where() + .join(user.friend(), friend).on(friend.firstName.eq("Mary")) + .join(user.enemy(), enemy).on(enemy.firstName.eq("Ann")) + .fetchFirst().getFirstName()); + } + + @Test + public void deep() { + // Mike -> Mary -> Jane + assertEquals("Mike", where() + .join(user.friend(), friend).on(friend.firstName.isNotNull()) + .join(friend.friend(), friend2).on(friend2.firstName.eq("Jane")) + .fetchFirst().getFirstName()); + } + + private MorphiaQuery<User> query() { + return new MorphiaQuery<User>(morphia, ds, user); + } + + private MorphiaQuery<User> where(Predicate... e) { + return query().where(e); + } +} diff --git a/querydsl-mongodb/src/test/java/com/querydsl/mongodb/MongodbQueryTest.java b/querydsl-mongodb/src/test/java/com/querydsl/mongodb/MongodbQueryTest.java new file mode 100644 index 0000000000..396549ae8e --- /dev/null +++ b/querydsl-mongodb/src/test/java/com/querydsl/mongodb/MongodbQueryTest.java @@ -0,0 +1,701 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.mongodb; + +import static java.util.Arrays.asList; +import static org.junit.Assert.*; + +import java.net.UnknownHostException; +import java.util.*; + +import org.bson.types.ObjectId; +import org.junit.Before; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.mongodb.morphia.Datastore; +import org.mongodb.morphia.Morphia; + +import com.mongodb.BasicDBObject; +import com.mongodb.MongoClient; +import com.mongodb.MongoException; +import com.mongodb.ReadPreference; +import com.querydsl.core.NonUniqueResultException; +import com.querydsl.core.QueryResults; +import com.querydsl.core.testutil.MongoDB; +import com.querydsl.core.types.EntityPath; +import com.querydsl.core.types.OrderSpecifier; +import com.querydsl.core.types.Predicate; +import com.querydsl.core.types.dsl.ListPath; +import com.querydsl.core.types.dsl.StringPath; +import com.querydsl.mongodb.domain.*; +import com.querydsl.mongodb.domain.User.Gender; +import com.querydsl.mongodb.morphia.MorphiaQuery; + +@Category(MongoDB.class) +public class MongodbQueryTest { + + private final MongoClient mongo; + private final Morphia morphia; + private final Datastore ds; + + private final String dbname = "testdb"; + private final QUser user = QUser.user; + private final QItem item = QItem.item; + private final QAddress address = QAddress.address; + private final QMapEntity mapEntity = QMapEntity.mapEntity; + private final QDates dates = QDates.dates; + private final QCountry country = QCountry.country; + + List<User> users = new ArrayList<>(); + User u1, u2, u3, u4; + City tampere, helsinki; + + public MongodbQueryTest() throws UnknownHostException, MongoException { + mongo = new MongoClient(); + morphia = new Morphia().map(User.class).map(Item.class).map(MapEntity.class).map(Dates.class); + ds = morphia.createDatastore(mongo, dbname); + } + + @Before + public void before() throws UnknownHostException, MongoException { + ds.delete(ds.createQuery(Item.class)); + ds.delete(ds.createQuery(User.class)); + ds.delete(ds.createQuery(Country.class)); + ds.delete(ds.createQuery(MapEntity.class)); + + tampere = new City("Tampere", 61.30, 23.50); + helsinki = new City("Helsinki", 60.15, 20.03); + + u1 = addUser("Jaakko", "Jantunen", 20, new Address("Aakatu", "00100", helsinki), + new Address("Aakatu1", "00100", helsinki), + new Address("Aakatu2", "00100", helsinki)); + u2 = addUser("Jaakki", "Jantunen", 30, new Address("Beekatu", "00200", helsinki)); + u3 = addUser("Jaana", "Aakkonen", 40, new Address("Ceekatu","00300", tampere)); + u4 = addUser("Jaana", "BeekkoNen", 50, new Address("Deekatu","00400",tampere)); + + // order users by lastname, firstname + users = Arrays.asList(u3, u4, u2, u1); + } + + @Test + public void query1() { + assertEquals(4L, query(user).fetchCount()); + assertEquals(4L, query(User.class).fetchCount()); + } + + @Test + public void list_keys() { + User u = where(user.firstName.eq("Jaakko")).fetch(user.firstName, user.mainAddress().street).get(0); + assertEquals("Jaakko", u.getFirstName()); + assertNull(u.getLastName()); + assertEquals("Aakatu", u.getMainAddress().street); + assertNull(u.getMainAddress().postCode); + } + + @Test + public void singleResult_keys() { + User u = where(user.firstName.eq("Jaakko")).fetchFirst(user.firstName); + assertEquals("Jaakko", u.getFirstName()); + assertNull(u.getLastName()); + } + + @Test + public void uniqueResult_keys() { + User u = where(user.firstName.eq("Jaakko")).fetchOne(user.firstName); + assertEquals("Jaakko", u.getFirstName()); + assertNull(u.getLastName()); + } + + @Test + public void list_deep_keys() { + User u = where(user.firstName.eq("Jaakko")).fetchFirst(user.addresses.any().street); + for (Address a : u.getAddresses()) { + assertNotNull(a.street); + assertNull(a.city); + } + } + + @Test + public void between() { + assertQuery(user.age.between(20, 30), u2, u1); + assertQuery(user.age.goe(20).and(user.age.loe(30)), u2, u1); + } + + @Test + public void between_not() { + assertQuery(user.age.between(20, 30).not(), u3, u4); + assertQuery(user.age.goe(20).and(user.age.loe(30)).not(), u3, u4); + } + + @Test + public void contains() { + assertQuery(user.friends.contains(u1), u3, u4, u2); + } + + @Test + public void contains2() { + assertQuery(user.friends.contains(u4)); + } + + @Test + public void notContains() { + assertQuery(user.friends.contains(u1).not(), u1); + } + + @Test + public void contains_key() { + MapEntity entity = new MapEntity(); + entity.getProperties().put("key", "value"); + ds.save(entity); + + assertTrue(query(mapEntity).where(mapEntity.properties.get("key").isNotNull()).fetchCount() > 0); + assertFalse(query(mapEntity).where(mapEntity.properties.get("key2").isNotNull()).fetchCount() > 0); + + assertTrue(query(mapEntity).where(mapEntity.properties.containsKey("key")).fetchCount() > 0); + assertFalse(query(mapEntity).where(mapEntity.properties.containsKey("key2")).fetchCount() > 0); + } + + @Test + public void contains_key_not() { + MapEntity entity = new MapEntity(); + entity.getProperties().put("key", "value"); + ds.save(entity); + + assertFalse(query(mapEntity).where(mapEntity.properties.get("key").isNotNull().not()).fetchCount() > 0); + assertTrue(query(mapEntity).where(mapEntity.properties.get("key2").isNotNull().not()).fetchCount() > 0); + + assertFalse(query(mapEntity).where(mapEntity.properties.containsKey("key").not()).fetchCount() > 0); + assertTrue(query(mapEntity).where(mapEntity.properties.containsKey("key2").not()).fetchCount() > 0); + } + + @Test + public void equals_ignore_case() { + assertTrue(where(user.firstName.equalsIgnoreCase("jAaKko")).fetchCount() > 0); + assertFalse(where(user.firstName.equalsIgnoreCase("AaKk")).fetchCount() > 0); + } + + @Test + public void equals_ignore_case_not() { + assertTrue(where(user.firstName.equalsIgnoreCase("jAaKko").not()).fetchCount() > 0); + assertTrue(where(user.firstName.equalsIgnoreCase("AaKk").not()).fetchCount() > 0); + } + + @Test + public void equals_and_between() { + assertQuery(user.firstName.startsWith("Jaa").and(user.age.between(20, 30)), u2, u1); + assertQuery(user.firstName.startsWith("Jaa").and(user.age.goe(20).and(user.age.loe(30))), u2, u1); + } + + @Test + public void equals_and_between_not() { + assertQuery(user.firstName.startsWith("Jaa").and(user.age.between(20, 30)).not(), u3, u4); + assertQuery(user.firstName.startsWith("Jaa").and(user.age.goe(20).and(user.age.loe(30))).not(), u3, u4); + } + + @Test + public void exists() { + assertTrue(where(user.firstName.eq("Jaakko")).fetchCount() > 0); + assertFalse(where(user.firstName.eq("JaakkoX")).fetchCount() > 0); + assertTrue(where(user.id.eq(u1.getId())).fetchCount() > 0); + } + + @Test + public void find_by_id() { + assertNotNull(where(user.id.eq(u1.getId())).fetchFirst() != null); + } + + @Test + public void notExists() { + assertFalse(where(user.firstName.eq("Jaakko")).fetchCount() == 0); + assertTrue(where(user.firstName.eq("JaakkoX")).fetchCount() == 0); + } + + @Test + public void uniqueResult() { + assertEquals("Jantunen", where(user.firstName.eq("Jaakko")).fetchOne().getLastName()); + } + + @Test(expected = NonUniqueResultException.class) + public void uniqueResultContract() { + where(user.firstName.isNotNull()).fetchOne(); + } + + @Test + public void singleResult() { + where(user.firstName.isNotNull()).fetchFirst(); + } + + @Test + public void longPath() { + assertEquals(2, query().where(user.mainAddress().city().name.eq("Helsinki")).fetchCount()); + assertEquals(2, query().where(user.mainAddress().city().name.eq("Tampere")).fetchCount()); + } + + @Test + public void collectionPath() { + assertEquals(1, query().where(user.addresses.any().street.eq("Aakatu1")).fetchCount()); + assertEquals(0, query().where(user.addresses.any().street.eq("akatu")).fetchCount()); + } + + @Test + public void dates() { + long current = System.currentTimeMillis(); + int dayInMillis = 24 * 60 * 60 * 1000; + Date start = new Date(current); + ds.delete(ds.createQuery(Dates.class)); + Dates d = new Dates(); + d.setDate(new Date(current + dayInMillis)); + ds.save(d); + Date end = new Date(current + 2 * dayInMillis); + + assertEquals(d, query(dates).where(dates.date.between(start, end)).fetchFirst()); + assertEquals(0, query(dates).where(dates.date.between(new Date(0), start)).fetchCount()); + } + + @Test + public void elemMatch() { +// { "addresses" : { "$elemMatch" : { "street" : "Aakatu1"}}} + assertEquals(1, query().anyEmbedded(user.addresses, address).on(address.street.eq("Aakatu1")).fetchCount()); +// { "addresses" : { "$elemMatch" : { "street" : "Aakatu1", "postCode" : "00100"}}} + assertEquals(1, query().anyEmbedded(user.addresses, address).on(address.street.eq("Aakatu1"), address.postCode.eq("00100")).fetchCount()); +// { "addresses" : { "$elemMatch" : { "street" : "akatu"}}} + assertEquals(0, query().anyEmbedded(user.addresses, address).on(address.street.eq("akatu")).fetchCount()); +// { "addresses" : { "$elemMatch" : { "street" : "Aakatu1", "postCode" : "00200"}}} + assertEquals(0, query().anyEmbedded(user.addresses, address).on(address.street.eq("Aakatu1"), address.postCode.eq("00200")).fetchCount()); + } + + @Test + public void indexedAccess() { + assertEquals(1, query().where(user.addresses.get(0).street.eq("Aakatu1")).fetchCount()); + assertEquals(0, query().where(user.addresses.get(1).street.eq("Aakatu1")).fetchCount()); + } + + @Test + public void count() { + assertEquals(4, query().fetchCount()); + } + + @Test + public void order() { + List<User> users = query().orderBy(user.age.asc()).fetch(); + assertEquals(asList(u1, u2, u3, u4), users); + + users = query().orderBy(user.age.desc()).fetch(); + assertEquals(asList(u4, u3, u2, u1), users); + } + + @Test + public void restrict() { + assertEquals(asList(u1, u2), query().limit(2).orderBy(user.age.asc()).fetch()); + assertEquals(asList(u2, u3), query().limit(2).offset(1).orderBy(user.age.asc()).fetch()); + } + + @Test + public void listResults() { + QueryResults<User> results = query().limit(2).orderBy(user.age.asc()).fetchResults(); + assertEquals(4L, results.getTotal()); + assertEquals(2, results.getResults().size()); + + results = query().offset(2).orderBy(user.age.asc()).fetchResults(); + assertEquals(4L, results.getTotal()); + assertEquals(2, results.getResults().size()); + } + + @Test + public void emptyResults() { + QueryResults<User> results = query().where(user.firstName.eq("XXX")).fetchResults(); + assertEquals(0L, results.getTotal()); + assertEquals(Collections.emptyList(), results.getResults()); + } + + @Test + public void eqInAndOrderByQueries() { + assertQuery(user.firstName.eq("Jaakko"), u1); + assertQuery(user.firstName.equalsIgnoreCase("jaakko"), u1); + assertQuery(user.lastName.eq("Aakkonen"), u3); + + assertQuery(user.firstName.in("Jaakko","Teppo"), u1); + assertQuery(user.lastName.in("Aakkonen","BeekkoNen"), u3, u4); + + assertQuery(user.firstName.eq("Jouko")); + + assertQuery(user.firstName.eq("Jaana"), user.lastName.asc(), u3, u4); + assertQuery(user.firstName.eq("Jaana"), user.lastName.desc(), u4, u3); + assertQuery(user.lastName.eq("Jantunen"), user.firstName.asc(), u2, u1); + assertQuery(user.lastName.eq("Jantunen"), user.firstName.desc(), u1, u2); + + assertQuery(user.firstName.eq("Jaana").and(user.lastName.eq("Aakkonen")), u3); + //This should produce 'and' also + assertQuery(where(user.firstName.eq("Jaana"), user.lastName.eq("Aakkonen")), u3); + + assertQuery(user.firstName.ne("Jaana"), u2, u1); + } + + @Test + public void regexQueries() { + assertQuery(user.firstName.startsWith("Jaan"), u3, u4); + assertQuery(user.firstName.startsWith("jaan")); + assertQuery(user.firstName.startsWithIgnoreCase("jaan"), u3, u4); + + assertQuery(user.lastName.endsWith("unen"), u2, u1); + + assertQuery(user.lastName.endsWithIgnoreCase("onen"), u3, u4); + + assertQuery(user.lastName.contains("oN"), u4); + assertQuery(user.lastName.containsIgnoreCase("on"), u3, u4); + + assertQuery(user.firstName.matches(".*aa.*[^i]$"), u3, u4, u1); + } + + @Test + public void regexQueries_not() { + assertQuery(user.firstName.startsWith("Jaan").not(), u2, u1); + assertQuery(user.firstName.startsWith("jaan").not(), u3, u4, u2, u1); + assertQuery(user.firstName.startsWithIgnoreCase("jaan").not(), u2, u1); + + assertQuery(user.lastName.endsWith("unen").not(), u3, u4); + + assertQuery(user.lastName.endsWithIgnoreCase("onen").not(), u2, u1); + + assertQuery(user.lastName.contains("oN").not(), u3, u2, u1); + assertQuery(user.lastName.containsIgnoreCase("on").not(), u2, u1); + + assertQuery(user.firstName.matches(".*aa.*[^i]$").not(), u2); + } + + @Test + public void like() { + assertQuery(user.firstName.like("Jaan")); + assertQuery(user.firstName.like("Jaan%"), u3, u4); + assertQuery(user.firstName.like("jaan%")); + + assertQuery(user.lastName.like("%unen"), u2, u1); + } + + @Test + public void like_not() { + assertQuery(user.firstName.like("Jaan").not(), u3, u4, u2, u1); + assertQuery(user.firstName.like("Jaan%").not(), u2, u1); + assertQuery(user.firstName.like("jaan%").not(), u3, u4, u2, u1); + + assertQuery(user.lastName.like("%unen").not(), u3, u4); + } + + @Test + public void likeIgnoreCase() { + assertQuery(user.firstName.likeIgnoreCase("JAAN")); + assertQuery(user.firstName.likeIgnoreCase("Jaan%"), u3, u4); + assertQuery(user.firstName.likeIgnoreCase("JAAN%"), u3, u4); + assertQuery(user.firstName.likeIgnoreCase("jaan%"), u3, u4); + + assertQuery(user.lastName.likeIgnoreCase("%unen"), u2, u1); + assertQuery(user.lastName.likeIgnoreCase("%UNEN"), u2, u1); + } + + @Test + public void likeIgnoreCase_not() { + assertQuery(user.firstName.likeIgnoreCase("Jaan").not(), u3, u4, u2, u1); + assertQuery(user.firstName.likeIgnoreCase("Jaan%").not(), u2, u1); + assertQuery(user.firstName.likeIgnoreCase("JAAN%").not(), u2, u1); + assertQuery(user.firstName.likeIgnoreCase("jaan%").not(), u2, u1); + + assertQuery(user.lastName.likeIgnoreCase("%unen").not(), u3, u4); + assertQuery(user.lastName.likeIgnoreCase("%UNEN").not(), u3, u4); + } + + @Test + public void isNotNull() { + assertQuery(user.firstName.isNotNull(), u3, u4, u2, u1); + } + + @Test + public void isNotNull_not() { + assertQuery(user.firstName.isNotNull().not()); + } + + @Test + public void isNull() { + assertQuery(user.firstName.isNull()); + } + + @Test + public void isNull_not() { + assertQuery(user.firstName.isNull().not(), u3, u4, u2, u1); + } + + @Test + public void isEmpty() { + assertQuery(user.firstName.isEmpty()); + assertQuery(user.friends.isEmpty(), u1); + } + + @Test + public void isEmpty_not() { + assertQuery(user.firstName.isEmpty().not(), u3, u4, u2, u1); + assertQuery(user.friends.isEmpty().not(), u3, u4, u2); + } + + @Test + public void not() { + assertQuery(user.firstName.eq("Jaakko").not(), u3, u4, u2); + assertQuery(user.firstName.ne("Jaakko").not(), u1); + assertQuery(user.firstName.matches("Jaakko").not(), u3, u4, u2); + assertQuery(user.friends.isNotEmpty(), u3, u4, u2); + } + + @Test + public void or() { + assertQuery(user.lastName.eq("Aakkonen").or(user.lastName.eq("BeekkoNen")), u3, u4); + } + + @Test + public void or_not() { + assertQuery(user.lastName.eq("Aakkonen").or(user.lastName.eq("BeekkoNen")).not(), u2, u1); + } + + @Test + public void iterate() { + User a = addUser("A", "A"); + User b = addUser("A1", "B"); + User c = addUser("A2", "C"); + + Iterator<User> i = where(user.firstName.startsWith("A")) + .orderBy(user.firstName.asc()) + .iterate(); + + assertEquals(a, i.next()); + assertEquals(b, i.next()); + assertEquals(c, i.next()); + assertEquals(false, i.hasNext()); + } + + @Test + public void uniqueResultAndLimitAndOffset() { + MorphiaQuery<User> q = query().where(user.firstName.startsWith("Ja")).orderBy(user.age.asc()); + assertEquals(4, q.fetch().size()); + assertEquals(u1, q.fetch().get(0)); + } + + @Test + public void references() { + for (User u : users) { + if (u.getFriend() != null) { + assertQuery(user.friend().eq(u.getFriend()), u); + assertQuery(user.friend().id.eq(u.getFriend().getId()), u); + assertQuery(user.friend().ne(u.getFriend()), otherUsers(u)); + assertQuery(user.friend().id.ne(u.getFriend().getId()), otherUsers(u)); + } + } + } + + @Test + public void references2() { + for (User u : users) { + if (u.getFriend() != null) { + assertQuery(user.enemy().eq(u.getEnemy()), u); + assertQuery(user.enemy().id.eq(u.getEnemy().getId()), u); + assertQuery(user.enemy().ne(u.getEnemy()), otherUsers(u)); + assertQuery(user.enemy().id.ne(u.getEnemy().getId()), otherUsers(u)); + } + } + } + + private User[] otherUsers(User user) { + List<User> list = new ArrayList<>(); + for (User u : users) { + if (!u.equals(user)) { + list.add(u); + } + } + return list.toArray(new User[0]); + } + + @Test + public void various() { + ListPath<Address, QAddress> list = user.addresses; + StringPath str = user.lastName; + List<Predicate> predicates = new ArrayList<Predicate>(); + predicates.add(str.between("a", "b")); + predicates.add(str.contains("a")); + predicates.add(str.containsIgnoreCase("a")); + predicates.add(str.endsWith("a")); + predicates.add(str.endsWithIgnoreCase("a")); + predicates.add(str.eq("a")); + predicates.add(str.equalsIgnoreCase("a")); + predicates.add(str.goe("a")); + predicates.add(str.gt("a")); + predicates.add(str.in("a","b","c")); + predicates.add(str.isEmpty()); + predicates.add(str.isNotNull()); + predicates.add(str.isNull()); + predicates.add(str.like("a")); + predicates.add(str.loe("a")); + predicates.add(str.lt("a")); + predicates.add(str.matches("a")); + predicates.add(str.ne("a")); + predicates.add(str.notBetween("a", "b")); + predicates.add(str.notIn("a","b","c")); + predicates.add(str.startsWith("a")); + predicates.add(str.startsWithIgnoreCase("a")); + predicates.add(list.isEmpty()); + predicates.add(list.isNotEmpty()); + + for (Predicate predicate : predicates) { + long count1 = where(predicate).fetchCount(); + long count2 = where(predicate.not()).fetchCount(); + assertEquals(predicate.toString(), 4, count1 + count2); + } + } + + @Test + public void enum_eq() { + assertQuery(user.gender.eq(Gender.MALE), u3, u4, u2, u1); + } + + @Test + public void enum_ne() { + assertQuery(user.gender.ne(Gender.MALE)); + } + + @Test + public void in_objectIds() { + Item i = new Item(); + i.setCtds(Arrays.asList(ObjectId.get(), ObjectId.get(), ObjectId.get())); + ds.save(i); + + assertTrue(where(item, item.ctds.contains(i.getCtds().get(0))).fetchCount() > 0); + assertTrue(where(item, item.ctds.contains(ObjectId.get())).fetchCount() == 0); + } + + @Test + public void in_objectIds2() { + Item i = new Item(); + i.setCtds(Arrays.asList(ObjectId.get(), ObjectId.get(), ObjectId.get())); + ds.save(i); + + assertTrue(where(item, item.ctds.any().in(i.getCtds())).fetchCount() > 0); + assertTrue(where(item, item.ctds.any().in(Arrays.asList(ObjectId.get(), ObjectId.get()))).fetchCount() == 0); + } + + @Test + public void size() { + assertQuery(user.addresses.size().eq(2), u1); + } + + @Test + public void size_not() { + assertQuery(user.addresses.size().eq(2).not(), u3, u4, u2); + } + + @Test + public void readPreference() { + MorphiaQuery<User> query = query(); + query.setReadPreference(ReadPreference.primary()); + assertEquals(4, query.fetchCount()); + } + + @Test + public void asDBObject() { + MorphiaQuery<User> query = query(); + query.where(user.firstName.eq("Bob"), user.lastName.eq("Wilson")); + assertEquals( + new BasicDBObject().append("firstName", "Bob").append("lastName", "Wilson"), + query.asDBObject()); + } + + @Test + public void converter() { + Country germany = new Country("Germany", Locale.GERMANY); + ds.save(germany); + + Country fetchedCountry = query(Country.class).where(country.defaultLocale.eq(Locale.GERMANY)).fetchOne(); + assertEquals(germany, fetchedCountry); + } + + //TODO + // - test dates + // - test with empty values and nulls + // - test more complex ands + + private void assertQuery(Predicate e, User... expected) { + assertQuery(where(e).orderBy(user.lastName.asc(), user.firstName.asc()), expected); + } + + private void assertQuery(Predicate e, OrderSpecifier<?> orderBy, User... expected) { + assertQuery(where(e).orderBy(orderBy), expected); + } + + private <T> MorphiaQuery<T> where(EntityPath<T> entity, Predicate... e) { + return new MorphiaQuery<T>(morphia, ds, entity).where(e); + } + + private MorphiaQuery<User> where(Predicate... e) { + return query().where(e); + } + + private MorphiaQuery<User> query() { + return new MorphiaQuery<User>(morphia, ds, user); + } + + private <T> MorphiaQuery<T> query(EntityPath<T> path) { + return new MorphiaQuery<T>(morphia, ds, path); + } + + + private <T> MorphiaQuery<T> query(Class<? extends T> clazz) { + return new MorphiaQuery<T>(morphia, ds, clazz); + } + + private void assertQuery(MorphiaQuery<User> query, User... expected) { + String toString = query.toString(); + List<User> results = query.fetch(); + + assertNotNull(toString, results); + if (expected == null) { + assertEquals("Should get empty result", 0, results.size()); + return; + } + assertEquals(toString, expected.length, results.size()); + int i = 0; + for (User u : expected) { + assertEquals(toString, u, results.get(i++)); + } + } + + private User addUser(String first, String last) { + User user = new User(first, last); + ds.save(user); + return user; + } + + private User addUser(String first, String last, int age, Address mainAddress, Address... addresses) { + User user = new User(first, last, age, new Date()); + user.setGender(Gender.MALE); + user.setMainAddress(mainAddress); + for (Address address : addresses) { + user.addAddress(address); + } + for (User u : users) { + user.addFriend(u); + } + if (!users.isEmpty()) { + user.setFriend(users.get(users.size() - 1)); + user.setEnemy(users.get(users.size() - 1)); + } + ds.save(user); + users.add(user); + return user; + } + +} diff --git a/querydsl-mongodb/src/test/java/com/querydsl/mongodb/MongodbSerializerTest.java b/querydsl-mongodb/src/test/java/com/querydsl/mongodb/MongodbSerializerTest.java new file mode 100644 index 0000000000..11edf23acb --- /dev/null +++ b/querydsl-mongodb/src/test/java/com/querydsl/mongodb/MongodbSerializerTest.java @@ -0,0 +1,311 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.mongodb; + +import com.mongodb.BasicDBList; +import com.mongodb.BasicDBObject; +import com.mongodb.DBObject; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.OrderSpecifier; +import com.querydsl.core.types.dsl.*; +import com.querydsl.mongodb.domain.*; +import com.querydsl.mongodb.morphia.MorphiaSerializer; +import org.bson.types.ObjectId; +import org.junit.Before; +import org.junit.Test; +import org.mongodb.morphia.Morphia; + +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.List; + +import static org.junit.Assert.assertEquals; + +public class MongodbSerializerTest { + + private PathBuilder<Object> entityPath; + private StringPath title; + private NumberPath<Integer> year; + private NumberPath<Double> gross; + + private NumberPath<Long> longField; + private NumberPath<Short> shortField; + private NumberPath<Byte> byteField; + private NumberPath<Float> floatField; + + private DatePath<Date> date; + private final Date dateVal = new Date(); + private DateTimePath<Timestamp> dateTime; + private final Timestamp dateTimeVal = new Timestamp(System.currentTimeMillis()); + + private MongodbSerializer serializer; + + @Before + public void before() { + serializer = new MorphiaSerializer(new Morphia()); + entityPath = new PathBuilder<Object>(Object.class, "obj"); + title = entityPath.getString("title"); + year = entityPath.getNumber("year", Integer.class); + gross = entityPath.getNumber("gross", Double.class); + longField = entityPath.getNumber("longField", Long.class); + shortField = entityPath.getNumber("shortField", Short.class); + byteField = entityPath.getNumber("byteField", Byte.class); + floatField = entityPath.getNumber("floatField", Float.class); + date = entityPath.getDate("date", Date.class); + dateTime = entityPath.getDateTime("dateTime", Timestamp.class); + } + + @Test + public void paths() { + QUser user = QUser.user; + assertEquals("user", serializer.visit(user, null)); + assertEquals("addresses", serializer.visit(user.addresses, null)); + assertEquals("addresses", serializer.visit(user.addresses.any(), null)); + assertEquals("addresses.street", serializer.visit(user.addresses.any().street, null)); + assertEquals("firstName", serializer.visit(user.firstName, null)); + } + + @Test + public void propertyAnnotation() { + QDummyEntity entity = QDummyEntity.dummyEntity; + assertEquals("prop", serializer.visit(entity.property, null)); + } + + @Test + public void indexedAccess() { + QUser user = QUser.user; + assertEquals("addresses.0.street", serializer.visit(user.addresses.get(0).street, null)); + } + + @Test + public void collectionAny() { + QUser user = QUser.user; + assertQuery(user.addresses.any().street.eq("Aakatu"), dbo("addresses.street", "Aakatu")); + } + + @Test + public void collectionIsEmpty() { + BasicDBObject expected = dbo("$or", + dblist( + dbo("addresses", dblist()), + dbo("addresses", + dbo("$exists", false)))); + assertQuery(QUser.user.addresses.isEmpty(), expected); + } + + @Test + public void collectionIsNotEmpty() { + BasicDBObject expected = dbo("$nor", + dblist( + dbo("addresses", dblist()), + dbo("addresses", + dbo("$exists", false)))); + assertQuery(QUser.user.addresses.isNotEmpty(), expected); + } + + @Test + public void equals() { + assertQuery(title.eq("A"), dbo("title", "A")); + assertQuery(year.eq(1), dbo("year", 1)); + assertQuery(gross.eq(1.0D), dbo("gross", 1.0D)); + assertQuery(longField.eq(1L), dbo("longField", 1L)); + assertQuery(shortField.eq((short) 1), dbo("shortField", 1)); + assertQuery(byteField.eq((byte) 1), dbo("byteField", (byte) 1)); + assertQuery(floatField.eq(1.0F), dbo("floatField", 1.0F)); + + assertQuery(date.eq(dateVal), dbo("date", dateVal)); + assertQuery(dateTime.eq(dateTimeVal), dbo("dateTime", dateTimeVal)); + } + + @Test + public void eqAndEq() { + assertQuery( + title.eq("A").and(year.eq(1)), + dbo("title", "A").append("year", 1) + ); + + assertQuery( + title.eq("A").and(year.eq(1).and(gross.eq(1.0D))), + dbo("title", "A").append("year", 1).append("gross", 1.0D) + ); + } + + @Test + public void notEq() { + assertQuery(title.ne("A"), dbo("title", dbo("$ne", "A"))); + } + + @Test + public void between() { + assertQuery(year.between(1, 10), dbo("year", dbo("$gte", 1).append("$lte", 10))); + } + + @Test + public void lessAndGreaterAndBetween() { + assertQuery(title.lt("A"), dbo("title", dbo("$lt", "A"))); + assertQuery(year.gt(1), dbo("year", dbo("$gt", 1))); + + assertQuery(title.loe("A"), dbo("title", dbo("$lte", "A"))); + assertQuery(year.goe(1), dbo("year", dbo("$gte", 1))); + + assertQuery( + year.gt(1).and(year.lt(10)), + dbo("$and", dblist( + dbo("year", dbo("$gt", 1)), + dbo("year", dbo("$lt", 10)))) + ); + + assertQuery( + year.between(1, 10), + dbo("year", dbo("$gte", 1).append("$lte", 10)) + ); + } + + @Test + public void in() { + assertQuery(year.in(1, 2, 3), dbo("year", dbo("$in", 1, 2, 3))); + } + + @Test + public void notIn() { + assertQuery(year.in(1, 2, 3).not(), dbo("year", dbo("$nin", 1, 2, 3))); + assertQuery(year.notIn(1, 2, 3), dbo("year", dbo("$nin", 1, 2, 3))); + } + + @Test + public void orderBy() { + DBObject orderBy = serializer.toSort(sortList(year.asc())); + assertEquals(dbo("year", 1), orderBy); + + orderBy = serializer.toSort(sortList(year.desc())); + assertEquals(dbo("year", -1), orderBy); + + orderBy = serializer.toSort(sortList(year.desc(), title.asc())); + assertEquals(dbo("year", -1).append("title", 1), orderBy); + } + + @Test + public void regexCases() { + assertQuery(title.startsWith("A"), + dbo("title", dbo("$regex", "^\\QA\\E").append("$options", ""))); + assertQuery(title.startsWithIgnoreCase("A"), + dbo("title", dbo("$regex", "^\\QA\\E").append("$options", "i"))); + + assertQuery(title.endsWith("A"), + dbo("title", dbo("$regex", "\\QA\\E$").append("$options", ""))); + assertQuery(title.endsWithIgnoreCase("A"), + dbo("title", dbo("$regex", "\\QA\\E$").append("$options", "i"))); + + assertQuery(title.equalsIgnoreCase("A"), + dbo("title", dbo("$regex", "^\\QA\\E$").append("$options", "i"))); + + assertQuery(title.contains("A"), + dbo("title", dbo("$regex", ".*\\QA\\E.*").append("$options", ""))); + assertQuery(title.containsIgnoreCase("A"), + dbo("title", dbo("$regex", ".*\\QA\\E.*").append("$options", "i"))); + + assertQuery(title.matches(".*A^"), + dbo("title", dbo("$regex", ".*A^").append("$options", ""))); + + } + + @Test + public void and() { + assertQuery( + title.startsWithIgnoreCase("a").and(title.endsWithIgnoreCase("b")), + + dbo("$and", dblist( + dbo("title", dbo("$regex", "^\\Qa\\E").append("$options", "i")), + dbo("title", dbo("$regex", "\\Qb\\E$").append("$options", "i"))))); + + } + + @Test + public void near() { + assertQuery(MongodbExpressions.near(new Point("point"), 1.0, 2.0), + dbo("point", dbo("$near", dblist(1.0, 2.0)))); + } + + @Test + public void near_sphere() { + assertQuery(MongodbExpressions.nearSphere(new Point("point"), 1.0, 2.0), + dbo("point", dbo("$nearSphere", dblist(1.0, 2.0)))); + } + + @Test + public void all() { + QItem item = QItem.item; + List<ObjectId> objectIds = new ArrayList<>(); + ObjectId objectId1 = new ObjectId(); + ObjectId objectId2 = new ObjectId(); + + objectIds.add(objectId1); + objectIds.add(objectId2); + + assertQuery( + MongodbExpressions.all(item.ctds, objectIds), + dbo("ctds", dbo("$all", dblist(objectId1, objectId2))) + ); + } + + @Test + public void not() { + assertQuery(title.eq("A").not(), dbo("title", dbo("$ne", "A"))); + + assertQuery(title.lt("A").not().and(year.ne(1800)), + dbo("title", dbo("$not", dbo("$lt", "A"))). + append("year", dbo("$ne", 1800))); + } + + @Test + public void objectId() { + ObjectId id = new ObjectId(); + QPerson person = QPerson.person; + assertQuery(person.id.eq(id), dbo("_id", id)); + assertQuery(person.addressId.eq(id), dbo("addressId", id)); + } + + @Test + public void path() { + QUser user = QUser.user; + assertEquals("firstName", serializer.visit(user.firstName, null)); + assertEquals("firstName", serializer.visit(user.as(QUser.class).firstName, null)); + assertEquals("mainAddress.street", serializer.visit(user.mainAddress().street, null)); + assertEquals("mainAddress.street", serializer.visit(user.mainAddress().as(QAddress.class).street, null)); + } + + private List<OrderSpecifier<?>> sortList(OrderSpecifier<?>... order) { + return Arrays.asList(order); + } + + private void assertQuery(Expression<?> e, BasicDBObject expected) { + BasicDBObject result = (BasicDBObject) serializer.handle(e); + assertEquals(expected.toString(), result.toString()); + } + + public static BasicDBObject dbo(String key, Object... value) { + if (value.length == 1) { + return new BasicDBObject(key, value[0]); + } + return new BasicDBObject(key, value); + } + + public static BasicDBList dblist(Object... contents) { + BasicDBList list = new BasicDBList(); + list.addAll(Arrays.asList(contents)); + return list; + } +} diff --git a/querydsl-mongodb/src/test/java/com/querydsl/mongodb/PackageVerification.java b/querydsl-mongodb/src/test/java/com/querydsl/mongodb/PackageVerification.java new file mode 100644 index 0000000000..ebb791edbf --- /dev/null +++ b/querydsl-mongodb/src/test/java/com/querydsl/mongodb/PackageVerification.java @@ -0,0 +1,56 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.mongodb; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.net.URL; +import java.net.URLClassLoader; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; + +import org.junit.Test; + +import com.querydsl.codegen.utils.CodeWriter; +import com.querydsl.apt.morphia.MorphiaAnnotationProcessor; +import com.querydsl.codegen.CodegenModule; +import com.querydsl.core.Entity; +import com.querydsl.core.types.Expression; + +public class PackageVerification { + + @Test + public void verify_package() throws Exception { + String version = System.getProperty("version"); + verify(new File("target/querydsl-mongodb-" + version + "-apt-one-jar.jar")); + } + + private void verify(File oneJar) throws Exception { + assertTrue(oneJar.getPath() + " doesn't exist", oneJar.exists()); + // verify classLoader + URLClassLoader oneJarClassLoader = new URLClassLoader(new URL[]{oneJar.toURI().toURL()}); + oneJarClassLoader.loadClass(Expression.class.getName()); // querydsl-core + oneJarClassLoader.loadClass(CodeWriter.class.getName()); // codegen + oneJarClassLoader.loadClass(CodegenModule.class.getName()).newInstance(); + oneJarClassLoader.loadClass(Entity.class.getName()); // morphia + Class cl = oneJarClassLoader.loadClass(MorphiaAnnotationProcessor.class.getName()); // querydsl-apt + cl.newInstance(); + String resourceKey = "META-INF/services/javax.annotation.processing.Processor"; + assertEquals(MorphiaAnnotationProcessor.class.getName(), new String(Files.readAllBytes(Paths.get(oneJarClassLoader.findResource(resourceKey).toURI())), StandardCharsets.UTF_8)); + } + +} diff --git a/querydsl-mongodb/src/test/java/com/querydsl/mongodb/PolymorphicCollectionTest.java b/querydsl-mongodb/src/test/java/com/querydsl/mongodb/PolymorphicCollectionTest.java new file mode 100644 index 0000000000..42deb8a15f --- /dev/null +++ b/querydsl-mongodb/src/test/java/com/querydsl/mongodb/PolymorphicCollectionTest.java @@ -0,0 +1,79 @@ +package com.querydsl.mongodb; + +import static org.junit.Assert.assertEquals; + +import java.net.UnknownHostException; + +import org.junit.Before; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.mongodb.morphia.Datastore; +import org.mongodb.morphia.Morphia; + +import com.mongodb.MongoClient; +import com.mongodb.MongoException; +import com.querydsl.core.testutil.MongoDB; +import com.querydsl.core.types.Predicate; +import com.querydsl.mongodb.domain.*; +import com.querydsl.mongodb.morphia.MorphiaQuery; + +@Category(MongoDB.class) +public class PolymorphicCollectionTest { + + private final Morphia morphia; + private final Datastore ds; + private final Fish f1 = new Fish("f1"); + private final Fish f2 = new Fish("f2"); + private final Chips c1 = new Chips("c1"); + + public PolymorphicCollectionTest() throws UnknownHostException, MongoException { + final MongoClient mongo = new MongoClient(); + morphia = new Morphia().map(Food.class); + ds = morphia.createDatastore(mongo, "testdb"); + } + + @Before + public void before() throws UnknownHostException, MongoException { + ds.delete(ds.createQuery(Food.class)); + ds.save(f1, f2, c1); + } + + @Test + public void basicCount() { + assertEquals(where().fetchCount(), 3); + } + + @Test + public void countFishFromName() { + assertEquals(where(QFood.food.name.eq("f1")).fetchCount(), 1); + } + + @Test + public void countFishFromNameAndBreed() { + assertEquals(where(QFood.food.name.eq("f1") + .and(QFish.fish.breed.eq("unknown"))).fetchCount(), 1); + } + + @Test + public void countFishFromNameAndBreedWithCast() { + assertEquals(where(QFood.food.name.eq("f1") + .and(QFood.food.as(QFish.class).breed.eq("unknown"))).fetchCount(), 1); + } + + @Test + public void countFishes() { + assertEquals(where(isFish()).fetchCount(), 2); + } + + private Predicate isFish() { + return QFood.food.name.startsWith("f"); + } + + private MorphiaQuery<Food> query() { + return new MorphiaQuery<Food>(morphia, ds, QFood.food); + } + + private MorphiaQuery<Food> where(final Predicate... e) { + return query().where(e); + } +} diff --git a/querydsl-mongodb/src/test/java/com/querydsl/mongodb/document/MongodbDocumentSerializerTest.java b/querydsl-mongodb/src/test/java/com/querydsl/mongodb/document/MongodbDocumentSerializerTest.java new file mode 100644 index 0000000000..7d64c92719 --- /dev/null +++ b/querydsl-mongodb/src/test/java/com/querydsl/mongodb/document/MongodbDocumentSerializerTest.java @@ -0,0 +1,302 @@ +/* + * Copyright 2020 the original author or 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. + */ +package com.querydsl.mongodb.document; + +import static org.junit.Assert.*; + +import java.sql.Timestamp; +import java.util.Arrays; +import java.util.Collections; +import java.util.Date; +import java.util.List; +import java.util.regex.Pattern; + +import com.mongodb.DBRef; +import com.querydsl.core.types.Path; +import org.bson.Document; +import org.bson.types.ObjectId; +import org.junit.Before; +import org.junit.Test; + +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.OrderSpecifier; +import com.querydsl.core.types.dsl.DatePath; +import com.querydsl.core.types.dsl.DateTimePath; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.PathBuilder; +import com.querydsl.core.types.dsl.StringPath; +import com.querydsl.mongodb.Point; +import com.querydsl.mongodb.domain.QAddress; +import com.querydsl.mongodb.domain.QPerson; +import com.querydsl.mongodb.domain.QUser; + +public class MongodbDocumentSerializerTest { + + private PathBuilder<Object> entityPath; + private StringPath title; + private NumberPath<Integer> year; + private NumberPath<Double> gross; + + private NumberPath<Long> longField; + private NumberPath<Short> shortField; + private NumberPath<Byte> byteField; + private NumberPath<Float> floatField; + + private DatePath<Date> date; + private final Date dateVal = new Date(); + private DateTimePath<Timestamp> dateTime; + private final Timestamp dateTimeVal = new Timestamp(System.currentTimeMillis()); + + private MongodbDocumentSerializer serializer; + + @Before + public void before() { + serializer = new MongodbDocumentSerializer() { + @Override + protected DBRef asReference(Object constant) { + return null; + } + + @Override + protected boolean isReference(Path<?> arg) { + return false; + } + }; + + entityPath = new PathBuilder<Object>(Object.class, "obj"); + title = entityPath.getString("title"); + year = entityPath.getNumber("year", Integer.class); + gross = entityPath.getNumber("gross", Double.class); + longField = entityPath.getNumber("longField", Long.class); + shortField = entityPath.getNumber("shortField", Short.class); + byteField = entityPath.getNumber("byteField", Byte.class); + floatField = entityPath.getNumber("floatField", Float.class); + date = entityPath.getDate("date", Date.class); + dateTime = entityPath.getDateTime("dateTime", Timestamp.class); + } + + @Test + public void paths() { + QUser user = QUser.user; + assertEquals("user", serializer.visit(user, null)); + assertEquals("addresses", serializer.visit(user.addresses, null)); + assertEquals("addresses", serializer.visit(user.addresses.any(), null)); + assertEquals("addresses.street", serializer.visit(user.addresses.any().street, null)); + assertEquals("firstName", serializer.visit(user.firstName, null)); + } + + @Test + public void indexedAccess() { + QUser user = QUser.user; + assertEquals("addresses.0.street", serializer.visit(user.addresses.get(0).street, null)); + } + + @Test + public void collectionAny() { + QUser user = QUser.user; + assertQuery(user.addresses.any().street.eq("Aakatu"), document("addresses.street","Aakatu")); + } + + @Test + public void collectionIsEmpty() { + Document expected = document("$or", + Arrays.asList( + document("addresses", Collections.emptyList()), + document("addresses", + document("$exists", false)))); + assertQuery(QUser.user.addresses.isEmpty(), expected); + } + + @Test + public void collectionIsNotEmpty() { + Document expected = document("$nor", + Arrays.asList( + document("addresses", Collections.emptyList()), + document("addresses", + document("$exists", false)))); + assertQuery(QUser.user.addresses.isNotEmpty(), expected); + } + + @Test + public void equals() { + assertQuery(title.eq("A"), document("title","A")); + assertQuery(year.eq(1), document("year",1)); + assertQuery(gross.eq(1.0D), document("gross", 1.0D)); + assertQuery(longField.eq(1L), document("longField", 1L)); + assertQuery(shortField.eq((short) 1), document("shortField", 1)); + assertQuery(byteField.eq((byte) 1), document("byteField", 1)); + assertQuery(floatField.eq(1.0F), document("floatField", 1.0F)); + + assertQuery(date.eq(dateVal), document("date", dateVal)); + } + + @Test + public void eqAndEq() { + assertQuery( + title.eq("A").and(year.eq(1)), + document("title","A").append("year", 1) + ); + + assertQuery( + title.eq("A").and(year.eq(1).and(gross.eq(1.0D))), + document("title","A").append("year", 1).append("gross", 1.0D) + ); + } + + @Test + public void notEq() { + assertQuery(title.ne("A"), document("title", document("$ne", "A"))); + } + + @Test + public void between() { + assertQuery(year.between(1, 10), document("year", document("$gte", 1).append("$lte", 10))); + } + + @Test + public void lessAndGreaterAndBetween() { + assertQuery(title.lt("A"), document("title", document("$lt", "A"))); + assertQuery(year.gt(1), document("year", document("$gt", 1))); + + assertQuery(title.loe("A"), document("title", document("$lte", "A"))); + assertQuery(year.goe(1), document("year", document("$gte", 1))); + + assertQuery( + year.gt(1).and(year.lt(10)), + document("$and", Arrays.asList( + document("year", document("$gt", 1)), + document("year", document("$lt", 10)))) + ); + + assertQuery( + year.between(1, 10), + document("year", document("$gte", 1).append("$lte", 10)) + ); + } + + @Test + public void in() { + assertQuery(year.in(1,2,3), document("year", document("$in", Arrays.asList(1,2,3)))); + } + + @Test + public void notIn() { + assertQuery(year.in(1,2,3).not(), document("year", document("$nin", Arrays.asList(1,2,3)))); + assertQuery(year.notIn(1,2,3), document("year", document("$nin", Arrays.asList(1,2,3)))); + } + + @Test + public void orderBy() { + Document orderBy = serializer.toSort(sortList(year.asc())); + assertEquals(document("year", 1), orderBy); + + orderBy = serializer.toSort(sortList(year.desc())); + assertEquals(document("year", -1), orderBy); + + orderBy = serializer.toSort(sortList(year.desc(), title.asc())); + assertEquals(document("year", -1).append("title", 1), orderBy); + } + + @Test + public void regexCases() { + assertQuery(title.startsWith("A"), + document("title", Pattern.compile("^\\QA\\E"))); + assertQuery(title.startsWithIgnoreCase("A"), + document("title", Pattern.compile("^\\QA\\E", Pattern.CASE_INSENSITIVE))); + + assertQuery(title.endsWith("A"), + document("title", Pattern.compile("\\QA\\E$"))); + assertQuery(title.endsWithIgnoreCase("A"), + document("title", Pattern.compile("\\QA\\E$", Pattern.CASE_INSENSITIVE))); + + assertQuery(title.equalsIgnoreCase("A"), + document("title", Pattern.compile("^\\QA\\E$", Pattern.CASE_INSENSITIVE))); + + assertQuery(title.contains("A"), + document("title", Pattern.compile(".*\\QA\\E.*"))); + assertQuery(title.containsIgnoreCase("A"), + document("title", Pattern.compile(".*\\QA\\E.*", Pattern.CASE_INSENSITIVE))); + + assertQuery(title.matches(".*A^"), + document("title", Pattern.compile(".*A^"))); + } + + @Test + public void and() { + assertQuery( + title.startsWithIgnoreCase("a").and(title.endsWithIgnoreCase("b")), + + document("$and", Arrays.asList( + document("title", document("$regex", "^\\Qa\\E").append("$options", "i")), + document("title", document("$regex", "\\Qb\\E$").append("$options", "i"))))); + + } + + @Test + public void near() { + assertQuery(MongodbExpressions.near(new Point("point"), 1.0, 2.0), + document("point", document("$near", Arrays.asList(1.0, 2.0)))); + } + + @Test + public void near_sphere() { + assertQuery(MongodbExpressions.nearSphere(new Point("point"), 1.0, 2.0), + document("point", document("$nearSphere", Arrays.asList(1.0, 2.0)))); + } + + @Test + public void not() { + assertQuery(title.eq("A").not(), document("title", document("$ne","A"))); + + assertQuery(title.lt("A").not().and(year.ne(1800)), + document("title", document("$not", document("$lt","A"))). + append("year", document("$ne", 1800))); + } + + @Test + public void objectId() { + ObjectId id = new ObjectId(); + QPerson person = QPerson.person; + assertQuery(person.id.eq(id), document("id",id)); + assertQuery(person.addressId.eq(id), document("addressId",id)); + } + + @Test + public void path() { + QUser user = QUser.user; + assertEquals("firstName", serializer.visit(user.firstName, null)); + assertEquals("firstName", serializer.visit(user.as(QUser.class).firstName, null)); + assertEquals("mainAddress.street", serializer.visit(user.mainAddress().street, null)); + assertEquals("mainAddress.street", serializer.visit(user.mainAddress().as(QAddress.class).street, null)); + } + + + private List<OrderSpecifier<?>> sortList(OrderSpecifier<?>... order) { + return Arrays.asList(order); + } + + private void assertQuery(Expression<?> e, Document expected) { + Document result = (Document) serializer.handle(e); + assertEquals(expected.toJson(), result.toJson()); + } + + public static Document document(String key, Object... value) { + if (value.length == 1) { + return new Document(key, value[0]); + } + return new Document(key, value); + } +} diff --git a/querydsl-mongodb/src/test/java/com/querydsl/mongodb/document/MongodbQueryTest.java b/querydsl-mongodb/src/test/java/com/querydsl/mongodb/document/MongodbQueryTest.java new file mode 100644 index 0000000000..f7f50dd50a --- /dev/null +++ b/querydsl-mongodb/src/test/java/com/querydsl/mongodb/document/MongodbQueryTest.java @@ -0,0 +1,750 @@ +/* + * Copyright 2020 the original author or 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. + */ +package com.querydsl.mongodb.document; + +import com.mongodb.DBRef; +import com.mongodb.MongoClient; +import com.mongodb.MongoException; +import com.mongodb.ReadPreference; +import com.mongodb.client.MongoCollection; +import com.mongodb.client.MongoDatabase; +import com.querydsl.core.NonUniqueResultException; +import com.querydsl.core.QueryResults; +import com.querydsl.core.testutil.MongoDB; +import com.querydsl.core.types.*; +import com.querydsl.core.types.dsl.ListPath; +import com.querydsl.core.types.dsl.StringPath; +import com.querydsl.mongodb.domain.*; +import com.querydsl.mongodb.domain.User.Gender; +import org.bson.Document; +import org.bson.types.ObjectId; +import org.junit.Before; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.mongodb.morphia.Datastore; +import org.mongodb.morphia.Key; +import org.mongodb.morphia.Morphia; +import org.mongodb.morphia.annotations.Id; +import org.mongodb.morphia.annotations.Property; +import org.mongodb.morphia.annotations.Reference; +import org.mongodb.morphia.mapping.Mapper; + +import java.lang.reflect.AnnotatedElement; +import java.net.UnknownHostException; +import java.util.*; +import java.util.function.Function; + +import static java.util.Arrays.asList; +import static org.junit.Assert.*; + +@Category(MongoDB.class) +public class MongodbQueryTest { + + private final MongoClient mongo; + private final Morphia morphia; + private final MongoDatabase database; + private final Datastore ds; + + private final String dbname = "testdb"; + private final QUser user = QUser.user; + private final QItem item = QItem.item; + private final QAddress address = QAddress.address; + private final QMapEntity mapEntity = QMapEntity.mapEntity; + private final QDates dates = QDates.dates; + private final QCountry country = QCountry.country; + + List<User> users = new ArrayList<>(); + List<Document> userDocuments = new ArrayList<>(); + User user1, user2, user3, user4; + Document u1, u2, u3, u4; + City tampere, helsinki; + + public MongodbQueryTest() throws UnknownHostException, MongoException { + mongo = new MongoClient(); + morphia = new Morphia().map(User.class).map(Item.class).map(MapEntity.class).map(Dates.class); + database = mongo.getDatabase(dbname); + ds = morphia.createDatastore(mongo, dbname); + } + + @Before + public void before() throws UnknownHostException, MongoException { + ds.delete(ds.createQuery(Item.class)); + ds.delete(ds.createQuery(User.class)); + ds.delete(ds.createQuery(Country.class)); + ds.delete(ds.createQuery(MapEntity.class)); + + tampere = new City("Tampere", 61.30, 23.50); + helsinki = new City("Helsinki", 60.15, 20.03); + + user1 = addUser("Jaakko", "Jantunen", 20, new Address("Aakatu", "00100", helsinki), + new Address("Aakatu1", "00100", helsinki), + new Address("Aakatu2", "00100", helsinki)); + user2 = addUser("Jaakki", "Jantunen", 30, new Address("Beekatu", "00200", helsinki)); + user3 = addUser("Jaana", "Aakkonen", 40, new Address("Ceekatu", "00300", tampere)); + user4 = addUser("Jaana", "BeekkoNen", 50, new Address("Deekatu", "00400", tampere)); + + u1 = asDocument(user1); + u2 = asDocument(user2); + u3 = asDocument(user3); + u4 = asDocument(user4); + + // order users by lastname, firstname + userDocuments = Arrays.asList(u3, u4, u2, u1); + } + + @Test + public void query1() { + assertEquals(4L, query(user).fetchCount()); + assertEquals(4L, query(User.class).fetchCount()); + } + + @Test + public void list_keys() { + Document u = where(user.firstName.eq("Jaakko")).fetch(user.firstName, user.mainAddress().street).get(0); + assertEquals("Jaakko", u.get("firstName")); + assertNull(u.get("lastName")); + assertEquals("Aakatu", u.get("mainAddress", Document.class).get("street")); + assertNull(u.get("mainAddress", Document.class).get("postCode")); + } + + @Test + public void singleResult_keys() { + Document u = where(user.firstName.eq("Jaakko")).fetchFirst(user.firstName); + assertEquals("Jaakko", u.get("firstName")); + assertNull(u.get("lastName")); + } + + @Test + public void uniqueResult_keys() { + Document u = where(user.firstName.eq("Jaakko")).fetchOne(user.firstName); + assertEquals("Jaakko", u.get("firstName")); + assertNull(u.get("lastName")); + } + + @Test + public void list_deep_keys() { + Document u = where(user.firstName.eq("Jaakko")).fetchFirst(user.addresses.any().street); + List<Document> addresses = u.get("addresses", List.class); + for (Document a : addresses) { + assertNotNull(a.get("street")); + assertNull(a.get("city")); + } + } + + @Test + public void between() { + assertQuery(user.age.between(20, 30), u2, u1); + assertQuery(user.age.goe(20).and(user.age.loe(30)), u2, u1); + } + + @Test + public void between_not() { + assertQuery(user.age.between(20, 30).not(), u3, u4); + assertQuery(user.age.goe(20).and(user.age.loe(30)).not(), u3, u4); + } + + @Test + public void contains_key() { + MapEntity entity = new MapEntity(); + entity.getProperties().put("key", "value"); + ds.save(entity); + + assertTrue(query(mapEntity).where(mapEntity.properties.get("key").isNotNull()).fetchCount() > 0); + assertFalse(query(mapEntity).where(mapEntity.properties.get("key2").isNotNull()).fetchCount() > 0); + + assertTrue(query(mapEntity).where(mapEntity.properties.containsKey("key")).fetchCount() > 0); + assertFalse(query(mapEntity).where(mapEntity.properties.containsKey("key2")).fetchCount() > 0); + } + + @Test + public void contains_key_not() { + MapEntity entity = new MapEntity(); + entity.getProperties().put("key", "value"); + ds.save(entity); + + assertFalse(query(mapEntity).where(mapEntity.properties.get("key").isNotNull().not()).fetchCount() > 0); + assertTrue(query(mapEntity).where(mapEntity.properties.get("key2").isNotNull().not()).fetchCount() > 0); + + assertFalse(query(mapEntity).where(mapEntity.properties.containsKey("key").not()).fetchCount() > 0); + assertTrue(query(mapEntity).where(mapEntity.properties.containsKey("key2").not()).fetchCount() > 0); + } + + @Test + public void equals_ignore_case() { + assertTrue(where(user.firstName.equalsIgnoreCase("jAaKko")).fetchCount() > 0); + assertFalse(where(user.firstName.equalsIgnoreCase("AaKk")).fetchCount() > 0); + } + + @Test + public void equals_ignore_case_not() { + assertTrue(where(user.firstName.equalsIgnoreCase("jAaKko").not()).fetchCount() > 0); + assertTrue(where(user.firstName.equalsIgnoreCase("AaKk").not()).fetchCount() > 0); + } + + @Test + public void equals_and_between() { + assertQuery(user.firstName.startsWith("Jaa").and(user.age.between(20, 30)), u2, u1); + assertQuery(user.firstName.startsWith("Jaa").and(user.age.goe(20).and(user.age.loe(30))), u2, u1); + } + + @Test + public void equals_and_between_not() { + assertQuery(user.firstName.startsWith("Jaa").and(user.age.between(20, 30)).not(), u3, u4); + assertQuery(user.firstName.startsWith("Jaa").and(user.age.goe(20).and(user.age.loe(30))).not(), u3, u4); + } + + @Test + public void exists() { + assertTrue(where(user.firstName.eq("Jaakko")).fetchCount() > 0); + assertFalse(where(user.firstName.eq("JaakkoX")).fetchCount() > 0); + } + + @Test + public void find_by_id() { + assertNotNull(where(user.id.eq(user1.getId())).fetchFirst() != null); + } + + @Test + public void notExists() { + assertFalse(where(user.firstName.eq("Jaakko")).fetchCount() == 0); + assertTrue(where(user.firstName.eq("JaakkoX")).fetchCount() == 0); + } + + @Test + public void uniqueResult() { + assertEquals("Jantunen", where(user.firstName.eq("Jaakko")).fetchOne().get("lastName")); + } + + @Test(expected = NonUniqueResultException.class) + public void uniqueResultContract() { + where(user.firstName.isNotNull()).fetchOne(); + } + + @Test + public void singleResult() { + where(user.firstName.isNotNull()).fetchFirst(); + } + + @Test + public void longPath() { + assertEquals(2, query().where(user.mainAddress().city().name.eq("Helsinki")).fetchCount()); + assertEquals(2, query().where(user.mainAddress().city().name.eq("Tampere")).fetchCount()); + } + + @Test + public void collectionPath() { + assertEquals(1, query().where(user.addresses.any().street.eq("Aakatu1")).fetchCount()); + assertEquals(0, query().where(user.addresses.any().street.eq("akatu")).fetchCount()); + } + + @Test + public void dates() { + long current = System.currentTimeMillis(); + int dayInMillis = 24 * 60 * 60 * 1000; + Date start = new Date(current); + ds.delete(ds.createQuery(Dates.class)); + Dates d = new Dates(); + d.setDate(new Date(current + dayInMillis)); + ds.save(d); + Date end = new Date(current + 2 * dayInMillis); + + Document datesDocument = asDocument(d); + + assertEquals(datesDocument, query(dates).where(dates.date.between(start, end)).fetchFirst()); + assertEquals(0, query(dates).where(dates.date.between(new Date(0), start)).fetchCount()); + } + + @Test + public void elemMatch() { +// { "addresses" : { "$elemMatch" : { "street" : "Aakatu1"}}} + assertEquals(1, query().anyEmbedded(user.addresses, address).on(address.street.eq("Aakatu1")).fetchCount()); +// { "addresses" : { "$elemMatch" : { "street" : "Aakatu1" , "postCode" : "00100"}}} + assertEquals(1, query().anyEmbedded(user.addresses, address) + .on(address.street.eq("Aakatu1"), address.postCode.eq("00100")).fetchCount()); +// { "addresses" : { "$elemMatch" : { "street" : "akatu"}}} + assertEquals(0, query().anyEmbedded(user.addresses, address).on(address.street.eq("akatu")).fetchCount()); +// { "addresses" : { "$elemMatch" : { "street" : "Aakatu1" , "postCode" : "00200"}}} + assertEquals(0, query().anyEmbedded(user.addresses, address) + .on(address.street.eq("Aakatu1"), address.postCode.eq("00200")).fetchCount()); + } + + @Test + public void indexedAccess() { + assertEquals(1, query().where(user.addresses.get(0).street.eq("Aakatu1")).fetchCount()); + assertEquals(0, query().where(user.addresses.get(1).street.eq("Aakatu1")).fetchCount()); + } + + @Test + public void count() { + assertEquals(4, query().fetchCount()); + } + + @Test + public void order() { + List<Document> users = query().orderBy(user.age.asc()).fetch(); + assertEquals(asList(u1, u2, u3, u4), users); + + users = query().orderBy(user.age.desc()).fetch(); + assertEquals(asList(u4, u3, u2, u1), users); + } + + @Test + public void restrict() { + assertEquals(asList(u1, u2), query().limit(2).orderBy(user.age.asc()).fetch()); + assertEquals(asList(u2, u3), query().limit(2).offset(1).orderBy(user.age.asc()).fetch()); + } + + @Test + public void listResults() { + QueryResults<Document> results = query().limit(2).orderBy(user.age.asc()).fetchResults(); + assertEquals(4L, results.getTotal()); + assertEquals(2, results.getResults().size()); + + results = query().offset(2).orderBy(user.age.asc()).fetchResults(); + assertEquals(4L, results.getTotal()); + assertEquals(2, results.getResults().size()); + } + + @Test + public void emptyResults() { + QueryResults<Document> results = query().where(user.firstName.eq("XXX")).fetchResults(); + assertEquals(0L, results.getTotal()); + assertEquals(Collections.emptyList(), results.getResults()); + } + + @Test + public void eqInAndOrderByQueries() { + assertQuery(user.firstName.eq("Jaakko"), u1); + assertQuery(user.firstName.equalsIgnoreCase("jaakko"), u1); + assertQuery(user.lastName.eq("Aakkonen"), u3); + + assertQuery(user.firstName.in("Jaakko", "Teppo"), u1); + assertQuery(user.lastName.in("Aakkonen", "BeekkoNen"), u3, u4); + + assertQuery(user.firstName.eq("Jouko")); + + assertQuery(user.firstName.eq("Jaana"), user.lastName.asc(), u3, u4); + assertQuery(user.firstName.eq("Jaana"), user.lastName.desc(), u4, u3); + assertQuery(user.lastName.eq("Jantunen"), user.firstName.asc(), u2, u1); + assertQuery(user.lastName.eq("Jantunen"), user.firstName.desc(), u1, u2); + + assertQuery(user.firstName.eq("Jaana").and(user.lastName.eq("Aakkonen")), u3); + //This should produce 'and' also + assertQuery(where(user.firstName.eq("Jaana"), user.lastName.eq("Aakkonen")), u3); + + assertQuery(user.firstName.ne("Jaana"), u2, u1); + } + + @Test + public void regexQueries() { + assertQuery(user.firstName.startsWith("Jaan"), u3, u4); + assertQuery(user.firstName.startsWith("jaan")); + assertQuery(user.firstName.startsWithIgnoreCase("jaan"), u3, u4); + + assertQuery(user.lastName.endsWith("unen"), u2, u1); + + assertQuery(user.lastName.endsWithIgnoreCase("onen"), u3, u4); + + assertQuery(user.lastName.contains("oN"), u4); + assertQuery(user.lastName.containsIgnoreCase("on"), u3, u4); + + assertQuery(user.firstName.matches(".*aa.*[^i]$"), u3, u4, u1); + } + + @Test + public void regexQueries_not() { + assertQuery(user.firstName.startsWith("Jaan").not(), u2, u1); + assertQuery(user.firstName.startsWith("jaan").not(), u3, u4, u2, u1); + assertQuery(user.firstName.startsWithIgnoreCase("jaan").not(), u2, u1); + + assertQuery(user.lastName.endsWith("unen").not(), u3, u4); + + assertQuery(user.lastName.endsWithIgnoreCase("onen").not(), u2, u1); + + assertQuery(user.lastName.contains("oN").not(), u3, u2, u1); + assertQuery(user.lastName.containsIgnoreCase("on").not(), u2, u1); + + assertQuery(user.firstName.matches(".*aa.*[^i]$").not(), u2); + } + + @Test + public void like() { + assertQuery(user.firstName.like("Jaan")); + assertQuery(user.firstName.like("Jaan%"), u3, u4); + assertQuery(user.firstName.like("jaan%")); + + assertQuery(user.lastName.like("%unen"), u2, u1); + } + + @Test + public void like_not() { + assertQuery(user.firstName.like("Jaan").not(), u3, u4, u2, u1); + assertQuery(user.firstName.like("Jaan%").not(), u2, u1); + assertQuery(user.firstName.like("jaan%").not(), u3, u4, u2, u1); + + assertQuery(user.lastName.like("%unen").not(), u3, u4); + } + + @Test + public void likeIgnoreCase() { + assertQuery(user.firstName.likeIgnoreCase("JAAN")); + assertQuery(user.firstName.likeIgnoreCase("Jaan%"), u3, u4); + assertQuery(user.firstName.likeIgnoreCase("JAAN%"), u3, u4); + assertQuery(user.firstName.likeIgnoreCase("jaan%"), u3, u4); + + assertQuery(user.lastName.likeIgnoreCase("%unen"), u2, u1); + assertQuery(user.lastName.likeIgnoreCase("%UNEN"), u2, u1); + } + + @Test + public void likeIgnoreCase_not() { + assertQuery(user.firstName.likeIgnoreCase("Jaan").not(), u3, u4, u2, u1); + assertQuery(user.firstName.likeIgnoreCase("Jaan%").not(), u2, u1); + assertQuery(user.firstName.likeIgnoreCase("JAAN%").not(), u2, u1); + assertQuery(user.firstName.likeIgnoreCase("jaan%").not(), u2, u1); + + assertQuery(user.lastName.likeIgnoreCase("%unen").not(), u3, u4); + assertQuery(user.lastName.likeIgnoreCase("%UNEN").not(), u3, u4); + } + + @Test + public void isNotNull() { + assertQuery(user.firstName.isNotNull(), u3, u4, u2, u1); + } + + @Test + public void isNotNull_not() { + assertQuery(user.firstName.isNotNull().not()); + } + + @Test + public void isNull() { + assertQuery(user.firstName.isNull()); + } + + @Test + public void isNull_not() { + assertQuery(user.firstName.isNull().not(), u3, u4, u2, u1); + } + + @Test + public void isEmpty() { + assertQuery(user.firstName.isEmpty()); + assertQuery(user.friends.isEmpty(), u1); + } + + @Test + public void isEmpty_not() { + assertQuery(user.firstName.isEmpty().not(), u3, u4, u2, u1); + assertQuery(user.friends.isEmpty().not(), u3, u4, u2); + } + + @Test + public void not() { + assertQuery(user.firstName.eq("Jaakko").not(), u3, u4, u2); + assertQuery(user.firstName.ne("Jaakko").not(), u1); + assertQuery(user.firstName.matches("Jaakko").not(), u3, u4, u2); + assertQuery(user.friends.isNotEmpty(), u3, u4, u2); + } + + @Test + public void or() { + assertQuery(user.lastName.eq("Aakkonen").or(user.lastName.eq("BeekkoNen")), u3, u4); + } + + @Test + public void or_not() { + assertQuery(user.lastName.eq("Aakkonen").or(user.lastName.eq("BeekkoNen")).not(), u2, u1); + } + + @Test + public void iterate() { + User a = addUser("A", "A"); + User b = addUser("A1", "B"); + User c = addUser("A2", "C"); + + Iterator<Document> i = where(user.firstName.startsWith("A")) + .orderBy(user.firstName.asc()) + .iterate(); + + assertEquals(a.getId(), i.next().get("_id")); + assertEquals(b.getId(), i.next().get("_id")); + assertEquals(c.getId(), i.next().get("_id")); + assertEquals(false, i.hasNext()); + } + + @Test + public void uniqueResultAndLimitAndOffset() { + SimpleMongodbQuery q = query().where(user.firstName.startsWith("Ja")).orderBy(user.age.asc()); + assertEquals(4, q.fetch().size()); + assertEquals(u1, q.fetch().get(0)); + } + + @Test + public void references() { + for (User u : users) { + if (u.getFriend() != null) { + assertQuery(user.friend().eq(u.getFriend()), asDocument(u)); + } + } + } + + @Test + public void references2() { + for (User u : users) { + if (u.getFriend() != null) { + assertQuery(user.enemy().eq(u.getEnemy()), asDocument(u)); + } + } + } + + @Test + public void various() { + ListPath<Address, QAddress> list = user.addresses; + StringPath str = user.lastName; + List<Predicate> predicates = new ArrayList<Predicate>(); + predicates.add(str.between("a", "b")); + predicates.add(str.contains("a")); + predicates.add(str.containsIgnoreCase("a")); + predicates.add(str.endsWith("a")); + predicates.add(str.endsWithIgnoreCase("a")); + predicates.add(str.eq("a")); + predicates.add(str.equalsIgnoreCase("a")); + predicates.add(str.goe("a")); + predicates.add(str.gt("a")); + predicates.add(str.in("a", "b", "c")); + predicates.add(str.isEmpty()); + predicates.add(str.isNotNull()); + predicates.add(str.isNull()); + predicates.add(str.like("a")); + predicates.add(str.loe("a")); + predicates.add(str.lt("a")); + predicates.add(str.matches("a")); + predicates.add(str.ne("a")); + predicates.add(str.notBetween("a", "b")); + predicates.add(str.notIn("a", "b", "c")); + predicates.add(str.startsWith("a")); + predicates.add(str.startsWithIgnoreCase("a")); + predicates.add(list.isEmpty()); + predicates.add(list.isNotEmpty()); + + for (Predicate predicate : predicates) { + long count1 = where(predicate).fetchCount(); + long count2 = where(predicate.not()).fetchCount(); + assertEquals(predicate.toString(), 4, count1 + count2); + } + } + + @Test + public void enum_eq() { + assertQuery(user.gender.eq(Gender.MALE), u3, u4, u2, u1); + } + + @Test + public void enum_ne() { + assertQuery(user.gender.ne(Gender.MALE)); + } + + @Test + public void in_objectIds() { + Item i = new Item(); + i.setCtds(Arrays.asList(ObjectId.get(), ObjectId.get(), ObjectId.get())); + ds.save(i); + + assertTrue(where(item, item.ctds.contains(i.getCtds().get(0))).fetchCount() > 0); + assertTrue(where(item, item.ctds.contains(ObjectId.get())).fetchCount() == 0); + } + + @Test + public void in_objectIds2() { + Item i = new Item(); + i.setCtds(Arrays.asList(ObjectId.get(), ObjectId.get(), ObjectId.get())); + ds.save(i); + + assertTrue(where(item, item.ctds.any().in(i.getCtds())).fetchCount() > 0); + assertTrue(where(item, item.ctds.any().in(Arrays.asList(ObjectId.get(), ObjectId.get()))).fetchCount() == 0); + } + + @Test + public void size() { + assertQuery(user.addresses.size().eq(2), u1); + } + + @Test + public void size_not() { + assertQuery(user.addresses.size().eq(2).not(), u3, u4, u2); + } + + @Test + public void readPreference() { + SimpleMongodbQuery query = query(); + query.setReadPreference(ReadPreference.primary()); + assertEquals(4, query.fetchCount()); + } + + @Test + public void asDBObject() { + SimpleMongodbQuery query = query(); + query.where(user.firstName.eq("Bob"), user.lastName.eq("Wilson")); + assertEquals( + new Document().append("firstName", "Bob").append("lastName", "Wilson"), + query.asDocument()); + } + + private Document asDocument(AbstractEntity entity) { + return database.getCollection(ds.getCollection(entity.getClass()).getName()) + .find(new Document("_id", entity.getId())).first(); + } + + private void assertQuery(Predicate e, Document... expected) { + assertQuery(where(e).orderBy(user.lastName.asc(), user.firstName.asc()), expected); + } + + private void assertQuery(Predicate e, OrderSpecifier<?> orderBy, Document... expected) { + assertQuery(where(e).orderBy(orderBy), expected); + } + + private <T> SimpleMongodbQuery where(EntityPath<T> entity, Predicate... e) { + return new SimpleMongodbQuery(morphia, ds, entity.getType(), database).where(e); + } + + private SimpleMongodbQuery where(Predicate... e) { + return query().where(e); + } + + private SimpleMongodbQuery query() { + return new SimpleMongodbQuery(morphia, ds, user.getType(), database); + } + + private <T> SimpleMongodbQuery query(EntityPath<T> path) { + return new SimpleMongodbQuery(morphia, ds, path.getType(), database); + } + + private <T> SimpleMongodbQuery query(Class<? extends T> clazz) { + return new SimpleMongodbQuery(morphia, ds, clazz, database); + } + + private void assertQuery(SimpleMongodbQuery query, Document... expected) { + String toString = query.toString(); + List<Document> results = query.fetch(); + + assertNotNull(toString, results); + if (expected == null) { + assertEquals("Should get empty result", 0, results.size()); + return; + } + assertEquals(toString, expected.length, results.size()); + int i = 0; + for (Document u : expected) { + assertEquals(toString, u, results.get(i++)); + } + } + + private User addUser(String first, String last) { + User user = new User(first, last); + ds.save(user); + return user; + } + + private User addUser(String first, String last, int age, Address mainAddress, Address... addresses) { + User user = new User(first, last, age, new Date()); + user.setGender(Gender.MALE); + user.setMainAddress(mainAddress); + for (Address address : addresses) { + user.addAddress(address); + } + for (User u : users) { + user.addFriend(u); + } + if (!users.isEmpty()) { + user.setFriend(users.get(users.size() - 1)); + user.setEnemy(users.get(users.size() - 1)); + } + ds.save(user); + users.add(user); + + return user; + } + + private static class SimpleMongodbQuery extends AbstractFetchableMongodbQuery<Document, SimpleMongodbQuery> { + + private final Datastore datastore; + private final MongoDatabase database; + + SimpleMongodbQuery(final Morphia morphia, final Datastore datastore, final Class<?> entityType, + final MongoDatabase database) { + super(database.getCollection(datastore.getCollection(entityType).getName()), Function.identity(), + new SampleSerializer(morphia)); + this.datastore = datastore; + this.database = database; + } + + @Override + protected MongoCollection<Document> getCollection(Class<?> type) { + return database.getCollection(datastore.getCollection(type).getName()); + } + } + + static class SampleSerializer extends MongodbDocumentSerializer { + private final Morphia morphia; + + SampleSerializer(Morphia morphia) { + this.morphia = morphia; + } + + @Override + protected boolean isReference(Path<?> arg) { + return arg.getAnnotatedElement().isAnnotationPresent(Reference.class); + } + + @Override + protected DBRef asReference(Object constant) { + Key<?> key = morphia.getMapper().getKey(constant); + return morphia.getMapper().keyToDBRef(key); + } + + @Override + protected DBRef asReferenceKey(Class<?> entity, Object id) { + String collection = morphia.getMapper().getCollectionName(entity); + Key<?> key = new Key<Object>(entity, collection, id); + return morphia.getMapper().keyToDBRef(key); + } + + @Override + protected String getKeyForPath(Path<?> expr, PathMetadata metadata) { + AnnotatedElement annotations = expr.getAnnotatedElement(); + if (annotations.isAnnotationPresent(Id.class)) { + Path<?> parent = expr.getMetadata().getParent(); + if (parent.getAnnotatedElement().isAnnotationPresent(Reference.class)) { + return null; // go to parent + } else { + return "_id"; + } + } else if (annotations.isAnnotationPresent(Property.class)) { + Property property = annotations.getAnnotation(Property.class); + if (!property.value().equals(Mapper.IGNORED_FIELDNAME)) { + return property.value(); + } + } else if (annotations.isAnnotationPresent(Reference.class)) { + Reference reference = annotations.getAnnotation(Reference.class); + if (!reference.value().equals(Mapper.IGNORED_FIELDNAME)) { + return reference.value(); + } + } + return super.getKeyForPath(expr, metadata); + } + } +} diff --git a/querydsl-mongodb/src/test/java/com/querydsl/mongodb/domain/AbstractEntity.java b/querydsl-mongodb/src/test/java/com/querydsl/mongodb/domain/AbstractEntity.java new file mode 100644 index 0000000000..55697a5fc7 --- /dev/null +++ b/querydsl-mongodb/src/test/java/com/querydsl/mongodb/domain/AbstractEntity.java @@ -0,0 +1,54 @@ +package com.querydsl.mongodb.domain; + +import org.bson.types.ObjectId; +import org.mongodb.morphia.annotations.Id; + +import com.querydsl.core.annotations.QuerySupertype; + +@QuerySupertype +public abstract class AbstractEntity { + + @Id + private ObjectId id; + + public ObjectId getId() { + return id; + } + + public void setId(ObjectId id) { + this.id = id; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((id == null) ? 0 : id.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + AbstractEntity other = (AbstractEntity) obj; + if (id == null) { + if (other.id != null) { + return false; + } + + } else if (!id.equals(other.id)) { + return false; + } + return true; + } + + +} diff --git a/querydsl-mongodb/src/test/java/com/querydsl/mongodb/domain/Address.java b/querydsl-mongodb/src/test/java/com/querydsl/mongodb/domain/Address.java new file mode 100644 index 0000000000..19c90ce7b5 --- /dev/null +++ b/querydsl-mongodb/src/test/java/com/querydsl/mongodb/domain/Address.java @@ -0,0 +1,35 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.mongodb.domain; + +import org.mongodb.morphia.annotations.Embedded; + +public final class Address { + + public Address() { + + } + + public Address(String street, String postCode, City city) { + this.street = street; this.postCode = postCode; this.city = city; + } + + public String street; + + public String postCode; + + @Embedded + public City city; + +} diff --git a/querydsl-mongodb/src/test/java/com/querydsl/mongodb/domain/Chips.java b/querydsl-mongodb/src/test/java/com/querydsl/mongodb/domain/Chips.java new file mode 100644 index 0000000000..192d819116 --- /dev/null +++ b/querydsl-mongodb/src/test/java/com/querydsl/mongodb/domain/Chips.java @@ -0,0 +1,24 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.mongodb.domain; + +import org.mongodb.morphia.annotations.Entity; + +@Entity("food") +public class Chips extends Food { + + public Chips(final String name) { + super(name); + } +} diff --git a/querydsl-mongodb/src/test/java/com/querydsl/mongodb/domain/City.java b/querydsl-mongodb/src/test/java/com/querydsl/mongodb/domain/City.java new file mode 100644 index 0000000000..baaba321bf --- /dev/null +++ b/querydsl-mongodb/src/test/java/com/querydsl/mongodb/domain/City.java @@ -0,0 +1,33 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.mongodb.domain; + + +public final class City { + + public City() { } + + public City(String name, Double latitude, Double longitude) { + this.name = name; + this.latitude = latitude; + this.longitude = longitude; + } + + public String name; + + public Double latitude; + + public Double longitude; + +} diff --git a/querydsl-mongodb/src/test/java/com/querydsl/mongodb/domain/Country.java b/querydsl-mongodb/src/test/java/com/querydsl/mongodb/domain/Country.java new file mode 100644 index 0000000000..afac00143c --- /dev/null +++ b/querydsl-mongodb/src/test/java/com/querydsl/mongodb/domain/Country.java @@ -0,0 +1,29 @@ +package com.querydsl.mongodb.domain; + +import java.util.Locale; + +import org.mongodb.morphia.annotations.Converters; +import org.mongodb.morphia.annotations.Entity; + +@Entity +@Converters(LocaleConverter.class) +public class Country extends AbstractEntity { + private String name; + private Locale defaultLocale; + + Country() { } + + public Country(String name, Locale defaultLocale) { + this.name = name; + this.defaultLocale = defaultLocale; + } + + public String getName() { + return name; + } + + public Locale getDefaultLocale() { + return defaultLocale; + } + +} diff --git a/querydsl-mongodb/src/test/java/com/mysema/query/mongodb/domain/Dates.java b/querydsl-mongodb/src/test/java/com/querydsl/mongodb/domain/Dates.java similarity index 87% rename from querydsl-mongodb/src/test/java/com/mysema/query/mongodb/domain/Dates.java rename to querydsl-mongodb/src/test/java/com/querydsl/mongodb/domain/Dates.java index 1f718b900f..6c4927b35a 100644 --- a/querydsl-mongodb/src/test/java/com/mysema/query/mongodb/domain/Dates.java +++ b/querydsl-mongodb/src/test/java/com/querydsl/mongodb/domain/Dates.java @@ -1,4 +1,4 @@ -package com.mysema.query.mongodb.domain; +package com.querydsl.mongodb.domain; import java.util.Date; diff --git a/querydsl-mongodb/src/test/java/com/querydsl/mongodb/domain/DummyEntity.java b/querydsl-mongodb/src/test/java/com/querydsl/mongodb/domain/DummyEntity.java new file mode 100644 index 0000000000..cae09a2ed5 --- /dev/null +++ b/querydsl-mongodb/src/test/java/com/querydsl/mongodb/domain/DummyEntity.java @@ -0,0 +1,33 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.mongodb.domain; + +import org.mongodb.morphia.annotations.Entity; +import org.mongodb.morphia.annotations.Property; + +@Entity +public class DummyEntity extends AbstractEntity { + + @Property("prop") + private String property; + + public String getProperty() { + return property; + } + + public void setProperty(String property) { + this.property = property; + } + +} diff --git a/querydsl-mongodb/src/test/java/com/querydsl/mongodb/domain/Fish.java b/querydsl-mongodb/src/test/java/com/querydsl/mongodb/domain/Fish.java new file mode 100644 index 0000000000..95098dce95 --- /dev/null +++ b/querydsl-mongodb/src/test/java/com/querydsl/mongodb/domain/Fish.java @@ -0,0 +1,36 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.mongodb.domain; + +import org.mongodb.morphia.annotations.Entity; + +@Entity("food") +public class Fish extends Food { + + private final String breed; + + public Fish(final String name) { + super(name); + this.breed = "unknown"; + } + + public Fish(final String name, final String breed) { + super(name); + this.breed = breed; + } + + public String getBreed() { + return breed; + } +} diff --git a/querydsl-mongodb/src/test/java/com/querydsl/mongodb/domain/Food.java b/querydsl-mongodb/src/test/java/com/querydsl/mongodb/domain/Food.java new file mode 100644 index 0000000000..4bb0f7c43c --- /dev/null +++ b/querydsl-mongodb/src/test/java/com/querydsl/mongodb/domain/Food.java @@ -0,0 +1,29 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.mongodb.domain; + +import org.mongodb.morphia.annotations.Entity; + +@Entity("food") +public class Food extends AbstractEntity { + private final String name; + + public Food(final String name) { + this.name = name; + } + + public String getName() { + return name; + } +} diff --git a/querydsl-mongodb/src/test/java/com/querydsl/mongodb/domain/GeoEntity.java b/querydsl-mongodb/src/test/java/com/querydsl/mongodb/domain/GeoEntity.java new file mode 100644 index 0000000000..fea700183b --- /dev/null +++ b/querydsl-mongodb/src/test/java/com/querydsl/mongodb/domain/GeoEntity.java @@ -0,0 +1,44 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.mongodb.domain; + +import org.mongodb.morphia.annotations.Entity; +import org.mongodb.morphia.annotations.Field; +import org.mongodb.morphia.annotations.Index; +import org.mongodb.morphia.annotations.Indexes; +import org.mongodb.morphia.utils.IndexType; + + +@Entity +@Indexes({@Index(fields = @Field(value = "location", type = IndexType.GEO2D))}) +public class GeoEntity extends AbstractEntity { + + private Double[] location; + + public GeoEntity(double l1, double l2) { + location = new Double[]{l1, l2}; + } + + public GeoEntity() { } + + public Double[] getLocation() { + return location; + } + + public void setLocation(Double[] location) { + this.location = location; + } + + +} diff --git a/querydsl-mongodb/src/test/java/com/querydsl/mongodb/domain/Item.java b/querydsl-mongodb/src/test/java/com/querydsl/mongodb/domain/Item.java new file mode 100644 index 0000000000..1fda09d0c6 --- /dev/null +++ b/querydsl-mongodb/src/test/java/com/querydsl/mongodb/domain/Item.java @@ -0,0 +1,34 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.mongodb.domain; + +import java.util.List; + +import org.bson.types.ObjectId; +import org.mongodb.morphia.annotations.Entity; + +@Entity +public class Item extends AbstractEntity { + + private List<ObjectId> ctds; + + public List<ObjectId> getCtds() { + return ctds; + } + + public void setCtds(List<ObjectId> ctds) { + this.ctds = ctds; + } + +} diff --git a/querydsl-mongodb/src/test/java/com/querydsl/mongodb/domain/LocaleConverter.java b/querydsl-mongodb/src/test/java/com/querydsl/mongodb/domain/LocaleConverter.java new file mode 100644 index 0000000000..97e2f2c2e4 --- /dev/null +++ b/querydsl-mongodb/src/test/java/com/querydsl/mongodb/domain/LocaleConverter.java @@ -0,0 +1,38 @@ +package com.querydsl.mongodb.domain; + +import java.util.Locale; + +import org.mongodb.morphia.converters.SimpleValueConverter; +import org.mongodb.morphia.converters.TypeConverter; +import org.mongodb.morphia.mapping.MappedField; +import org.mongodb.morphia.mapping.MappingException; + +public class LocaleConverter extends TypeConverter implements SimpleValueConverter { + + public LocaleConverter() { + super(Locale.class); + } + + @Override + public final Object encode(Object value, MappedField optionalExtraInfo) throws MappingException { + if (value == null) { + return null; + } + if (!(value instanceof Locale)) { + throw new MappingException("Unable to convert " + value.getClass().getName()); + } + return ((Locale) value).toLanguageTag(); + } + + @Override + @SuppressWarnings("rawtypes") + public Locale decode(Class targetClass, Object fromDBObject, MappedField optionalExtraInfo) throws MappingException { + if (fromDBObject == null) { + return null; + } + if (fromDBObject instanceof String) { + return Locale.forLanguageTag((String) fromDBObject); + } + throw new MappingException("Unable to convert " + fromDBObject.getClass().getName()); + } +} diff --git a/querydsl-mongodb/src/test/java/com/mysema/query/mongodb/domain/MapEntity.java b/querydsl-mongodb/src/test/java/com/querydsl/mongodb/domain/MapEntity.java similarity index 91% rename from querydsl-mongodb/src/test/java/com/mysema/query/mongodb/domain/MapEntity.java rename to querydsl-mongodb/src/test/java/com/querydsl/mongodb/domain/MapEntity.java index cd64350564..4a9627990a 100644 --- a/querydsl-mongodb/src/test/java/com/mysema/query/mongodb/domain/MapEntity.java +++ b/querydsl-mongodb/src/test/java/com/querydsl/mongodb/domain/MapEntity.java @@ -1,4 +1,4 @@ -package com.mysema.query.mongodb.domain; +package com.querydsl.mongodb.domain; import java.util.HashMap; import java.util.Map; @@ -19,5 +19,5 @@ public Map<String, String> getProperties() { public void setProperties(Map<String, String> properties) { this.properties = properties; } - + } diff --git a/querydsl-mongodb/src/test/java/com/querydsl/mongodb/domain/Person.java b/querydsl-mongodb/src/test/java/com/querydsl/mongodb/domain/Person.java new file mode 100644 index 0000000000..4e3a637fd4 --- /dev/null +++ b/querydsl-mongodb/src/test/java/com/querydsl/mongodb/domain/Person.java @@ -0,0 +1,16 @@ +package com.querydsl.mongodb.domain; + +import org.bson.types.ObjectId; +import org.mongodb.morphia.annotations.Entity; +import org.mongodb.morphia.annotations.Id; + +@Entity +class Person { + @Id + public ObjectId id; + + public String name; + + // manual reference to an address + public ObjectId addressId; +} \ No newline at end of file diff --git a/querydsl-mongodb/src/test/java/com/querydsl/mongodb/domain/User.java b/querydsl-mongodb/src/test/java/com/querydsl/mongodb/domain/User.java new file mode 100644 index 0000000000..74f693265e --- /dev/null +++ b/querydsl-mongodb/src/test/java/com/querydsl/mongodb/domain/User.java @@ -0,0 +1,168 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.mongodb.domain; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import org.mongodb.morphia.annotations.Embedded; +import org.mongodb.morphia.annotations.Entity; +import org.mongodb.morphia.annotations.Reference; + +@Entity +public class User extends AbstractEntity { + + public enum Gender { MALE, FEMALE } + + private String firstName; + + private String lastName; + + private Date created; + + private Gender gender; + + @Embedded + private final List<Address> addresses = new ArrayList<Address>(); + + @Embedded + private Address mainAddress; + + @Reference + private final List<User> friends = new ArrayList<User>(); + + @Reference + private User friend; + + @Reference("enemyRef") + private User enemy; + + private int age; + + public User() { + } + + public User(String firstName, String lastName, User friend) { + this(firstName, lastName); + this.friend = friend; + } + + public User(String firstName, String lastName) { + this.firstName = firstName; this.lastName = lastName; + this.created = new Date(); + } + + public User(String firstName, String lastName, int age, Date created) { + this.firstName = firstName; this.lastName = lastName; this.age = age; this.created = created; + } + + @Override + public String toString() { + return "TestUser [id=" + getId() + ", firstName=" + firstName + ", lastName=" + lastName + + "]"; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public Date getCreated() { + return created; + } + + public void setCreated(Date created) { + this.created = created; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + + public Address getMainAddress() { + return mainAddress; + } + + public void setMainAddress(Address mainAddress) { + this.mainAddress = mainAddress; + } + + public void setMainAddress(String street, String postCode, City city) { + this.mainAddress = new Address(street, postCode, city); + } + + public User addAddress(Address address) { + addresses.add(address); + return this; + } + + public User addAddress(String street, String postalCode, City city) { + addresses.add(new Address(street, postalCode, city)); + return this; + } + + public List<Address> getAddresses() { + return addresses; + } + + public User addFriend(User friend) { + friends.add(friend); + return this; + } + + public List<User> getFriends() { + return friends; + } + + public Gender getGender() { + return gender; + } + + public void setGender(Gender gender) { + this.gender = gender; + } + + public User getFriend() { + return friend; + } + + public void setFriend(User friend) { + this.friend = friend; + } + + public User getEnemy() { + return enemy; + } + + public void setEnemy(User enemy) { + this.enemy = enemy; + } + +} diff --git a/querydsl-mongodb/src/test/java/com/querydsl/mongodb/domain/UserTest.java b/querydsl-mongodb/src/test/java/com/querydsl/mongodb/domain/UserTest.java new file mode 100644 index 0000000000..6f13b882c8 --- /dev/null +++ b/querydsl-mongodb/src/test/java/com/querydsl/mongodb/domain/UserTest.java @@ -0,0 +1,60 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.mongodb.domain; + +import static org.junit.Assert.assertNotNull; + +import org.bson.types.ObjectId; +import org.junit.Test; +import org.mongodb.morphia.Morphia; + +public class UserTest { + + private static final Morphia morphia = new Morphia().map(User.class); + + @Test + public void map() { + City tampere = new City("Tampere", 61.30, 23.50); + + User user = new User(); + user.setAge(12); + user.setFirstName("Jaakko"); + user.addAddress("Aakatu", "00300", tampere); + + assertNotNull(morphia.toDBObject(user)); + } + + @Test + public void friend() { + User friend = new User(); + friend.setId(ObjectId.createFromLegacyFormat(1,2,3)); + + User user = new User(); + user.setFriend(friend); + + assertNotNull(morphia.toDBObject(user)); + } + + @Test + public void friends() { + User friend = new User(); + friend.setId(ObjectId.createFromLegacyFormat(1,2,3)); + + User user = new User(); + user.addFriend(friend); + + assertNotNull(morphia.toDBObject(user)); + } + +} diff --git a/querydsl-mongodb/src/test/java/com/querydsl/mongodb/domain/package-info.java b/querydsl-mongodb/src/test/java/com/querydsl/mongodb/domain/package-info.java new file mode 100644 index 0000000000..f4310476e3 --- /dev/null +++ b/querydsl-mongodb/src/test/java/com/querydsl/mongodb/domain/package-info.java @@ -0,0 +1,5 @@ +@Config(entityAccessors = true) +package com.querydsl.mongodb.domain; + +import com.querydsl.core.annotations.Config; + diff --git a/querydsl-mongodb/src/test/java/com/querydsl/mongodb/domain2/User.java b/querydsl-mongodb/src/test/java/com/querydsl/mongodb/domain2/User.java new file mode 100644 index 0000000000..c9ebb1b184 --- /dev/null +++ b/querydsl-mongodb/src/test/java/com/querydsl/mongodb/domain2/User.java @@ -0,0 +1,27 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.mongodb.domain2; + +import java.util.Map; + +import org.mongodb.morphia.annotations.Embedded; +import org.mongodb.morphia.annotations.Entity; + +@Entity(value = "USER", noClassnameStored = true) +public class User { + + @Embedded + Map<String, UserAttribute> properties; + +} \ No newline at end of file diff --git a/querydsl-mongodb/src/test/java/com/mysema/query/mongodb/domain2/UserAttribute.java b/querydsl-mongodb/src/test/java/com/querydsl/mongodb/domain2/UserAttribute.java similarity index 86% rename from querydsl-mongodb/src/test/java/com/mysema/query/mongodb/domain2/UserAttribute.java rename to querydsl-mongodb/src/test/java/com/querydsl/mongodb/domain2/UserAttribute.java index 6723c828c4..3c319c2f9e 100644 --- a/querydsl-mongodb/src/test/java/com/mysema/query/mongodb/domain2/UserAttribute.java +++ b/querydsl-mongodb/src/test/java/com/querydsl/mongodb/domain2/UserAttribute.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.mongodb.domain2; +package com.querydsl.mongodb.domain2; import org.mongodb.morphia.annotations.Embedded; @@ -19,5 +19,5 @@ public class UserAttribute { //simple property values (String, Object or Date) - + } \ No newline at end of file diff --git a/querydsl-mongodb/template.mf b/querydsl-mongodb/template.mf deleted file mode 100644 index 876b62b9b6..0000000000 --- a/querydsl-mongodb/template.mf +++ /dev/null @@ -1,15 +0,0 @@ -Bundle-SymbolicName: com.mysema.querydsl.mongodb -Bundle-Name: Querydsl Mongodb -Bundle-Vendor: Mysema -Bundle-ManifestVersion: 2 -Import-Template: - com.mongodb.*;version="0", - org.mongodb.morphia.*;version="${morphia.version}";resolution:=optional, - com.mysema.commons.lang.*;version="${mysema.lang.version}", - com.mysema.query.apt;version="${project.version}";resolution:=optional, - com.mysema.query.*;version="${project.version}", - javax.annotation.*;version="0";resolution:=optional, - javax.lang.model.*;version="0", - javax.tools.*;version="0", - com.google.common.*;version="${guava.version}", - org.bson.*;version="0" diff --git a/querydsl-root/dist.sh b/querydsl-root/dist.sh deleted file mode 100755 index 28fb0f7958..0000000000 --- a/querydsl-root/dist.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/sh -rm -rf target/dist -mkdir -p target/dist - -echo "Creating javadocs" -mvn javadoc:aggregate - -echo "Creating release bundles" -for module in apt collections hibernate-search jpa jdo lucene3 lucene4 sql sql-codegen -do - cd ../querydsl-$module - mvn -Dtest=X clean assembly:assembly -done - -echo "Creating reference documentation" -cd ../querydsl-docs -mkdir -p ../querydsl-root/target/dist/reference -mvn -Dxslthl.config=http://docbook.sourceforge.net/release/xsl/current/highlighting/xslthl-config.xml clean package -cp -R target/docbook/publish/en-US/* ../querydsl-root/target/dist/reference/ -mvn -Dxslthl.config=http://docbook.sourceforge.net/release/xsl/current/highlighting/xslthl-config.xml -Dtranslation=ko-KR clean package -cp -R target/docbook/publish/ko-KR ../querydsl-root/target/dist/reference/ -cd ../querydsl-root - -echo "done." diff --git a/querydsl-root/docs.sh b/querydsl-root/docs.sh deleted file mode 100755 index d25efa4868..0000000000 --- a/querydsl-root/docs.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh -echo "Creating reference documentation" -cd ../querydsl-docs -mvn -Dxslthl.config=http://docbook.sourceforge.net/release/xsl/current/highlighting/xslthl-config.xml clean package -cd ../querydsl-root -echo "done." diff --git a/querydsl-root/pom.xml b/querydsl-root/pom.xml deleted file mode 100644 index 3601c7740c..0000000000 --- a/querydsl-root/pom.xml +++ /dev/null @@ -1,562 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> - - <modelVersion>4.0.0</modelVersion> - <groupId>com.mysema.querydsl</groupId> - <artifactId>querydsl-root</artifactId> - <version>3.4.1.BUILD-SNAPSHOT</version> - <name>Querydsl</name> - <description>parent project for Querydsl modules</description> - <url>${project.homepage}</url> - - <parent> - <groupId>com.mysema.home</groupId> - <artifactId>mysema-source</artifactId> - <version>0.3.1</version> - </parent> - - <packaging>pom</packaging> - - <inceptionYear>2007</inceptionYear> - - <properties> - <failIfNoTests>false</failIfNoTests> - <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> - <project.homepage>http://www.querydsl.com</project.homepage> - <project.githubpage>http://github.com/querydsl/querydsl</project.githubpage> - <project.checkout>scm:git:git@github.com:querydsl/querydsl.git</project.checkout> - - <!-- deps --> - <derby.version>10.10.1.1</derby.version> - <hsqldb.version>2.3.1</hsqldb.version> - <h2.version>1.4.178</h2.version> - <postgresql.version>9.3-1101-jdbc41</postgresql.version> - <oracle.version>11.1.0.7.0</oracle.version> - <mysql.version>5.1.30</mysql.version> - <jtds.version>1.3.1</jtds.version> - <cubrid.version>8.4.0</cubrid.version> - <sqlite.version>3.7.2</sqlite.version> - <teradata.version>13.10.00.35</teradata.version> - - <guava.version>14.0</guava.version> - <codegen.version>0.6.2</codegen.version> - <mysema.lang.version>0.2.4</mysema.lang.version> - <cglib.version>2.2.2</cglib.version> - <findbugs.version>1.3.2</findbugs.version> - <slf4j.version>1.6.1</slf4j.version> - </properties> - - <dependencies> - <dependency> - <groupId>junit</groupId> - <artifactId>junit</artifactId> - <version>4.8.1</version> - <scope>test</scope> - <exclusions> - <exclusion> - <groupId>javax.servlet</groupId> - <artifactId>servlet-api</artifactId> - </exclusion> - </exclusions> - </dependency> - - <dependency> - <groupId>org.easymock</groupId> - <artifactId>easymock</artifactId> - <version>3.0</version> - <scope>test</scope> - <exclusions> - <exclusion> - <groupId>cglib</groupId> - <artifactId>cglib-nodep</artifactId> - </exclusion> - </exclusions> - </dependency> - </dependencies> - - <dependencyManagement> - <dependencies> - <dependency> - <groupId>org.slf4j</groupId> - <artifactId>slf4j-api</artifactId> - <version>${slf4j.version}</version> - </dependency> - <dependency> - <groupId>org.slf4j</groupId> - <artifactId>slf4j-log4j12</artifactId> - <version>${slf4j.version}</version> - <scope>provided</scope> - </dependency> - </dependencies> - </dependencyManagement> - - <scm> - <connection>${project.checkout}</connection> - <developerConnection>${project.checkout}</developerConnection> - <url>${project.githubpage}</url> - </scm> - - <developers> - <developer> - <id>tiwe</id> - <name>Timo Westkämper</name> - <email>timo.westkamper@gmail.com</email> - <organization>Mysema Ltd</organization> - <roles> - <role>Project Manager</role> - <role>Architect</role> - </roles> - </developer> - <developer> - <id>sasa</id> - <name>Samppa Saarela</name> - <email>samppa.saarela@mysema.com</email> - <organization>Mysema Ltd</organization> - <roles> - <role>Developer</role> - </roles> - </developer> - <developer> - <id>vema</id> - <name>Vesa Marttila</name> - <email>vesa.marttila@mysema.com</email> - <organization>Mysema Ltd</organization> - <roles> - <role>Developer</role> - </roles> - </developer> - <developer> - <id>laim</id> - <name>Lassi Immonen</name> - <email>lassi.immonen@mysema.com</email> - <organization>Mysema Ltd</organization> - <roles> - <role>Developer</role> - </roles> - </developer> - </developers> - - <licenses> - <license> - <name>Apache License, Version 2.0</name> - <url>LICENSE.txt</url> - </license> - </licenses> - - <build> - <pluginManagement> - <plugins> - <plugin> - <groupId>org.apache.maven.plugins</groupId> - <artifactId>maven-assembly-plugin</artifactId> - <version>2.4</version> - </plugin> - <plugin> - <groupId>com.mysema.maven</groupId> - <artifactId>apt-maven-plugin</artifactId> - <version>1.0.9</version> - </plugin> - <plugin> - <groupId>org.apache.maven.plugins</groupId> - <artifactId>maven-surefire-plugin</artifactId> - <version>2.16</version> - </plugin> - <plugin> - <groupId>com.springsource.bundlor</groupId> - <artifactId>com.springsource.bundlor.maven</artifactId> - <version>1.0.0.RELEASE</version> - <executions> - <execution> - <id>bundlor</id> - <goals> - <goal>bundlor</goal> - </goals> - </execution> - </executions> - <configuration> - <failOnWarnings>true</failOnWarnings> - </configuration> - </plugin> - </plugins> - </pluginManagement> - - <plugins> - <plugin> - <groupId>org.apache.maven.plugins</groupId> - <artifactId>maven-enforcer-plugin</artifactId> - <version>1.3.1</version> - <executions> - <execution> - <id>check</id> - <phase>verify</phase> - <goals> - <goal>enforce</goal> - </goals> - <configuration> - <rules> - <requireBackwardCompatibility implementation="org.semver.enforcer.RequireBackwardCompatibility"> - <compatibilityType>BACKWARD_COMPATIBLE_USER</compatibilityType> - <dumpDetails>true</dumpDetails> - <publicOnly>true</publicOnly> - </requireBackwardCompatibility> - </rules> - </configuration> - </execution> - </executions> - <dependencies> - <dependency> - <groupId>org.semver</groupId> - <artifactId>enforcer-rule</artifactId> - <version>0.9.24</version> - </dependency> - </dependencies> - </plugin> - <plugin> - <artifactId>maven-assembly-plugin</artifactId> - <configuration> - <descriptors> - <descriptor>../querydsl-root/src/main/assembly.xml</descriptor> - </descriptors> - <outputDirectory>../querydsl-root/target/dist</outputDirectory> - </configuration> - </plugin> - <plugin> - <groupId>org.apache.maven.plugins</groupId> - <artifactId>maven-javadoc-plugin</artifactId> - <version>2.9.1</version> - <configuration> - <outputDirectory>${project.build.directory}/dist/apidocs</outputDirectory> - <reportOutputDirectory>${project.build.directory}/dist/apidocs</reportOutputDirectory> - <groups> - <group> - <title>Core - com.mysema.query:com.mysema.query.alias:com.mysema.query.annotations:com.mysema.query.codegen:com.mysema.query.dml:com.mysema.query.functions:com.mysema.query.serialization:com.mysema.query.support:com.mysema.query.types* - - - APT - com.mysema.query.apt* - - - Spatial - com.mysema.query.spatial* - - - Collections - com.mysema.query.collections* - - - JPA - com.mysema.query.jpa* - - - JDO - com.mysema.query.jdo* - - - SQL - com.mysema.query.sql* - - - Spatial - com.mysema.query.spatial* - - - Lucene - com.mysema.query.lucene - - - Hibernate Search - com.mysema.query.search - - - Mongodb - com.mysema.query.mongodb* - - - - - - com.mysema.maven - maven-version-plugin - 0.1.0 - - - org.apache.maven.plugins - maven-pmd-plugin - 2.3 - - 1.6 - true - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.1 - - 1.6 - 1.6 - - - - org.apache.maven.plugins - maven-source-plugin - 2.2.1 - - - package - - jar - - - - - - org.apache.maven.plugins - maven-jar-plugin - 2.4 - - true - - - - org.apache.maven.plugins - maven-surefire-plugin - - -Xms256m -Xmx512m -XX:MaxPermSize=512m - com.mysema.testutil.ExternalDB - - - - org.apache.maven.surefire - surefire-junit47 - 2.16 - - - - - - - - - jahia - http://maven.jahia.org/maven2 - - - com.springsource.repository.bundles.release - http://repository.springsource.com/maven/bundles/release - - - geoapi - http://maven.geotoolkit.org - - - opengeo - http://repo.opengeo.org - - - nexus - https://maven.nuxeo.org/nexus/content/groups/public - - - - - - com.springsource.repository.bundles.release - http://repository.springsource.com/maven/bundles/release - - - com.springsource.repository.bundles.external - http://repository.springsource.com/maven/bundles/external - - - - - - all - true - - ../querydsl-core - ../querydsl-codegen - ../querydsl-spatial - ../querydsl-apt - ../querydsl-collections - ../querydsl-sql - ../querydsl-sql-codegen - ../querydsl-maven-plugin - ../querydsl-jpa - ../querydsl-jpa-codegen - ../querydsl-jdo - - - ../querydsl-lucene3 - ../querydsl-lucene4 - ../querydsl-hibernate-search - - - ../querydsl-mongodb - - - ../querydsl-scala - - - - - hibernate-search - - ../querydsl-core - ../querydsl-codegen - ../querydsl-lucene3 - ../querydsl-hibernate-search - - - - - jpa - - ../querydsl-core - ../querydsl-codegen - ../querydsl-spatial - ../querydsl-apt - ../querydsl-sql - ../querydsl-sql-codegen - ../querydsl-maven-plugin - ../querydsl-jpa - ../querydsl-jpa-codegen - - - - - jdo - - ../querydsl-core - ../querydsl-codegen - ../querydsl-spatial - ../querydsl-apt - ../querydsl-sql - ../querydsl-sql-codegen - ../querydsl-maven-plugin - ../querydsl-jdo - - - - - lucene - - ../querydsl-core - ../querydsl-codegen - ../querydsl-apt - ../querydsl-lucene3 - ../querydsl-lucene4 - - - - - mongodb - - ../querydsl-core - ../querydsl-codegen - ../querydsl-apt - ../querydsl-mongodb - - - - - sql - - ../querydsl-core - ../querydsl-codegen - ../querydsl-spatial - ../querydsl-sql - ../querydsl-sql-codegen - ../querydsl-maven-plugin - - - - - collections - - ../querydsl-core - ../querydsl-codegen - ../querydsl-apt - ../querydsl-collections - - - - - jenkins - - - - org.apache.maven.plugins - maven-surefire-plugin - - com.mysema.testutil.DummyInterface - - **/*$* - **/MSSQLSuiteTest.java - **/TeradataSuiteTest.java - - - - - - - - - travis - - - - org.apache.maven.plugins - maven-surefire-plugin - - com.mysema.testutil.DummyInterface - - **/*$* - **/ExportOracleTest.java - **/ExportTeradataTest.java - **/OracleSuiteTest.java - **/OracleWithQuotingTest.java - **/MSSQLSuiteTest.java - **/TeradataSuiteTest.java - - - - - - - - - - - - - - org.apache.maven.plugins - maven-javadoc-plugin - 2.9.1 - - true - - - - org.codehaus.mojo - junit-report-maven-plugin - devel - - true - - - - org.apache.maven.plugins - maven-jxr-plugin - 2.3 - - true - - - - - - diff --git a/querydsl-scala/pom.xml b/querydsl-scala/pom.xml index d073535585..3fe168e462 100644 --- a/querydsl-scala/pom.xml +++ b/querydsl-scala/pom.xml @@ -1,31 +1,46 @@ - + 4.0.0 - com.mysema.querydsl + com.querydsl querydsl-root - 3.4.1.BUILD-SNAPSHOT - ../querydsl-root/pom.xml + 5.1.0 + ../pom.xml - com.mysema.querydsl + com.querydsl querydsl-scala Querydsl - Scala support jar - + UTF-8 + -Xms256m -Xmx512m -Xss2m + true - 2.10 - 2.10.0 - 3.5.1-Final - 4.0.2.GA + 2.11.12 + 3.5.6-Final + + + + + org.scala-lang + scala-library + ${scala.full.version} + + + - + - com.mysema.querydsl + org.jetbrains + annotations + provided + + + com.querydsl querydsl-core ${project.version} @@ -44,13 +59,13 @@ - com.mysema.querydsl + com.querydsl querydsl-sql ${project.version} provided - com.mysema.querydsl + com.querydsl querydsl-sql-codegen ${project.version} provided @@ -58,7 +73,7 @@ - com.mysema.querydsl + com.querydsl querydsl-core ${project.version} test @@ -66,39 +81,29 @@ - com.mysema.querydsl + com.querydsl querydsl-jpa ${project.version} test - - - - org.hibernate - hibernate-annotations - ${hibernate.version} - - - cglib - cglib - - - asm - asm - - - test - + + - org.hibernate - hibernate-entitymanager - ${hibernate.version} + jakarta.persistence + jakarta.persistence-api test + - org.hibernate + org.hibernate.validator hibernate-validator ${hibernate.validator.version} test + + + slf4j-api + org.slf4j + + @@ -110,16 +115,9 @@ com.h2database h2 - ${h2.version} test - - org.slf4j - slf4j-log4j12 - provided - - @@ -139,6 +137,7 @@ -unchecked -deprecation + -nobootcp @@ -174,7 +173,7 @@ - com.mysema.querydsl + joda-time + joda-time + ${jodatime.version} + test + + + com.querydsl querydsl-core ${project.version} test test-jar + + com.querydsl + querydsl-apt + ${project.version} + test + - com.springsource.bundlor - com.springsource.bundlor.maven + org.apache.felix + maven-bundle-plugin org.apache.maven.plugins @@ -54,6 +91,13 @@ + + + + com.querydsl.spatial + + + maven-source-plugin @@ -66,10 +110,25 @@ + + com.mysema.maven + apt-maven-plugin + + + generate-test-sources + + test-process + add-test-sources + + + target/generated-test-sources/java + + com.querydsl.apt.QuerydslAnnotationProcessor + + + + + - - - 1.11 - - + diff --git a/querydsl-spatial/src/main/java/com/mysema/query/spatial/CurveExpression.java b/querydsl-spatial/src/main/java/com/mysema/query/spatial/CurveExpression.java deleted file mode 100644 index b07b1bee63..0000000000 --- a/querydsl-spatial/src/main/java/com/mysema/query/spatial/CurveExpression.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright 2014, Mysema Ltd - * - * 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. - */ -package com.mysema.query.spatial; - -import javax.annotation.Nullable; - -import org.geolatte.geom.Geometry; -import org.geolatte.geom.Point; - -import com.mysema.query.types.Expression; -import com.mysema.query.types.expr.BooleanExpression; -import com.mysema.query.types.expr.BooleanOperation; -import com.mysema.query.types.expr.NumberExpression; -import com.mysema.query.types.expr.NumberOperation; - -/** - * A Curve is a 1-dimensional geometric object usually stored as a sequence of Points, with the subtype of Curve - * specifying the form of the interpolation between Points. This standard defines only one subclass of Curve, - * LineString, which uses linear interpolation between Points. - * - * @author tiwe - * - * @param - */ -public abstract class CurveExpression extends GeometryExpression { - - private static final long serialVersionUID = 6139188586728676033L; - - @Nullable - private volatile NumberExpression length; - - @Nullable - private volatile PointExpression startPoint, endPoint; - - @Nullable - private volatile BooleanExpression closed, ring; - - public CurveExpression(Expression mixin) { - super(mixin); - } - - /** - * The length of this Curve in its associated spatial reference. - * - * @return - */ - public NumberExpression length() { - if (length == null) { - length = NumberOperation.create(Double.class, SpatialOps.LENGTH, mixin); - } - return length; - } - - /** - * The start Point of this Curve. - * - * @return - */ - public PointExpression startPoint() { - if (startPoint == null) { - startPoint = PointOperation.create(Point.class, SpatialOps.START_POINT, mixin); - } - return startPoint; - } - - /** - * The end Point of this Curve. - * - * @return - */ - public PointExpression endPoint() { - if (endPoint == null) { - endPoint = PointOperation.create(Point.class, SpatialOps.END_POINT, mixin); - } - return endPoint; - } - - /** - * Returns 1 (TRUE) if this Curve is closed [StartPoint ( ) = EndPoint ( )]. - * - * @return - */ - public BooleanExpression isClosed() { - if (closed == null) { - closed = BooleanOperation.create(SpatialOps.IS_CLOSED, mixin); - } - return closed; - } - - /** - * Returns 1 (TRUE) if this Curve is closed [StartPoint ( ) = EndPoint ( )] and this Curve is - * simple (does not pass through the same Point more than once). - * - * @return - */ - public BooleanExpression isRing() { - if (ring == null) { - ring = BooleanOperation.create(SpatialOps.IS_RING, mixin); - } - return ring; - } - -} diff --git a/querydsl-spatial/src/main/java/com/mysema/query/spatial/GeometryCollectionExpression.java b/querydsl-spatial/src/main/java/com/mysema/query/spatial/GeometryCollectionExpression.java deleted file mode 100644 index 4b88530aac..0000000000 --- a/querydsl-spatial/src/main/java/com/mysema/query/spatial/GeometryCollectionExpression.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2014, Mysema Ltd - * - * 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. - */ -package com.mysema.query.spatial; - -import javax.annotation.Nullable; - -import org.geolatte.geom.Geometry; -import org.geolatte.geom.GeometryCollection; - -import com.mysema.query.types.ConstantImpl; -import com.mysema.query.types.Expression; -import com.mysema.query.types.expr.NumberExpression; -import com.mysema.query.types.expr.NumberOperation; - -/** - * A GeometryCollection is a geometric object that is a collection of some number of geometric objects. - * - * @author tiwe - * - * @param - */ -public abstract class GeometryCollectionExpression extends GeometryExpression { - - private static final long serialVersionUID = 8874174644259834690L; - - @Nullable - private volatile NumberExpression numGeometries; - - public GeometryCollectionExpression(Expression mixin) { - super(mixin); - } - - /** - * Returns the number of geometries in this GeometryCollection. - * - * @return - */ - public NumberExpression numGeometries() { - if (numGeometries == null) { - numGeometries = NumberOperation.create(Integer.class, SpatialOps.NUM_GEOMETRIES, mixin); - } - return numGeometries; - } - - /** - * Returns the Nth geometry in this GeometryCollection. - * - * @param n - * @return - */ - public GeometryExpression geometryN(Integer n) { - return GeometryOperation.create(Geometry.class, SpatialOps.GEOMETRYN, mixin, ConstantImpl.create(n)); - } - -} diff --git a/querydsl-spatial/src/main/java/com/mysema/query/spatial/GeometryExpression.java b/querydsl-spatial/src/main/java/com/mysema/query/spatial/GeometryExpression.java deleted file mode 100644 index 6183505bc3..0000000000 --- a/querydsl-spatial/src/main/java/com/mysema/query/spatial/GeometryExpression.java +++ /dev/null @@ -1,527 +0,0 @@ -/* - * Copyright 2014, Mysema Ltd - * - * 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. - */ -package com.mysema.query.spatial; - -import javax.annotation.Nullable; - -import org.geolatte.geom.Geometry; - -import com.mysema.query.types.ConstantImpl; -import com.mysema.query.types.Expression; -import com.mysema.query.types.expr.BooleanExpression; -import com.mysema.query.types.expr.BooleanOperation; -import com.mysema.query.types.expr.NumberExpression; -import com.mysema.query.types.expr.NumberOperation; -import com.mysema.query.types.expr.SimpleExpression; -import com.mysema.query.types.expr.SimpleOperation; -import com.mysema.query.types.expr.StringExpression; -import com.mysema.query.types.expr.StringOperation; - -/** - * Geometry is the root class of the hierarchy. Geometry is an abstract (non-instantiable) class. - * - * @author tiwe - * - * @param - */ -public abstract class GeometryExpression extends SimpleExpression { - - private static final long serialVersionUID = -1183228394472681995L; - - @Nullable - private volatile NumberExpression dimension, coordinateDimension, spatialDimension, srid; - - @Nullable - private volatile StringExpression geometryType; - - @Nullable - private volatile StringExpression text; - - @Nullable - private volatile GeometryExpression envelope, boundary, convexHull; - - @Nullable - private volatile BooleanExpression empty, simple, threed, measured; - - private volatile SimpleExpression binary; - - public GeometryExpression(Expression mixin) { - super(mixin); - } - - /** - * The inherent dimension of this geometric object, which must be less than or equal - * to the coordinate dimension. In non-homogeneous collections, this will return the largest topological - * dimension of the contained objects. - * - * @return - */ - public NumberExpression dimension() { - if (dimension == null) { - dimension = NumberOperation.create(Integer.class, SpatialOps.DIMENSION, mixin); - } - return dimension; - } - - /** - * Returns the name of the instantiable subtype of Geometry of which this - * geometric object is an instantiable member. The name of the subtype of Geometry is returned as a string. - * - * @return - */ - public StringExpression geometryType() { - if (geometryType == null) { - geometryType = StringOperation.create(SpatialOps.GEOMETRY_TYPE, mixin); - } - return geometryType; - } - - /** - * Returns the Spatial Reference System ID for this geometric object. This will normally be a - * foreign key to an index of reference systems stored in either the same or some other datastore. - * - * @return - */ - public NumberExpression srid() { - if (srid == null) { - srid = NumberOperation.create(Integer.class, SpatialOps.SRID, mixin); - } - return srid; - } - - /** - * The minimum bounding box for this Geometry, returned as a Geometry. The - * polygon is defined by the corner points of the bounding box [(MINX, MINY), (MAXX, MINY), (MAXX, MAXY), - * (MINX, MAXY), (MINX, MINY)]. Minimums for Z and M may be added. The simplest representation of an - * Envelope is as two direct positions, one containing all the minimums, and another all the maximums. In some - * cases, this coordinate will be outside the range of validity for the Spatial Reference System. - * - * @return - */ - public GeometryExpression envelope() { - if (envelope == null) { - envelope = GeometryOperation.create(Geometry.class, SpatialOps.ENVELOPE, mixin); - } - return envelope; - } - - /** - * Exports this geometric object to a specific Well-known Text Representation of Geometry. - * - * @return - */ - public StringExpression asText() { - if (text == null) { - text = StringOperation.create(SpatialOps.AS_TEXT, mixin); - } - return text; - } - - /** - * Exports this geometric object to a specific Well-known Binary Representation of - * Geometry. - * - * @return - */ - public SimpleExpression asBinary() { - if (binary == null) { - binary = SimpleOperation.create(byte[].class, SpatialOps.AS_BINARY, mixin); - } - return binary; - } - - /** - * Returns 1 (TRUE) if this geometric object is the empty Geometry. If true, then this - * geometric object represents the empty point set ∅ for the coordinate space. - * - * @return - */ - public BooleanExpression isEmpty() { - if (empty == null) { - empty = BooleanOperation.create(SpatialOps.IS_EMPTY, mixin); - } - return empty; - } - - /** - * Returns 1 (TRUE) if this geometric object has no anomalous geometric points, such - * as self intersection or self tangency. The description of each instantiable geometric class - * will include the specific conditions that cause an instance of that class to be classified as not simple. - * - * @return - */ - public BooleanExpression isSimple() { - if (simple == null) { - simple = BooleanOperation.create(SpatialOps.IS_SIMPLE, mixin); - } - return simple; - } - - /** - * Returns the closure of the combinatorial boundary of this geometric object - * - * @return - */ - public GeometryExpression boundary() { - if (boundary == null) { - boundary = GeometryOperation.create(Geometry.class, SpatialOps.BOUNDARY, mixin); - } - return boundary; - } - - // query - - /* (non-Javadoc) - * @see com.mysema.query.types.expr.SimpleExpression#eq(java.lang.Object) - */ - @Override - public BooleanExpression eq(Geometry right) { - return eq(ConstantImpl.create(right)); - } - - /* (non-Javadoc) - * @see com.mysema.query.types.expr.SimpleExpression#eq(com.mysema.query.types.Expression) - */ - @Override - public BooleanExpression eq(Expression right) { - return BooleanOperation.create(SpatialOps.EQUALS, mixin, right); - } - - /** - * Returns 1 (TRUE) if this geometric object is “spatially disjoint” from anotherGeometry. - * - * @param geometry - * @return - */ - public BooleanExpression disjoint(Geometry geometry) { - return disjoint(ConstantImpl.create(geometry)); - } - - /** - * Returns 1 (TRUE) if this geometric object is “spatially disjoint” from anotherGeometry. - * - * @param geometry - * @return - */ - public BooleanExpression disjoint(Expression geometry) { - return BooleanOperation.create(SpatialOps.DISJOINT, mixin, geometry); - } - - /** - * Returns 1 (TRUE) if this geometric object “spatially intersects” anotherGeometry. - * - * @param geometry - * @return - */ - public BooleanExpression intersects(Geometry geometry) { - return intersects(ConstantImpl.create(geometry)); - } - - /** - * Returns 1 (TRUE) if this geometric object “spatially intersects” anotherGeometry. - * - * @param geometry - * @return - */ - public BooleanExpression intersects(Expression geometry) { - return BooleanOperation.create(SpatialOps.INTERSECTS, mixin, geometry); - } - - /** - * Returns 1 (TRUE) if this geometric object “spatially touches” anotherGeometry. - * - * @param geometry - * @return - */ - public BooleanExpression touches(Geometry geometry) { - return touches(ConstantImpl.create(geometry)); - } - - /** - * Returns 1 (TRUE) if this geometric object “spatially touches” anotherGeometry. - * - * @param geometry - * @return - */ - public BooleanExpression touches(Expression geometry) { - return BooleanOperation.create(SpatialOps.TOUCHES, mixin, geometry); - } - - /** - * Returns 1 (TRUE) if this geometric object “spatially crosses’ anotherGeometry. - * - * @param geometry - * @return - */ - public BooleanExpression crosses(Geometry geometry) { - return crosses(ConstantImpl.create(geometry)); - } - - /** - * Returns 1 (TRUE) if this geometric object “spatially crosses’ anotherGeometry. - * - * @param geometry - * @return - */ - public BooleanExpression crosses(Expression geometry) { - return BooleanOperation.create(SpatialOps.CROSSES, mixin, geometry); - } - - /** - * Returns 1 (TRUE) if this geometric object is “spatially within” anotherGeometry. - * - * @param geometry - * @return - */ - public BooleanExpression within(Geometry geometry) { - return within(ConstantImpl.create(geometry)); - } - - /** - * Returns 1 (TRUE) if this geometric object is “spatially within” anotherGeometry. - * - * @param geometry - * @return - */ - public BooleanExpression within(Expression geometry) { - return BooleanOperation.create(SpatialOps.WITHIN, mixin, geometry); - } - - /** - * Returns 1 (TRUE) if this geometric object “spatially contains” anotherGeometry. - * - * @param geometry - * @return - */ - public BooleanExpression contains(Geometry geometry) { - return contains(ConstantImpl.create(geometry)); - } - - /** - * Returns 1 (TRUE) if this geometric object “spatially contains” anotherGeometry. - * - * @param geometry - * @return - */ - public BooleanExpression contains(Expression geometry) { - return BooleanOperation.create(SpatialOps.CONTAINS, mixin, geometry); - } - - /** - * Returns 1 (TRUE) if this geometric object “spatially overlaps” anotherGeometry. - * - * @param geometry - * @return - */ - public BooleanExpression overlaps(Geometry geometry) { - return overlaps(ConstantImpl.create(geometry)); - } - - /** - * Returns 1 (TRUE) if this geometric object “spatially overlaps” anotherGeometry. - * - * @param geometry - * @return - */ - public BooleanExpression overlaps(Expression geometry) { - return BooleanOperation.create(SpatialOps.OVERLAPS, mixin, geometry); - } - - /** - * Returns 1 (TRUE) if this geometric object is spatially related to anotherGeometry by testing - * for intersections between the interior, boundary and exterior of the two geometric objects - * as specified by the values in the intersectionPatternMatrix. This returns FALSE if all the - * tested intersections are empty except exterior (this) intersect exterior (another). - * - * @param geometry - * @param matrix - * @return - */ - public BooleanExpression relate(Geometry geometry, String matrix) { - return relate(ConstantImpl.create(geometry), matrix); - } - - /** - * Returns 1 (TRUE) if this geometric object is spatially related to anotherGeometry by testing - * for intersections between the interior, boundary and exterior of the two geometric objects - * as specified by the values in the intersectionPatternMatrix. This returns FALSE if all the - * tested intersections are empty except exterior (this) intersect exterior (another). - * - * @param geometry - * @param matrix - * @return - */ - public BooleanExpression relate(Expression geometry, String matrix) { - return BooleanOperation.create(SpatialOps.RELATE, mixin, geometry, ConstantImpl.create(matrix)); - } - - // analysis - - /** - * Returns the shortest distance between any two Points in the two geometric objects as - * calculated in the spatial reference system of this geometric object. Because the geometries - * are closed, it is possible to find a point on each geometric object involved, such that the - * distance between these 2 points is the returned distance between their geometric objects. - * - * @param geometry - * @return - */ - public NumberExpression distance(Geometry geometry) { - return distance(ConstantImpl.create(geometry)); - } - - /** - * Returns the shortest distance between any two Points in the two geometric objects as - * calculated in the spatial reference system of this geometric object. Because the geometries - * are closed, it is possible to find a point on each geometric object involved, such that the - * distance between these 2 points is the returned distance between their geometric objects. - * - * @param geometry - * @return - */ - public NumberExpression distance(Expression geometry) { - return NumberOperation.create(Double.class, SpatialOps.DISTANCE, mixin, geometry); - } - - // TODO maybe move out - public NumberExpression distanceSphere(Expression geometry) { - return NumberOperation.create(Double.class, SpatialOps.DISTANCE_SPHERE, mixin, geometry); - } - - // TODO maybe move out - public NumberExpression distanceSpheroid(Expression geometry) { - return NumberOperation.create(Double.class, SpatialOps.DISTANCE_SPHEROID, mixin, geometry); - } - - /** - * Returns a geometric object that represents all Points whose distance from this geometric - * object is less than or equal to distance. Calculations are in the spatial reference system - * of this geometric object. Because of the limitations of linear interpolation, there will - * often be some relatively small error in this distance, but it should be near the resolution - * of the coordinates used. - * - * @param distance - * @return - */ - public GeometryExpression buffer(double distance) { - return GeometryOperation.create(Geometry.class, SpatialOps.BUFFER, mixin, ConstantImpl.create(distance)); - } - - /** - * Returns a geometric object that represents the convex hull of this geometric object. - * Convex hulls, being dependent on straight lines, can be accurately represented in linear - * interpolations for any geometry restricted to linear interpolations. - * - * @return - */ - public GeometryExpression convexHull() { - if (convexHull == null) { - convexHull = GeometryOperation.create(Geometry.class, SpatialOps.CONVEXHULL, mixin); - } - return convexHull; - } - - /** - * Returns a geometric object that represents the Point set intersection of this geometric - * object with anotherGeometry. - * - * @param geometry - * @return - */ - public GeometryExpression intersection(Geometry geometry) { - return intersection(ConstantImpl.create(geometry)); - } - - /** - * Returns a geometric object that represents the Point set intersection of this geometric - * object with anotherGeometry. - * - * @param geometry - * @return - */ - public GeometryExpression intersection(Expression geometry) { - return GeometryOperation.create(Geometry.class, SpatialOps.INTERSECTION, mixin, geometry); - } - - /** - * Returns a geometric object that represents the Point set - * union of this geometric object with anotherGeometry. - * - * @param geometry - * @return - */ - public GeometryExpression union(Geometry geometry) { - return union(ConstantImpl.create(geometry)); - } - - /** - * Returns a geometric object that represents the Point set - * union of this geometric object with anotherGeometry. - * - * @param geometry - * @return - */ - public GeometryExpression union(Expression geometry) { - return GeometryOperation.create(Geometry.class, SpatialOps.UNION, mixin, geometry); - } - - /** - * Returns a geometric object that represents the Point - * set difference of this geometric object with anotherGeometry. - * - * @param geometry - * @return - */ - public GeometryExpression difference(Geometry geometry) { - return difference(ConstantImpl.create(geometry)); - } - - /** - * Returns a geometric object that represents the Point - * set difference of this geometric object with anotherGeometry. - * - * @param geometry - * @return - */ - public GeometryExpression difference(Expression geometry) { - return GeometryOperation.create(Geometry.class, SpatialOps.DIFFERENCE, mixin, geometry); - } - - /** - * Returns a geometric object that represents the - * Point set symmetric difference of this geometric object with anotherGeometry. - * - * @param geometry - * @return - */ - public GeometryExpression symDifference(Geometry geometry) { - return symDifference(ConstantImpl.create(geometry)); - } - - /** - * Returns a geometric object that represents the - * Point set symmetric difference of this geometric object with anotherGeometry. - * - * @param geometry - * @return - */ - public GeometryExpression symDifference(Expression geometry) { - return GeometryOperation.create(Geometry.class, SpatialOps.SYMDIFFERENCE, mixin, geometry); - } - - public GeometryExpression transform(int srid) { - return GeometryOperation.create(Geometry.class, SpatialOps.TRANSFORM, mixin, ConstantImpl.create(srid)); - } - -} diff --git a/querydsl-spatial/src/main/java/com/mysema/query/spatial/GeometryOperation.java b/querydsl-spatial/src/main/java/com/mysema/query/spatial/GeometryOperation.java deleted file mode 100644 index ccb2d3a767..0000000000 --- a/querydsl-spatial/src/main/java/com/mysema/query/spatial/GeometryOperation.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2014, Mysema Ltd - * - * 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. - */ -package com.mysema.query.spatial; - -import java.util.List; - -import org.geolatte.geom.Geometry; - -import com.google.common.collect.ImmutableList; -import com.mysema.query.types.Expression; -import com.mysema.query.types.Operation; -import com.mysema.query.types.OperationImpl; -import com.mysema.query.types.Operator; -import com.mysema.query.types.Visitor; - -/** - * @author tiwe - * - * @param - */ -public class GeometryOperation extends GeometryExpression implements Operation { - - private static final long serialVersionUID = 3433471874808633698L; - - public static GeometryOperation create(Class type, Operator op, Expression one) { - return new GeometryOperation(type, op, ImmutableList.>of(one)); - } - - public static GeometryOperation create(Class type, Operator op, Expression one, Expression two) { - return new GeometryOperation(type, op, ImmutableList.of(one, two)); - } - - public static GeometryOperation create(Class type, Operator op, Expression... args) { - return new GeometryOperation(type, op, args); - } - - private final OperationImpl< T> opMixin; - - protected GeometryOperation(Class type, Operator op, Expression... args) { - this(type, op, ImmutableList.copyOf(args)); - } - - protected GeometryOperation(Class type, Operator op, ImmutableList> args) { - super(new OperationImpl(type, op, args)); - this.opMixin = (OperationImpl)mixin; - } - - @Override - public final R accept(Visitor v, C context) { - return v.visit(opMixin, context); - } - - @Override - public Expression getArg(int index) { - return opMixin.getArg(index); - } - - @Override - public List> getArgs() { - return opMixin.getArgs(); - } - - @Override - public Operator getOperator() { - return opMixin.getOperator(); - } - -} diff --git a/querydsl-spatial/src/main/java/com/mysema/query/spatial/LineStringExpression.java b/querydsl-spatial/src/main/java/com/mysema/query/spatial/LineStringExpression.java deleted file mode 100644 index 31f91ad9ae..0000000000 --- a/querydsl-spatial/src/main/java/com/mysema/query/spatial/LineStringExpression.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2014, Mysema Ltd - * - * 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. - */ -package com.mysema.query.spatial; - -import javax.annotation.Nullable; - -import org.geolatte.geom.LineString; -import org.geolatte.geom.Point; - -import com.mysema.query.types.ConstantImpl; -import com.mysema.query.types.Expression; -import com.mysema.query.types.expr.NumberExpression; -import com.mysema.query.types.expr.NumberOperation; - -/** - * A LineString is a Curve with linear interpolation between Points. Each consecutive pair of Points defines a Line - * segment. - * - * @author tiwe - * - * @param - */ -public abstract class LineStringExpression extends CurveExpression { - - private static final long serialVersionUID = -6572984614863252657L; - - @Nullable - private volatile NumberExpression numPoints; - - public LineStringExpression(Expression mixin) { - super(mixin); - } - - /** - * The number of Points in this LineString. - * - * @return - */ - public NumberExpression numPoints() { - if (numPoints == null) { - numPoints = NumberOperation.create(Integer.class, SpatialOps.NUM_POINTS, mixin); - } - return numPoints; - } - - /** - * Returns the specified Point N in this LineString. - * - * @param idx - * @return - */ - public PointExpression pointN(int idx) { - return PointOperation.create(Point.class, SpatialOps.POINTN, mixin, ConstantImpl.create(idx)); - } - -} diff --git a/querydsl-spatial/src/main/java/com/mysema/query/spatial/LineStringOperation.java b/querydsl-spatial/src/main/java/com/mysema/query/spatial/LineStringOperation.java deleted file mode 100644 index fb8f15f3a2..0000000000 --- a/querydsl-spatial/src/main/java/com/mysema/query/spatial/LineStringOperation.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2014, Mysema Ltd - * - * 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. - */ -package com.mysema.query.spatial; - -import java.util.List; - -import org.geolatte.geom.LineString; - -import com.google.common.collect.ImmutableList; -import com.mysema.query.types.Expression; -import com.mysema.query.types.Operation; -import com.mysema.query.types.OperationImpl; -import com.mysema.query.types.Operator; -import com.mysema.query.types.Visitor; - -/** - * @author tiwe - * - * @param - */ -public class LineStringOperation extends LineStringExpression implements Operation { - - private static final long serialVersionUID = 3433471874808633698L; - - public static LineStringOperation create(Class type, Operator op, Expression one) { - return new LineStringOperation(type, op, ImmutableList.>of(one)); - } - - public static LineStringOperation create(Class type, Operator op, Expression one, Expression two) { - return new LineStringOperation(type, op, ImmutableList.of(one, two)); - } - - public static LineStringOperation create(Class type, Operator op, Expression... args) { - return new LineStringOperation(type, op, args); - } - - private final OperationImpl< T> opMixin; - - protected LineStringOperation(Class type, Operator op, Expression... args) { - this(type, op, ImmutableList.copyOf(args)); - } - - protected LineStringOperation(Class type, Operator op, ImmutableList> args) { - super(new OperationImpl(type, op, args)); - this.opMixin = (OperationImpl)mixin; - } - - @Override - public final R accept(Visitor v, C context) { - return v.visit(opMixin, context); - } - - @Override - public Expression getArg(int index) { - return opMixin.getArg(index); - } - - @Override - public List> getArgs() { - return opMixin.getArgs(); - } - - @Override - public Operator getOperator() { - return opMixin.getOperator(); - } - -} diff --git a/querydsl-spatial/src/main/java/com/mysema/query/spatial/MultiCurveExpression.java b/querydsl-spatial/src/main/java/com/mysema/query/spatial/MultiCurveExpression.java deleted file mode 100644 index 17be357493..0000000000 --- a/querydsl-spatial/src/main/java/com/mysema/query/spatial/MultiCurveExpression.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2014, Mysema Ltd - * - * 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. - */ -package com.mysema.query.spatial; - -import javax.annotation.Nullable; - -import org.geolatte.geom.GeometryCollection; - -import com.mysema.query.types.Expression; -import com.mysema.query.types.expr.BooleanExpression; -import com.mysema.query.types.expr.BooleanOperation; -import com.mysema.query.types.expr.NumberExpression; -import com.mysema.query.types.expr.NumberOperation; - -/** - * A MultiCurve is a 1-dimensional GeometryCollection whose elements are Curves. - * - * @author tiwe - * - * @param - */ -public abstract class MultiCurveExpression extends GeometryCollectionExpression { - - private static final long serialVersionUID = 6983316799469849656L; - - @Nullable - private volatile BooleanExpression closed; - - @Nullable - private volatile NumberExpression length; - - public MultiCurveExpression(Expression mixin) { - super(mixin); - } - - /** - * Returns 1 (TRUE) if this MultiCurve is closed [StartPoint ( ) = EndPoint ( ) for each - * Curve in this MultiCurve]. - * - * @return - */ - public BooleanExpression isClosed() { - if (closed == null) { - closed = BooleanOperation.create(SpatialOps.IS_CLOSED, mixin); - } - return closed; - } - - /** - * The Length of this MultiCurve which is equal to the sum of the lengths of the element - * Curves. - * - * @return - */ - public NumberExpression length() { - if (length == null) { - length = NumberOperation.create(Double.class, SpatialOps.LENGTH, mixin); - } - return length; - } - -} diff --git a/querydsl-spatial/src/main/java/com/mysema/query/spatial/MultiSurfaceExpression.java b/querydsl-spatial/src/main/java/com/mysema/query/spatial/MultiSurfaceExpression.java deleted file mode 100644 index e81fafee6a..0000000000 --- a/querydsl-spatial/src/main/java/com/mysema/query/spatial/MultiSurfaceExpression.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 2014, Mysema Ltd - * - * 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. - */ -package com.mysema.query.spatial; - -import javax.annotation.Nullable; - -import org.geolatte.geom.GeometryCollection; -import org.geolatte.geom.Point; - -import com.mysema.query.types.Expression; -import com.mysema.query.types.expr.NumberExpression; -import com.mysema.query.types.expr.NumberOperation; - -/** - * A MultiSurface is a 2-dimensional GeometryCollection whose elements are Surfaces, all using coordinates from - * the same coordinate reference system. The geometric interiors of any two Surfaces in a MultiSurface may not - * intersect in the full coordinate system. The boundaries of any two coplanar elements in a MultiSurface may - * intersect, at most, at a finite number of Points. If they were to meet along a curve, they could be merged into a - * single surface. - * - * @author tiwe - * - * @param - */ -public abstract class MultiSurfaceExpression extends GeometryCollectionExpression { - - private static final long serialVersionUID = 4133386816772862010L; - - @Nullable - private volatile PointExpression centroid, pointOnSurface; - - @Nullable - private volatile NumberExpression area; - - public MultiSurfaceExpression(Expression mixin) { - super(mixin); - } - - /** - * The area of this MultiSurface, as measured in the spatial reference system of this MultiSurface. - * - * @return - */ - public NumberExpression area() { - if (area == null) { - area = NumberOperation.create(Double.class, SpatialOps.AREA, mixin); - } - return area; - } - - /** - * The mathematical centroid for this MultiSurface. The result is not guaranteed to be on - * this MultiSurface. - * - * @return - */ - public PointExpression centroid() { - if (centroid == null) { - centroid = PointOperation.create(Point.class, SpatialOps.CENTROID, mixin); - } - return centroid; - } - - /** - * A Point guaranteed to be on this MultiSurface. - * - * @return - */ - public PointExpression pointOnSurface() { - if (pointOnSurface == null) { - pointOnSurface = PointOperation.create(Point.class, SpatialOps.POINT_ON_SURFACE, mixin); - } - return pointOnSurface; - } - -} diff --git a/querydsl-spatial/src/main/java/com/mysema/query/spatial/PointExpression.java b/querydsl-spatial/src/main/java/com/mysema/query/spatial/PointExpression.java deleted file mode 100644 index fa6af4ccf7..0000000000 --- a/querydsl-spatial/src/main/java/com/mysema/query/spatial/PointExpression.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright 2014, Mysema Ltd - * - * 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. - */ -package com.mysema.query.spatial; - -import javax.annotation.Nullable; - -import org.geolatte.geom.Point; - -import com.mysema.query.types.Expression; -import com.mysema.query.types.expr.NumberExpression; -import com.mysema.query.types.expr.NumberOperation; - -/** - * A Point is a 0-dimensional geometric object and represents a single location in coordinate space. A Point has an - * x-coordinate value, a y-coordinate value. If called for by the associated Spatial Reference System, it may also - * have coordinate values for z and m. - * - * @author tiwe - * - * @param - */ -public abstract class PointExpression extends GeometryExpression { - - private static final long serialVersionUID = -3549448861390349654L; - - @Nullable - private volatile NumberExpression x, y, z, m; - - public PointExpression(Expression mixin) { - super(mixin); - } - - /** - * The x-coordinate value for this Point. - * - * @return - */ - public NumberExpression x() { - if (x == null) { - x = NumberOperation.create(Double.class, SpatialOps.X, mixin); - } - return x; - } - - /** - * The y-coordinate value for this Point. - * - * @return - */ - public NumberExpression y() { - if (y == null) { - y = NumberOperation.create(Double.class, SpatialOps.Y, mixin); - } - return y; - } - - /** - * The z-coordinate value for this Point, if it has one. Returns NIL otherwise. - * - * @return - */ - public NumberExpression z() { - if (z == null) { - z = NumberOperation.create(Double.class, SpatialOps.Z, mixin); - } - return z; - } - - /** - * The m-coordinate value for this Point, if it has one. Returns NIL otherwise. - * - * @return - */ - public NumberExpression m() { - if (m == null) { - m = NumberOperation.create(Double.class, SpatialOps.M, mixin); - } - return m; - } -} diff --git a/querydsl-spatial/src/main/java/com/mysema/query/spatial/PointOperation.java b/querydsl-spatial/src/main/java/com/mysema/query/spatial/PointOperation.java deleted file mode 100644 index ce7f44674d..0000000000 --- a/querydsl-spatial/src/main/java/com/mysema/query/spatial/PointOperation.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2014, Mysema Ltd - * - * 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. - */ -package com.mysema.query.spatial; - -import java.util.List; - -import org.geolatte.geom.Point; - -import com.google.common.collect.ImmutableList; -import com.mysema.query.types.Expression; -import com.mysema.query.types.Operation; -import com.mysema.query.types.OperationImpl; -import com.mysema.query.types.Operator; -import com.mysema.query.types.Visitor; - -/** - * @author tiwe - * - * @param - */ -public class PointOperation extends PointExpression implements Operation { - - private static final long serialVersionUID = 3433471874808633698L; - - public static PointOperation create(Class type, Operator op, Expression one) { - return new PointOperation(type, op, ImmutableList.>of(one)); - } - - public static PointOperation create(Class type, Operator op, Expression one, Expression two) { - return new PointOperation(type, op, ImmutableList.of(one, two)); - } - - public static PointOperation create(Class type, Operator op, Expression... args) { - return new PointOperation(type, op, args); - } - - private final OperationImpl< T> opMixin; - - protected PointOperation(Class type, Operator op, Expression... args) { - this(type, op, ImmutableList.copyOf(args)); - } - - protected PointOperation(Class type, Operator op, ImmutableList> args) { - super(new OperationImpl(type, op, args)); - this.opMixin = (OperationImpl)mixin; - } - - @Override - public final R accept(Visitor v, C context) { - return v.visit(opMixin, context); - } - - @Override - public Expression getArg(int index) { - return opMixin.getArg(index); - } - - @Override - public List> getArgs() { - return opMixin.getArgs(); - } - - @Override - public Operator getOperator() { - return opMixin.getOperator(); - } -} diff --git a/querydsl-spatial/src/main/java/com/mysema/query/spatial/PolygonExpression.java b/querydsl-spatial/src/main/java/com/mysema/query/spatial/PolygonExpression.java deleted file mode 100644 index 27544c5d35..0000000000 --- a/querydsl-spatial/src/main/java/com/mysema/query/spatial/PolygonExpression.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2014, Mysema Ltd - * - * 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. - */ -package com.mysema.query.spatial; - -import javax.annotation.Nullable; - -import org.geolatte.geom.LineString; -import org.geolatte.geom.Polygon; - -import com.mysema.query.types.ConstantImpl; -import com.mysema.query.types.Expression; -import com.mysema.query.types.expr.NumberExpression; -import com.mysema.query.types.expr.NumberOperation; - -/** - * A Polygon is a planar Surface defined by 1 exterior boundary and 0 or more interior boundaries. Each interior - * boundary defines a hole in the Polygon. A Triangle is a polygon with 3 distinct, non-collinear vertices and no - * interior boundary. - * - * @author tiwe - * - * @param - */ -public abstract class PolygonExpression extends SurfaceExpression { - - private static final long serialVersionUID = 7544382956232485312L; - - @Nullable - private volatile NumberExpression numInteriorRing; - - @Nullable - private volatile LineStringExpression exterorRing; - - public PolygonExpression(Expression mixin) { - super(mixin); - } - - /** - * Returns the exterior ring of this Polygon. - * - * @return - */ - public LineStringExpression exteriorRing() { - if (exterorRing == null) { - exterorRing = LineStringOperation.create(LineString.class, SpatialOps.EXTERIOR_RING, mixin); - } - return exterorRing; - } - - /** - * Returns the number of interior rings in this Polygon. - * - * @return - */ - public NumberExpression numInteriorRing() { - if (numInteriorRing == null) { - numInteriorRing = NumberOperation.create(Integer.class, SpatialOps.NUM_INTERIOR_RING, mixin); - } - return numInteriorRing; - } - - /** - * Returns the N th interior ring for this Polygon as a LineString. - * - * @param idx - * @return - */ - public LineStringExpression interiorRingN(int idx) { - return LineStringOperation.create(LineString.class, SpatialOps.INTERIOR_RINGN, mixin, ConstantImpl.create(idx)); - } -} diff --git a/querydsl-spatial/src/main/java/com/mysema/query/spatial/PolygonOperation.java b/querydsl-spatial/src/main/java/com/mysema/query/spatial/PolygonOperation.java deleted file mode 100644 index 1aecde7182..0000000000 --- a/querydsl-spatial/src/main/java/com/mysema/query/spatial/PolygonOperation.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2014, Mysema Ltd - * - * 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. - */ -package com.mysema.query.spatial; - -import java.util.List; - -import org.geolatte.geom.Polygon; - -import com.google.common.collect.ImmutableList; -import com.mysema.query.types.Expression; -import com.mysema.query.types.Operation; -import com.mysema.query.types.OperationImpl; -import com.mysema.query.types.Operator; -import com.mysema.query.types.Visitor; - -/** - * @author tiwe - * - * @param - */ -public class PolygonOperation extends PolygonExpression implements Operation { - - private static final long serialVersionUID = 3433471874808633698L; - - public static PolygonOperation create(Class type, Operator op, Expression one) { - return new PolygonOperation(type, op, ImmutableList.>of(one)); - } - - public static PolygonOperation create(Class type, Operator op, Expression one, Expression two) { - return new PolygonOperation(type, op, ImmutableList.of(one, two)); - } - - public static PolygonOperation create(Class type, Operator op, Expression... args) { - return new PolygonOperation(type, op, args); - } - - private final OperationImpl< T> opMixin; - - protected PolygonOperation(Class type, Operator op, Expression... args) { - this(type, op, ImmutableList.copyOf(args)); - } - - protected PolygonOperation(Class type, Operator op, ImmutableList> args) { - super(new OperationImpl(type, op, args)); - this.opMixin = (OperationImpl)mixin; - } - - @Override - public final R accept(Visitor v, C context) { - return v.visit(opMixin, context); - } - - @Override - public Expression getArg(int index) { - return opMixin.getArg(index); - } - - @Override - public List> getArgs() { - return opMixin.getArgs(); - } - - @Override - public Operator getOperator() { - return opMixin.getOperator(); - } -} diff --git a/querydsl-spatial/src/main/java/com/mysema/query/spatial/PolyhedralSurfaceExpression.java b/querydsl-spatial/src/main/java/com/mysema/query/spatial/PolyhedralSurfaceExpression.java deleted file mode 100644 index f1cbd076b1..0000000000 --- a/querydsl-spatial/src/main/java/com/mysema/query/spatial/PolyhedralSurfaceExpression.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2014, Mysema Ltd - * - * 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. - */ -package com.mysema.query.spatial; - -import javax.annotation.Nullable; - -import org.geolatte.geom.PolyHedralSurface; -import org.geolatte.geom.Polygon; - -import com.mysema.query.types.ConstantImpl; -import com.mysema.query.types.Expression; -import com.mysema.query.types.expr.BooleanExpression; -import com.mysema.query.types.expr.BooleanOperation; -import com.mysema.query.types.expr.NumberExpression; -import com.mysema.query.types.expr.NumberOperation; - -/** - * A PolyhedralSurface is a contiguous collection of polygons, which share common boundary segments. - * For each pair of polygons that “touch”, the common boundary shall be expressible as a finite - * collection of LineStrings. Each such LineString shall be part of the boundary of at most 2 Polygon - * patches. - * - * @author tiwe - * - * @param - */ -public abstract class PolyhedralSurfaceExpression extends SurfaceExpression { - - private static final long serialVersionUID = -6732418858467327780L; - - @Nullable - private volatile NumberExpression numPatches; - - @Nullable - private volatile BooleanExpression closed; - - public PolyhedralSurfaceExpression(Expression mixin) { - super(mixin); - } - - /** - * Returns the number of including polygons - * - * @return - */ - public NumberExpression numPatches() { - if (numPatches == null) { - numPatches = NumberOperation.create(Integer.class, SpatialOps.NUM_SURFACES, mixin); - } - return numPatches; - } - - /** - * Returns a polygon in this surface, the order is arbitrary. - * - * @param n - * @return - */ - public PolygonExpression patchN(int n) { - return PolygonOperation.create(Polygon.class, SpatialOps.SURFACE, mixin, ConstantImpl.create(n)); - } - - /** - * Returns 1 (True) if the polygon closes on itself, and thus has no boundary and - * encloses a solid - * - * @return - */ - public BooleanExpression isClosed() { - if (closed == null) { - closed = BooleanOperation.create(SpatialOps.IS_CLOSED, mixin); - } - return closed; - } -} diff --git a/querydsl-spatial/src/main/java/com/mysema/query/spatial/SpatialOps.java b/querydsl-spatial/src/main/java/com/mysema/query/spatial/SpatialOps.java deleted file mode 100644 index a2ab2afeaf..0000000000 --- a/querydsl-spatial/src/main/java/com/mysema/query/spatial/SpatialOps.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright 2014, Mysema Ltd - * - * 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. - */ -package com.mysema.query.spatial; - -import com.mysema.query.types.Operator; -import com.mysema.query.types.OperatorImpl; - -/** - * @author tiwe - * - */ -public final class SpatialOps { - - private static final String NS = SpatialOps.class.getName(); - - // Geometry - public static final Operator DIMENSION = new OperatorImpl(NS, "DIMENSION"); - public static final Operator GEOMETRY_TYPE = new OperatorImpl(NS, "GEOMETRY_TYPE"); - public static final Operator AS_TEXT = new OperatorImpl(NS, "AS_TEXT"); - public static final Operator AS_BINARY = new OperatorImpl(NS, "AS_BINARY"); - public static final Operator SRID = new OperatorImpl(NS, "SRID"); - public static final Operator SRID2 = new OperatorImpl(NS, "SRID2"); - public static final Operator IS_EMPTY = new OperatorImpl(NS, "IS_EMPTY"); - public static final Operator IS_SIMPLE = new OperatorImpl(NS, "IS_SIMPLE"); - public static final Operator BOUNDARY = new OperatorImpl(NS, "BOUNDARY"); - public static final Operator ENVELOPE = new OperatorImpl(NS, "ENVELOPE"); - public static final Operator WKTTOSQL = new OperatorImpl(NS, "WKTTOSQL"); - public static final Operator WKBTOSQL = new OperatorImpl(NS, "WKBTOSQL"); - public static final Operator EQUALS = new OperatorImpl(NS, "EQUALS"); - public static final Operator DISJOINT = new OperatorImpl(NS, "DISJOINT"); - public static final Operator INTERSECTS = new OperatorImpl(NS, "INTERSECTS"); - public static final Operator TOUCHES = new OperatorImpl(NS, "TOUCHES"); - public static final Operator CROSSES = new OperatorImpl(NS, "CROSSES"); - public static final Operator WITHIN = new OperatorImpl(NS, "WITHIN"); - public static final Operator CONTAINS = new OperatorImpl(NS, "CONTAINS"); - public static final Operator OVERLAPS = new OperatorImpl(NS, "OVERLAPS"); - public static final Operator RELATE = new OperatorImpl(NS, "RELATE"); - public static final Operator DISTANCE = new OperatorImpl(NS, "DISTANCE"); - public static final Operator DISTANCE2 = new OperatorImpl(NS, "DISTANCE2"); - public static final Operator DISTANCE_SPHERE = new OperatorImpl(NS, "DISTANCE_SPHERE"); - public static final Operator DISTANCE_SPHEROID = new OperatorImpl(NS, "DISTANCE_SPHEROID"); - public static final Operator INTERSECTION = new OperatorImpl(NS, "INTERSECTION"); - public static final Operator DIFFERENCE = new OperatorImpl(NS, "DIFFERENCE"); - public static final Operator UNION = new OperatorImpl(NS, "UNION"); - public static final Operator SYMDIFFERENCE = new OperatorImpl(NS, "SYMDIFFERENCE"); - public static final Operator BUFFER = new OperatorImpl(NS, "BUFFER"); - public static final Operator BUFFER2 = new OperatorImpl(NS, "BUFFER2"); - public static final Operator CONVEXHULL = new OperatorImpl(NS, "CONVEXHULL"); - public static final Operator TRANSFORM = new OperatorImpl(NS, "TRANSFORM"); - - // Point - public static final Operator X = new OperatorImpl(NS, "X"); - public static final Operator X2 = new OperatorImpl(NS, "X2"); - public static final Operator Y = new OperatorImpl(NS, "Y"); - public static final Operator Y2 = new OperatorImpl(NS, "Y2"); - public static final Operator Z = new OperatorImpl(NS, "Z"); - public static final Operator Z2 = new OperatorImpl(NS, "Z2"); - public static final Operator M = new OperatorImpl(NS, "M"); - public static final Operator M2 = new OperatorImpl(NS, "M2"); - - // Curve - public static final Operator START_POINT = new OperatorImpl(NS, "START_POINT"); - public static final Operator END_POINT = new OperatorImpl(NS, "END_POINT"); - public static final Operator IS_RING = new OperatorImpl(NS, "IS_RING"); - public static final Operator LENGTH = new OperatorImpl(NS, "LENGTH"); - public static final Operator LENGTH2 = new OperatorImpl(NS, "LENGTH2"); - - //LineString - public static final Operator NUM_POINTS = new OperatorImpl(NS, "NUM_POINTS"); - public static final Operator POINTN = new OperatorImpl(NS, "POINTN"); - - // Surface - public static final Operator AREA = new OperatorImpl(NS, "AREA"); - public static final Operator AREA2 = new OperatorImpl(NS, "AREA2"); - public static final Operator CENTROID = new OperatorImpl(NS, "CENTROID"); - public static final Operator POINT_ON_SURFACE = new OperatorImpl(NS, "POINT_ON_SURFACE"); - - // Polygon - public static final Operator EXTERIOR_RING = new OperatorImpl(NS, "EXTERIOR_RING"); - public static final Operator EXTERIOR_RING2 = new OperatorImpl(NS, "EXTERIOR_RING2"); - public static final Operator INTERIOR_RINGS = new OperatorImpl(NS, "INTERIOR_RINGS"); - public static final Operator INTERIOR_RINGS2 = new OperatorImpl(NS, "INTERIOR_RINGS2"); - public static final Operator NUM_INTERIOR_RING = new OperatorImpl(NS, "NUM_INTERIOR_RING"); - public static final Operator INTERIOR_RINGN = new OperatorImpl(NS, "INTERIOR_RINGN"); - - // Polyhedral Surface - public static final Operator GEOMETRIES = new OperatorImpl(NS, "GEOMETRIES"); - public static final Operator NUM_SURFACES = new OperatorImpl(NS, "NUM_SURFACES"); - public static final Operator SURFACE = new OperatorImpl(NS, "SURFACE"); - - // GeometryCollection - public static final Operator NUM_GEOMETRIES = new OperatorImpl(NS, "NUM_GEOMETRIES"); - public static final Operator GEOMETRYN = new OperatorImpl(NS, "GEOMETRYN"); - - // MultiCurve - public static final Operator IS_CLOSED = new OperatorImpl(NS, "IS_CLOSED"); - - } \ No newline at end of file diff --git a/querydsl-spatial/src/main/java/com/mysema/query/spatial/SurfaceExpression.java b/querydsl-spatial/src/main/java/com/mysema/query/spatial/SurfaceExpression.java deleted file mode 100644 index e197d28ec3..0000000000 --- a/querydsl-spatial/src/main/java/com/mysema/query/spatial/SurfaceExpression.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2014, Mysema Ltd - * - * 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. - */ -package com.mysema.query.spatial; - -import javax.annotation.Nullable; - -import org.geolatte.geom.Geometry; -import org.geolatte.geom.Point; - -import com.mysema.query.types.Expression; -import com.mysema.query.types.expr.NumberExpression; -import com.mysema.query.types.expr.NumberOperation; - -/** - * A Surface is a 2-dimensional geometric object. - * - * @author tiwe - * - * @param - */ -public abstract class SurfaceExpression extends GeometryExpression { - - private static final long serialVersionUID = 3534197011234723698L; - - @Nullable - private volatile PointExpression centroid, pointOnSurface; - - @Nullable - private volatile NumberExpression area; - - public SurfaceExpression(Expression mixin) { - super(mixin); - } - - /** - * The area of this Surface, as measured in the spatial reference system of this Surface. - * - * @return - */ - public NumberExpression area() { - if (area == null) { - area = NumberOperation.create(Double.class, SpatialOps.AREA, mixin); - } - return area; - } - - /** - * The mathematical centroid for this Surface as a Point. The result is not guaranteed to - * be on this Surface. - * - * @return - */ - public PointExpression centroid() { - if (centroid == null) { - centroid = PointOperation.create(Point.class, SpatialOps.CENTROID, mixin); - } - return centroid; - } - - /** - * A Point guaranteed to be on this Surface. - * - * @return - */ - public PointExpression pointOnSurface() { - if (pointOnSurface == null) { - pointOnSurface = PointOperation.create(Point.class, SpatialOps.POINT_ON_SURFACE, mixin); - } - return pointOnSurface; - } - -} diff --git a/querydsl-spatial/src/main/java/com/mysema/query/spatial/path/GeometryPath.java b/querydsl-spatial/src/main/java/com/mysema/query/spatial/path/GeometryPath.java deleted file mode 100644 index 64041ee57f..0000000000 --- a/querydsl-spatial/src/main/java/com/mysema/query/spatial/path/GeometryPath.java +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright 2014, Mysema Ltd - * - * 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. - */ -package com.mysema.query.spatial.path; - -import java.lang.reflect.AnnotatedElement; - -import org.geolatte.geom.Geometry; -import org.geolatte.geom.GeometryCollection; -import org.geolatte.geom.LineString; -import org.geolatte.geom.LinearRing; -import org.geolatte.geom.MultiLineString; -import org.geolatte.geom.MultiPoint; -import org.geolatte.geom.MultiPolygon; -import org.geolatte.geom.Point; -import org.geolatte.geom.PolyHedralSurface; -import org.geolatte.geom.Polygon; - -import com.mysema.query.spatial.GeometryExpression; -import com.mysema.query.types.Path; -import com.mysema.query.types.PathImpl; -import com.mysema.query.types.PathMetadata; -import com.mysema.query.types.PathMetadataFactory; -import com.mysema.query.types.Visitor; - -/** - * @author tiwe - * - * @param - */ -public class GeometryPath extends GeometryExpression implements Path { - - private static final long serialVersionUID = 312776751843333543L; - - private final PathImpl pathMixin; - - private volatile GeometryCollectionPath collection; - - private volatile LinearRingPath linearRing; - - private volatile LineStringPath lineString; - - private volatile MultiLineStringPath multiLineString; - - private volatile MultiPointPath multiPoint; - - private volatile MultiPolygonPath multiPolygon; - - private volatile PointPath point; - - private volatile PolygonPath polygon; - - private volatile PolyhedralSurfacePath polyhedralSurface; - - public GeometryPath(Path parent, String property) { - this((Class) Geometry.class, parent, property); - } - - public GeometryPath(Class type, Path parent, String property) { - this(type, PathMetadataFactory.forProperty(parent, property)); - } - - public GeometryPath(PathMetadata metadata) { - this((Class) Geometry.class, metadata); - } - - public GeometryPath(Class type, PathMetadata metadata) { - super(new PathImpl(type, metadata)); - this.pathMixin = (PathImpl)mixin; - } - - public GeometryPath(String var) { - this((Class) Geometry.class, PathMetadataFactory.forVariable(var)); - } - - public GeometryCollectionPath asCollection() { - if (collection == null) { - collection = new GeometryCollectionPath(pathMixin.getMetadata()); - } - return collection; - } - - public LinearRingPath asLinearRing() { - if (linearRing == null) { - linearRing = new LinearRingPath(pathMixin.getMetadata()); - } - return linearRing; - } - - public LineStringPath asLineString() { - if (lineString == null) { - lineString = new LineStringPath(pathMixin.getMetadata()); - } - return lineString; - } - - public MultiLineStringPath asMultiLineString() { - if (multiLineString == null) { - multiLineString = new MultiLineStringPath(pathMixin.getMetadata()); - } - return multiLineString; - } - - public MultiPointPath asMultiPoint() { - if (multiPoint == null) { - multiPoint = new MultiPointPath(pathMixin.getMetadata()); - } - return multiPoint; - } - - public MultiPolygonPath asMultiPolygon() { - if (multiPolygon == null) { - multiPolygon = new MultiPolygonPath(pathMixin.getMetadata()); - } - return multiPolygon; - } - - public PointPath asPoint() { - if (point == null) { - point = new PointPath(pathMixin.getMetadata()); - } - return point; - } - - public PolygonPath asPolygon() { - if (polygon == null) { - polygon = new PolygonPath(pathMixin.getMetadata()); - } - return polygon; - } - - public PolyhedralSurfacePath asPolygHedralSurface() { - if (polyhedralSurface == null) { - polyhedralSurface = new PolyhedralSurfacePath(pathMixin.getMetadata()); - } - return polyhedralSurface; - } - - @Override - public final R accept(Visitor v, C context) { - return v.visit(pathMixin, context); - } - - public GeometryPath(Class type, String var) { - this(type, PathMetadataFactory.forVariable(var)); - } - - @Override - public PathMetadata getMetadata() { - return pathMixin.getMetadata(); - } - - @Override - public Path getRoot() { - return pathMixin.getRoot(); - } - - @Override - public AnnotatedElement getAnnotatedElement() { - return pathMixin.getAnnotatedElement(); - } - -} diff --git a/querydsl-spatial/src/main/java/com/mysema/query/spatial/path/GeometryPaths.java b/querydsl-spatial/src/main/java/com/mysema/query/spatial/path/GeometryPaths.java deleted file mode 100644 index d9532a7d12..0000000000 --- a/querydsl-spatial/src/main/java/com/mysema/query/spatial/path/GeometryPaths.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2014, Mysema Ltd - * - * 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. - */ -package com.mysema.query.spatial.path; - -import org.geolatte.geom.Geometry; -import org.geolatte.geom.GeometryCollection; -import org.geolatte.geom.LineString; -import org.geolatte.geom.LinearRing; -import org.geolatte.geom.MultiLineString; -import org.geolatte.geom.MultiPoint; -import org.geolatte.geom.MultiPolygon; -import org.geolatte.geom.Point; -import org.geolatte.geom.PolyHedralSurface; -import org.geolatte.geom.Polygon; - -/** - * @author tiwe - * - */ -public interface GeometryPaths { - - GeometryCollectionPath createGeometryCollection(String property, Class type); - - GeometryPath createGeometry(String property, Class type); - - LinearRingPath createLinearRing(String property, Class type); - - LineStringPath createLineString(String property, Class type); - - MultiLineStringPath createMultiLineString(String property, Class type); - - MultiPointPath createMultiPoint(String property, Class type); - - MultiPolygonPath createMultiPolygon(String property, Class type); - - PointPath createPoint(String property, Class type); - - PolygonPath createPolygon(String property, Class type); - - PolyhedralSurfacePath createPolyhedralSurface(String property, Class type); - -} diff --git a/querydsl-spatial/src/main/java/com/mysema/query/spatial/path/PolyhedralSurfacePath.java b/querydsl-spatial/src/main/java/com/mysema/query/spatial/path/PolyhedralSurfacePath.java deleted file mode 100644 index 77ce84bfb9..0000000000 --- a/querydsl-spatial/src/main/java/com/mysema/query/spatial/path/PolyhedralSurfacePath.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2014, Mysema Ltd - * - * 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. - */ -package com.mysema.query.spatial.path; - -import java.lang.reflect.AnnotatedElement; - -import org.geolatte.geom.PolyHedralSurface; - -import com.mysema.query.spatial.PolyhedralSurfaceExpression; -import com.mysema.query.types.Path; -import com.mysema.query.types.PathImpl; -import com.mysema.query.types.PathMetadata; -import com.mysema.query.types.PathMetadataFactory; -import com.mysema.query.types.Visitor; - -/** - * @author tiwe - * - * @param - */ -public class PolyhedralSurfacePath extends PolyhedralSurfaceExpression implements Path { - - private static final long serialVersionUID = 312776751843333543L; - - private final PathImpl pathMixin; - - public PolyhedralSurfacePath(Path parent, String property) { - this((Class) PolyHedralSurface.class, parent, property); - } - - public PolyhedralSurfacePath(Class type, Path parent, String property) { - this(type, PathMetadataFactory.forProperty(parent, property)); - } - - public PolyhedralSurfacePath(PathMetadata metadata) { - this((Class) PolyHedralSurface.class, metadata); - } - - public PolyhedralSurfacePath(Class type, PathMetadata metadata) { - super(new PathImpl(type, metadata)); - this.pathMixin = (PathImpl)mixin; - } - - public PolyhedralSurfacePath(String var) { - this((Class) PolyHedralSurface.class, PathMetadataFactory.forVariable(var)); - } - - @Override - public final R accept(Visitor v, C context) { - return v.visit(pathMixin, context); - } - - public PolyhedralSurfacePath(Class type, String var) { - this(type, PathMetadataFactory.forVariable(var)); - } - - @Override - public PathMetadata getMetadata() { - return pathMixin.getMetadata(); - } - - @Override - public Path getRoot() { - return pathMixin.getRoot(); - } - - @Override - public AnnotatedElement getAnnotatedElement() { - return pathMixin.getAnnotatedElement(); - } - -} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/AbstractGeometryCollectionExpression.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/AbstractGeometryCollectionExpression.java new file mode 100644 index 0000000000..0c63739b04 --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/AbstractGeometryCollectionExpression.java @@ -0,0 +1,64 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial; + +import com.querydsl.core.types.ConstantImpl; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberExpression; +import org.geolatte.geom.AbstractGeometryCollection; +import org.geolatte.geom.Geometry; +import org.jetbrains.annotations.Nullable; + +/** + * A GeometryCollection is a geometric object that is a collection of some number of geometric objects. + * + * @author tiwe + * + * @param + */ +public abstract class AbstractGeometryCollectionExpression extends GeometryExpression { + + private static final long serialVersionUID = 8874174644259834690L; + + @Nullable + private transient volatile NumberExpression numGeometries; + + public AbstractGeometryCollectionExpression(Expression mixin) { + super(mixin); + } + + /** + * Returns the number of geometries in this GeometryCollection. + * + * @return number of geometries + */ + public NumberExpression numGeometries() { + if (numGeometries == null) { + numGeometries = Expressions.numberOperation(Integer.class, SpatialOps.NUM_GEOMETRIES, mixin); + } + return numGeometries; + } + + /** + * Returns the Nth geometry in this GeometryCollection. + * + * @param n one based index + * @return matching geometry + */ + public GeometryExpression geometryN(Integer n) { + return GeometryExpressions.geometryOperation(SpatialOps.GEOMETRYN, mixin, ConstantImpl.create(n)); + } + +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/CurveExpression.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/CurveExpression.java new file mode 100644 index 0000000000..2c4b64787b --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/CurveExpression.java @@ -0,0 +1,113 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial; + +import org.jetbrains.annotations.Nullable; + +import org.geolatte.geom.Geometry; +import org.geolatte.geom.Point; + +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.dsl.BooleanExpression; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberExpression; + +/** + * A Curve is a 1-dimensional geometric object usually stored as a sequence of Points, with the subtype of Curve + * specifying the form of the interpolation between Points. This standard defines only one subclass of Curve, + * LineString, which uses linear interpolation between Points. + * + * @author tiwe + * + * @param + */ +public abstract class CurveExpression extends GeometryExpression { + + private static final long serialVersionUID = 6139188586728676033L; + + @Nullable + private transient volatile NumberExpression length; + + @Nullable + private transient volatile PointExpression startPoint, endPoint; + + @Nullable + private transient volatile BooleanExpression closed, ring; + + public CurveExpression(Expression mixin) { + super(mixin); + } + + /** + * The length of this Curve in its associated spatial reference. + * + * @return length + */ + public NumberExpression length() { + if (length == null) { + length = Expressions.numberOperation(Double.class, SpatialOps.LENGTH, mixin); + } + return length; + } + + /** + * The start Point of this Curve. + * + * @return start point + */ + public PointExpression startPoint() { + if (startPoint == null) { + startPoint = GeometryExpressions.pointOperation(SpatialOps.START_POINT, mixin); + } + return startPoint; + } + + /** + * The end Point of this Curve. + * + * @return end point + */ + public PointExpression endPoint() { + if (endPoint == null) { + endPoint = GeometryExpressions.pointOperation(SpatialOps.END_POINT, mixin); + } + return endPoint; + } + + /** + * Returns 1 (TRUE) if this Curve is closed [StartPoint ( ) = EndPoint ( )]. + * + * @return closed + */ + public BooleanExpression isClosed() { + if (closed == null) { + closed = Expressions.booleanOperation(SpatialOps.IS_CLOSED, mixin); + } + return closed; + } + + /** + * Returns 1 (TRUE) if this Curve is closed [StartPoint ( ) = EndPoint ( )] and this Curve is + * simple (does not pass through the same Point more than once). + * + * @return ring + */ + public BooleanExpression isRing() { + if (ring == null) { + ring = Expressions.booleanOperation(SpatialOps.IS_RING, mixin); + } + return ring; + } + +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/GeometryCollectionExpression.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/GeometryCollectionExpression.java new file mode 100644 index 0000000000..4aa2e7a292 --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/GeometryCollectionExpression.java @@ -0,0 +1,39 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial; + +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.dsl.NumberExpression; +import org.geolatte.geom.GeometryCollection; +import org.jetbrains.annotations.Nullable; + +/** + * A GeometryCollection is a geometric object that is a collection of some number of geometric objects. + * + * @author tiwe + * + * @param + */ +public abstract class GeometryCollectionExpression extends AbstractGeometryCollectionExpression { + + private static final long serialVersionUID = 8874174644259834690L; + + @Nullable + private transient volatile NumberExpression numGeometries; + + public GeometryCollectionExpression(Expression mixin) { + super(mixin); + } + +} diff --git a/querydsl-spatial/src/main/java/com/mysema/query/spatial/path/GeometryCollectionPath.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/GeometryCollectionPath.java similarity index 78% rename from querydsl-spatial/src/main/java/com/mysema/query/spatial/path/GeometryCollectionPath.java rename to querydsl-spatial/src/main/java/com/querydsl/spatial/GeometryCollectionPath.java index 1ff07ae563..a4134c03fc 100644 --- a/querydsl-spatial/src/main/java/com/mysema/query/spatial/path/GeometryCollectionPath.java +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/GeometryCollectionPath.java @@ -1,5 +1,5 @@ /* - * Copyright 2014, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,20 +11,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.spatial.path; +package com.querydsl.spatial; import java.lang.reflect.AnnotatedElement; import org.geolatte.geom.GeometryCollection; -import com.mysema.query.spatial.GeometryCollectionExpression; -import com.mysema.query.types.Path; -import com.mysema.query.types.PathImpl; -import com.mysema.query.types.PathMetadata; -import com.mysema.query.types.PathMetadataFactory; -import com.mysema.query.types.Visitor; +import com.querydsl.core.types.*; /** + * {@code GeometryCollectionPath} extends {@link GeometryCollectionExpression} to implement the + * {@link Path} interface + * * @author tiwe * * @param @@ -35,6 +33,7 @@ public class GeometryCollectionPath extends Geomet private final PathImpl pathMixin; + @SuppressWarnings("unchecked") public GeometryCollectionPath(Path parent, String property) { this((Class) GeometryCollection.class, parent, property); } @@ -43,15 +42,17 @@ public GeometryCollectionPath(Class type, Path parent, String pr this(type, PathMetadataFactory.forProperty(parent, property)); } - public GeometryCollectionPath(PathMetadata metadata) { + @SuppressWarnings("unchecked") + public GeometryCollectionPath(PathMetadata metadata) { this((Class) GeometryCollection.class, metadata); } - public GeometryCollectionPath(Class type, PathMetadata metadata) { - super(new PathImpl(type, metadata)); - this.pathMixin = (PathImpl)mixin; + public GeometryCollectionPath(Class type, PathMetadata metadata) { + super(ExpressionUtils.path(type, metadata)); + this.pathMixin = (PathImpl) mixin; } + @SuppressWarnings("unchecked") public GeometryCollectionPath(String var) { this((Class) GeometryCollection.class, PathMetadataFactory.forVariable(var)); } @@ -66,7 +67,7 @@ public GeometryCollectionPath(Class type, String var) { } @Override - public PathMetadata getMetadata() { + public PathMetadata getMetadata() { return pathMixin.getMetadata(); } diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/GeometryExpression.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/GeometryExpression.java new file mode 100644 index 0000000000..9bc4f71b1a --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/GeometryExpression.java @@ -0,0 +1,520 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial; + +import org.jetbrains.annotations.Nullable; + +import org.geolatte.geom.Geometry; + +import com.querydsl.core.types.ConstantImpl; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.dsl.*; + +/** + * Geometry is the root class of the hierarchy. Geometry is an abstract (non-instantiable) class. + * + * @author tiwe + * + * @param + */ +public abstract class GeometryExpression extends SimpleExpression { + + private static final long serialVersionUID = -1183228394472681995L; + + @Nullable + private transient volatile NumberExpression dimension, coordinateDimension, spatialDimension, srid; + + @Nullable + private transient volatile StringExpression geometryType; + + @Nullable + private transient volatile StringExpression text; + + @Nullable + private transient volatile GeometryExpression envelope, boundary, convexHull; + + @Nullable + private transient volatile BooleanExpression empty, simple, threed, measured; + + private transient volatile SimpleExpression binary; + + public GeometryExpression(Expression mixin) { + super(mixin); + } + + /** + * The inherent dimension of this geometric object, which must be less than or equal + * to the coordinate dimension. In non-homogeneous collections, this will return the largest topological + * dimension of the contained objects. + * + * @return dimension + */ + public NumberExpression dimension() { + if (dimension == null) { + dimension = Expressions.numberOperation(Integer.class, SpatialOps.DIMENSION, mixin); + } + return dimension; + } + + /** + * Returns the name of the instantiable subtype of Geometry of which this + * geometric object is an instantiable member. The name of the subtype of Geometry is returned as a string. + * + * @return geometry type + */ + public StringExpression geometryType() { + if (geometryType == null) { + geometryType = Expressions.stringOperation(SpatialOps.GEOMETRY_TYPE, mixin); + } + return geometryType; + } + + /** + * Returns the Spatial Reference System ID for this geometric object. This will normally be a + * foreign key to an index of reference systems stored in either the same or some other datastore. + * + * @return SRID + */ + public NumberExpression srid() { + if (srid == null) { + srid = Expressions.numberOperation(Integer.class, SpatialOps.SRID, mixin); + } + return srid; + } + + /** + * The minimum bounding box for this Geometry, returned as a Geometry. The + * polygon is defined by the corner points of the bounding box [(MINX, MINY), (MAXX, MINY), (MAXX, MAXY), + * (MINX, MAXY), (MINX, MINY)]. Minimums for Z and M may be added. The simplest representation of an + * Envelope is as two direct positions, one containing all the minimums, and another all the maximums. In some + * cases, this coordinate will be outside the range of validity for the Spatial Reference System. + * + * @return envelope + */ + public GeometryExpression envelope() { + if (envelope == null) { + envelope = GeometryExpressions.geometryOperation(SpatialOps.ENVELOPE, mixin); + } + return envelope; + } + + /** + * Exports this geometric object to a specific Well-known Text Representation of Geometry. + * + * @return text representation + */ + public StringExpression asText() { + if (text == null) { + text = Expressions.stringOperation(SpatialOps.AS_TEXT, mixin); + } + return text; + } + + /** + * Exports this geometric object to a specific Well-known Binary Representation of + * Geometry. + * + * @return binary representation + */ + public SimpleExpression asBinary() { + if (binary == null) { + binary = Expressions.operation(byte[].class, SpatialOps.AS_BINARY, mixin); + } + return binary; + } + + /** + * Returns 1 (TRUE) if this geometric object is the empty Geometry. If true, then this + * geometric object represents the empty point set ∅ for the coordinate space. + * + * @return empty + */ + public BooleanExpression isEmpty() { + if (empty == null) { + empty = Expressions.booleanOperation(SpatialOps.IS_EMPTY, mixin); + } + return empty; + } + + /** + * Returns 1 (TRUE) if this geometric object has no anomalous geometric points, such + * as self intersection or self tangency. The description of each instantiable geometric class + * will include the specific conditions that cause an instance of that class to be classified as not simple. + * + * @return simple + */ + public BooleanExpression isSimple() { + if (simple == null) { + simple = Expressions.booleanOperation(SpatialOps.IS_SIMPLE, mixin); + } + return simple; + } + + /** + * Returns the closure of the combinatorial boundary of this geometric object + * + * @return boundary + */ + public GeometryExpression boundary() { + if (boundary == null) { + boundary = GeometryExpressions.geometryOperation(SpatialOps.BOUNDARY, mixin); + } + return boundary; + } + + // query + + /* (non-Javadoc) + * @see com.querydsl.core.types.dsl.SimpleExpression#eq(java.lang.Object) + */ + @Override + public BooleanExpression eq(Geometry right) { + return eq(ConstantImpl.create(right)); + } + + /* (non-Javadoc) + * @see com.querydsl.core.types.dsl.SimpleExpression#eq(com.querydsl.core.types.Expression) + */ + @Override + public BooleanExpression eq(Expression right) { + return Expressions.booleanOperation(SpatialOps.EQUALS, mixin, right); + } + + /** + * Returns 1 (TRUE) if this geometric object is “spatially disjoint” from anotherGeometry. + * + * @param geometry other geometry + * @return true, if disjoint + */ + public BooleanExpression disjoint(Geometry geometry) { + return disjoint(ConstantImpl.create(geometry)); + } + + /** + * Returns 1 (TRUE) if this geometric object is “spatially disjoint” from anotherGeometry. + * + * @param geometry other geometry + * @return true, if disjoint + */ + public BooleanExpression disjoint(Expression geometry) { + return Expressions.booleanOperation(SpatialOps.DISJOINT, mixin, geometry); + } + + /** + * Returns 1 (TRUE) if this geometric object “spatially intersects” anotherGeometry. + * + * @param geometry other geometry + * @return true, if intersects + */ + public BooleanExpression intersects(Geometry geometry) { + return intersects(ConstantImpl.create(geometry)); + } + + /** + * Returns 1 (TRUE) if this geometric object “spatially intersects” anotherGeometry. + * + * @param geometry other geometry + * @return true, if intersects + */ + public BooleanExpression intersects(Expression geometry) { + return Expressions.booleanOperation(SpatialOps.INTERSECTS, mixin, geometry); + } + + /** + * Returns 1 (TRUE) if this geometric object “spatially touches” anotherGeometry. + * + * @param geometry other geometry + * @return true, if touches + */ + public BooleanExpression touches(Geometry geometry) { + return touches(ConstantImpl.create(geometry)); + } + + /** + * Returns 1 (TRUE) if this geometric object “spatially touches” anotherGeometry. + * + * @param geometry other geometry + * @return true, if touches + */ + public BooleanExpression touches(Expression geometry) { + return Expressions.booleanOperation(SpatialOps.TOUCHES, mixin, geometry); + } + + /** + * Returns 1 (TRUE) if this geometric object “spatially crosses’ anotherGeometry. + * + * @param geometry other geometry + * @return trye, if crosses + */ + public BooleanExpression crosses(Geometry geometry) { + return crosses(ConstantImpl.create(geometry)); + } + + /** + * Returns 1 (TRUE) if this geometric object “spatially crosses’ anotherGeometry. + * + * @param geometry other geometry + * @return true, if crosses + */ + public BooleanExpression crosses(Expression geometry) { + return Expressions.booleanOperation(SpatialOps.CROSSES, mixin, geometry); + } + + /** + * Returns 1 (TRUE) if this geometric object is “spatially within” anotherGeometry. + * + * @param geometry other geometry + * @return true, if within + */ + public BooleanExpression within(Geometry geometry) { + return within(ConstantImpl.create(geometry)); + } + + /** + * Returns 1 (TRUE) if this geometric object is “spatially within” anotherGeometry. + * + * @param geometry other geometry + * @return true, if within + */ + public BooleanExpression within(Expression geometry) { + return Expressions.booleanOperation(SpatialOps.WITHIN, mixin, geometry); + } + + /** + * Returns 1 (TRUE) if this geometric object “spatially contains” anotherGeometry. + * + * @param geometry other geometry + * @return true, if contains + */ + public BooleanExpression contains(Geometry geometry) { + return contains(ConstantImpl.create(geometry)); + } + + /** + * Returns 1 (TRUE) if this geometric object “spatially contains” anotherGeometry. + * + * @param geometry other geometry + * @return true, if contains + */ + public BooleanExpression contains(Expression geometry) { + return Expressions.booleanOperation(SpatialOps.CONTAINS, mixin, geometry); + } + + /** + * Returns 1 (TRUE) if this geometric object “spatially overlaps” anotherGeometry. + * + * @param geometry other geometry + * @return true, if overlaps + */ + public BooleanExpression overlaps(Geometry geometry) { + return overlaps(ConstantImpl.create(geometry)); + } + + /** + * Returns 1 (TRUE) if this geometric object “spatially overlaps” anotherGeometry. + * + * @param geometry other geometry + * @return true, if overlaps + */ + public BooleanExpression overlaps(Expression geometry) { + return Expressions.booleanOperation(SpatialOps.OVERLAPS, mixin, geometry); + } + + /** + * Returns 1 (TRUE) if this geometric object is spatially related to anotherGeometry by testing + * for intersections between the interior, boundary and exterior of the two geometric objects + * as specified by the values in the intersectionPatternMatrix. This returns FALSE if all the + * tested intersections are empty except exterior (this) intersect exterior (another). + * + * @param geometry other geometry + * @param matrix matrix + * @return true, if this geometry is spatially related to the other + */ + public BooleanExpression relate(Geometry geometry, String matrix) { + return relate(ConstantImpl.create(geometry), matrix); + } + + /** + * Returns 1 (TRUE) if this geometric object is spatially related to anotherGeometry by testing + * for intersections between the interior, boundary and exterior of the two geometric objects + * as specified by the values in the intersectionPatternMatrix. This returns FALSE if all the + * tested intersections are empty except exterior (this) intersect exterior (another). + * + * @param geometry other geometry + * @param matrix matrix + * @return true, if this geometry is spatially related to the other + */ + public BooleanExpression relate(Expression geometry, String matrix) { + return Expressions.booleanOperation(SpatialOps.RELATE, mixin, geometry, ConstantImpl.create(matrix)); + } + + // analysis + + /** + * Returns the shortest distance between any two Points in the two geometric objects as + * calculated in the spatial reference system of this geometric object. Because the geometries + * are closed, it is possible to find a point on each geometric object involved, such that the + * distance between these 2 points is the returned distance between their geometric objects. + * + * @param geometry other geometry + * @return distance between this and the other geometry + */ + public NumberExpression distance(Geometry geometry) { + return distance(ConstantImpl.create(geometry)); + } + + /** + * Returns the shortest distance between any two Points in the two geometric objects as + * calculated in the spatial reference system of this geometric object. Because the geometries + * are closed, it is possible to find a point on each geometric object involved, such that the + * distance between these 2 points is the returned distance between their geometric objects. + * + * @param geometry other geometry + * @return distance between this and the other geometry + */ + public NumberExpression distance(Expression geometry) { + return Expressions.numberOperation(Double.class, SpatialOps.DISTANCE, mixin, geometry); + } + + // TODO maybe move out + public NumberExpression distanceSphere(Expression geometry) { + return Expressions.numberOperation(Double.class, SpatialOps.DISTANCE_SPHERE, mixin, geometry); + } + + // TODO maybe move out + public NumberExpression distanceSpheroid(Expression geometry) { + return Expressions.numberOperation(Double.class, SpatialOps.DISTANCE_SPHEROID, mixin, geometry); + } + + /** + * Returns a geometric object that represents all Points whose distance from this geometric + * object is less than or equal to distance. Calculations are in the spatial reference system + * of this geometric object. Because of the limitations of linear interpolation, there will + * often be some relatively small error in this distance, but it should be near the resolution + * of the coordinates used. + * + * @param distance distance + * @return buffer + */ + public GeometryExpression buffer(double distance) { + return GeometryExpressions.geometryOperation(SpatialOps.BUFFER, mixin, ConstantImpl.create(distance)); + } + + /** + * Returns a geometric object that represents the convex hull of this geometric object. + * Convex hulls, being dependent on straight lines, can be accurately represented in linear + * interpolations for any geometry restricted to linear interpolations. + * + * @return convex hull + */ + public GeometryExpression convexHull() { + if (convexHull == null) { + convexHull = GeometryExpressions.geometryOperation(SpatialOps.CONVEXHULL, mixin); + } + return convexHull; + } + + /** + * Returns a geometric object that represents the Point set intersection of this geometric + * object with anotherGeometry. + * + * @param geometry other geometry + * @return intersection of this and the other geometry + */ + public GeometryExpression intersection(Geometry geometry) { + return intersection(ConstantImpl.create(geometry)); + } + + /** + * Returns a geometric object that represents the Point set intersection of this geometric + * object with anotherGeometry. + * + * @param geometry other geometry + * @return intersection of this and the other geometry + */ + public GeometryExpression intersection(Expression geometry) { + return GeometryExpressions.geometryOperation(SpatialOps.INTERSECTION, mixin, geometry); + } + + /** + * Returns a geometric object that represents the Point set + * union of this geometric object with anotherGeometry. + * + * @param geometry other geometry + * @return union of this and the other geometry + */ + public GeometryExpression union(Geometry geometry) { + return union(ConstantImpl.create(geometry)); + } + + /** + * Returns a geometric object that represents the Point set + * union of this geometric object with anotherGeometry. + * + * @param geometry other geometry + * @return union of this and the other geometry + */ + public GeometryExpression union(Expression geometry) { + return GeometryExpressions.geometryOperation(SpatialOps.UNION, mixin, geometry); + } + + /** + * Returns a geometric object that represents the Point + * set difference of this geometric object with anotherGeometry. + * + * @param geometry other geometry + * @return difference between this and the other geometry + */ + public GeometryExpression difference(Geometry geometry) { + return difference(ConstantImpl.create(geometry)); + } + + /** + * Returns a geometric object that represents the Point + * set difference of this geometric object with anotherGeometry. + * + * @param geometry other geometry + * @return difference between this and the other geometry + */ + public GeometryExpression difference(Expression geometry) { + return GeometryExpressions.geometryOperation(SpatialOps.DIFFERENCE, mixin, geometry); + } + + /** + * Returns a geometric object that represents the + * Point set symmetric difference of this geometric object with anotherGeometry. + * + * @param geometry other geometry + * @return symmetric difference between this and the other geometry + */ + public GeometryExpression symDifference(Geometry geometry) { + return symDifference(ConstantImpl.create(geometry)); + } + + /** + * Returns a geometric object that represents the + * Point set symmetric difference of this geometric object with anotherGeometry. + * + * @param geometry other geometry + * @return symmetric difference between this and the geometry + */ + public GeometryExpression symDifference(Expression geometry) { + return GeometryExpressions.geometryOperation(SpatialOps.SYMDIFFERENCE, mixin, geometry); + } + + public GeometryExpression transform(int srid) { + return GeometryExpressions.geometryOperation(SpatialOps.TRANSFORM, mixin, ConstantImpl.create(srid)); + } + +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/GeometryExpressions.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/GeometryExpressions.java new file mode 100644 index 0000000000..5072faa662 --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/GeometryExpressions.java @@ -0,0 +1,290 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial; + +import org.geolatte.geom.*; + +import com.querydsl.core.types.*; +import com.querydsl.core.types.dsl.*; + +/** + * GeometryExpressions contains static functions for GEO operations + */ +public final class GeometryExpressions { + + private GeometryExpressions() { } + + /** + * Return a specified ST_Geometry value from Extended Well-Known Text representation (EWKT). + * + * @param expr geometry + * @return serialized form + */ + public static StringExpression asEWKT(GeometryExpression expr) { + return Expressions.stringOperation(SpatialOps.AS_EWKT, expr); + } + + /** + * Return a specified ST_Geometry value from Well-Known Text representation (WKT). + * + * @param text WKT form + * @return geometry + */ + public static GeometryExpression fromText(String text) { + return geometryOperation(SpatialOps.GEOM_FROM_TEXT, ConstantImpl.create(text)); + } + + /** + * Return a specified ST_Geometry value from Well-Known Text representation (WKT). + * + * @param text WKT form + * @return geometry + */ + public static GeometryExpression fromText(Expression text) { + return geometryOperation(SpatialOps.GEOM_FROM_TEXT, text); + } + + /** + * Sets the SRID on a geometry to a particular integer value. + * + * @param expr geometry + * @param srid SRID + * @param + * @return converted geometry + */ + public static GeometryExpression setSRID(Expression expr, int srid) { + return geometryOperation(expr.getType(), SpatialOps.SET_SRID, expr, ConstantImpl.create(srid)); + } + + /** + * Returns X minima of a bounding box 2d or 3d or a geometry. + * + * @param expr geometry + * @return x minima + */ + public static NumberExpression xmin(GeometryExpression expr) { + return Expressions.numberOperation(Double.class, SpatialOps.XMIN, expr); + } + + /** + * Returns X maxima of a bounding box 2d or 3d or a geometry. + * + * @param expr geometry + * @return x maxima + */ + public static NumberExpression xmax(GeometryExpression expr) { + return Expressions.numberOperation(Double.class, SpatialOps.XMAX, expr); + } + + /** + * Returns Y minima of a bounding box 2d or 3d or a geometry. + * + * @param expr geometry + * @return y minima + */ + public static NumberExpression ymin(GeometryExpression expr) { + return Expressions.numberOperation(Double.class, SpatialOps.YMIN, expr); + } + + /** + * Returns Y maxima of a bounding box 2d or 3d or a geometry. + * + * @param expr geometry + * @return y maxima + */ + public static NumberExpression ymax(GeometryExpression expr) { + return Expressions.numberOperation(Double.class, SpatialOps.YMAX, expr); + } + + /** + * Returns true if the geometries are within the specified distance of one another. + * For geometry units are in those of spatial reference and For geography units are in meters. + * + * @param expr1 geometry + * @param expr2 other geometry + * @param distance distance + * @return true, if within distance of each other + */ + public static BooleanExpression dwithin(Expression expr1, + Expression expr2, Expression distance) { + return Expressions.booleanOperation(SpatialOps.DWITHIN, expr1, expr2, distance); + } + + /** + * Returns true if the geometries are within the specified distance of one another. + * For geometry units are in those of spatial reference and For geography units are in meters. + * + * @param expr1 geometry + * @param expr2 other geometry + * @param distance distance + * @return true, if within distance of each other + */ + public static BooleanExpression dwithin(Expression expr1, + Expression expr2, double distance) { + return Expressions.booleanOperation(SpatialOps.DWITHIN, expr1, expr2, ConstantImpl.create(distance)); + } + + /** + * Returns the bounding box that bounds rows of geometries. + * + * @param collection geometry collection + * @return bounding box + */ + public static GeometryExpression extent(Expression collection) { + return geometryOperation(SpatialOps.EXTENT, collection); + } + + /** + * Return a specified ST_Geometry value from a collection of other geometries. + * + * @param collection geometry collection + * @return geometry collection + */ + public static GeometryExpression collect(Expression collection) { + return geometryOperation(SpatialOps.COLLECT, collection); + } + + /** + * Return a specified ST_Geometry value from a collection of other geometries. + * + * @param expr1 geometry + * @param expr2 other geometry + * @return geometry collection + */ + public static GeometryExpression collect(Expression expr1, Expression expr2) { + return geometryOperation(SpatialOps.COLLECT2, expr1, expr2); + } + + /** + * Translates the geometry to a new location using the numeric parameters as offsets. + * + * @param expr geometry + * @param deltax x offset + * @param deltay y offset + * @param + * @return geometry + */ + public static GeometryExpression translate(Expression expr, float deltax, float deltay) { + return geometryOperation(expr.getType(), SpatialOps.TRANSLATE, + expr, ConstantImpl.create(deltax), ConstantImpl.create(deltay)); + } + + /** + * Translates the geometry to a new location using the numeric parameters as offsets. + * + * @param expr geometry + * @param deltax x offset + * @param deltay y offset + * @param deltaz z offset + * @param + * @return geometry + */ + public static GeometryExpression translate(Expression expr, float deltax, float deltay, float deltaz) { + return geometryOperation(expr.getType(), SpatialOps.TRANSLATE2, + expr, ConstantImpl.create(deltax), ConstantImpl.create(deltay), ConstantImpl.create(deltaz)); + } + + /** + * Create a new Geometry operation expression + * + * @param op operator + * @param args arguments + * @return operation expression + */ + public static GeometryExpression geometryOperation(Operator op, Expression... args) { + return new GeometryOperation(Geometry.class, op, args); + } + + /** + * Create a new Geometry operation expression + * + * @param op operator + * @param args arguments + * @return operation expression + */ + public static GeometryExpression geometryOperation(Class type, + Operator op, Expression... args) { + return new GeometryOperation(type, op, args); + } + + /** + * Create a new LineString operation expression + * + * @param op operator + * @param args arguments + * @return operation expression + */ + public static LineStringExpression lineStringOperation(Operator op, Expression... args) { + return new LineStringOperation(LineString.class, op, args); + } + + /** + * Create a new Point operation expression + * + * @param op operator + * @param args arguments + * @return operation expression + */ + public static PointExpression pointOperation(Operator op, Expression... args) { + return new PointOperation(Point.class, op, args); + } + + /** + * Create a new Polygon operation expression + * + * @param op operator + * @param args arguments + * @return operation expression + */ + public static PolygonExpression polygonOperation(Operator op, Expression... args) { + return new PolygonOperation(Polygon.class, op, args); + } + + /** + * Create a new GeometryExpression + * + * @param expr Expression of type Geometry + * @return new GeometryExpression + */ + public static GeometryExpression asGeometry(Expression expr) { + Expression underlyingMixin = ExpressionUtils.extract(expr); + if (underlyingMixin instanceof PathImpl) { + return new GeometryPath((PathImpl) underlyingMixin); + } else if (underlyingMixin instanceof OperationImpl) { + return new GeometryOperation((OperationImpl) underlyingMixin); + } else { + return new GeometryExpression(underlyingMixin) { + + private static final long serialVersionUID = -6714044005570420009L; + + @Override + public R accept(Visitor v, C context) { + return this.mixin.accept(v, context); + } + + }; + } + } + + /** + * Create a new GeometryExpression + * + * @param value Geometry + * @return new GeometryExpression + */ + public static GeometryExpression asGeometry(T value) { + return asGeometry(Expressions.constant(value)); + } + +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/GeometryOperation.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/GeometryOperation.java new file mode 100644 index 0000000000..e392aa3289 --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/GeometryOperation.java @@ -0,0 +1,71 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial; + +import java.util.Arrays; +import java.util.List; + +import org.geolatte.geom.Geometry; + +import com.querydsl.core.types.*; + +/** + * {@code GeometryOperation} extends {@link GeometryCollectionExpression} to implement the + * {@link Operation} interface + * + * @author tiwe + * + * @param + */ +public class GeometryOperation extends GeometryExpression implements Operation { + + private static final long serialVersionUID = 3433471874808633698L; + + private final OperationImpl opMixin; + + protected GeometryOperation(OperationImpl mixin) { + super(mixin); + this.opMixin = mixin; + } + + protected GeometryOperation(Class type, Operator op, Expression... args) { + this(type, op, Arrays.asList(args)); + } + + protected GeometryOperation(Class type, Operator op, List> args) { + super(ExpressionUtils.operation(type, op, args)); + this.opMixin = (OperationImpl) mixin; + } + + @Override + public final R accept(Visitor v, C context) { + return v.visit(opMixin, context); + } + + @Override + public Expression getArg(int index) { + return opMixin.getArg(index); + } + + @Override + public List> getArgs() { + return opMixin.getArgs(); + } + + @Override + public Operator getOperator() { + return opMixin.getOperator(); + } + +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/GeometryPath.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/GeometryPath.java new file mode 100644 index 0000000000..9e4fe380f9 --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/GeometryPath.java @@ -0,0 +1,161 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial; + +import java.lang.reflect.AnnotatedElement; + +import org.geolatte.geom.*; + +import com.querydsl.core.types.*; + +/** + * {@code GeometryPath} extends {@link GeometryExpression} to implement the + * {@link Path} interface + * + * @author tiwe + * + * @param + */ +public class GeometryPath extends GeometryExpression implements Path { + + private static final long serialVersionUID = 312776751843333543L; + + private final PathImpl pathMixin; + + private transient volatile GeometryCollectionPath collection; + + private transient volatile LinearRingPath linearRing; + + private transient volatile LineStringPath lineString; + + private transient volatile MultiLineStringPath multiLineString; + + private transient volatile MultiPointPath multiPoint; + + private transient volatile MultiPolygonPath multiPolygon; + + private transient volatile PointPath point; + + private transient volatile PolygonPath polygon; + + protected GeometryPath(PathImpl mixin) { + super(mixin); + this.pathMixin = mixin; + } + + @SuppressWarnings("unchecked") + public GeometryPath(Path parent, String property) { + this((Class) Geometry.class, parent, property); + } + + public GeometryPath(Class type, Path parent, String property) { + this(type, PathMetadataFactory.forProperty(parent, property)); + } + + @SuppressWarnings("unchecked") + public GeometryPath(PathMetadata metadata) { + this((Class) Geometry.class, metadata); + } + + public GeometryPath(Class type, PathMetadata metadata) { + super(ExpressionUtils.path(type, metadata)); + this.pathMixin = (PathImpl) mixin; + } + + @SuppressWarnings("unchecked") + public GeometryPath(String var) { + this((Class) Geometry.class, PathMetadataFactory.forVariable(var)); + } + + public GeometryCollectionPath asCollection() { + if (collection == null) { + collection = new GeometryCollectionPath(pathMixin.getMetadata()); + } + return collection; + } + + public LinearRingPath asLinearRing() { + if (linearRing == null) { + linearRing = new LinearRingPath(pathMixin.getMetadata()); + } + return linearRing; + } + + public LineStringPath asLineString() { + if (lineString == null) { + lineString = new LineStringPath(pathMixin.getMetadata()); + } + return lineString; + } + + public MultiLineStringPath asMultiLineString() { + if (multiLineString == null) { + multiLineString = new MultiLineStringPath(pathMixin.getMetadata()); + } + return multiLineString; + } + + public MultiPointPath asMultiPoint() { + if (multiPoint == null) { + multiPoint = new MultiPointPath(pathMixin.getMetadata()); + } + return multiPoint; + } + + public MultiPolygonPath asMultiPolygon() { + if (multiPolygon == null) { + multiPolygon = new MultiPolygonPath(pathMixin.getMetadata()); + } + return multiPolygon; + } + + public PointPath asPoint() { + if (point == null) { + point = new PointPath(pathMixin.getMetadata()); + } + return point; + } + + public PolygonPath asPolygon() { + if (polygon == null) { + polygon = new PolygonPath(pathMixin.getMetadata()); + } + return polygon; + } + + @Override + public final R accept(Visitor v, C context) { + return v.visit(pathMixin, context); + } + + public GeometryPath(Class type, String var) { + this(type, PathMetadataFactory.forVariable(var)); + } + + @Override + public PathMetadata getMetadata() { + return pathMixin.getMetadata(); + } + + @Override + public Path getRoot() { + return pathMixin.getRoot(); + } + + @Override + public AnnotatedElement getAnnotatedElement() { + return pathMixin.getAnnotatedElement(); + } + +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/GeometryPaths.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/GeometryPaths.java new file mode 100644 index 0000000000..a22cf4700a --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/GeometryPaths.java @@ -0,0 +1,44 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial; + +import org.geolatte.geom.*; + +/** + * {@code GeometryPaths} provides factory methods for {@link GeometryExpression} creation + * + * @author tiwe + * + */ +public interface GeometryPaths { + + GeometryCollectionPath createGeometryCollection(String property, Class type); + + GeometryPath createGeometry(String property, Class type); + + LinearRingPath createLinearRing(String property, Class type); + + LineStringPath createLineString(String property, Class type); + + MultiLineStringPath createMultiLineString(String property, Class type); + + MultiPointPath createMultiPoint(String property, Class type); + + MultiPolygonPath createMultiPolygon(String property, Class type); + + PointPath createPoint(String property, Class type); + + PolygonPath createPolygon(String property, Class type); + +} diff --git a/querydsl-spatial/src/main/java/com/mysema/query/spatial/LineExpression.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/LineExpression.java similarity index 86% rename from querydsl-spatial/src/main/java/com/mysema/query/spatial/LineExpression.java rename to querydsl-spatial/src/main/java/com/querydsl/spatial/LineExpression.java index 400d17962a..6782ceae81 100644 --- a/querydsl-spatial/src/main/java/com/mysema/query/spatial/LineExpression.java +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/LineExpression.java @@ -1,5 +1,5 @@ /* - * Copyright 2014, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,11 +11,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.spatial; +package com.querydsl.spatial; import org.geolatte.geom.LineString; -import com.mysema.query.types.Expression; +import com.querydsl.core.types.Expression; /** * A Line is a LineString with exactly 2 Points. diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/LineStringExpression.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/LineStringExpression.java new file mode 100644 index 0000000000..d3bdbca3b4 --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/LineStringExpression.java @@ -0,0 +1,67 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial; + +import org.jetbrains.annotations.Nullable; + +import org.geolatte.geom.LineString; +import org.geolatte.geom.Point; + +import com.querydsl.core.types.ConstantImpl; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberExpression; + +/** + * A LineString is a Curve with linear interpolation between Points. Each consecutive pair of Points defines a Line + * segment. + * + * @author tiwe + * + * @param + */ +public abstract class LineStringExpression extends CurveExpression { + + private static final long serialVersionUID = -6572984614863252657L; + + @Nullable + private transient volatile NumberExpression numPoints; + + public LineStringExpression(Expression mixin) { + super(mixin); + } + + /** + * The number of Points in this LineString. + * + * @return number of points + */ + public NumberExpression numPoints() { + if (numPoints == null) { + numPoints = Expressions.numberOperation(Integer.class, SpatialOps.NUM_POINTS, mixin); + } + return numPoints; + } + + /** + * Returns the specified Point N in this LineString. + * + * @param idx one-based index of element + * @return matched element + */ + public PointExpression pointN(int idx) { + return GeometryExpressions.pointOperation(SpatialOps.POINTN, mixin, ConstantImpl.create(idx)); + } + +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/LineStringOperation.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/LineStringOperation.java new file mode 100644 index 0000000000..38c0f2b798 --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/LineStringOperation.java @@ -0,0 +1,66 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial; + +import java.util.Arrays; +import java.util.List; + +import org.geolatte.geom.LineString; + +import com.querydsl.core.types.*; + +/** + * {@code LineStringOperation} extends {@link LineStringExpression} to implement the + * {@link Operation} interface + * + * @author tiwe + * + * @param + */ +public class LineStringOperation extends LineStringExpression implements Operation { + + private static final long serialVersionUID = 3433471874808633698L; + + private final OperationImpl opMixin; + + protected LineStringOperation(Class type, Operator op, Expression... args) { + this(type, op, Arrays.asList(args)); + } + + protected LineStringOperation(Class type, Operator op, List> args) { + super(ExpressionUtils.operation(type, op, args)); + this.opMixin = (OperationImpl) mixin; + } + + @Override + public final R accept(Visitor v, C context) { + return v.visit(opMixin, context); + } + + @Override + public Expression getArg(int index) { + return opMixin.getArg(index); + } + + @Override + public List> getArgs() { + return opMixin.getArgs(); + } + + @Override + public Operator getOperator() { + return opMixin.getOperator(); + } + +} diff --git a/querydsl-spatial/src/main/java/com/mysema/query/spatial/path/LineStringPath.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/LineStringPath.java similarity index 76% rename from querydsl-spatial/src/main/java/com/mysema/query/spatial/path/LineStringPath.java rename to querydsl-spatial/src/main/java/com/querydsl/spatial/LineStringPath.java index a83c33de7f..f49d5b4955 100644 --- a/querydsl-spatial/src/main/java/com/mysema/query/spatial/path/LineStringPath.java +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/LineStringPath.java @@ -1,5 +1,5 @@ /* - * Copyright 2014, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,20 +11,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.spatial.path; +package com.querydsl.spatial; import java.lang.reflect.AnnotatedElement; import org.geolatte.geom.LineString; -import com.mysema.query.spatial.LineStringExpression; -import com.mysema.query.types.Path; -import com.mysema.query.types.PathImpl; -import com.mysema.query.types.PathMetadata; -import com.mysema.query.types.PathMetadataFactory; -import com.mysema.query.types.Visitor; +import com.querydsl.core.types.*; /** + * {@code LineStringPath} extends {@link LineStringExpression} to implement the + * {@link Path} interface + * * @author tiwe * * @param @@ -35,6 +33,7 @@ public class LineStringPath extends LineStringExpression pathMixin; + @SuppressWarnings("unchecked") public LineStringPath(Path parent, String property) { this((Class) LineString.class, parent, property); } @@ -43,15 +42,17 @@ public LineStringPath(Class type, Path parent, String property) this(type, PathMetadataFactory.forProperty(parent, property)); } - public LineStringPath(PathMetadata metadata) { + @SuppressWarnings("unchecked") + public LineStringPath(PathMetadata metadata) { this((Class) LineString.class, metadata); } - public LineStringPath(Class type, PathMetadata metadata) { - super(new PathImpl(type, metadata)); - this.pathMixin = (PathImpl)mixin; + public LineStringPath(Class type, PathMetadata metadata) { + super(ExpressionUtils.path(type, metadata)); + this.pathMixin = (PathImpl) mixin; } + @SuppressWarnings("unchecked") public LineStringPath(String var) { this((Class) LineString.class, PathMetadataFactory.forVariable(var)); } @@ -66,7 +67,7 @@ public LineStringPath(Class type, String var) { } @Override - public PathMetadata getMetadata() { + public PathMetadata getMetadata() { return pathMixin.getMetadata(); } diff --git a/querydsl-spatial/src/main/java/com/mysema/query/spatial/LinearRingExpression.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/LinearRingExpression.java similarity index 87% rename from querydsl-spatial/src/main/java/com/mysema/query/spatial/LinearRingExpression.java rename to querydsl-spatial/src/main/java/com/querydsl/spatial/LinearRingExpression.java index 865d7f8ebd..ebd87a9c2d 100644 --- a/querydsl-spatial/src/main/java/com/mysema/query/spatial/LinearRingExpression.java +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/LinearRingExpression.java @@ -1,5 +1,5 @@ /* - * Copyright 2014, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,11 +11,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.spatial; +package com.querydsl.spatial; import org.geolatte.geom.LineString; -import com.mysema.query.types.Expression; +import com.querydsl.core.types.Expression; /** * A LinearRing is a LineString that is both closed and simple. diff --git a/querydsl-spatial/src/main/java/com/mysema/query/spatial/path/LinearRingPath.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/LinearRingPath.java similarity index 76% rename from querydsl-spatial/src/main/java/com/mysema/query/spatial/path/LinearRingPath.java rename to querydsl-spatial/src/main/java/com/querydsl/spatial/LinearRingPath.java index 3aaaac77a9..a878215497 100644 --- a/querydsl-spatial/src/main/java/com/mysema/query/spatial/path/LinearRingPath.java +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/LinearRingPath.java @@ -1,5 +1,5 @@ /* - * Copyright 2014, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,20 +11,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.spatial.path; +package com.querydsl.spatial; import java.lang.reflect.AnnotatedElement; import org.geolatte.geom.LinearRing; -import com.mysema.query.spatial.LinearRingExpression; -import com.mysema.query.types.Path; -import com.mysema.query.types.PathImpl; -import com.mysema.query.types.PathMetadata; -import com.mysema.query.types.PathMetadataFactory; -import com.mysema.query.types.Visitor; +import com.querydsl.core.types.*; /** + * {@code LinearRingPath} extends {@link LinearRingExpression} to implement the + * {@link Path} interface + * * @author tiwe * * @param @@ -35,6 +33,7 @@ public class LinearRingPath extends LinearRingExpression pathMixin; + @SuppressWarnings("unchecked") public LinearRingPath(Path parent, String property) { this((Class) LinearRing.class, parent, property); } @@ -43,15 +42,17 @@ public LinearRingPath(Class type, Path parent, String property) this(type, PathMetadataFactory.forProperty(parent, property)); } - public LinearRingPath(PathMetadata metadata) { + @SuppressWarnings("unchecked") + public LinearRingPath(PathMetadata metadata) { this((Class) LinearRing.class, metadata); } - public LinearRingPath(Class type, PathMetadata metadata) { - super(new PathImpl(type, metadata)); - this.pathMixin = (PathImpl)mixin; + public LinearRingPath(Class type, PathMetadata metadata) { + super(ExpressionUtils.path(type, metadata)); + this.pathMixin = (PathImpl) mixin; } + @SuppressWarnings("unchecked") public LinearRingPath(String var) { this((Class) LinearRing.class, PathMetadataFactory.forVariable(var)); } @@ -66,7 +67,7 @@ public LinearRingPath(Class type, String var) { } @Override - public PathMetadata getMetadata() { + public PathMetadata getMetadata() { return pathMixin.getMetadata(); } diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/MultiCurveExpression.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/MultiCurveExpression.java new file mode 100644 index 0000000000..e141657513 --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/MultiCurveExpression.java @@ -0,0 +1,70 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial; + +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.dsl.BooleanExpression; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberExpression; +import org.geolatte.geom.AbstractGeometryCollection; +import org.jetbrains.annotations.Nullable; + +/** + * A MultiCurve is a 1-dimensional GeometryCollection whose elements are Curves. + * + * @author tiwe + * + * @param + */ +public abstract class MultiCurveExpression extends AbstractGeometryCollectionExpression { + + private static final long serialVersionUID = 6983316799469849656L; + + @Nullable + private transient volatile BooleanExpression closed; + + @Nullable + private transient volatile NumberExpression length; + + public MultiCurveExpression(Expression mixin) { + super(mixin); + } + + /** + * Returns 1 (TRUE) if this MultiCurve is closed [StartPoint ( ) = EndPoint ( ) for each + * Curve in this MultiCurve]. + * + * @return closed + */ + public BooleanExpression isClosed() { + if (closed == null) { + closed = Expressions.booleanOperation(SpatialOps.IS_CLOSED, mixin); + } + return closed; + } + + /** + * The Length of this MultiCurve which is equal to the sum of the lengths of the element + * Curves. + * + * @return length + */ + public NumberExpression length() { + if (length == null) { + length = Expressions.numberOperation(Double.class, SpatialOps.LENGTH, mixin); + } + return length; + } + +} diff --git a/querydsl-spatial/src/main/java/com/mysema/query/spatial/MultiLineStringExpression.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/MultiLineStringExpression.java similarity index 87% rename from querydsl-spatial/src/main/java/com/mysema/query/spatial/MultiLineStringExpression.java rename to querydsl-spatial/src/main/java/com/querydsl/spatial/MultiLineStringExpression.java index 42fefa2e8f..fa859351eb 100644 --- a/querydsl-spatial/src/main/java/com/mysema/query/spatial/MultiLineStringExpression.java +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/MultiLineStringExpression.java @@ -1,5 +1,5 @@ /* - * Copyright 2014, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,11 +11,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.spatial; +package com.querydsl.spatial; import org.geolatte.geom.MultiLineString; -import com.mysema.query.types.Expression; +import com.querydsl.core.types.Expression; /** * A MultiLineString is a MultiCurve whose elements are LineStrings. diff --git a/querydsl-spatial/src/main/java/com/mysema/query/spatial/path/MultiLineStringPath.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/MultiLineStringPath.java similarity index 78% rename from querydsl-spatial/src/main/java/com/mysema/query/spatial/path/MultiLineStringPath.java rename to querydsl-spatial/src/main/java/com/querydsl/spatial/MultiLineStringPath.java index 37f6338f43..d3d72cfb32 100644 --- a/querydsl-spatial/src/main/java/com/mysema/query/spatial/path/MultiLineStringPath.java +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/MultiLineStringPath.java @@ -1,5 +1,5 @@ /* - * Copyright 2014, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,20 +11,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.spatial.path; +package com.querydsl.spatial; import java.lang.reflect.AnnotatedElement; import org.geolatte.geom.MultiLineString; -import com.mysema.query.spatial.MultiLineStringExpression; -import com.mysema.query.types.Path; -import com.mysema.query.types.PathImpl; -import com.mysema.query.types.PathMetadata; -import com.mysema.query.types.PathMetadataFactory; -import com.mysema.query.types.Visitor; +import com.querydsl.core.types.*; /** + * {@code MultiLineStringPath} extends {@link MultiLineStringExpression} to implement the + * {@link Path} interface + * * @author tiwe * * @param @@ -35,6 +33,7 @@ public class MultiLineStringPath extends MultiLineStr private final PathImpl pathMixin; + @SuppressWarnings("unchecked") public MultiLineStringPath(Path parent, String property) { this((Class) MultiLineString.class, parent, property); } @@ -43,30 +42,32 @@ public MultiLineStringPath(Class type, Path parent, String prope this(type, PathMetadataFactory.forProperty(parent, property)); } - public MultiLineStringPath(PathMetadata metadata) { + @SuppressWarnings("unchecked") + public MultiLineStringPath(PathMetadata metadata) { this((Class) MultiLineString.class, metadata); } - public MultiLineStringPath(Class type, PathMetadata metadata) { - super(new PathImpl(type, metadata)); - this.pathMixin = (PathImpl)mixin; + public MultiLineStringPath(Class type, PathMetadata metadata) { + super(ExpressionUtils.path(type, metadata)); + this.pathMixin = (PathImpl) mixin; } + @SuppressWarnings("unchecked") public MultiLineStringPath(String var) { this((Class) MultiLineString.class, PathMetadataFactory.forVariable(var)); } + public MultiLineStringPath(Class type, String var) { + this(type, PathMetadataFactory.forVariable(var)); + } + @Override public final R accept(Visitor v, C context) { return v.visit(pathMixin, context); } - public MultiLineStringPath(Class type, String var) { - this(type, PathMetadataFactory.forVariable(var)); - } - @Override - public PathMetadata getMetadata() { + public PathMetadata getMetadata() { return pathMixin.getMetadata(); } diff --git a/querydsl-spatial/src/main/java/com/mysema/query/spatial/MultiPointExpression.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/MultiPointExpression.java similarity index 85% rename from querydsl-spatial/src/main/java/com/mysema/query/spatial/MultiPointExpression.java rename to querydsl-spatial/src/main/java/com/querydsl/spatial/MultiPointExpression.java index b24c057fcd..434ddf04e9 100644 --- a/querydsl-spatial/src/main/java/com/mysema/query/spatial/MultiPointExpression.java +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/MultiPointExpression.java @@ -1,5 +1,5 @@ /* - * Copyright 2014, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,11 +11,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.spatial; +package com.querydsl.spatial; import org.geolatte.geom.MultiPoint; -import com.mysema.query.types.Expression; +import com.querydsl.core.types.Expression; /** * A MultiPoint is a 0-dimensional GeometryCollection. The elements of a MultiPoint are restricted to Points. The @@ -26,7 +26,7 @@ * * @param */ -public abstract class MultiPointExpression extends GeometryCollectionExpression { +public abstract class MultiPointExpression extends AbstractGeometryCollectionExpression { private static final long serialVersionUID = 7221702165705045865L; diff --git a/querydsl-spatial/src/main/java/com/mysema/query/spatial/path/MultiPointPath.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/MultiPointPath.java similarity index 76% rename from querydsl-spatial/src/main/java/com/mysema/query/spatial/path/MultiPointPath.java rename to querydsl-spatial/src/main/java/com/querydsl/spatial/MultiPointPath.java index 27b979cec0..a62436f991 100644 --- a/querydsl-spatial/src/main/java/com/mysema/query/spatial/path/MultiPointPath.java +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/MultiPointPath.java @@ -1,5 +1,5 @@ /* - * Copyright 2014, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,20 +11,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.spatial.path; +package com.querydsl.spatial; import java.lang.reflect.AnnotatedElement; import org.geolatte.geom.MultiPoint; -import com.mysema.query.spatial.MultiPointExpression; -import com.mysema.query.types.Path; -import com.mysema.query.types.PathImpl; -import com.mysema.query.types.PathMetadata; -import com.mysema.query.types.PathMetadataFactory; -import com.mysema.query.types.Visitor; +import com.querydsl.core.types.*; /** + * {@code MultiPointPath} extends {@link MultiPointExpression} to implement the + * {@link Path} interface + * * @author tiwe * * @param @@ -35,6 +33,7 @@ public class MultiPointPath extends MultiPointExpression pathMixin; + @SuppressWarnings("unchecked") public MultiPointPath(Path parent, String property) { this((Class) MultiPoint.class, parent, property); } @@ -43,30 +42,32 @@ public MultiPointPath(Class type, Path parent, String property) this(type, PathMetadataFactory.forProperty(parent, property)); } - public MultiPointPath(PathMetadata metadata) { + @SuppressWarnings("unchecked") + public MultiPointPath(PathMetadata metadata) { this((Class) MultiPoint.class, metadata); } - public MultiPointPath(Class type, PathMetadata metadata) { - super(new PathImpl(type, metadata)); - this.pathMixin = (PathImpl)mixin; + public MultiPointPath(Class type, PathMetadata metadata) { + super(ExpressionUtils.path(type, metadata)); + this.pathMixin = (PathImpl) mixin; } + @SuppressWarnings("unchecked") public MultiPointPath(String var) { this((Class) MultiPoint.class, PathMetadataFactory.forVariable(var)); } + public MultiPointPath(Class type, String var) { + this(type, PathMetadataFactory.forVariable(var)); + } + @Override public final R accept(Visitor v, C context) { return v.visit(pathMixin, context); } - public MultiPointPath(Class type, String var) { - this(type, PathMetadataFactory.forVariable(var)); - } - @Override - public PathMetadata getMetadata() { + public PathMetadata getMetadata() { return pathMixin.getMetadata(); } diff --git a/querydsl-spatial/src/main/java/com/mysema/query/spatial/MultiPolygonExpression.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/MultiPolygonExpression.java similarity index 87% rename from querydsl-spatial/src/main/java/com/mysema/query/spatial/MultiPolygonExpression.java rename to querydsl-spatial/src/main/java/com/querydsl/spatial/MultiPolygonExpression.java index 95a9da5e0c..301d55368b 100644 --- a/querydsl-spatial/src/main/java/com/mysema/query/spatial/MultiPolygonExpression.java +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/MultiPolygonExpression.java @@ -1,5 +1,5 @@ /* - * Copyright 2014, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,11 +11,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.spatial; +package com.querydsl.spatial; import org.geolatte.geom.MultiPolygon; -import com.mysema.query.types.Expression; +import com.querydsl.core.types.Expression; /** * A MultiPolygon is a MultiSurface whose elements are Polygons. diff --git a/querydsl-spatial/src/main/java/com/mysema/query/spatial/path/MultiPolygonPath.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/MultiPolygonPath.java similarity index 78% rename from querydsl-spatial/src/main/java/com/mysema/query/spatial/path/MultiPolygonPath.java rename to querydsl-spatial/src/main/java/com/querydsl/spatial/MultiPolygonPath.java index d486d177af..517a35b232 100644 --- a/querydsl-spatial/src/main/java/com/mysema/query/spatial/path/MultiPolygonPath.java +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/MultiPolygonPath.java @@ -1,5 +1,5 @@ /* - * Copyright 2014, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,20 +11,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.spatial.path; +package com.querydsl.spatial; import java.lang.reflect.AnnotatedElement; import org.geolatte.geom.MultiPolygon; -import com.mysema.query.spatial.MultiPolygonExpression; -import com.mysema.query.types.Path; -import com.mysema.query.types.PathImpl; -import com.mysema.query.types.PathMetadata; -import com.mysema.query.types.PathMetadataFactory; -import com.mysema.query.types.Visitor; +import com.querydsl.core.types.*; /** + * {@code MultiPolygonPath} extends {@link MultiPolygonExpression} to implement the + * {@link Path} interface + * * @author tiwe * * @param @@ -35,6 +33,7 @@ public class MultiPolygonPath extends MultiPolygonExpres private final PathImpl pathMixin; + @SuppressWarnings("unchecked") public MultiPolygonPath(Path parent, String property) { this((Class) MultiPolygon.class, parent, property); } @@ -43,15 +42,17 @@ public MultiPolygonPath(Class type, Path parent, String property this(type, PathMetadataFactory.forProperty(parent, property)); } - public MultiPolygonPath(PathMetadata metadata) { + @SuppressWarnings("unchecked") + public MultiPolygonPath(PathMetadata metadata) { this((Class) MultiPolygon.class, metadata); } - public MultiPolygonPath(Class type, PathMetadata metadata) { - super(new PathImpl(type, metadata)); - this.pathMixin = (PathImpl)mixin; + public MultiPolygonPath(Class type, PathMetadata metadata) { + super(ExpressionUtils.path(type, metadata)); + this.pathMixin = (PathImpl) mixin; } + @SuppressWarnings("unchecked") public MultiPolygonPath(String var) { this((Class) MultiPolygon.class, PathMetadataFactory.forVariable(var)); } @@ -66,7 +67,7 @@ public MultiPolygonPath(Class type, String var) { } @Override - public PathMetadata getMetadata() { + public PathMetadata getMetadata() { return pathMixin.getMetadata(); } diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/MultiSurfaceExpression.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/MultiSurfaceExpression.java new file mode 100644 index 0000000000..e11bc21b8e --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/MultiSurfaceExpression.java @@ -0,0 +1,85 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial; + +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberExpression; +import org.geolatte.geom.AbstractGeometryCollection; +import org.geolatte.geom.Point; +import org.jetbrains.annotations.Nullable; + +/** + * A MultiSurface is a 2-dimensional GeometryCollection whose elements are Surfaces, all using coordinates from + * the same coordinate reference system. The geometric interiors of any two Surfaces in a MultiSurface may not + * intersect in the full coordinate system. The boundaries of any two coplanar elements in a MultiSurface may + * intersect, at most, at a finite number of Points. If they were to meet along a curve, they could be merged into a + * single surface. + * + * @author tiwe + * + * @param + */ +public abstract class MultiSurfaceExpression extends AbstractGeometryCollectionExpression { + + private static final long serialVersionUID = 4133386816772862010L; + + @Nullable + private transient volatile PointExpression centroid, pointOnSurface; + + @Nullable + private transient volatile NumberExpression area; + + public MultiSurfaceExpression(Expression mixin) { + super(mixin); + } + + /** + * The area of this MultiSurface, as measured in the spatial reference system of this MultiSurface. + * + * @return area + */ + public NumberExpression area() { + if (area == null) { + area = Expressions.numberOperation(Double.class, SpatialOps.AREA, mixin); + } + return area; + } + + /** + * The mathematical centroid for this MultiSurface. The result is not guaranteed to be on + * this MultiSurface. + * + * @return centroid + */ + public PointExpression centroid() { + if (centroid == null) { + centroid = GeometryExpressions.pointOperation(SpatialOps.CENTROID, mixin); + } + return centroid; + } + + /** + * A Point guaranteed to be on this MultiSurface. + * + * @return point on surface + */ + public PointExpression pointOnSurface() { + if (pointOnSurface == null) { + pointOnSurface = GeometryExpressions.pointOperation(SpatialOps.POINT_ON_SURFACE, mixin); + } + return pointOnSurface; + } + +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/PointExpression.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/PointExpression.java new file mode 100644 index 0000000000..87dbff6033 --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/PointExpression.java @@ -0,0 +1,91 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial; + +import org.jetbrains.annotations.Nullable; + +import org.geolatte.geom.Point; + +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberExpression; + +/** + * A Point is a 0-dimensional geometric object and represents a single location in coordinate space. A Point has an + * x-coordinate value, a y-coordinate value. If called for by the associated Spatial Reference System, it may also + * have coordinate values for z and m. + * + * @author tiwe + * + * @param + */ +public abstract class PointExpression extends GeometryExpression { + + private static final long serialVersionUID = -3549448861390349654L; + + @Nullable + private transient volatile NumberExpression x, y, z, m; + + public PointExpression(Expression mixin) { + super(mixin); + } + + /** + * The x-coordinate value for this Point. + * + * @return x-coordinate + */ + public NumberExpression x() { + if (x == null) { + x = Expressions.numberOperation(Double.class, SpatialOps.X, mixin); + } + return x; + } + + /** + * The y-coordinate value for this Point. + * + * @return y-coordinate + */ + public NumberExpression y() { + if (y == null) { + y = Expressions.numberOperation(Double.class, SpatialOps.Y, mixin); + } + return y; + } + + /** + * The z-coordinate value for this Point, if it has one. Returns NIL otherwise. + * + * @return z-coordinate + */ + public NumberExpression z() { + if (z == null) { + z = Expressions.numberOperation(Double.class, SpatialOps.Z, mixin); + } + return z; + } + + /** + * The m-coordinate value for this Point, if it has one. Returns NIL otherwise. + * + * @return m-coordinate + */ + public NumberExpression m() { + if (m == null) { + m = Expressions.numberOperation(Double.class, SpatialOps.M, mixin); + } + return m; + } +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/PointOperation.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/PointOperation.java new file mode 100644 index 0000000000..32e29da228 --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/PointOperation.java @@ -0,0 +1,65 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial; + +import java.util.Arrays; +import java.util.List; + +import org.geolatte.geom.Point; + +import com.querydsl.core.types.*; + +/** + * {@code PointOperation} extends {@link PointExpression} to implement the + * {@link Operation} interface + * + * @author tiwe + * + * @param + */ +public class PointOperation extends PointExpression implements Operation { + + private static final long serialVersionUID = 3433471874808633698L; + + private final OperationImpl opMixin; + + protected PointOperation(Class type, Operator op, Expression... args) { + this(type, op, Arrays.asList(args)); + } + + protected PointOperation(Class type, Operator op, List> args) { + super(ExpressionUtils.operation(type, op, args)); + this.opMixin = (OperationImpl) mixin; + } + + @Override + public final R accept(Visitor v, C context) { + return v.visit(opMixin, context); + } + + @Override + public Expression getArg(int index) { + return opMixin.getArg(index); + } + + @Override + public List> getArgs() { + return opMixin.getArgs(); + } + + @Override + public Operator getOperator() { + return opMixin.getOperator(); + } +} diff --git a/querydsl-spatial/src/main/java/com/mysema/query/spatial/path/PointPath.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/PointPath.java similarity index 76% rename from querydsl-spatial/src/main/java/com/mysema/query/spatial/path/PointPath.java rename to querydsl-spatial/src/main/java/com/querydsl/spatial/PointPath.java index e3b78d86f8..21fe55348c 100644 --- a/querydsl-spatial/src/main/java/com/mysema/query/spatial/path/PointPath.java +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/PointPath.java @@ -1,5 +1,5 @@ /* - * Copyright 2014, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,20 +11,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.spatial.path; +package com.querydsl.spatial; import java.lang.reflect.AnnotatedElement; import org.geolatte.geom.Point; -import com.mysema.query.spatial.PointExpression; -import com.mysema.query.types.Path; -import com.mysema.query.types.PathImpl; -import com.mysema.query.types.PathMetadata; -import com.mysema.query.types.PathMetadataFactory; -import com.mysema.query.types.Visitor; +import com.querydsl.core.types.*; /** + * {@code PointPath} extends {@link PointExpression} to implement the + * {@link Path} interface + * * @author tiwe * * @param @@ -35,6 +33,7 @@ public class PointPath extends PointExpression implements Pa private final PathImpl pathMixin; + @SuppressWarnings("unchecked") public PointPath(Path parent, String property) { this((Class) Point.class, parent, property); } @@ -43,15 +42,17 @@ public PointPath(Class type, Path parent, String property) { this(type, PathMetadataFactory.forProperty(parent, property)); } - public PointPath(PathMetadata metadata) { + @SuppressWarnings("unchecked") + public PointPath(PathMetadata metadata) { this((Class) Point.class, metadata); } - public PointPath(Class type, PathMetadata metadata) { - super(new PathImpl(type, metadata)); - this.pathMixin = (PathImpl)mixin; + public PointPath(Class type, PathMetadata metadata) { + super(ExpressionUtils.path(type, metadata)); + this.pathMixin = (PathImpl) mixin; } + @SuppressWarnings("unchecked") public PointPath(String var) { this((Class) Point.class, PathMetadataFactory.forVariable(var)); } @@ -66,7 +67,7 @@ public PointPath(Class type, String var) { } @Override - public PathMetadata getMetadata() { + public PathMetadata getMetadata() { return pathMixin.getMetadata(); } diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/PolygonExpression.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/PolygonExpression.java new file mode 100644 index 0000000000..7991f3b328 --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/PolygonExpression.java @@ -0,0 +1,82 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial; + +import org.jetbrains.annotations.Nullable; + +import org.geolatte.geom.LineString; +import org.geolatte.geom.Polygon; + +import com.querydsl.core.types.ConstantImpl; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberExpression; + +/** + * A Polygon is a planar Surface defined by 1 exterior boundary and 0 or more interior boundaries. Each interior + * boundary defines a hole in the Polygon. A Triangle is a polygon with 3 distinct, non-collinear vertices and no + * interior boundary. + * + * @author tiwe + * + * @param + */ +public abstract class PolygonExpression extends SurfaceExpression { + + private static final long serialVersionUID = 7544382956232485312L; + + @Nullable + private transient volatile NumberExpression numInteriorRing; + + @Nullable + private transient volatile LineStringExpression exterorRing; + + public PolygonExpression(Expression mixin) { + super(mixin); + } + + /** + * Returns the exterior ring of this Polygon. + * + * @return exterior ring + */ + public LineStringExpression exteriorRing() { + if (exterorRing == null) { + exterorRing = GeometryExpressions.lineStringOperation(SpatialOps.EXTERIOR_RING, mixin); + } + return exterorRing; + } + + /** + * Returns the number of interior rings in this Polygon. + * + * @return number of interior rings + */ + public NumberExpression numInteriorRing() { + if (numInteriorRing == null) { + numInteriorRing = Expressions.numberOperation(Integer.class, SpatialOps.NUM_INTERIOR_RING, mixin); + } + return numInteriorRing; + } + + /** + * Returns the N th interior ring for this Polygon as a LineString. + * + * @param idx one based index + * @return interior ring at index + */ + public LineStringExpression interiorRingN(int idx) { + return GeometryExpressions.lineStringOperation(SpatialOps.INTERIOR_RINGN, mixin, ConstantImpl.create(idx)); + } +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/PolygonOperation.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/PolygonOperation.java new file mode 100644 index 0000000000..713cdb2120 --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/PolygonOperation.java @@ -0,0 +1,65 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial; + +import java.util.Arrays; +import java.util.List; + +import org.geolatte.geom.Polygon; + +import com.querydsl.core.types.*; + +/** + * {@code PolygonOperation} extends {@link PolygonExpression} to implement the + * {@link Operation} interface + * + * @author tiwe + * + * @param + */ +public class PolygonOperation extends PolygonExpression implements Operation { + + private static final long serialVersionUID = 3433471874808633698L; + + private final OperationImpl opMixin; + + protected PolygonOperation(Class type, Operator op, Expression... args) { + this(type, op, Arrays.asList(args)); + } + + protected PolygonOperation(Class type, Operator op, List> args) { + super(ExpressionUtils.operation(type, op, args)); + this.opMixin = (OperationImpl) mixin; + } + + @Override + public final R accept(Visitor v, C context) { + return v.visit(opMixin, context); + } + + @Override + public Expression getArg(int index) { + return opMixin.getArg(index); + } + + @Override + public List> getArgs() { + return opMixin.getArgs(); + } + + @Override + public Operator getOperator() { + return opMixin.getOperator(); + } +} diff --git a/querydsl-spatial/src/main/java/com/mysema/query/spatial/path/PolygonPath.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/PolygonPath.java similarity index 76% rename from querydsl-spatial/src/main/java/com/mysema/query/spatial/path/PolygonPath.java rename to querydsl-spatial/src/main/java/com/querydsl/spatial/PolygonPath.java index da0523d120..5578f412c9 100644 --- a/querydsl-spatial/src/main/java/com/mysema/query/spatial/path/PolygonPath.java +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/PolygonPath.java @@ -1,5 +1,5 @@ /* - * Copyright 2014, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,20 +11,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.spatial.path; +package com.querydsl.spatial; import java.lang.reflect.AnnotatedElement; import org.geolatte.geom.Polygon; -import com.mysema.query.spatial.PolygonExpression; -import com.mysema.query.types.Path; -import com.mysema.query.types.PathImpl; -import com.mysema.query.types.PathMetadata; -import com.mysema.query.types.PathMetadataFactory; -import com.mysema.query.types.Visitor; +import com.querydsl.core.types.*; /** + * {@code PolygonPath} extends {@link PolygonExpression} to implement the + * {@link Path} interface + * * @author tiwe * * @param @@ -35,6 +33,7 @@ public class PolygonPath extends PolygonExpression impleme private final PathImpl pathMixin; + @SuppressWarnings("unchecked") public PolygonPath(Path parent, String property) { this((Class) Polygon.class, parent, property); } @@ -43,15 +42,17 @@ public PolygonPath(Class type, Path parent, String property) { this(type, PathMetadataFactory.forProperty(parent, property)); } - public PolygonPath(PathMetadata metadata) { + @SuppressWarnings("unchecked") + public PolygonPath(PathMetadata metadata) { this((Class) Polygon.class, metadata); } - public PolygonPath(Class type, PathMetadata metadata) { - super(new PathImpl(type, metadata)); - this.pathMixin = (PathImpl)mixin; + public PolygonPath(Class type, PathMetadata metadata) { + super(ExpressionUtils.path(type, metadata)); + this.pathMixin = (PathImpl) mixin; } + @SuppressWarnings("unchecked") public PolygonPath(String var) { this((Class) Polygon.class, PathMetadataFactory.forVariable(var)); } @@ -66,7 +67,7 @@ public PolygonPath(Class type, String var) { } @Override - public PathMetadata getMetadata() { + public PathMetadata getMetadata() { return pathMixin.getMetadata(); } diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/SpatialOps.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/SpatialOps.java new file mode 100644 index 0000000000..e5307f95b7 --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/SpatialOps.java @@ -0,0 +1,133 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial; + +import com.querydsl.core.types.Operator; + +/** + * {@code SpatialOps} provides {@link Operator} instances for spatial operations + * + * @author tiwe + * + */ +public enum SpatialOps implements Operator { + + // Geometry + DIMENSION(Integer.class), + GEOMETRY_TYPE(String.class), + AS_TEXT(String.class), + AS_BINARY(Object.class), + SRID(Integer.class), + SRID2(Integer.class), + IS_EMPTY(Boolean.class), + IS_SIMPLE(Boolean.class), + BOUNDARY(Object.class), + ENVELOPE(Object.class), + WKTTOSQL(Object.class), + WKBTOSQL(Object.class), + EQUALS(Boolean.class), + DISJOINT(Boolean.class), + INTERSECTS(Boolean.class), + TOUCHES(Boolean.class), + CROSSES(Boolean.class), + WITHIN(Boolean.class), + CONTAINS(Boolean.class), + OVERLAPS(Boolean.class), + RELATE(Boolean.class), + DISTANCE(Number.class), + DISTANCE2(Number.class), + DISTANCE_SPHERE(Number.class), + DISTANCE_SPHEROID(Number.class), + INTERSECTION(Object.class), + DIFFERENCE(Object.class), + UNION(Object.class), + SYMDIFFERENCE(Object.class), + BUFFER(Object.class), + BUFFER2(Object.class), + CONVEXHULL(Object.class), + TRANSFORM(Object.class), + + // Point + X(Number.class), + X2(Number.class), + Y(Number.class), + Y2(Number.class), + Z(Number.class), + Z2(Number.class), + M(Number.class), + M2(Number.class), + + // Curve + START_POINT(Object.class), + END_POINT(Object.class), + IS_RING(Object.class), + LENGTH(Object.class), + LENGTH2(Object.class), + + // LineString + NUM_POINTS(Integer.class), + POINTN(Object.class), + + // Surface + AREA(Number.class), + AREA2(Number.class), + CENTROID(Object.class), + POINT_ON_SURFACE(Object.class), + + // Polygon + EXTERIOR_RING(Object.class), + EXTERIOR_RING2(Object.class), + INTERIOR_RINGS(Object.class), + INTERIOR_RINGS2(Object.class), + NUM_INTERIOR_RING(Integer.class), + INTERIOR_RINGN(Object.class), + + // Polyhedral Surface + GEOMETRIES(Object.class), + NUM_SURFACES(Integer.class), + SURFACE(Object.class), + + // GeometryCollection + NUM_GEOMETRIES(Integer.class), + GEOMETRYN(Object.class), + + // MultiCurve + IS_CLOSED(Boolean.class), + + // Extensions + AS_EWKT(String.class), + GEOM_FROM_TEXT(Object.class), + SET_SRID(Object.class), + XMIN(Number.class), + XMAX(Number.class), + YMIN(Number.class), + YMAX(Number.class), + DWITHIN(Boolean.class), + EXTENT(Object.class), + COLLECT(Object.class), + COLLECT2(Object.class), + TRANSLATE(Object.class), + TRANSLATE2(Object.class); + + private final Class type; + + SpatialOps(Class type) { + this.type = type; + } + + @Override + public Class getType() { + return type; + } +} \ No newline at end of file diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/SurfaceExpression.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/SurfaceExpression.java new file mode 100644 index 0000000000..a80b07fc23 --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/SurfaceExpression.java @@ -0,0 +1,83 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial; + +import org.jetbrains.annotations.Nullable; + +import org.geolatte.geom.Geometry; +import org.geolatte.geom.Point; + +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberExpression; + +/** + * A Surface is a 2-dimensional geometric object. + * + * @author tiwe + * + * @param + */ +public abstract class SurfaceExpression extends GeometryExpression { + + private static final long serialVersionUID = 3534197011234723698L; + + @Nullable + private transient volatile PointExpression centroid, pointOnSurface; + + @Nullable + private transient volatile NumberExpression area; + + public SurfaceExpression(Expression mixin) { + super(mixin); + } + + /** + * The area of this Surface, as measured in the spatial reference system of this Surface. + * + * @return area + */ + public NumberExpression area() { + if (area == null) { + area = Expressions.numberOperation(Double.class, SpatialOps.AREA, mixin); + } + return area; + } + + /** + * The mathematical centroid for this Surface as a Point. The result is not guaranteed to + * be on this Surface. + * + * @return centroid + */ + public PointExpression centroid() { + if (centroid == null) { + centroid = GeometryExpressions.pointOperation(SpatialOps.CENTROID, mixin); + } + return centroid; + } + + /** + * A Point guaranteed to be on this Surface. + * + * @return point on surface + */ + public PointExpression pointOnSurface() { + if (pointOnSurface == null) { + pointOnSurface = GeometryExpressions.pointOperation(SpatialOps.POINT_ON_SURFACE, mixin); + } + return pointOnSurface; + } + +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/apt/SpatialSupport.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/apt/SpatialSupport.java new file mode 100644 index 0000000000..b5cca1d804 --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/apt/SpatialSupport.java @@ -0,0 +1,101 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial.apt; + +import com.querydsl.codegen.Extension; +import com.querydsl.codegen.utils.model.SimpleType; +import com.querydsl.codegen.AbstractModule; +import com.querydsl.codegen.CodegenModule; +import com.querydsl.codegen.TypeMappings; + +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +/** + * {@code SpatialSupport} provides support for spatial types in code generation + * + * @author tiwe + * + */ +public final class SpatialSupport implements Extension { + + private static void registerTypes(TypeMappings typeMappings) { + Map additions = new HashMap<>(); + additions.put("Geometry", "GeometryPath"); + additions.put("GeometryCollection", "GeometryCollectionPath"); + additions.put("LinearRing", "LinearRingPath"); + additions.put("LineString", "LineStringPath"); + additions.put("MultiLineString", "MultiLineStringPath"); + additions.put("MultiPoint", "MultiPointPath"); + additions.put("MultiPolygon", "MultiPolygonPath"); + additions.put("Point", "PointPath"); + additions.put("Polygon", "PolygonPath"); + for (Map.Entry entry : additions.entrySet()) { + typeMappings.register( + new SimpleType("org.geolatte.geom." + entry.getKey()), + new SimpleType("com.querydsl.spatial." + entry.getValue())); + } + } + + private static void registerJTSTypes(TypeMappings typeMappings) { + Map additions = new HashMap<>(); + additions.put("Geometry", "JTSGeometryPath"); + additions.put("GeometryCollection", "JTSGeometryCollectionPath"); + additions.put("LinearRing", "JTSLinearRingPath"); + additions.put("LineString", "JTSLineStringPath"); + additions.put("MultiLineString", "JTSMultiLineStringPath"); + additions.put("MultiPoint", "JTSMultiPointPath"); + additions.put("MultiPolygon", "JTSMultiPolygonPath"); + additions.put("Point", "JTSPointPath"); + additions.put("Polygon", "JTSPolygonPath"); + for (Map.Entry entry : additions.entrySet()) { + typeMappings.register( + new SimpleType("com.vividsolutions.jts.geom." + entry.getKey()), + new SimpleType("com.querydsl.spatial.jts." + entry.getValue())); + typeMappings.register( + new SimpleType("org.locationtech.jts.geom." + entry.getKey()), + new SimpleType("com.querydsl.spatial.locationtech.jts." + entry.getValue())); + } + } + + private static void addImports(AbstractModule module, String packageName) { + @SuppressWarnings("unchecked") + Set imports = module.get(Set.class, CodegenModule.IMPORTS); + if (imports.isEmpty()) { + imports = Collections.singleton(packageName); + } else { + Set old = imports; + imports = new HashSet<>(); + imports.addAll(old); + imports.add(packageName); + } + module.bind(CodegenModule.IMPORTS, imports); + } + + /** + * Register spatial types to the given codegen module + * + * @param module module to be customized for spatial support + */ + public void addSupport(AbstractModule module) { + registerTypes(module.get(TypeMappings.class)); + addImports(module,"com.querydsl.spatial.path"); + registerJTSTypes(module.get(TypeMappings.class)); + addImports(module,"com.querydsl.spatial.jts.path"); + } + +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/apt/package-info.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/apt/package-info.java new file mode 100644 index 0000000000..b2bf88c99f --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/apt/package-info.java @@ -0,0 +1,18 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ + +/** + * APT extension for registering spatial types. + */ +package com.querydsl.spatial.apt; diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/hibernate/HibernateSpatialSupport.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/hibernate/HibernateSpatialSupport.java new file mode 100644 index 0000000000..f2be42c520 --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/hibernate/HibernateSpatialSupport.java @@ -0,0 +1,116 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial.hibernate; + +import java.util.HashMap; +import java.util.Map; + +import com.querydsl.core.types.Operator; +import com.querydsl.spatial.SpatialOps; + +/** + * {@code HibernateSpatialSupport} provides mappings from operators to serialization templates + * to be used in Hibernate Spatial + */ +public final class HibernateSpatialSupport { + + private HibernateSpatialSupport() { } + + public static Map getSpatialOps() { + Map ops = new HashMap<>(); + ops.put(SpatialOps.DIMENSION, "dimension({0})"); + ops.put(SpatialOps.GEOMETRY_TYPE, "geometrytype({0}, {1})"); + ops.put(SpatialOps.SRID, "srid({0})"); + ops.put(SpatialOps.SRID2, "srid2({0}, {1})"); + ops.put(SpatialOps.ENVELOPE, "envelope({0})"); + ops.put(SpatialOps.AS_TEXT, "astext({0})"); + ops.put(SpatialOps.AS_BINARY, "asbinary({0})"); + ops.put(SpatialOps.IS_EMPTY, "isempty({0})"); + ops.put(SpatialOps.IS_SIMPLE, "issimple({0})"); + ops.put(SpatialOps.BOUNDARY, "boundary({0})"); + ops.put(SpatialOps.EXTENT, "extent({0})"); + + ops.put(SpatialOps.EQUALS, "equals({0}, {1}) = true"); + ops.put(SpatialOps.DISJOINT, "disjoint({0}, {1}) = true"); + ops.put(SpatialOps.INTERSECTS, "intersects({0}, {1}) = true"); + ops.put(SpatialOps.TOUCHES, "touches({0}, {1}) = true"); + ops.put(SpatialOps.CROSSES, "crosses({0}, {1}) = true"); + ops.put(SpatialOps.WITHIN, "within({0}, {1}) = true"); + ops.put(SpatialOps.CONTAINS, "contains({0}, {1}) = true"); + ops.put(SpatialOps.OVERLAPS, "overlaps({0}, {1}) = true"); + ops.put(SpatialOps.RELATE, "relate({0}, {1}, {2}) = true"); + + ops.put(SpatialOps.DISTANCE, "distance({0}, {1})"); + ops.put(SpatialOps.DISTANCE2, "distance({0}, {1}, {2})"); + ops.put(SpatialOps.DISTANCE_SPHERE, "distancesphere({0}, {1})"); + ops.put(SpatialOps.DISTANCE_SPHEROID, "distancespheroid({0}, {1})"); + + ops.put(SpatialOps.BUFFER, "buffer({0}, {1})"); + ops.put(SpatialOps.BUFFER2, "buffer({0}, {1}, {2})"); + ops.put(SpatialOps.CONVEXHULL, "convexhull({0})"); + ops.put(SpatialOps.INTERSECTION, "intersection({0}, {1})"); + ops.put(SpatialOps.UNION, "geomunion({0}, {1})"); + ops.put(SpatialOps.DIFFERENCE, "difference({0}, {1})"); + ops.put(SpatialOps.SYMDIFFERENCE, "symdifference({0}, {1})"); + ops.put(SpatialOps.DWITHIN, "dwithin({0}, {1}, {2}) = true"); + ops.put(SpatialOps.TRANSFORM, "transform({0}, {1})"); + + // custom + ops.put(SpatialOps.WKTTOSQL, "wkttosql({0}, {1})"); + ops.put(SpatialOps.WKBTOSQL, "wkbtosql({0}, {1})"); + ops.put(SpatialOps.X, "x({0})"); + ops.put(SpatialOps.X2, "x({0}, {1})"); + ops.put(SpatialOps.Y, "y({0})"); + ops.put(SpatialOps.Y2, "y({0}, {1})"); + ops.put(SpatialOps.Z, "y({0})"); + ops.put(SpatialOps.Z2, "y({0}, {1})"); + ops.put(SpatialOps.M, "y({0})"); + ops.put(SpatialOps.M2, "y({0}, {1})"); + ops.put(SpatialOps.START_POINT, "startpoint({0})"); + ops.put(SpatialOps.END_POINT, "endpoint({0})"); + ops.put(SpatialOps.IS_RING, "isring({0})"); + ops.put(SpatialOps.LENGTH, "length({0})"); + ops.put(SpatialOps.LENGTH2, "length({0}, {1})"); + ops.put(SpatialOps.NUM_POINTS, "numpoints({0})"); + ops.put(SpatialOps.POINTN, "pointn({0})"); + ops.put(SpatialOps.AREA, "area({0})"); + ops.put(SpatialOps.AREA2, "area({0}, {1})"); + ops.put(SpatialOps.CENTROID, "centroid({0})"); + ops.put(SpatialOps.POINT_ON_SURFACE, "pointonsurface({0})"); + ops.put(SpatialOps.EXTERIOR_RING, "exteriorring({0})"); + ops.put(SpatialOps.EXTERIOR_RING2, "exteriorring({0}, {1})"); + ops.put(SpatialOps.INTERIOR_RINGS, "interiorrings({0})"); + ops.put(SpatialOps.INTERIOR_RINGS2, "interiorrings({0}, {1})"); + ops.put(SpatialOps.NUM_INTERIOR_RING, "numinteriorring({0})"); + ops.put(SpatialOps.INTERIOR_RINGN, "interiorringn({0}, {1})"); + ops.put(SpatialOps.GEOMETRIES, "geometries({0})"); + ops.put(SpatialOps.NUM_SURFACES, "numsurfaces({0})"); + ops.put(SpatialOps.SURFACE, "surface({0})"); + ops.put(SpatialOps.NUM_GEOMETRIES, "numgeometries({0})"); + ops.put(SpatialOps.GEOMETRYN, "geometryn({0})"); + ops.put(SpatialOps.IS_CLOSED, "isclosed({0})"); + ops.put(SpatialOps.AS_EWKT, "asewkt({0})"); + ops.put(SpatialOps.GEOM_FROM_TEXT, "geomfromtext({0})"); + ops.put(SpatialOps.SET_SRID, "setsrid({0}, {1})"); + ops.put(SpatialOps.XMIN, "xmin({0})"); + ops.put(SpatialOps.XMAX, "xmax({0})"); + ops.put(SpatialOps.YMIN, "ymin({0})"); + ops.put(SpatialOps.YMAX, "ymax({0})"); + ops.put(SpatialOps.COLLECT, "collect({0})"); + ops.put(SpatialOps.COLLECT2, "collect({0}, {1})"); + ops.put(SpatialOps.TRANSLATE, "translate({0})"); + ops.put(SpatialOps.TRANSLATE2, "translate({0}, {1})"); + return ops; + } +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/hibernate/package-info.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/hibernate/package-info.java new file mode 100644 index 0000000000..d33071dec7 --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/hibernate/package-info.java @@ -0,0 +1,18 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ + +/** + * Serialization patterns for Hibernate Spatial + */ +package com.querydsl.spatial.hibernate; diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSCurveExpression.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSCurveExpression.java new file mode 100644 index 0000000000..087708ebf8 --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSCurveExpression.java @@ -0,0 +1,113 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial.jts; + +import org.jetbrains.annotations.Nullable; + +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.dsl.BooleanExpression; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberExpression; +import com.querydsl.spatial.SpatialOps; +import com.vividsolutions.jts.geom.Geometry; +import com.vividsolutions.jts.geom.Point; + +/** + * A Curve is a 1-dimensional geometric object usually stored as a sequence of Points, with the subtype of Curve + * specifying the form of the interpolation between Points. This standard defines only one subclass of Curve, + * LineString, which uses linear interpolation between Points. + * + * @author tiwe + * + * @param + */ +public abstract class JTSCurveExpression extends JTSGeometryExpression { + + private static final long serialVersionUID = 6139188586728676033L; + + @Nullable + private transient volatile NumberExpression length; + + @Nullable + private transient volatile JTSPointExpression startPoint, endPoint; + + @Nullable + private transient volatile BooleanExpression closed, ring; + + public JTSCurveExpression(Expression mixin) { + super(mixin); + } + + /** + * The length of this Curve in its associated spatial reference. + * + * @return length + */ + public NumberExpression length() { + if (length == null) { + length = Expressions.numberOperation(Double.class, SpatialOps.LENGTH, mixin); + } + return length; + } + + /** + * The start Point of this Curve. + * + * @return start point + */ + public JTSPointExpression startPoint() { + if (startPoint == null) { + startPoint = JTSGeometryExpressions.pointOperation(SpatialOps.START_POINT, mixin); + } + return startPoint; + } + + /** + * The end Point of this Curve. + * + * @return end point + */ + public JTSPointExpression endPoint() { + if (endPoint == null) { + endPoint = JTSGeometryExpressions.pointOperation(SpatialOps.END_POINT, mixin); + } + return endPoint; + } + + /** + * Returns 1 (TRUE) if this Curve is closed [StartPoint ( ) = EndPoint ( )]. + * + * @return closed + */ + public BooleanExpression isClosed() { + if (closed == null) { + closed = Expressions.booleanOperation(SpatialOps.IS_CLOSED, mixin); + } + return closed; + } + + /** + * Returns 1 (TRUE) if this Curve is closed [StartPoint ( ) = EndPoint ( )] and this Curve is + * simple (does not pass through the same Point more than once). + * + * @return ring + */ + public BooleanExpression isRing() { + if (ring == null) { + ring = Expressions.booleanOperation(SpatialOps.IS_RING, mixin); + } + return ring; + } + +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSGeometryCollectionExpression.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSGeometryCollectionExpression.java new file mode 100644 index 0000000000..559748105f --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSGeometryCollectionExpression.java @@ -0,0 +1,66 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial.jts; + +import org.jetbrains.annotations.Nullable; + +import com.querydsl.core.types.ConstantImpl; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberExpression; +import com.querydsl.spatial.SpatialOps; +import com.vividsolutions.jts.geom.Geometry; +import com.vividsolutions.jts.geom.GeometryCollection; + +/** + * A Geometry collection is a geometric object that is a collection of some number of geometric objects. + * + * @author tiwe + * + * @param + */ +public abstract class JTSGeometryCollectionExpression extends JTSGeometryExpression { + + private static final long serialVersionUID = 8874174644259834690L; + + @Nullable + private transient volatile NumberExpression numGeometries; + + public JTSGeometryCollectionExpression(Expression mixin) { + super(mixin); + } + + /** + * Returns the number of geometries in this GeometryCollection. + * + * @return numbers of geometries + */ + public NumberExpression numGeometries() { + if (numGeometries == null) { + numGeometries = Expressions.numberOperation(Integer.class, SpatialOps.NUM_GEOMETRIES, mixin); + } + return numGeometries; + } + + /** + * Returns the Nth geometry in this GeometryCollection. + * + * @param n one based index + * @return matching geometry + */ + public JTSGeometryExpression geometryN(Integer n) { + return JTSGeometryExpressions.geometryOperation(SpatialOps.GEOMETRYN, mixin, ConstantImpl.create(n)); + } + +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSGeometryCollectionPath.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSGeometryCollectionPath.java new file mode 100644 index 0000000000..d4e9aab7ce --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSGeometryCollectionPath.java @@ -0,0 +1,83 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial.jts; + +import java.lang.reflect.AnnotatedElement; + +import com.querydsl.core.types.*; +import com.vividsolutions.jts.geom.GeometryCollection; + +/** + * {@code JTSGeometryCollectionPath} extends {@link JTSGeometryCollectionExpression} to implement the + * {@link Path} interface + * + * @author tiwe + * + * @param + */ +public class JTSGeometryCollectionPath extends JTSGeometryCollectionExpression implements Path { + + private static final long serialVersionUID = 312776751843333543L; + + private final PathImpl pathMixin; + + @SuppressWarnings("unchecked") + public JTSGeometryCollectionPath(Path parent, String property) { + this((Class) GeometryCollection.class, parent, property); + } + + public JTSGeometryCollectionPath(Class type, Path parent, String property) { + this(type, PathMetadataFactory.forProperty(parent, property)); + } + + @SuppressWarnings("unchecked") + public JTSGeometryCollectionPath(PathMetadata metadata) { + this((Class) GeometryCollection.class, metadata); + } + + public JTSGeometryCollectionPath(Class type, PathMetadata metadata) { + super(ExpressionUtils.path(type, metadata)); + this.pathMixin = (PathImpl) mixin; + } + + @SuppressWarnings("unchecked") + public JTSGeometryCollectionPath(String var) { + this((Class) GeometryCollection.class, PathMetadataFactory.forVariable(var)); + } + + @Override + public final R accept(Visitor v, C context) { + return v.visit(pathMixin, context); + } + + public JTSGeometryCollectionPath(Class type, String var) { + this(type, PathMetadataFactory.forVariable(var)); + } + + @Override + public PathMetadata getMetadata() { + return pathMixin.getMetadata(); + } + + @Override + public Path getRoot() { + return pathMixin.getRoot(); + } + + @Override + public AnnotatedElement getAnnotatedElement() { + return pathMixin.getAnnotatedElement(); + } + +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSGeometryExpression.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSGeometryExpression.java new file mode 100644 index 0000000000..c3bdbfdfda --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSGeometryExpression.java @@ -0,0 +1,520 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial.jts; + +import org.jetbrains.annotations.Nullable; + +import com.querydsl.core.types.ConstantImpl; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.dsl.*; +import com.querydsl.spatial.SpatialOps; +import com.vividsolutions.jts.geom.Geometry; + +/** + * Geometry is the root class of the hierarchy. Geometry is an abstract (non-instantiable) class. + * + * @author tiwe + * + * @param + */ +public abstract class JTSGeometryExpression extends SimpleExpression { + + private static final long serialVersionUID = -1183228394472681995L; + + @Nullable + private transient volatile NumberExpression dimension, coordinateDimension, spatialDimension, srid; + + @Nullable + private transient volatile StringExpression geometryType; + + @Nullable + private transient volatile StringExpression text; + + @Nullable + private transient volatile JTSGeometryExpression envelope, boundary, convexHull; + + @Nullable + private transient volatile BooleanExpression empty, simple, threed, measured; + + private transient volatile SimpleExpression binary; + + public JTSGeometryExpression(Expression mixin) { + super(mixin); + } + + /** + * The inherent dimension of this geometric object, which must be less than or equal + * to the coordinate dimension. In non-homogeneous collections, this will return the largest topological + * dimension of the contained objects. + * + * @return dimension + */ + public NumberExpression dimension() { + if (dimension == null) { + dimension = Expressions.numberOperation(Integer.class, SpatialOps.DIMENSION, mixin); + } + return dimension; + } + + /** + * Returns the name of the instantiable subtype of Geometry of which this + * geometric object is an instantiable member. The name of the subtype of Geometry is returned as a string. + * + * @return geometry type + */ + public StringExpression geometryType() { + if (geometryType == null) { + geometryType = Expressions.stringOperation(SpatialOps.GEOMETRY_TYPE, mixin); + } + return geometryType; + } + + /** + * Returns the Spatial Reference System ID for this geometric object. This will normally be a + * foreign key to an index of reference systems stored in either the same or some other datastore. + * + * @return SRID + */ + public NumberExpression srid() { + if (srid == null) { + srid = Expressions.numberOperation(Integer.class, SpatialOps.SRID, mixin); + } + return srid; + } + + /** + * The minimum bounding box for this Geometry, returned as a Geometry. The + * polygon is defined by the corner points of the bounding box [(MINX, MINY), (MAXX, MINY), (MAXX, MAXY), + * (MINX, MAXY), (MINX, MINY)]. Minimums for Z and M may be added. The simplest representation of an + * Envelope is as two direct positions, one containing all the minimums, and another all the maximums. In some + * cases, this coordinate will be outside the range of validity for the Spatial Reference System. + * + * @return envelope + */ + public JTSGeometryExpression envelope() { + if (envelope == null) { + envelope = JTSGeometryExpressions.geometryOperation(SpatialOps.ENVELOPE, mixin); + } + return envelope; + } + + /** + * Exports this geometric object to a specific Well-known Text Representation of Geometry. + * + * @return text representation + */ + public StringExpression asText() { + if (text == null) { + text = Expressions.stringOperation(SpatialOps.AS_TEXT, mixin); + } + return text; + } + + /** + * Exports this geometric object to a specific Well-known Binary Representation of + * Geometry. + * + * @return binary representation + */ + public SimpleExpression asBinary() { + if (binary == null) { + binary = Expressions.operation(byte[].class, SpatialOps.AS_BINARY, mixin); + } + return binary; + } + + /** + * Returns 1 (TRUE) if this geometric object is the empty Geometry. If true, then this + * geometric object represents the empty point set ∅ for the coordinate space. + * + * @return empty + */ + public BooleanExpression isEmpty() { + if (empty == null) { + empty = Expressions.booleanOperation(SpatialOps.IS_EMPTY, mixin); + } + return empty; + } + + /** + * Returns 1 (TRUE) if this geometric object has no anomalous geometric points, such + * as self intersection or self tangency. The description of each instantiable geometric class + * will include the specific conditions that cause an instance of that class to be classified as not simple. + * + * @return simple + */ + public BooleanExpression isSimple() { + if (simple == null) { + simple = Expressions.booleanOperation(SpatialOps.IS_SIMPLE, mixin); + } + return simple; + } + + /** + * Returns the closure of the combinatorial boundary of this geometric object + * + * @return boundary + */ + public JTSGeometryExpression boundary() { + if (boundary == null) { + boundary = JTSGeometryExpressions.geometryOperation(SpatialOps.BOUNDARY, mixin); + } + return boundary; + } + + // query + + /* (non-Javadoc) + * @see com.querydsl.core.types.dsl.SimpleExpression#eq(java.lang.Object) + */ + @Override + public BooleanExpression eq(Geometry right) { + return eq(ConstantImpl.create(right)); + } + + /* (non-Javadoc) + * @see com.querydsl.core.types.dsl.SimpleExpression#eq(com.querydsl.core.types.Expression) + */ + @Override + public BooleanExpression eq(Expression right) { + return Expressions.booleanOperation(SpatialOps.EQUALS, mixin, right); + } + + /** + * Returns 1 (TRUE) if this geometric object is “spatially disjoint” from anotherGeometry. + * + * @param geometry other geometry + * @return true, if disjoint + */ + public BooleanExpression disjoint(Geometry geometry) { + return disjoint(ConstantImpl.create(geometry)); + } + + /** + * Returns 1 (TRUE) if this geometric object is “spatially disjoint” from anotherGeometry. + * + * @param geometry other geometry + * @return true, if disjoint + */ + public BooleanExpression disjoint(Expression geometry) { + return Expressions.booleanOperation(SpatialOps.DISJOINT, mixin, geometry); + } + + /** + * Returns 1 (TRUE) if this geometric object “spatially intersects” anotherGeometry. + * + * @param geometry other geometry + * @return true, if intersects + */ + public BooleanExpression intersects(Geometry geometry) { + return intersects(ConstantImpl.create(geometry)); + } + + /** + * Returns 1 (TRUE) if this geometric object “spatially intersects” anotherGeometry. + * + * @param geometry other geometry + * @return true, if intersects + */ + public BooleanExpression intersects(Expression geometry) { + return Expressions.booleanOperation(SpatialOps.INTERSECTS, mixin, geometry); + } + + /** + * Returns 1 (TRUE) if this geometric object “spatially touches” anotherGeometry. + * + * @param geometry other geometry + * @return true, if touches + */ + public BooleanExpression touches(Geometry geometry) { + return touches(ConstantImpl.create(geometry)); + } + + /** + * Returns 1 (TRUE) if this geometric object “spatially touches” anotherGeometry. + * + * @param geometry other geometry + * @return true, if touches + */ + public BooleanExpression touches(Expression geometry) { + return Expressions.booleanOperation(SpatialOps.TOUCHES, mixin, geometry); + } + + /** + * Returns 1 (TRUE) if this geometric object “spatially crosses’ anotherGeometry. + * + * @param geometry other geometry + * @return true, if crosses + */ + public BooleanExpression crosses(Geometry geometry) { + return crosses(ConstantImpl.create(geometry)); + } + + /** + * Returns 1 (TRUE) if this geometric object “spatially crosses’ anotherGeometry. + * + * @param geometry other geometry + * @return true, if crosses + */ + public BooleanExpression crosses(Expression geometry) { + return Expressions.booleanOperation(SpatialOps.CROSSES, mixin, geometry); + } + + /** + * Returns 1 (TRUE) if this geometric object is “spatially within” anotherGeometry. + * + * @param geometry other geometry + * @return true, if within + */ + public BooleanExpression within(Geometry geometry) { + return within(ConstantImpl.create(geometry)); + } + + /** + * Returns 1 (TRUE) if this geometric object is “spatially within” anotherGeometry. + * + * @param geometry other geometry + * @return true, if within + */ + public BooleanExpression within(Expression geometry) { + return Expressions.booleanOperation(SpatialOps.WITHIN, mixin, geometry); + } + + /** + * Returns 1 (TRUE) if this geometric object “spatially contains” anotherGeometry. + * + * @param geometry other geometry + * @return true, if contains + */ + public BooleanExpression contains(Geometry geometry) { + return contains(ConstantImpl.create(geometry)); + } + + /** + * Returns 1 (TRUE) if this geometric object “spatially contains” anotherGeometry. + * + * @param geometry other geometry + * @return true, if contains + */ + public BooleanExpression contains(Expression geometry) { + return Expressions.booleanOperation(SpatialOps.CONTAINS, mixin, geometry); + } + + /** + * Returns 1 (TRUE) if this geometric object “spatially overlaps” anotherGeometry. + * + * @param geometry other geometry + * @return true, if overlaps + */ + public BooleanExpression overlaps(Geometry geometry) { + return overlaps(ConstantImpl.create(geometry)); + } + + /** + * Returns 1 (TRUE) if this geometric object “spatially overlaps” anotherGeometry. + * + * @param geometry other geometry + * @return true, if overlaps + */ + public BooleanExpression overlaps(Expression geometry) { + return Expressions.booleanOperation(SpatialOps.OVERLAPS, mixin, geometry); + } + + /** + * Returns 1 (TRUE) if this geometric object is spatially related to anotherGeometry by testing + * for intersections between the interior, boundary and exterior of the two geometric objects + * as specified by the values in the intersectionPatternMatrix. This returns FALSE if all the + * tested intersections are empty except exterior (this) intersect exterior (another). + * + * @param geometry other geometry + * @param matrix matrix + * @return true, if this geometry is spatially related to the other + */ + public BooleanExpression relate(Geometry geometry, String matrix) { + return relate(ConstantImpl.create(geometry), matrix); + } + + /** + * Returns 1 (TRUE) if this geometric object is spatially related to anotherGeometry by testing + * for intersections between the interior, boundary and exterior of the two geometric objects + * as specified by the values in the intersectionPatternMatrix. This returns FALSE if all the + * tested intersections are empty except exterior (this) intersect exterior (another). + * + * @param geometry other geometry + * @param matrix matrix + * @return true, if this geometry is spatially related to the other + */ + public BooleanExpression relate(Expression geometry, String matrix) { + return Expressions.booleanOperation(SpatialOps.RELATE, mixin, geometry, ConstantImpl.create(matrix)); + } + + // analysis + + /** + * Returns the shortest distance between any two Points in the two geometric objects as + * calculated in the spatial reference system of this geometric object. Because the geometries + * are closed, it is possible to find a point on each geometric object involved, such that the + * distance between these 2 points is the returned distance between their geometric objects. + * + * @param geometry other geometry + * @return distance + */ + public NumberExpression distance(Geometry geometry) { + return distance(ConstantImpl.create(geometry)); + } + + /** + * Returns the shortest distance between any two Points in the two geometric objects as + * calculated in the spatial reference system of this geometric object. Because the geometries + * are closed, it is possible to find a point on each geometric object involved, such that the + * distance between these 2 points is the returned distance between their geometric objects. + * + * @param geometry other geometry + * @return distance + */ + public NumberExpression distance(Expression geometry) { + return Expressions.numberOperation(Double.class, SpatialOps.DISTANCE, mixin, geometry); + } + + // TODO maybe move out + public NumberExpression distanceSphere(Expression geometry) { + return Expressions.numberOperation(Double.class, SpatialOps.DISTANCE_SPHERE, mixin, geometry); + } + + // TODO maybe move out + public NumberExpression distanceSpheroid(Expression geometry) { + return Expressions.numberOperation(Double.class, SpatialOps.DISTANCE_SPHEROID, mixin, geometry); + } + + /** + * Returns a geometric object that represents all Points whose distance from this geometric + * object is less than or equal to distance. Calculations are in the spatial reference system + * of this geometric object. Because of the limitations of linear interpolation, there will + * often be some relatively small error in this distance, but it should be near the resolution + * of the coordinates used. + * + * @param distance distance + * @return buffer + */ + public JTSGeometryExpression buffer(double distance) { + return JTSGeometryExpressions.geometryOperation(SpatialOps.BUFFER, mixin, ConstantImpl.create(distance)); + } + + /** + * Returns a geometric object that represents the convex hull of this geometric object. + * Convex hulls, being dependent on straight lines, can be accurately represented in linear + * interpolations for any geometry restricted to linear interpolations. + * + * @return convex hull + */ + public JTSGeometryExpression convexHull() { + if (convexHull == null) { + convexHull = JTSGeometryExpressions.geometryOperation(SpatialOps.CONVEXHULL, mixin); + } + return convexHull; + } + + /** + * Returns a geometric object that represents the Point set intersection of this geometric + * object with anotherGeometry. + * + * @param geometry other geometry + * @return intersection of this and the other geometry + */ + public JTSGeometryExpression intersection(Geometry geometry) { + return intersection(ConstantImpl.create(geometry)); + } + + /** + * Returns a geometric object that represents the Point set intersection of this geometric + * object with anotherGeometry. + * + * @param geometry other geometry + * @return intersection of this and the other geometry + */ + public JTSGeometryExpression intersection(Expression geometry) { + return JTSGeometryExpressions.geometryOperation(SpatialOps.INTERSECTION, mixin, geometry); + } + + /** + * Returns a geometric object that represents the Point set + * union of this geometric object with anotherGeometry. + * + * @param geometry other geometry + * @return union of this and the other geometry + */ + public JTSGeometryExpression union(Geometry geometry) { + return union(ConstantImpl.create(geometry)); + } + + /** + * Returns a geometric object that represents the Point set + * union of this geometric object with anotherGeometry. + * + * @param geometry other geometry + * @return union of this and the other geometry + */ + public JTSGeometryExpression union(Expression geometry) { + return JTSGeometryExpressions.geometryOperation(SpatialOps.UNION, mixin, geometry); + } + + /** + * Returns a geometric object that represents the Point + * set difference of this geometric object with anotherGeometry. + * + * @param geometry other geometry + * @return difference between this and the other geometry + */ + public JTSGeometryExpression difference(Geometry geometry) { + return difference(ConstantImpl.create(geometry)); + } + + /** + * Returns a geometric object that represents the Point + * set difference of this geometric object with anotherGeometry. + * + * @param geometry other geometry + * @return difference between this and the other geometry + */ + public JTSGeometryExpression difference(Expression geometry) { + return JTSGeometryExpressions.geometryOperation(SpatialOps.DIFFERENCE, mixin, geometry); + } + + /** + * Returns a geometric object that represents the + * Point set symmetric difference of this geometric object with anotherGeometry. + * + * @param geometry other geometry + * @return symmetric difference + */ + public JTSGeometryExpression symDifference(Geometry geometry) { + return symDifference(ConstantImpl.create(geometry)); + } + + /** + * Returns a geometric object that represents the + * Point set symmetric difference of this geometric object with anotherGeometry. + * + * @param geometry other geometry + * @return symmetric difference + */ + public JTSGeometryExpression symDifference(Expression geometry) { + return JTSGeometryExpressions.geometryOperation(SpatialOps.SYMDIFFERENCE, mixin, geometry); + } + + public JTSGeometryExpression transform(int srid) { + return JTSGeometryExpressions.geometryOperation(SpatialOps.TRANSFORM, mixin, ConstantImpl.create(srid)); + } + +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSGeometryExpressions.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSGeometryExpressions.java new file mode 100644 index 0000000000..5f764434f8 --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSGeometryExpressions.java @@ -0,0 +1,293 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial.jts; + +import com.querydsl.core.types.ConstantImpl; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.ExpressionUtils; +import com.querydsl.core.types.Operator; +import com.querydsl.core.types.Visitor; +import com.querydsl.core.types.dsl.BooleanExpression; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberExpression; +import com.querydsl.core.types.dsl.StringExpression; +import com.querydsl.spatial.SpatialOps; +import com.vividsolutions.jts.geom.*; + +/** + * GeometryExpressions contains static functions for GEO operations + */ +public final class JTSGeometryExpressions { + + private JTSGeometryExpressions() { } + + /** + * Return a specified ST_Geometry value from Extended Well-Known Text representation (EWKT). + * + * @param expr geometry + * @return EWKT form + */ + public static StringExpression asEWKT(JTSGeometryExpression expr) { + return Expressions.stringOperation(SpatialOps.AS_EWKT, expr); + } + + /** + * Return a specified ST_Geometry value from Well-Known Text representation (WKT). + * + * @param text WKT form + * @return geometry + */ + public static JTSGeometryExpression fromText(String text) { + return geometryOperation(SpatialOps.GEOM_FROM_TEXT, ConstantImpl.create(text)); + } + + /** + * Return a specified ST_Geometry value from Well-Known Text representation (WKT). + * + * @param text WKT form + * @return geometry + */ + public static JTSGeometryExpression fromText(Expression text) { + return geometryOperation(SpatialOps.GEOM_FROM_TEXT, text); + } + + /** + * Sets the SRID on a geometry to a particular integer value. + * + * @param expr geometry + * @param srid SRID + * @param + * @return geometry + */ + public static JTSGeometryExpression setSRID(Expression expr, int srid) { + return geometryOperation(expr.getType(), SpatialOps.SET_SRID, + expr, ConstantImpl.create(srid)); + } + + /** + * Returns X minima of a bounding box 2d or 3d or a geometry. + * + * @param expr geometry + * @return x minima + */ + public static NumberExpression xmin(JTSGeometryExpression expr) { + return Expressions.numberOperation(Double.class, SpatialOps.XMIN, expr); + } + + /** + * Returns X maxima of a bounding box 2d or 3d or a geometry. + * + * @param expr geometry + * @return x maxima + */ + public static NumberExpression xmax(JTSGeometryExpression expr) { + return Expressions.numberOperation(Double.class, SpatialOps.XMAX, expr); + } + + /** + * Returns Y minima of a bounding box 2d or 3d or a geometry. + * + * @param expr geometry + * @return y minima + */ + public static NumberExpression ymin(JTSGeometryExpression expr) { + return Expressions.numberOperation(Double.class, SpatialOps.YMIN, expr); + } + + /** + * Returns Y maxima of a bounding box 2d or 3d or a geometry. + * + * @param expr geometry + * @return y maxima + */ + public static NumberExpression ymax(JTSGeometryExpression expr) { + return Expressions.numberOperation(Double.class, SpatialOps.YMAX, expr); + } + + /** + * Returns true if the geometries are within the specified distance of one another. + * For geometry units are in those of spatial reference and For geography units are in meters. + * + * @param expr1 geometry + * @param expr2 other geometry + * @param distance distance + * @return true, if with distance of each other + */ + public static BooleanExpression dwithin(Expression expr1, + Expression expr2, Expression distance) { + return Expressions.booleanOperation(SpatialOps.DWITHIN, expr1, expr2, distance); + } + + /** + * Returns true if the geometries are within the specified distance of one another. + * For geometry units are in those of spatial reference and For geography units are in meters. + * + * @param expr1 geometry + * @param expr2 other geometry + * @param distance distance + * @return true, if with distance of each other + */ + public static BooleanExpression dwithin(Expression expr1, + Expression expr2, double distance) { + return Expressions.booleanOperation(SpatialOps.DWITHIN, expr1, expr2, ConstantImpl.create(distance)); + } + + /** + * Returns the bounding box that bounds rows of geometries. + * + * @param collection geometry collection + * @return geometry collection + */ + public static JTSGeometryExpression extent(Expression collection) { + return geometryOperation(SpatialOps.EXTENT, collection); + } + + /** + * Return a specified ST_Geometry value from a collection of other geometries. + * + * @param collection geometry collection + * @return geometry collection + */ + public static JTSGeometryExpression collect(Expression collection) { + return geometryOperation(SpatialOps.COLLECT, collection); + } + + /** + * Return a specified ST_Geometry value from a collection of other geometries. + * + * @param expr1 geometry + * @param expr2 other geometry + * @return geometry collection + */ + public static JTSGeometryExpression collect(Expression expr1, Expression expr2) { + return geometryOperation(SpatialOps.COLLECT2, expr1, expr2); + } + + /** + * Translates the geometry to a new location using the numeric parameters as offsets. + * + * @param expr geometry + * @param deltax x offset + * @param deltay y offset + * @param + * @return geometry + */ + public static JTSGeometryExpression translate(Expression expr, float deltax, float deltay) { + return geometryOperation(expr.getType(), SpatialOps.TRANSLATE, + expr, ConstantImpl.create(deltax), ConstantImpl.create(deltay)); + } + + /** + * Translates the geometry to a new location using the numeric parameters as offsets. + * + * @param expr geometry + * @param deltax x offset + * @param deltay y offset + * @param deltaz z offset + * @param + * @return geometry + */ + public static JTSGeometryExpression translate(Expression expr, float deltax, float deltay, float deltaz) { + return geometryOperation(expr.getType(), SpatialOps.TRANSLATE2, + expr, ConstantImpl.create(deltax), ConstantImpl.create(deltay), ConstantImpl.create(deltaz)); + } + + /** + * Create a new Geometry operation expression + * + * @param op operator + * @param args arguments + * @return operation expression + */ + public static JTSGeometryExpression geometryOperation(Operator op, Expression... args) { + return new JTSGeometryOperation(Geometry.class, op, args); + } + + /** + * Create a new Geometry operation expression + * + * @param op operator + * @param args arguments + * @return operation expression + */ + public static JTSGeometryExpression geometryOperation(Class type, + Operator op, Expression... args) { + return new JTSGeometryOperation(type, op, args); + } + + /** + * Create a new LineString operation expression + * + * @param op operator + * @param args arguments + * @return operation expression + */ + public static JTSLineStringExpression lineStringOperation(Operator op, Expression... args) { + return new JTSLineStringOperation(LineString.class, op, args); + } + + /** + * Create a new Point operation expression + * + * @param op operator + * @param args arguments + * @return operation expression + */ + public static JTSPointExpression pointOperation(Operator op, Expression... args) { + return new JTSPointOperation(Point.class, op, args); + } + + /** + * Create a new Polygon operation expression + * + * @param op operator + * @param args arguments + * @return operation expression + */ + public static JTSPolygonExpression polygonOperation(Operator op, Expression... args) { + return new JTSPolygonOperation(Polygon.class, op, args); + } + + /** + * Create a new JTSGeometryExpression + * + * @param expr Expression of type Geometry + * @return new JTSGeometryExpression + */ + public static JTSGeometryExpression asJTSGeometry( + Expression expr) { + Expression underlyingMixin = ExpressionUtils.extract(expr); + return new JTSGeometryExpression(underlyingMixin) { + + private static final long serialVersionUID = -6714044005570420009L; + + @Override + public R accept(Visitor v, C context) { + return this.mixin.accept(v, context); + } + + }; + } + + /** + * Create a new JTSGeometryExpression + * + * @param value Geometry + * @return new JTSGeometryExpression + */ + public static JTSGeometryExpression asJTSGeometry(T value) { + return asJTSGeometry(Expressions.constant(value)); + } + +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSGeometryOperation.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSGeometryOperation.java new file mode 100644 index 0000000000..9f112ac641 --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSGeometryOperation.java @@ -0,0 +1,65 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial.jts; + +import java.util.Arrays; +import java.util.List; + +import com.querydsl.core.types.*; +import com.vividsolutions.jts.geom.Geometry; + +/** + * {@code JTSGeometryOperation} extends {@link JTSGeometryExpression} to implement the + * {@link Operation} interface + * + * @author tiwe + * + * @param + */ +public class JTSGeometryOperation extends JTSGeometryExpression implements Operation { + + private static final long serialVersionUID = 3433471874808633698L; + + private final OperationImpl opMixin; + + protected JTSGeometryOperation(Class type, Operator op, Expression... args) { + this(type, op, Arrays.asList(args)); + } + + protected JTSGeometryOperation(Class type, Operator op, List> args) { + super(ExpressionUtils.operation(type, op, args)); + this.opMixin = (OperationImpl) mixin; + } + + @Override + public final R accept(Visitor v, C context) { + return v.visit(opMixin, context); + } + + @Override + public Expression getArg(int index) { + return opMixin.getArg(index); + } + + @Override + public List> getArgs() { + return opMixin.getArgs(); + } + + @Override + public Operator getOperator() { + return opMixin.getOperator(); + } + +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSGeometryPath.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSGeometryPath.java new file mode 100644 index 0000000000..452549a142 --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSGeometryPath.java @@ -0,0 +1,155 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial.jts; + +import java.lang.reflect.AnnotatedElement; + +import com.querydsl.core.types.*; +import com.vividsolutions.jts.geom.*; + +/** + * {@code JTSGeometryPath} extends {@link JTSGeometryExpression} to implement the + * {@link Path} interface + * + * @author tiwe + * + * @param + */ +public class JTSGeometryPath extends JTSGeometryExpression implements Path { + + private static final long serialVersionUID = 312776751843333543L; + + private final PathImpl pathMixin; + + private transient volatile JTSGeometryCollectionPath collection; + + private transient volatile JTSLinearRingPath linearRing; + + private transient volatile JTSLineStringPath lineString; + + private transient volatile JTSMultiLineStringPath multiLineString; + + private transient volatile JTSMultiPointPath multiPoint; + + private transient volatile JTSMultiPolygonPath multiPolygon; + + private transient volatile JTSPointPath point; + + private transient volatile JTSPolygonPath polygon; + + @SuppressWarnings("unchecked") + public JTSGeometryPath(Path parent, String property) { + this((Class) Geometry.class, parent, property); + } + + public JTSGeometryPath(Class type, Path parent, String property) { + this(type, PathMetadataFactory.forProperty(parent, property)); + } + + @SuppressWarnings("unchecked") + public JTSGeometryPath(PathMetadata metadata) { + this((Class) Geometry.class, metadata); + } + + public JTSGeometryPath(Class type, PathMetadata metadata) { + super(ExpressionUtils.path(type, metadata)); + this.pathMixin = (PathImpl) mixin; + } + + @SuppressWarnings("unchecked") + public JTSGeometryPath(String var) { + this((Class) Geometry.class, PathMetadataFactory.forVariable(var)); + } + + public JTSGeometryCollectionPath asCollection() { + if (collection == null) { + collection = new JTSGeometryCollectionPath(pathMixin.getMetadata()); + } + return collection; + } + + public JTSLinearRingPath asLinearRing() { + if (linearRing == null) { + linearRing = new JTSLinearRingPath(pathMixin.getMetadata()); + } + return linearRing; + } + + public JTSLineStringPath asLineString() { + if (lineString == null) { + lineString = new JTSLineStringPath(pathMixin.getMetadata()); + } + return lineString; + } + + public JTSMultiLineStringPath asMultiLineString() { + if (multiLineString == null) { + multiLineString = new JTSMultiLineStringPath(pathMixin.getMetadata()); + } + return multiLineString; + } + + public JTSMultiPointPath asMultiPoint() { + if (multiPoint == null) { + multiPoint = new JTSMultiPointPath(pathMixin.getMetadata()); + } + return multiPoint; + } + + public JTSMultiPolygonPath asMultiPolygon() { + if (multiPolygon == null) { + multiPolygon = new JTSMultiPolygonPath(pathMixin.getMetadata()); + } + return multiPolygon; + } + + public JTSPointPath asPoint() { + if (point == null) { + point = new JTSPointPath(pathMixin.getMetadata()); + } + return point; + } + + public JTSPolygonPath asPolygon() { + if (polygon == null) { + polygon = new JTSPolygonPath(pathMixin.getMetadata()); + } + return polygon; + } + + @Override + public final R accept(Visitor v, C context) { + return v.visit(pathMixin, context); + } + + public JTSGeometryPath(Class type, String var) { + this(type, PathMetadataFactory.forVariable(var)); + } + + @Override + public PathMetadata getMetadata() { + return pathMixin.getMetadata(); + } + + @Override + public Path getRoot() { + return pathMixin.getRoot(); + } + + @Override + public AnnotatedElement getAnnotatedElement() { + return pathMixin.getAnnotatedElement(); + } + +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSGeometryPaths.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSGeometryPaths.java new file mode 100644 index 0000000000..54829fd73c --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSGeometryPaths.java @@ -0,0 +1,44 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial.jts; + +import com.vividsolutions.jts.geom.*; + +/** + * {@code JTSGeometryPaths} provides factory methods for {@link JTSGeometryExpression} creation + * + * @author tiwe + * + */ +public interface JTSGeometryPaths { + + JTSGeometryCollectionPath createGeometryCollection(String property, Class type); + + JTSGeometryPath createGeometry(String property, Class type); + + JTSLinearRingPath createLinearRing(String property, Class type); + + JTSLineStringPath createLineString(String property, Class type); + + JTSMultiLineStringPath createMultiLineString(String property, Class type); + + JTSMultiPointPath createMultiPoint(String property, Class type); + + JTSMultiPolygonPath createMultiPolygon(String property, Class type); + + JTSPointPath createPoint(String property, Class type); + + JTSPolygonPath createPolygon(String property, Class type); + +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSLineExpression.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSLineExpression.java new file mode 100644 index 0000000000..50c314ee0f --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSLineExpression.java @@ -0,0 +1,34 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial.jts; + +import com.querydsl.core.types.Expression; +import com.vividsolutions.jts.geom.LineString; + +/** + * A Line is a LineString with exactly 2 Points. + * + * @author tiwe + * + * @param + */ +public abstract class JTSLineExpression extends JTSLineStringExpression { + + private static final long serialVersionUID = -4849454664355502296L; + + public JTSLineExpression(Expression mixin) { + super(mixin); + } + +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSLineStringExpression.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSLineStringExpression.java new file mode 100644 index 0000000000..2e28e4815b --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSLineStringExpression.java @@ -0,0 +1,67 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial.jts; + +import org.jetbrains.annotations.Nullable; + +import com.querydsl.core.types.ConstantImpl; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberExpression; +import com.querydsl.spatial.SpatialOps; +import com.vividsolutions.jts.geom.LineString; +import com.vividsolutions.jts.geom.Point; + +/** + * A LineString is a Curve with linear interpolation between Points. Each consecutive pair of Points defines a Line + * segment. + * + * @author tiwe + * + * @param + */ +public abstract class JTSLineStringExpression extends JTSCurveExpression { + + private static final long serialVersionUID = -6572984614863252657L; + + @Nullable + private transient volatile NumberExpression numPoints; + + public JTSLineStringExpression(Expression mixin) { + super(mixin); + } + + /** + * The number of Points in this LineString. + * + * @return number of points + */ + public NumberExpression numPoints() { + if (numPoints == null) { + numPoints = Expressions.numberOperation(Integer.class, SpatialOps.NUM_POINTS, mixin); + } + return numPoints; + } + + /** + * Returns the specified Point N in this LineString. + * + * @param idx one based index + * @return point at index + */ + public JTSPointExpression pointN(int idx) { + return JTSGeometryExpressions.pointOperation(SpatialOps.POINTN, mixin, ConstantImpl.create(idx)); + } + +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSLineStringOperation.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSLineStringOperation.java new file mode 100644 index 0000000000..aa9eb624d4 --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSLineStringOperation.java @@ -0,0 +1,65 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial.jts; + +import java.util.Arrays; +import java.util.List; + +import com.querydsl.core.types.*; +import com.vividsolutions.jts.geom.LineString; + +/** + * {@code JTSLineStringOperation} extends {@link JTSLineStringExpression} to implement the + * {@link Operation} interface + * + * @author tiwe + * + * @param + */ +public class JTSLineStringOperation extends JTSLineStringExpression implements Operation { + + private static final long serialVersionUID = 3433471874808633698L; + + private final OperationImpl< T> opMixin; + + protected JTSLineStringOperation(Class type, Operator op, Expression... args) { + this(type, op, Arrays.asList(args)); + } + + protected JTSLineStringOperation(Class type, Operator op, List> args) { + super(ExpressionUtils.operation(type, op, args)); + this.opMixin = (OperationImpl) mixin; + } + + @Override + public final R accept(Visitor v, C context) { + return v.visit(opMixin, context); + } + + @Override + public Expression getArg(int index) { + return opMixin.getArg(index); + } + + @Override + public List> getArgs() { + return opMixin.getArgs(); + } + + @Override + public Operator getOperator() { + return opMixin.getOperator(); + } + +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSLineStringPath.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSLineStringPath.java new file mode 100644 index 0000000000..750d6a8af6 --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSLineStringPath.java @@ -0,0 +1,83 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial.jts; + +import java.lang.reflect.AnnotatedElement; + +import com.querydsl.core.types.*; +import com.vividsolutions.jts.geom.LineString; + +/** + * {@code JTSLineStringPath} extends {@link JTSLineStringExpression} to implement the + * {@link Path} interface + * + * @author tiwe + * + * @param + */ +public class JTSLineStringPath extends JTSLineStringExpression implements Path { + + private static final long serialVersionUID = 312776751843333543L; + + private final PathImpl pathMixin; + + @SuppressWarnings("unchecked") + public JTSLineStringPath(Path parent, String property) { + this((Class) LineString.class, parent, property); + } + + public JTSLineStringPath(Class type, Path parent, String property) { + this(type, PathMetadataFactory.forProperty(parent, property)); + } + + @SuppressWarnings("unchecked") + public JTSLineStringPath(PathMetadata metadata) { + this((Class) LineString.class, metadata); + } + + public JTSLineStringPath(Class type, PathMetadata metadata) { + super(ExpressionUtils.path(type, metadata)); + this.pathMixin = (PathImpl) mixin; + } + + @SuppressWarnings("unchecked") + public JTSLineStringPath(String var) { + this((Class) LineString.class, PathMetadataFactory.forVariable(var)); + } + + @Override + public final R accept(Visitor v, C context) { + return v.visit(pathMixin, context); + } + + public JTSLineStringPath(Class type, String var) { + this(type, PathMetadataFactory.forVariable(var)); + } + + @Override + public PathMetadata getMetadata() { + return pathMixin.getMetadata(); + } + + @Override + public Path getRoot() { + return pathMixin.getRoot(); + } + + @Override + public AnnotatedElement getAnnotatedElement() { + return pathMixin.getAnnotatedElement(); + } + +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSLinearRingExpression.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSLinearRingExpression.java new file mode 100644 index 0000000000..259bc598c6 --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSLinearRingExpression.java @@ -0,0 +1,34 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial.jts; + +import com.querydsl.core.types.Expression; +import com.vividsolutions.jts.geom.LineString; + +/** + * A LinearRing is a LineString that is both closed and simple. + * + * @author tiwe + * + * @param + */ +public abstract class JTSLinearRingExpression extends JTSLineStringExpression { + + private static final long serialVersionUID = -759466658721392938L; + + public JTSLinearRingExpression(Expression mixin) { + super(mixin); + } + +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSLinearRingPath.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSLinearRingPath.java new file mode 100644 index 0000000000..d2cb1a2de4 --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSLinearRingPath.java @@ -0,0 +1,83 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial.jts; + +import java.lang.reflect.AnnotatedElement; + +import com.querydsl.core.types.*; +import com.vividsolutions.jts.geom.LinearRing; + +/** + * {@code JTSLinearRingPath} extends {@link JTSLinearRingExpression} to implement the + * {@link Path} interface + * + * @author tiwe + * + * @param + */ +public class JTSLinearRingPath extends JTSLinearRingExpression implements Path { + + private static final long serialVersionUID = 312776751843333543L; + + private final PathImpl pathMixin; + + @SuppressWarnings("unchecked") + public JTSLinearRingPath(Path parent, String property) { + this((Class) LinearRing.class, parent, property); + } + + public JTSLinearRingPath(Class type, Path parent, String property) { + this(type, PathMetadataFactory.forProperty(parent, property)); + } + + @SuppressWarnings("unchecked") + public JTSLinearRingPath(PathMetadata metadata) { + this((Class) LinearRing.class, metadata); + } + + public JTSLinearRingPath(Class type, PathMetadata metadata) { + super(ExpressionUtils.path(type, metadata)); + this.pathMixin = (PathImpl) mixin; + } + + @SuppressWarnings("unchecked") + public JTSLinearRingPath(String var) { + this((Class) LinearRing.class, PathMetadataFactory.forVariable(var)); + } + + @Override + public final R accept(Visitor v, C context) { + return v.visit(pathMixin, context); + } + + public JTSLinearRingPath(Class type, String var) { + this(type, PathMetadataFactory.forVariable(var)); + } + + @Override + public PathMetadata getMetadata() { + return pathMixin.getMetadata(); + } + + @Override + public Path getRoot() { + return pathMixin.getRoot(); + } + + @Override + public AnnotatedElement getAnnotatedElement() { + return pathMixin.getAnnotatedElement(); + } + +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSMultiCurveExpression.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSMultiCurveExpression.java new file mode 100644 index 0000000000..3e21bc9ce0 --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSMultiCurveExpression.java @@ -0,0 +1,72 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial.jts; + +import org.jetbrains.annotations.Nullable; + +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.dsl.BooleanExpression; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberExpression; +import com.querydsl.spatial.SpatialOps; +import com.vividsolutions.jts.geom.GeometryCollection; + +/** + * A MultiCurve is a 1-dimensional GeometryCollection whose elements are Curves. + * + * @author tiwe + * + * @param + */ +public abstract class JTSMultiCurveExpression extends JTSGeometryCollectionExpression { + + private static final long serialVersionUID = 6983316799469849656L; + + @Nullable + private transient volatile BooleanExpression closed; + + @Nullable + private transient volatile NumberExpression length; + + public JTSMultiCurveExpression(Expression mixin) { + super(mixin); + } + + /** + * Returns 1 (TRUE) if this MultiCurve is closed [StartPoint ( ) = EndPoint ( ) for each + * Curve in this MultiCurve]. + * + * @return closed + */ + public BooleanExpression isClosed() { + if (closed == null) { + closed = Expressions.booleanOperation(SpatialOps.IS_CLOSED, mixin); + } + return closed; + } + + /** + * The Length of this MultiCurve which is equal to the sum of the lengths of the element + * Curves. + * + * @return length + */ + public NumberExpression length() { + if (length == null) { + length = Expressions.numberOperation(Double.class, SpatialOps.LENGTH, mixin); + } + return length; + } + +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSMultiLineStringExpression.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSMultiLineStringExpression.java new file mode 100644 index 0000000000..b78441e827 --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSMultiLineStringExpression.java @@ -0,0 +1,34 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial.jts; + +import com.querydsl.core.types.Expression; +import com.vividsolutions.jts.geom.MultiLineString; + +/** + * A MultiLineString is a MultiCurve whose elements are LineStrings. + * + * @author tiwe + * + * @param + */ +public abstract class JTSMultiLineStringExpression extends JTSMultiCurveExpression { + + private static final long serialVersionUID = -3103756880812584473L; + + public JTSMultiLineStringExpression(Expression mixin) { + super(mixin); + } + +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSMultiLineStringPath.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSMultiLineStringPath.java new file mode 100644 index 0000000000..bb194345d5 --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSMultiLineStringPath.java @@ -0,0 +1,83 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial.jts; + +import java.lang.reflect.AnnotatedElement; + +import com.querydsl.core.types.*; +import com.vividsolutions.jts.geom.MultiLineString; + +/** + * {@code JTSMultiLineStringPath} extends {@link JTSMultiLineStringExpression} to implement the + * {@link Path} interface + * + * @author tiwe + * + * @param + */ +public class JTSMultiLineStringPath extends JTSMultiLineStringExpression implements Path { + + private static final long serialVersionUID = 312776751843333543L; + + private final PathImpl pathMixin; + + @SuppressWarnings("unchecked") + public JTSMultiLineStringPath(Path parent, String property) { + this((Class) MultiLineString.class, parent, property); + } + + public JTSMultiLineStringPath(Class type, Path parent, String property) { + this(type, PathMetadataFactory.forProperty(parent, property)); + } + + @SuppressWarnings("unchecked") + public JTSMultiLineStringPath(PathMetadata metadata) { + this((Class) MultiLineString.class, metadata); + } + + public JTSMultiLineStringPath(Class type, PathMetadata metadata) { + super(ExpressionUtils.path(type, metadata)); + this.pathMixin = (PathImpl) mixin; + } + + @SuppressWarnings("unchecked") + public JTSMultiLineStringPath(String var) { + this((Class) MultiLineString.class, PathMetadataFactory.forVariable(var)); + } + + @Override + public final R accept(Visitor v, C context) { + return v.visit(pathMixin, context); + } + + public JTSMultiLineStringPath(Class type, String var) { + this(type, PathMetadataFactory.forVariable(var)); + } + + @Override + public PathMetadata getMetadata() { + return pathMixin.getMetadata(); + } + + @Override + public Path getRoot() { + return pathMixin.getRoot(); + } + + @Override + public AnnotatedElement getAnnotatedElement() { + return pathMixin.getAnnotatedElement(); + } + +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSMultiPointExpression.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSMultiPointExpression.java new file mode 100644 index 0000000000..4fd5af8dfc --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSMultiPointExpression.java @@ -0,0 +1,36 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial.jts; + +import com.querydsl.core.types.Expression; +import com.vividsolutions.jts.geom.MultiPoint; + +/** + * A MultiPoint is a 0-dimensional GeometryCollection. The elements of a MultiPoint are restricted to Points. The + * Points are not connected or ordered in any semantically important way (see the discussion at + * GeometryCollection). + * + * @author tiwe + * + * @param + */ +public abstract class JTSMultiPointExpression extends JTSGeometryCollectionExpression { + + private static final long serialVersionUID = 7221702165705045865L; + + public JTSMultiPointExpression(Expression mixin) { + super(mixin); + } + +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSMultiPointPath.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSMultiPointPath.java new file mode 100644 index 0000000000..6d9361ed35 --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSMultiPointPath.java @@ -0,0 +1,83 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial.jts; + +import java.lang.reflect.AnnotatedElement; + +import com.querydsl.core.types.*; +import com.vividsolutions.jts.geom.MultiPoint; + +/** + * {@code JTSMultiPointPath} extends {@link JTSMultiPointExpression} to implement the + * {@link Path} interface + * + * @author tiwe + * + * @param + */ +public class JTSMultiPointPath extends JTSMultiPointExpression implements Path { + + private static final long serialVersionUID = 312776751843333543L; + + private final PathImpl pathMixin; + + @SuppressWarnings("unchecked") + public JTSMultiPointPath(Path parent, String property) { + this((Class) MultiPoint.class, parent, property); + } + + public JTSMultiPointPath(Class type, Path parent, String property) { + this(type, PathMetadataFactory.forProperty(parent, property)); + } + + @SuppressWarnings("unchecked") + public JTSMultiPointPath(PathMetadata metadata) { + this((Class) MultiPoint.class, metadata); + } + + public JTSMultiPointPath(Class type, PathMetadata metadata) { + super(ExpressionUtils.path(type, metadata)); + this.pathMixin = (PathImpl) mixin; + } + + @SuppressWarnings("unchecked") + public JTSMultiPointPath(String var) { + this((Class) MultiPoint.class, PathMetadataFactory.forVariable(var)); + } + + @Override + public final R accept(Visitor v, C context) { + return v.visit(pathMixin, context); + } + + public JTSMultiPointPath(Class type, String var) { + this(type, PathMetadataFactory.forVariable(var)); + } + + @Override + public PathMetadata getMetadata() { + return pathMixin.getMetadata(); + } + + @Override + public Path getRoot() { + return pathMixin.getRoot(); + } + + @Override + public AnnotatedElement getAnnotatedElement() { + return pathMixin.getAnnotatedElement(); + } + +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSMultiPolygonExpression.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSMultiPolygonExpression.java new file mode 100644 index 0000000000..d0fbc0238c --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSMultiPolygonExpression.java @@ -0,0 +1,34 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial.jts; + +import com.querydsl.core.types.Expression; +import com.vividsolutions.jts.geom.MultiPolygon; + +/** + * A MultiPolygon is a MultiSurface whose elements are Polygons. + * + * @author tiwe + * + * @param + */ +public abstract class JTSMultiPolygonExpression extends JTSMultiSurfaceExpression { + + private static final long serialVersionUID = -2285946852207189655L; + + public JTSMultiPolygonExpression(Expression mixin) { + super(mixin); + } + +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSMultiPolygonPath.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSMultiPolygonPath.java new file mode 100644 index 0000000000..6d4f795081 --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSMultiPolygonPath.java @@ -0,0 +1,83 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial.jts; + +import java.lang.reflect.AnnotatedElement; + +import com.querydsl.core.types.*; +import com.vividsolutions.jts.geom.MultiPolygon; + +/** + * {@code JTSMultiPolygonPath} extends {@link JTSMultiPolygonExpression} to implement the + * {@link Path} interface + * + * @author tiwe + * + * @param + */ +public class JTSMultiPolygonPath extends JTSMultiPolygonExpression implements Path { + + private static final long serialVersionUID = 312776751843333543L; + + private final PathImpl pathMixin; + + @SuppressWarnings("unchecked") + public JTSMultiPolygonPath(Path parent, String property) { + this((Class) MultiPolygon.class, parent, property); + } + + public JTSMultiPolygonPath(Class type, Path parent, String property) { + this(type, PathMetadataFactory.forProperty(parent, property)); + } + + @SuppressWarnings("unchecked") + public JTSMultiPolygonPath(PathMetadata metadata) { + this((Class) MultiPolygon.class, metadata); + } + + public JTSMultiPolygonPath(Class type, PathMetadata metadata) { + super(ExpressionUtils.path(type, metadata)); + this.pathMixin = (PathImpl) mixin; + } + + @SuppressWarnings("unchecked") + public JTSMultiPolygonPath(String var) { + this((Class) MultiPolygon.class, PathMetadataFactory.forVariable(var)); + } + + @Override + public final R accept(Visitor v, C context) { + return v.visit(pathMixin, context); + } + + public JTSMultiPolygonPath(Class type, String var) { + this(type, PathMetadataFactory.forVariable(var)); + } + + @Override + public PathMetadata getMetadata() { + return pathMixin.getMetadata(); + } + + @Override + public Path getRoot() { + return pathMixin.getRoot(); + } + + @Override + public AnnotatedElement getAnnotatedElement() { + return pathMixin.getAnnotatedElement(); + } + +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSMultiSurfaceExpression.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSMultiSurfaceExpression.java new file mode 100644 index 0000000000..22ca6468ad --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSMultiSurfaceExpression.java @@ -0,0 +1,87 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial.jts; + +import org.jetbrains.annotations.Nullable; + +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberExpression; +import com.querydsl.spatial.SpatialOps; +import com.vividsolutions.jts.geom.GeometryCollection; +import com.vividsolutions.jts.geom.Point; + +/** + * A MultiSurface is a 2-dimensional GeometryCollection whose elements are Surfaces, all using coordinates from + * the same coordinate reference system. The geometric interiors of any two Surfaces in a MultiSurface may not + * intersect in the full coordinate system. The boundaries of any two coplanar elements in a MultiSurface may + * intersect, at most, at a finite number of Points. If they were to meet along a curve, they could be merged into a + * single surface. + * + * @author tiwe + * + * @param + */ +public abstract class JTSMultiSurfaceExpression extends JTSGeometryCollectionExpression { + + private static final long serialVersionUID = 4133386816772862010L; + + @Nullable + private transient volatile JTSPointExpression centroid, pointOnSurface; + + @Nullable + private transient volatile NumberExpression area; + + public JTSMultiSurfaceExpression(Expression mixin) { + super(mixin); + } + + /** + * The area of this MultiSurface, as measured in the spatial reference system of this MultiSurface. + * + * @return area + */ + public NumberExpression area() { + if (area == null) { + area = Expressions.numberOperation(Double.class, SpatialOps.AREA, mixin); + } + return area; + } + + /** + * The mathematical centroid for this MultiSurface. The result is not guaranteed to be on + * this MultiSurface. + * + * @return centroid + */ + public JTSPointExpression centroid() { + if (centroid == null) { + centroid = JTSGeometryExpressions.pointOperation(SpatialOps.CENTROID, mixin); + } + return centroid; + } + + /** + * A Point guaranteed to be on this MultiSurface. + * + * @return point on surface + */ + public JTSPointExpression pointOnSurface() { + if (pointOnSurface == null) { + pointOnSurface = JTSGeometryExpressions.pointOperation(SpatialOps.POINT_ON_SURFACE, mixin); + } + return pointOnSurface; + } + +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSPointExpression.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSPointExpression.java new file mode 100644 index 0000000000..0659d2ecd1 --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSPointExpression.java @@ -0,0 +1,91 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial.jts; + +import org.jetbrains.annotations.Nullable; + +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberExpression; +import com.querydsl.spatial.SpatialOps; +import com.vividsolutions.jts.geom.Point; + +/** + * A Point is a 0-dimensional geometric object and represents a single location in coordinate space. A Point has an + * x-coordinate value, a y-coordinate value. If called for by the associated Spatial Reference System, it may also + * have coordinate values for z and m. + * + * @author tiwe + * + * @param + */ +public abstract class JTSPointExpression extends JTSGeometryExpression { + + private static final long serialVersionUID = -3549448861390349654L; + + @Nullable + private transient volatile NumberExpression x, y, z, m; + + public JTSPointExpression(Expression mixin) { + super(mixin); + } + + /** + * The x-coordinate value for this Point. + * + * @return x-coordinate + */ + public NumberExpression x() { + if (x == null) { + x = Expressions.numberOperation(Double.class, SpatialOps.X, mixin); + } + return x; + } + + /** + * The y-coordinate value for this Point. + * + * @return y-coordinate + */ + public NumberExpression y() { + if (y == null) { + y = Expressions.numberOperation(Double.class, SpatialOps.Y, mixin); + } + return y; + } + + /** + * The z-coordinate value for this Point, if it has one. Returns NIL otherwise. + * + * @return z-coordinate + */ + public NumberExpression z() { + if (z == null) { + z = Expressions.numberOperation(Double.class, SpatialOps.Z, mixin); + } + return z; + } + + /** + * The m-coordinate value for this Point, if it has one. Returns NIL otherwise. + * + * @return m-coordinate + */ + public NumberExpression m() { + if (m == null) { + m = Expressions.numberOperation(Double.class, SpatialOps.M, mixin); + } + return m; + } +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSPointOperation.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSPointOperation.java new file mode 100644 index 0000000000..562c4dabf0 --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSPointOperation.java @@ -0,0 +1,64 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial.jts; + +import java.util.Arrays; +import java.util.List; + +import com.querydsl.core.types.*; +import com.vividsolutions.jts.geom.Point; + +/** + * {@code JTSPointOperation} extends {@link JTSPointExpression} to implement the + * {@link Operation} interface + * + * @author tiwe + * + * @param + */ +public class JTSPointOperation extends JTSPointExpression implements Operation { + + private static final long serialVersionUID = 3433471874808633698L; + + private final OperationImpl opMixin; + + protected JTSPointOperation(Class type, Operator op, Expression... args) { + this(type, op, Arrays.asList(args)); + } + + protected JTSPointOperation(Class type, Operator op, List> args) { + super(ExpressionUtils.operation(type, op, args)); + this.opMixin = (OperationImpl) mixin; + } + + @Override + public final R accept(Visitor v, C context) { + return v.visit(opMixin, context); + } + + @Override + public Expression getArg(int index) { + return opMixin.getArg(index); + } + + @Override + public List> getArgs() { + return opMixin.getArgs(); + } + + @Override + public Operator getOperator() { + return opMixin.getOperator(); + } +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSPointPath.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSPointPath.java new file mode 100644 index 0000000000..4fc5b28b93 --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSPointPath.java @@ -0,0 +1,83 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial.jts; + +import java.lang.reflect.AnnotatedElement; + +import com.querydsl.core.types.*; +import com.vividsolutions.jts.geom.Point; + +/** + * {@code JTSPointPath} extends {@link JTSPointExpression} to implement the + * {@link Path} interface + * + * @author tiwe + * + * @param + */ +public class JTSPointPath extends JTSPointExpression implements Path { + + private static final long serialVersionUID = 312776751843333543L; + + private final PathImpl pathMixin; + + @SuppressWarnings("unchecked") + public JTSPointPath(Path parent, String property) { + this((Class) Point.class, parent, property); + } + + public JTSPointPath(Class type, Path parent, String property) { + this(type, PathMetadataFactory.forProperty(parent, property)); + } + + @SuppressWarnings("unchecked") + public JTSPointPath(PathMetadata metadata) { + this((Class) Point.class, metadata); + } + + public JTSPointPath(Class type, PathMetadata metadata) { + super(ExpressionUtils.path(type, metadata)); + this.pathMixin = (PathImpl) mixin; + } + + @SuppressWarnings("unchecked") + public JTSPointPath(String var) { + this((Class) Point.class, PathMetadataFactory.forVariable(var)); + } + + @Override + public final R accept(Visitor v, C context) { + return v.visit(pathMixin, context); + } + + public JTSPointPath(Class type, String var) { + this(type, PathMetadataFactory.forVariable(var)); + } + + @Override + public PathMetadata getMetadata() { + return pathMixin.getMetadata(); + } + + @Override + public Path getRoot() { + return pathMixin.getRoot(); + } + + @Override + public AnnotatedElement getAnnotatedElement() { + return pathMixin.getAnnotatedElement(); + } + +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSPolygonExpression.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSPolygonExpression.java new file mode 100644 index 0000000000..f086c1e416 --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSPolygonExpression.java @@ -0,0 +1,82 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial.jts; + +import org.jetbrains.annotations.Nullable; + +import com.querydsl.core.types.ConstantImpl; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberExpression; +import com.querydsl.spatial.SpatialOps; +import com.vividsolutions.jts.geom.LineString; +import com.vividsolutions.jts.geom.Polygon; + +/** + * A Polygon is a planar Surface defined by 1 exterior boundary and 0 or more interior boundaries. Each interior + * boundary defines a hole in the Polygon. A Triangle is a polygon with 3 distinct, non-collinear vertices and no + * interior boundary. + * + * @author tiwe + * + * @param + */ +public abstract class JTSPolygonExpression extends JTSSurfaceExpression { + + private static final long serialVersionUID = 7544382956232485312L; + + @Nullable + private transient volatile NumberExpression numInteriorRing; + + @Nullable + private transient volatile JTSLineStringExpression exteriorRing; + + public JTSPolygonExpression(Expression mixin) { + super(mixin); + } + + /** + * Returns the exterior ring of this Polygon. + * + * @return exterior ring + */ + public JTSLineStringExpression exteriorRing() { + if (exteriorRing == null) { + exteriorRing = JTSGeometryExpressions.lineStringOperation(SpatialOps.EXTERIOR_RING, mixin); + } + return exteriorRing; + } + + /** + * Returns the number of interior rings in this Polygon. + * + * @return number of interior rings + */ + public NumberExpression numInteriorRing() { + if (numInteriorRing == null) { + numInteriorRing = Expressions.numberOperation(Integer.class, SpatialOps.NUM_INTERIOR_RING, mixin); + } + return numInteriorRing; + } + + /** + * Returns the N th interior ring for this Polygon as a LineString. + * + * @param idx one based index + * @return interior ring at index + */ + public JTSLineStringExpression interiorRingN(int idx) { + return JTSGeometryExpressions.lineStringOperation(SpatialOps.INTERIOR_RINGN, mixin, ConstantImpl.create(idx)); + } +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSPolygonOperation.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSPolygonOperation.java new file mode 100644 index 0000000000..537b79a90d --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSPolygonOperation.java @@ -0,0 +1,64 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial.jts; + +import java.util.Arrays; +import java.util.List; + +import com.querydsl.core.types.*; +import com.vividsolutions.jts.geom.Polygon; + +/** + * {@code JTSPolygonOperation} extends {@link JTSPolygonExpression} to implement the + * {@link Operation} interface + * + * @author tiwe + * + * @param + */ +public class JTSPolygonOperation extends JTSPolygonExpression implements Operation { + + private static final long serialVersionUID = 3433471874808633698L; + + private final OperationImpl opMixin; + + protected JTSPolygonOperation(Class type, Operator op, Expression... args) { + this(type, op, Arrays.asList(args)); + } + + protected JTSPolygonOperation(Class type, Operator op, List> args) { + super(ExpressionUtils.operation(type, op, args)); + this.opMixin = (OperationImpl) mixin; + } + + @Override + public final R accept(Visitor v, C context) { + return v.visit(opMixin, context); + } + + @Override + public Expression getArg(int index) { + return opMixin.getArg(index); + } + + @Override + public List> getArgs() { + return opMixin.getArgs(); + } + + @Override + public Operator getOperator() { + return opMixin.getOperator(); + } +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSPolygonPath.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSPolygonPath.java new file mode 100644 index 0000000000..fb390c1f6b --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSPolygonPath.java @@ -0,0 +1,83 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial.jts; + +import java.lang.reflect.AnnotatedElement; + +import com.querydsl.core.types.*; +import com.vividsolutions.jts.geom.Polygon; + +/** + * {@code JTSPolygonPath} extends {@link JTSPolygonExpression} to implement the + * {@link Path} interface + * + * @author tiwe + * + * @param + */ +public class JTSPolygonPath extends JTSPolygonExpression implements Path { + + private static final long serialVersionUID = 312776751843333543L; + + private final PathImpl pathMixin; + + @SuppressWarnings("unchecked") + public JTSPolygonPath(Path parent, String property) { + this((Class) Polygon.class, parent, property); + } + + public JTSPolygonPath(Class type, Path parent, String property) { + this(type, PathMetadataFactory.forProperty(parent, property)); + } + + @SuppressWarnings("unchecked") + public JTSPolygonPath(PathMetadata metadata) { + this((Class) Polygon.class, metadata); + } + + public JTSPolygonPath(Class type, PathMetadata metadata) { + super(ExpressionUtils.path(type, metadata)); + this.pathMixin = (PathImpl) mixin; + } + + @SuppressWarnings("unchecked") + public JTSPolygonPath(String var) { + this((Class) Polygon.class, PathMetadataFactory.forVariable(var)); + } + + @Override + public final R accept(Visitor v, C context) { + return v.visit(pathMixin, context); + } + + public JTSPolygonPath(Class type, String var) { + this(type, PathMetadataFactory.forVariable(var)); + } + + @Override + public PathMetadata getMetadata() { + return pathMixin.getMetadata(); + } + + @Override + public Path getRoot() { + return pathMixin.getRoot(); + } + + @Override + public AnnotatedElement getAnnotatedElement() { + return pathMixin.getAnnotatedElement(); + } + +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSSurfaceExpression.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSSurfaceExpression.java new file mode 100644 index 0000000000..8c3afaae65 --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/JTSSurfaceExpression.java @@ -0,0 +1,83 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial.jts; + +import org.jetbrains.annotations.Nullable; + +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberExpression; +import com.querydsl.spatial.SpatialOps; +import com.vividsolutions.jts.geom.Geometry; +import com.vividsolutions.jts.geom.Point; + +/** + * A Surface is a 2-dimensional geometric object. + * + * @author tiwe + * + * @param + */ +public abstract class JTSSurfaceExpression extends JTSGeometryExpression { + + private static final long serialVersionUID = 3534197011234723698L; + + @Nullable + private transient volatile JTSPointExpression centroid, pointOnSurface; + + @Nullable + private transient volatile NumberExpression area; + + public JTSSurfaceExpression(Expression mixin) { + super(mixin); + } + + /** + * The area of this Surface, as measured in the spatial reference system of this Surface. + * + * @return area + */ + public NumberExpression area() { + if (area == null) { + area = Expressions.numberOperation(Double.class, SpatialOps.AREA, mixin); + } + return area; + } + + /** + * The mathematical centroid for this Surface as a Point. The result is not guaranteed to + * be on this Surface. + * + * @return centroid + */ + public JTSPointExpression centroid() { + if (centroid == null) { + centroid = JTSGeometryExpressions.pointOperation(SpatialOps.CENTROID, mixin); + } + return centroid; + } + + /** + * A Point guaranteed to be on this Surface. + * + * @return point on surface + */ + public JTSPointExpression pointOnSurface() { + if (pointOnSurface == null) { + pointOnSurface = JTSGeometryExpressions.pointOperation(SpatialOps.POINT_ON_SURFACE, mixin); + } + return pointOnSurface; + } + +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/package-info.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/package-info.java new file mode 100644 index 0000000000..0e62d747c8 --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/jts/package-info.java @@ -0,0 +1,18 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ + +/** + * Spatial types using JTS + */ +package com.querydsl.spatial.jts; diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSCurveExpression.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSCurveExpression.java new file mode 100644 index 0000000000..a6cc0d550b --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSCurveExpression.java @@ -0,0 +1,112 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial.locationtech.jts; + +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.dsl.BooleanExpression; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberExpression; +import com.querydsl.spatial.SpatialOps; +import org.locationtech.jts.geom.Geometry; +import org.locationtech.jts.geom.Point; +import org.jetbrains.annotations.Nullable; + +/** + * A Curve is a 1-dimensional geometric object usually stored as a sequence of Points, with the subtype of Curve + * specifying the form of the interpolation between Points. This standard defines only one subclass of Curve, + * LineString, which uses linear interpolation between Points. + * + * @author tiwe + * + * @param + */ +public abstract class JTSCurveExpression extends JTSGeometryExpression { + + private static final long serialVersionUID = 6139188586728676033L; + + @Nullable + private transient volatile NumberExpression length; + + @Nullable + private transient volatile JTSPointExpression startPoint, endPoint; + + @Nullable + private transient volatile BooleanExpression closed, ring; + + public JTSCurveExpression(Expression mixin) { + super(mixin); + } + + /** + * The length of this Curve in its associated spatial reference. + * + * @return length + */ + public NumberExpression length() { + if (length == null) { + length = Expressions.numberOperation(Double.class, SpatialOps.LENGTH, mixin); + } + return length; + } + + /** + * The start Point of this Curve. + * + * @return start point + */ + public JTSPointExpression startPoint() { + if (startPoint == null) { + startPoint = JTSGeometryExpressions.pointOperation(SpatialOps.START_POINT, mixin); + } + return startPoint; + } + + /** + * The end Point of this Curve. + * + * @return end point + */ + public JTSPointExpression endPoint() { + if (endPoint == null) { + endPoint = JTSGeometryExpressions.pointOperation(SpatialOps.END_POINT, mixin); + } + return endPoint; + } + + /** + * Returns 1 (TRUE) if this Curve is closed [StartPoint ( ) = EndPoint ( )]. + * + * @return closed + */ + public BooleanExpression isClosed() { + if (closed == null) { + closed = Expressions.booleanOperation(SpatialOps.IS_CLOSED, mixin); + } + return closed; + } + + /** + * Returns 1 (TRUE) if this Curve is closed [StartPoint ( ) = EndPoint ( )] and this Curve is + * simple (does not pass through the same Point more than once). + * + * @return ring + */ + public BooleanExpression isRing() { + if (ring == null) { + ring = Expressions.booleanOperation(SpatialOps.IS_RING, mixin); + } + return ring; + } + +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSGeometryCollectionExpression.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSGeometryCollectionExpression.java new file mode 100644 index 0000000000..c66c68c3d2 --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSGeometryCollectionExpression.java @@ -0,0 +1,65 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial.locationtech.jts; + +import com.querydsl.core.types.ConstantImpl; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberExpression; +import com.querydsl.spatial.SpatialOps; +import org.locationtech.jts.geom.Geometry; +import org.locationtech.jts.geom.GeometryCollection; +import org.jetbrains.annotations.Nullable; + +/** + * A Geometry collection is a geometric object that is a collection of some number of geometric objects. + * + * @author tiwe + * + * @param + */ +public abstract class JTSGeometryCollectionExpression extends JTSGeometryExpression { + + private static final long serialVersionUID = 8874174644259834690L; + + @Nullable + private transient volatile NumberExpression numGeometries; + + public JTSGeometryCollectionExpression(Expression mixin) { + super(mixin); + } + + /** + * Returns the number of geometries in this GeometryCollection. + * + * @return numbers of geometries + */ + public NumberExpression numGeometries() { + if (numGeometries == null) { + numGeometries = Expressions.numberOperation(Integer.class, SpatialOps.NUM_GEOMETRIES, mixin); + } + return numGeometries; + } + + /** + * Returns the Nth geometry in this GeometryCollection. + * + * @param n one based index + * @return matching geometry + */ + public JTSGeometryExpression geometryN(Integer n) { + return JTSGeometryExpressions.geometryOperation(SpatialOps.GEOMETRYN, mixin, ConstantImpl.create(n)); + } + +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSGeometryCollectionPath.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSGeometryCollectionPath.java new file mode 100644 index 0000000000..b40c05e363 --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSGeometryCollectionPath.java @@ -0,0 +1,88 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial.locationtech.jts; + +import com.querydsl.core.types.ExpressionUtils; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathImpl; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.PathMetadataFactory; +import com.querydsl.core.types.Visitor; +import org.locationtech.jts.geom.GeometryCollection; + +import java.lang.reflect.AnnotatedElement; + +/** + * {@code JTSGeometryCollectionPath} extends {@link JTSGeometryCollectionExpression} to implement the + * {@link Path} interface + * + * @author tiwe + * + * @param + */ +public class JTSGeometryCollectionPath extends JTSGeometryCollectionExpression implements Path { + + private static final long serialVersionUID = 312776751843333543L; + + private final PathImpl pathMixin; + + @SuppressWarnings("unchecked") + public JTSGeometryCollectionPath(Path parent, String property) { + this((Class) GeometryCollection.class, parent, property); + } + + public JTSGeometryCollectionPath(Class type, Path parent, String property) { + this(type, PathMetadataFactory.forProperty(parent, property)); + } + + @SuppressWarnings("unchecked") + public JTSGeometryCollectionPath(PathMetadata metadata) { + this((Class) GeometryCollection.class, metadata); + } + + public JTSGeometryCollectionPath(Class type, PathMetadata metadata) { + super(ExpressionUtils.path(type, metadata)); + this.pathMixin = (PathImpl) mixin; + } + + @SuppressWarnings("unchecked") + public JTSGeometryCollectionPath(String var) { + this((Class) GeometryCollection.class, PathMetadataFactory.forVariable(var)); + } + + @Override + public final R accept(Visitor v, C context) { + return v.visit(pathMixin, context); + } + + public JTSGeometryCollectionPath(Class type, String var) { + this(type, PathMetadataFactory.forVariable(var)); + } + + @Override + public PathMetadata getMetadata() { + return pathMixin.getMetadata(); + } + + @Override + public Path getRoot() { + return pathMixin.getRoot(); + } + + @Override + public AnnotatedElement getAnnotatedElement() { + return pathMixin.getAnnotatedElement(); + } + +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSGeometryExpression.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSGeometryExpression.java new file mode 100644 index 0000000000..79bda72d88 --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSGeometryExpression.java @@ -0,0 +1,523 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial.locationtech.jts; + +import com.querydsl.core.types.ConstantImpl; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.dsl.BooleanExpression; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberExpression; +import com.querydsl.core.types.dsl.SimpleExpression; +import com.querydsl.core.types.dsl.StringExpression; +import com.querydsl.spatial.SpatialOps; +import org.locationtech.jts.geom.Geometry; +import org.jetbrains.annotations.Nullable; + +/** + * Geometry is the root class of the hierarchy. Geometry is an abstract (non-instantiable) class. + * + * @author tiwe + * + * @param + */ +public abstract class JTSGeometryExpression extends SimpleExpression { + + private static final long serialVersionUID = -1183228394472681995L; + + @Nullable + private transient volatile NumberExpression dimension, coordinateDimension, spatialDimension, srid; + + @Nullable + private transient volatile StringExpression geometryType; + + @Nullable + private transient volatile StringExpression text; + + @Nullable + private transient volatile JTSGeometryExpression envelope, boundary, convexHull; + + @Nullable + private transient volatile BooleanExpression empty, simple, threed, measured; + + private transient volatile SimpleExpression binary; + + public JTSGeometryExpression(Expression mixin) { + super(mixin); + } + + /** + * The inherent dimension of this geometric object, which must be less than or equal + * to the coordinate dimension. In non-homogeneous collections, this will return the largest topological + * dimension of the contained objects. + * + * @return dimension + */ + public NumberExpression dimension() { + if (dimension == null) { + dimension = Expressions.numberOperation(Integer.class, SpatialOps.DIMENSION, mixin); + } + return dimension; + } + + /** + * Returns the name of the instantiable subtype of Geometry of which this + * geometric object is an instantiable member. The name of the subtype of Geometry is returned as a string. + * + * @return geometry type + */ + public StringExpression geometryType() { + if (geometryType == null) { + geometryType = Expressions.stringOperation(SpatialOps.GEOMETRY_TYPE, mixin); + } + return geometryType; + } + + /** + * Returns the Spatial Reference System ID for this geometric object. This will normally be a + * foreign key to an index of reference systems stored in either the same or some other datastore. + * + * @return SRID + */ + public NumberExpression srid() { + if (srid == null) { + srid = Expressions.numberOperation(Integer.class, SpatialOps.SRID, mixin); + } + return srid; + } + + /** + * The minimum bounding box for this Geometry, returned as a Geometry. The + * polygon is defined by the corner points of the bounding box [(MINX, MINY), (MAXX, MINY), (MAXX, MAXY), + * (MINX, MAXY), (MINX, MINY)]. Minimums for Z and M may be added. The simplest representation of an + * Envelope is as two direct positions, one containing all the minimums, and another all the maximums. In some + * cases, this coordinate will be outside the range of validity for the Spatial Reference System. + * + * @return envelope + */ + public JTSGeometryExpression envelope() { + if (envelope == null) { + envelope = JTSGeometryExpressions.geometryOperation(SpatialOps.ENVELOPE, mixin); + } + return envelope; + } + + /** + * Exports this geometric object to a specific Well-known Text Representation of Geometry. + * + * @return text representation + */ + public StringExpression asText() { + if (text == null) { + text = Expressions.stringOperation(SpatialOps.AS_TEXT, mixin); + } + return text; + } + + /** + * Exports this geometric object to a specific Well-known Binary Representation of + * Geometry. + * + * @return binary representation + */ + public SimpleExpression asBinary() { + if (binary == null) { + binary = Expressions.operation(byte[].class, SpatialOps.AS_BINARY, mixin); + } + return binary; + } + + /** + * Returns 1 (TRUE) if this geometric object is the empty Geometry. If true, then this + * geometric object represents the empty point set ∅ for the coordinate space. + * + * @return empty + */ + public BooleanExpression isEmpty() { + if (empty == null) { + empty = Expressions.booleanOperation(SpatialOps.IS_EMPTY, mixin); + } + return empty; + } + + /** + * Returns 1 (TRUE) if this geometric object has no anomalous geometric points, such + * as self intersection or self tangency. The description of each instantiable geometric class + * will include the specific conditions that cause an instance of that class to be classified as not simple. + * + * @return simple + */ + public BooleanExpression isSimple() { + if (simple == null) { + simple = Expressions.booleanOperation(SpatialOps.IS_SIMPLE, mixin); + } + return simple; + } + + /** + * Returns the closure of the combinatorial boundary of this geometric object + * + * @return boundary + */ + public JTSGeometryExpression boundary() { + if (boundary == null) { + boundary = JTSGeometryExpressions.geometryOperation(SpatialOps.BOUNDARY, mixin); + } + return boundary; + } + + // query + + /* (non-Javadoc) + * @see com.querydsl.core.types.dsl.SimpleExpression#eq(java.lang.Object) + */ + @Override + public BooleanExpression eq(Geometry right) { + return eq(ConstantImpl.create(right)); + } + + /* (non-Javadoc) + * @see com.querydsl.core.types.dsl.SimpleExpression#eq(com.querydsl.core.types.Expression) + */ + @Override + public BooleanExpression eq(Expression right) { + return Expressions.booleanOperation(SpatialOps.EQUALS, mixin, right); + } + + /** + * Returns 1 (TRUE) if this geometric object is “spatially disjoint” from anotherGeometry. + * + * @param geometry other geometry + * @return true, if disjoint + */ + public BooleanExpression disjoint(Geometry geometry) { + return disjoint(ConstantImpl.create(geometry)); + } + + /** + * Returns 1 (TRUE) if this geometric object is “spatially disjoint” from anotherGeometry. + * + * @param geometry other geometry + * @return true, if disjoint + */ + public BooleanExpression disjoint(Expression geometry) { + return Expressions.booleanOperation(SpatialOps.DISJOINT, mixin, geometry); + } + + /** + * Returns 1 (TRUE) if this geometric object “spatially intersects” anotherGeometry. + * + * @param geometry other geometry + * @return true, if intersects + */ + public BooleanExpression intersects(Geometry geometry) { + return intersects(ConstantImpl.create(geometry)); + } + + /** + * Returns 1 (TRUE) if this geometric object “spatially intersects” anotherGeometry. + * + * @param geometry other geometry + * @return true, if intersects + */ + public BooleanExpression intersects(Expression geometry) { + return Expressions.booleanOperation(SpatialOps.INTERSECTS, mixin, geometry); + } + + /** + * Returns 1 (TRUE) if this geometric object “spatially touches” anotherGeometry. + * + * @param geometry other geometry + * @return true, if touches + */ + public BooleanExpression touches(Geometry geometry) { + return touches(ConstantImpl.create(geometry)); + } + + /** + * Returns 1 (TRUE) if this geometric object “spatially touches” anotherGeometry. + * + * @param geometry other geometry + * @return true, if touches + */ + public BooleanExpression touches(Expression geometry) { + return Expressions.booleanOperation(SpatialOps.TOUCHES, mixin, geometry); + } + + /** + * Returns 1 (TRUE) if this geometric object “spatially crosses’ anotherGeometry. + * + * @param geometry other geometry + * @return true, if crosses + */ + public BooleanExpression crosses(Geometry geometry) { + return crosses(ConstantImpl.create(geometry)); + } + + /** + * Returns 1 (TRUE) if this geometric object “spatially crosses’ anotherGeometry. + * + * @param geometry other geometry + * @return true, if crosses + */ + public BooleanExpression crosses(Expression geometry) { + return Expressions.booleanOperation(SpatialOps.CROSSES, mixin, geometry); + } + + /** + * Returns 1 (TRUE) if this geometric object is “spatially within” anotherGeometry. + * + * @param geometry other geometry + * @return true, if within + */ + public BooleanExpression within(Geometry geometry) { + return within(ConstantImpl.create(geometry)); + } + + /** + * Returns 1 (TRUE) if this geometric object is “spatially within” anotherGeometry. + * + * @param geometry other geometry + * @return true, if within + */ + public BooleanExpression within(Expression geometry) { + return Expressions.booleanOperation(SpatialOps.WITHIN, mixin, geometry); + } + + /** + * Returns 1 (TRUE) if this geometric object “spatially contains” anotherGeometry. + * + * @param geometry other geometry + * @return true, if contains + */ + public BooleanExpression contains(Geometry geometry) { + return contains(ConstantImpl.create(geometry)); + } + + /** + * Returns 1 (TRUE) if this geometric object “spatially contains” anotherGeometry. + * + * @param geometry other geometry + * @return true, if contains + */ + public BooleanExpression contains(Expression geometry) { + return Expressions.booleanOperation(SpatialOps.CONTAINS, mixin, geometry); + } + + /** + * Returns 1 (TRUE) if this geometric object “spatially overlaps” anotherGeometry. + * + * @param geometry other geometry + * @return true, if overlaps + */ + public BooleanExpression overlaps(Geometry geometry) { + return overlaps(ConstantImpl.create(geometry)); + } + + /** + * Returns 1 (TRUE) if this geometric object “spatially overlaps” anotherGeometry. + * + * @param geometry other geometry + * @return true, if overlaps + */ + public BooleanExpression overlaps(Expression geometry) { + return Expressions.booleanOperation(SpatialOps.OVERLAPS, mixin, geometry); + } + + /** + * Returns 1 (TRUE) if this geometric object is spatially related to anotherGeometry by testing + * for intersections between the interior, boundary and exterior of the two geometric objects + * as specified by the values in the intersectionPatternMatrix. This returns FALSE if all the + * tested intersections are empty except exterior (this) intersect exterior (another). + * + * @param geometry other geometry + * @param matrix matrix + * @return true, if this geometry is spatially related to the other + */ + public BooleanExpression relate(Geometry geometry, String matrix) { + return relate(ConstantImpl.create(geometry), matrix); + } + + /** + * Returns 1 (TRUE) if this geometric object is spatially related to anotherGeometry by testing + * for intersections between the interior, boundary and exterior of the two geometric objects + * as specified by the values in the intersectionPatternMatrix. This returns FALSE if all the + * tested intersections are empty except exterior (this) intersect exterior (another). + * + * @param geometry other geometry + * @param matrix matrix + * @return true, if this geometry is spatially related to the other + */ + public BooleanExpression relate(Expression geometry, String matrix) { + return Expressions.booleanOperation(SpatialOps.RELATE, mixin, geometry, ConstantImpl.create(matrix)); + } + + // analysis + + /** + * Returns the shortest distance between any two Points in the two geometric objects as + * calculated in the spatial reference system of this geometric object. Because the geometries + * are closed, it is possible to find a point on each geometric object involved, such that the + * distance between these 2 points is the returned distance between their geometric objects. + * + * @param geometry other geometry + * @return distance + */ + public NumberExpression distance(Geometry geometry) { + return distance(ConstantImpl.create(geometry)); + } + + /** + * Returns the shortest distance between any two Points in the two geometric objects as + * calculated in the spatial reference system of this geometric object. Because the geometries + * are closed, it is possible to find a point on each geometric object involved, such that the + * distance between these 2 points is the returned distance between their geometric objects. + * + * @param geometry other geometry + * @return distance + */ + public NumberExpression distance(Expression geometry) { + return Expressions.numberOperation(Double.class, SpatialOps.DISTANCE, mixin, geometry); + } + + // TODO maybe move out + public NumberExpression distanceSphere(Expression geometry) { + return Expressions.numberOperation(Double.class, SpatialOps.DISTANCE_SPHERE, mixin, geometry); + } + + // TODO maybe move out + public NumberExpression distanceSpheroid(Expression geometry) { + return Expressions.numberOperation(Double.class, SpatialOps.DISTANCE_SPHEROID, mixin, geometry); + } + + /** + * Returns a geometric object that represents all Points whose distance from this geometric + * object is less than or equal to distance. Calculations are in the spatial reference system + * of this geometric object. Because of the limitations of linear interpolation, there will + * often be some relatively small error in this distance, but it should be near the resolution + * of the coordinates used. + * + * @param distance distance + * @return buffer + */ + public JTSGeometryExpression buffer(double distance) { + return JTSGeometryExpressions.geometryOperation(SpatialOps.BUFFER, mixin, ConstantImpl.create(distance)); + } + + /** + * Returns a geometric object that represents the convex hull of this geometric object. + * Convex hulls, being dependent on straight lines, can be accurately represented in linear + * interpolations for any geometry restricted to linear interpolations. + * + * @return convex hull + */ + public JTSGeometryExpression convexHull() { + if (convexHull == null) { + convexHull = JTSGeometryExpressions.geometryOperation(SpatialOps.CONVEXHULL, mixin); + } + return convexHull; + } + + /** + * Returns a geometric object that represents the Point set intersection of this geometric + * object with anotherGeometry. + * + * @param geometry other geometry + * @return intersection of this and the other geometry + */ + public JTSGeometryExpression intersection(Geometry geometry) { + return intersection(ConstantImpl.create(geometry)); + } + + /** + * Returns a geometric object that represents the Point set intersection of this geometric + * object with anotherGeometry. + * + * @param geometry other geometry + * @return intersection of this and the other geometry + */ + public JTSGeometryExpression intersection(Expression geometry) { + return JTSGeometryExpressions.geometryOperation(SpatialOps.INTERSECTION, mixin, geometry); + } + + /** + * Returns a geometric object that represents the Point set + * union of this geometric object with anotherGeometry. + * + * @param geometry other geometry + * @return union of this and the other geometry + */ + public JTSGeometryExpression union(Geometry geometry) { + return union(ConstantImpl.create(geometry)); + } + + /** + * Returns a geometric object that represents the Point set + * union of this geometric object with anotherGeometry. + * + * @param geometry other geometry + * @return union of this and the other geometry + */ + public JTSGeometryExpression union(Expression geometry) { + return JTSGeometryExpressions.geometryOperation(SpatialOps.UNION, mixin, geometry); + } + + /** + * Returns a geometric object that represents the Point + * set difference of this geometric object with anotherGeometry. + * + * @param geometry other geometry + * @return difference between this and the other geometry + */ + public JTSGeometryExpression difference(Geometry geometry) { + return difference(ConstantImpl.create(geometry)); + } + + /** + * Returns a geometric object that represents the Point + * set difference of this geometric object with anotherGeometry. + * + * @param geometry other geometry + * @return difference between this and the other geometry + */ + public JTSGeometryExpression difference(Expression geometry) { + return JTSGeometryExpressions.geometryOperation(SpatialOps.DIFFERENCE, mixin, geometry); + } + + /** + * Returns a geometric object that represents the + * Point set symmetric difference of this geometric object with anotherGeometry. + * + * @param geometry other geometry + * @return symmetric difference + */ + public JTSGeometryExpression symDifference(Geometry geometry) { + return symDifference(ConstantImpl.create(geometry)); + } + + /** + * Returns a geometric object that represents the + * Point set symmetric difference of this geometric object with anotherGeometry. + * + * @param geometry other geometry + * @return symmetric difference + */ + public JTSGeometryExpression symDifference(Expression geometry) { + return JTSGeometryExpressions.geometryOperation(SpatialOps.SYMDIFFERENCE, mixin, geometry); + } + + public JTSGeometryExpression transform(int srid) { + return JTSGeometryExpressions.geometryOperation(SpatialOps.TRANSFORM, mixin, ConstantImpl.create(srid)); + } + +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSGeometryExpressions.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSGeometryExpressions.java new file mode 100644 index 0000000000..086a71597a --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSGeometryExpressions.java @@ -0,0 +1,297 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial.locationtech.jts; + +import com.querydsl.core.types.ConstantImpl; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.ExpressionUtils; +import com.querydsl.core.types.Operator; +import com.querydsl.core.types.Visitor; +import com.querydsl.core.types.dsl.BooleanExpression; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberExpression; +import com.querydsl.core.types.dsl.StringExpression; +import com.querydsl.spatial.SpatialOps; +import org.locationtech.jts.geom.Geometry; +import org.locationtech.jts.geom.GeometryCollection; +import org.locationtech.jts.geom.LineString; +import org.locationtech.jts.geom.Point; +import org.locationtech.jts.geom.Polygon; + +/** + * GeometryExpressions contains static functions for GEO operations + */ +public final class JTSGeometryExpressions { + + private JTSGeometryExpressions() { } + + /** + * Return a specified ST_Geometry value from Extended Well-Known Text representation (EWKT). + * + * @param expr geometry + * @return EWKT form + */ + public static StringExpression asEWKT(JTSGeometryExpression expr) { + return Expressions.stringOperation(SpatialOps.AS_EWKT, expr); + } + + /** + * Return a specified ST_Geometry value from Well-Known Text representation (WKT). + * + * @param text WKT form + * @return geometry + */ + public static JTSGeometryExpression fromText(String text) { + return geometryOperation(SpatialOps.GEOM_FROM_TEXT, ConstantImpl.create(text)); + } + + /** + * Return a specified ST_Geometry value from Well-Known Text representation (WKT). + * + * @param text WKT form + * @return geometry + */ + public static JTSGeometryExpression fromText(Expression text) { + return geometryOperation(SpatialOps.GEOM_FROM_TEXT, text); + } + + /** + * Sets the SRID on a geometry to a particular integer value. + * + * @param expr geometry + * @param srid SRID + * @param + * @return geometry + */ + public static JTSGeometryExpression setSRID(Expression expr, int srid) { + return geometryOperation(expr.getType(), SpatialOps.SET_SRID, + expr, ConstantImpl.create(srid)); + } + + /** + * Returns X minima of a bounding box 2d or 3d or a geometry. + * + * @param expr geometry + * @return x minima + */ + public static NumberExpression xmin(JTSGeometryExpression expr) { + return Expressions.numberOperation(Double.class, SpatialOps.XMIN, expr); + } + + /** + * Returns X maxima of a bounding box 2d or 3d or a geometry. + * + * @param expr geometry + * @return x maxima + */ + public static NumberExpression xmax(JTSGeometryExpression expr) { + return Expressions.numberOperation(Double.class, SpatialOps.XMAX, expr); + } + + /** + * Returns Y minima of a bounding box 2d or 3d or a geometry. + * + * @param expr geometry + * @return y minima + */ + public static NumberExpression ymin(JTSGeometryExpression expr) { + return Expressions.numberOperation(Double.class, SpatialOps.YMIN, expr); + } + + /** + * Returns Y maxima of a bounding box 2d or 3d or a geometry. + * + * @param expr geometry + * @return y maxima + */ + public static NumberExpression ymax(JTSGeometryExpression expr) { + return Expressions.numberOperation(Double.class, SpatialOps.YMAX, expr); + } + + /** + * Returns true if the geometries are within the specified distance of one another. + * For geometry units are in those of spatial reference and For geography units are in meters. + * + * @param expr1 geometry + * @param expr2 other geometry + * @param distance distance + * @return true, if with distance of each other + */ + public static BooleanExpression dwithin(Expression expr1, + Expression expr2, Expression distance) { + return Expressions.booleanOperation(SpatialOps.DWITHIN, expr1, expr2, distance); + } + + /** + * Returns true if the geometries are within the specified distance of one another. + * For geometry units are in those of spatial reference and For geography units are in meters. + * + * @param expr1 geometry + * @param expr2 other geometry + * @param distance distance + * @return true, if with distance of each other + */ + public static BooleanExpression dwithin(Expression expr1, + Expression expr2, double distance) { + return Expressions.booleanOperation(SpatialOps.DWITHIN, expr1, expr2, ConstantImpl.create(distance)); + } + + /** + * Returns the bounding box that bounds rows of geometries. + * + * @param collection geometry collection + * @return geometry collection + */ + public static JTSGeometryExpression extent(Expression collection) { + return geometryOperation(SpatialOps.EXTENT, collection); + } + + /** + * Return a specified ST_Geometry value from a collection of other geometries. + * + * @param collection geometry collection + * @return geometry collection + */ + public static JTSGeometryExpression collect(Expression collection) { + return geometryOperation(SpatialOps.COLLECT, collection); + } + + /** + * Return a specified ST_Geometry value from a collection of other geometries. + * + * @param expr1 geometry + * @param expr2 other geometry + * @return geometry collection + */ + public static JTSGeometryExpression collect(Expression expr1, Expression expr2) { + return geometryOperation(SpatialOps.COLLECT2, expr1, expr2); + } + + /** + * Translates the geometry to a new location using the numeric parameters as offsets. + * + * @param expr geometry + * @param deltax x offset + * @param deltay y offset + * @param + * @return geometry + */ + public static JTSGeometryExpression translate(Expression expr, float deltax, float deltay) { + return geometryOperation(expr.getType(), SpatialOps.TRANSLATE, + expr, ConstantImpl.create(deltax), ConstantImpl.create(deltay)); + } + + /** + * Translates the geometry to a new location using the numeric parameters as offsets. + * + * @param expr geometry + * @param deltax x offset + * @param deltay y offset + * @param deltaz z offset + * @param + * @return geometry + */ + public static JTSGeometryExpression translate(Expression expr, float deltax, float deltay, float deltaz) { + return geometryOperation(expr.getType(), SpatialOps.TRANSLATE2, + expr, ConstantImpl.create(deltax), ConstantImpl.create(deltay), ConstantImpl.create(deltaz)); + } + + /** + * Create a new Geometry operation expression + * + * @param op operator + * @param args arguments + * @return operation expression + */ + public static JTSGeometryExpression geometryOperation(Operator op, Expression... args) { + return new JTSGeometryOperation(Geometry.class, op, args); + } + + /** + * Create a new Geometry operation expression + * + * @param op operator + * @param args arguments + * @return operation expression + */ + public static JTSGeometryExpression geometryOperation(Class type, + Operator op, Expression... args) { + return new JTSGeometryOperation(type, op, args); + } + + /** + * Create a new LineString operation expression + * + * @param op operator + * @param args arguments + * @return operation expression + */ + public static JTSLineStringExpression lineStringOperation(Operator op, Expression... args) { + return new JTSLineStringOperation(LineString.class, op, args); + } + + /** + * Create a new Point operation expression + * + * @param op operator + * @param args arguments + * @return operation expression + */ + public static JTSPointExpression pointOperation(Operator op, Expression... args) { + return new JTSPointOperation(Point.class, op, args); + } + + /** + * Create a new Polygon operation expression + * + * @param op operator + * @param args arguments + * @return operation expression + */ + public static JTSPolygonExpression polygonOperation(Operator op, Expression... args) { + return new JTSPolygonOperation(Polygon.class, op, args); + } + + /** + * Create a new JTSGeometryExpression + * + * @param expr Expression of type Geometry + * @return new JTSGeometryExpression + */ + public static JTSGeometryExpression asJTSGeometry( + Expression expr) { + Expression underlyingMixin = ExpressionUtils.extract(expr); + return new JTSGeometryExpression(underlyingMixin) { + + private static final long serialVersionUID = -6714044005570420009L; + + @Override + public R accept(Visitor v, C context) { + return this.mixin.accept(v, context); + } + + }; + } + + /** + * Create a new JTSGeometryExpression + * + * @param value Geometry + * @return new JTSGeometryExpression + */ + public static JTSGeometryExpression asJTSGeometry(T value) { + return asJTSGeometry(Expressions.constant(value)); + } + +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSGeometryOperation.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSGeometryOperation.java new file mode 100644 index 0000000000..42e968aa04 --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSGeometryOperation.java @@ -0,0 +1,70 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial.locationtech.jts; + +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.ExpressionUtils; +import com.querydsl.core.types.Operation; +import com.querydsl.core.types.OperationImpl; +import com.querydsl.core.types.Operator; +import com.querydsl.core.types.Visitor; +import org.locationtech.jts.geom.Geometry; + +import java.util.Arrays; +import java.util.List; + +/** + * {@code JTSGeometryOperation} extends {@link JTSGeometryExpression} to implement the + * {@link Operation} interface + * + * @author tiwe + * + * @param + */ +public class JTSGeometryOperation extends JTSGeometryExpression implements Operation { + + private static final long serialVersionUID = 3433471874808633698L; + + private final OperationImpl opMixin; + + protected JTSGeometryOperation(Class type, Operator op, Expression... args) { + this(type, op, Arrays.asList(args)); + } + + protected JTSGeometryOperation(Class type, Operator op, List> args) { + super(ExpressionUtils.operation(type, op, args)); + this.opMixin = (OperationImpl) mixin; + } + + @Override + public final R accept(Visitor v, C context) { + return v.visit(opMixin, context); + } + + @Override + public Expression getArg(int index) { + return opMixin.getArg(index); + } + + @Override + public List> getArgs() { + return opMixin.getArgs(); + } + + @Override + public Operator getOperator() { + return opMixin.getOperator(); + } + +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSGeometryPath.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSGeometryPath.java new file mode 100644 index 0000000000..b3d40f3ed2 --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSGeometryPath.java @@ -0,0 +1,168 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial.locationtech.jts; + +import com.querydsl.core.types.ExpressionUtils; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathImpl; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.PathMetadataFactory; +import com.querydsl.core.types.Visitor; +import org.locationtech.jts.geom.Geometry; +import org.locationtech.jts.geom.GeometryCollection; +import org.locationtech.jts.geom.LineString; +import org.locationtech.jts.geom.LinearRing; +import org.locationtech.jts.geom.MultiLineString; +import org.locationtech.jts.geom.MultiPoint; +import org.locationtech.jts.geom.MultiPolygon; +import org.locationtech.jts.geom.Point; +import org.locationtech.jts.geom.Polygon; + +import java.lang.reflect.AnnotatedElement; + +/** + * {@code JTSGeometryPath} extends {@link JTSGeometryExpression} to implement the + * {@link Path} interface + * + * @author tiwe + * + * @param + */ +public class JTSGeometryPath extends JTSGeometryExpression implements Path { + + private static final long serialVersionUID = 312776751843333543L; + + private final PathImpl pathMixin; + + private transient volatile JTSGeometryCollectionPath collection; + + private transient volatile JTSLinearRingPath linearRing; + + private transient volatile JTSLineStringPath lineString; + + private transient volatile JTSMultiLineStringPath multiLineString; + + private transient volatile JTSMultiPointPath multiPoint; + + private transient volatile JTSMultiPolygonPath multiPolygon; + + private transient volatile JTSPointPath point; + + private transient volatile JTSPolygonPath polygon; + + @SuppressWarnings("unchecked") + public JTSGeometryPath(Path parent, String property) { + this((Class) Geometry.class, parent, property); + } + + public JTSGeometryPath(Class type, Path parent, String property) { + this(type, PathMetadataFactory.forProperty(parent, property)); + } + + @SuppressWarnings("unchecked") + public JTSGeometryPath(PathMetadata metadata) { + this((Class) Geometry.class, metadata); + } + + public JTSGeometryPath(Class type, PathMetadata metadata) { + super(ExpressionUtils.path(type, metadata)); + this.pathMixin = (PathImpl) mixin; + } + + @SuppressWarnings("unchecked") + public JTSGeometryPath(String var) { + this((Class) Geometry.class, PathMetadataFactory.forVariable(var)); + } + + public JTSGeometryCollectionPath asCollection() { + if (collection == null) { + collection = new JTSGeometryCollectionPath(pathMixin.getMetadata()); + } + return collection; + } + + public JTSLinearRingPath asLinearRing() { + if (linearRing == null) { + linearRing = new JTSLinearRingPath(pathMixin.getMetadata()); + } + return linearRing; + } + + public JTSLineStringPath asLineString() { + if (lineString == null) { + lineString = new JTSLineStringPath(pathMixin.getMetadata()); + } + return lineString; + } + + public JTSMultiLineStringPath asMultiLineString() { + if (multiLineString == null) { + multiLineString = new JTSMultiLineStringPath(pathMixin.getMetadata()); + } + return multiLineString; + } + + public JTSMultiPointPath asMultiPoint() { + if (multiPoint == null) { + multiPoint = new JTSMultiPointPath(pathMixin.getMetadata()); + } + return multiPoint; + } + + public JTSMultiPolygonPath asMultiPolygon() { + if (multiPolygon == null) { + multiPolygon = new JTSMultiPolygonPath(pathMixin.getMetadata()); + } + return multiPolygon; + } + + public JTSPointPath asPoint() { + if (point == null) { + point = new JTSPointPath(pathMixin.getMetadata()); + } + return point; + } + + public JTSPolygonPath asPolygon() { + if (polygon == null) { + polygon = new JTSPolygonPath(pathMixin.getMetadata()); + } + return polygon; + } + + @Override + public final R accept(Visitor v, C context) { + return v.visit(pathMixin, context); + } + + public JTSGeometryPath(Class type, String var) { + this(type, PathMetadataFactory.forVariable(var)); + } + + @Override + public PathMetadata getMetadata() { + return pathMixin.getMetadata(); + } + + @Override + public Path getRoot() { + return pathMixin.getRoot(); + } + + @Override + public AnnotatedElement getAnnotatedElement() { + return pathMixin.getAnnotatedElement(); + } + +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSGeometryPaths.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSGeometryPaths.java new file mode 100644 index 0000000000..e77d973d48 --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSGeometryPaths.java @@ -0,0 +1,52 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial.locationtech.jts; + +import org.locationtech.jts.geom.Geometry; +import org.locationtech.jts.geom.GeometryCollection; +import org.locationtech.jts.geom.LineString; +import org.locationtech.jts.geom.LinearRing; +import org.locationtech.jts.geom.MultiLineString; +import org.locationtech.jts.geom.MultiPoint; +import org.locationtech.jts.geom.MultiPolygon; +import org.locationtech.jts.geom.Point; +import org.locationtech.jts.geom.Polygon; + +/** + * {@code JTSGeometryPaths} provides factory methods for {@link JTSGeometryExpression} creation + * + * @author tiwe + * + */ +public interface JTSGeometryPaths { + + JTSGeometryCollectionPath createGeometryCollection(String property, Class type); + + JTSGeometryPath createGeometry(String property, Class type); + + JTSLinearRingPath createLinearRing(String property, Class type); + + JTSLineStringPath createLineString(String property, Class type); + + JTSMultiLineStringPath createMultiLineString(String property, Class type); + + JTSMultiPointPath createMultiPoint(String property, Class type); + + JTSMultiPolygonPath createMultiPolygon(String property, Class type); + + JTSPointPath createPoint(String property, Class type); + + JTSPolygonPath createPolygon(String property, Class type); + +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSLineExpression.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSLineExpression.java new file mode 100644 index 0000000000..36c77d1c9b --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSLineExpression.java @@ -0,0 +1,34 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial.locationtech.jts; + +import com.querydsl.core.types.Expression; +import org.locationtech.jts.geom.LineString; + +/** + * A Line is a LineString with exactly 2 Points. + * + * @author tiwe + * + * @param + */ +public abstract class JTSLineExpression extends JTSLineStringExpression { + + private static final long serialVersionUID = -4849454664355502296L; + + public JTSLineExpression(Expression mixin) { + super(mixin); + } + +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSLineStringExpression.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSLineStringExpression.java new file mode 100644 index 0000000000..5700d89fbc --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSLineStringExpression.java @@ -0,0 +1,66 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial.locationtech.jts; + +import com.querydsl.core.types.ConstantImpl; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberExpression; +import com.querydsl.spatial.SpatialOps; +import org.locationtech.jts.geom.LineString; +import org.locationtech.jts.geom.Point; +import org.jetbrains.annotations.Nullable; + +/** + * A LineString is a Curve with linear interpolation between Points. Each consecutive pair of Points defines a Line + * segment. + * + * @author tiwe + * + * @param + */ +public abstract class JTSLineStringExpression extends JTSCurveExpression { + + private static final long serialVersionUID = -6572984614863252657L; + + @Nullable + private transient volatile NumberExpression numPoints; + + public JTSLineStringExpression(Expression mixin) { + super(mixin); + } + + /** + * The number of Points in this LineString. + * + * @return number of points + */ + public NumberExpression numPoints() { + if (numPoints == null) { + numPoints = Expressions.numberOperation(Integer.class, SpatialOps.NUM_POINTS, mixin); + } + return numPoints; + } + + /** + * Returns the specified Point N in this LineString. + * + * @param idx one based index + * @return point at index + */ + public JTSPointExpression pointN(int idx) { + return JTSGeometryExpressions.pointOperation(SpatialOps.POINTN, mixin, ConstantImpl.create(idx)); + } + +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSLineStringOperation.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSLineStringOperation.java new file mode 100644 index 0000000000..f267995406 --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSLineStringOperation.java @@ -0,0 +1,70 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial.locationtech.jts; + +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.ExpressionUtils; +import com.querydsl.core.types.Operation; +import com.querydsl.core.types.OperationImpl; +import com.querydsl.core.types.Operator; +import com.querydsl.core.types.Visitor; +import org.locationtech.jts.geom.LineString; + +import java.util.Arrays; +import java.util.List; + +/** + * {@code JTSLineStringOperation} extends {@link JTSLineStringExpression} to implement the + * {@link Operation} interface + * + * @author tiwe + * + * @param + */ +public class JTSLineStringOperation extends JTSLineStringExpression implements Operation { + + private static final long serialVersionUID = 3433471874808633698L; + + private final OperationImpl< T> opMixin; + + protected JTSLineStringOperation(Class type, Operator op, Expression... args) { + this(type, op, Arrays.asList(args)); + } + + protected JTSLineStringOperation(Class type, Operator op, List> args) { + super(ExpressionUtils.operation(type, op, args)); + this.opMixin = (OperationImpl) mixin; + } + + @Override + public final R accept(Visitor v, C context) { + return v.visit(opMixin, context); + } + + @Override + public Expression getArg(int index) { + return opMixin.getArg(index); + } + + @Override + public List> getArgs() { + return opMixin.getArgs(); + } + + @Override + public Operator getOperator() { + return opMixin.getOperator(); + } + +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSLineStringPath.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSLineStringPath.java new file mode 100644 index 0000000000..9107c44ea2 --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSLineStringPath.java @@ -0,0 +1,88 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial.locationtech.jts; + +import com.querydsl.core.types.ExpressionUtils; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathImpl; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.PathMetadataFactory; +import com.querydsl.core.types.Visitor; +import org.locationtech.jts.geom.LineString; + +import java.lang.reflect.AnnotatedElement; + +/** + * {@code JTSLineStringPath} extends {@link JTSLineStringExpression} to implement the + * {@link Path} interface + * + * @author tiwe + * + * @param + */ +public class JTSLineStringPath extends JTSLineStringExpression implements Path { + + private static final long serialVersionUID = 312776751843333543L; + + private final PathImpl pathMixin; + + @SuppressWarnings("unchecked") + public JTSLineStringPath(Path parent, String property) { + this((Class) LineString.class, parent, property); + } + + public JTSLineStringPath(Class type, Path parent, String property) { + this(type, PathMetadataFactory.forProperty(parent, property)); + } + + @SuppressWarnings("unchecked") + public JTSLineStringPath(PathMetadata metadata) { + this((Class) LineString.class, metadata); + } + + public JTSLineStringPath(Class type, PathMetadata metadata) { + super(ExpressionUtils.path(type, metadata)); + this.pathMixin = (PathImpl) mixin; + } + + @SuppressWarnings("unchecked") + public JTSLineStringPath(String var) { + this((Class) LineString.class, PathMetadataFactory.forVariable(var)); + } + + @Override + public final R accept(Visitor v, C context) { + return v.visit(pathMixin, context); + } + + public JTSLineStringPath(Class type, String var) { + this(type, PathMetadataFactory.forVariable(var)); + } + + @Override + public PathMetadata getMetadata() { + return pathMixin.getMetadata(); + } + + @Override + public Path getRoot() { + return pathMixin.getRoot(); + } + + @Override + public AnnotatedElement getAnnotatedElement() { + return pathMixin.getAnnotatedElement(); + } + +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSLinearRingExpression.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSLinearRingExpression.java new file mode 100644 index 0000000000..9a7de8fa62 --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSLinearRingExpression.java @@ -0,0 +1,34 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial.locationtech.jts; + +import com.querydsl.core.types.Expression; +import org.locationtech.jts.geom.LineString; + +/** + * A LinearRing is a LineString that is both closed and simple. + * + * @author tiwe + * + * @param + */ +public abstract class JTSLinearRingExpression extends JTSLineStringExpression { + + private static final long serialVersionUID = -759466658721392938L; + + public JTSLinearRingExpression(Expression mixin) { + super(mixin); + } + +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSLinearRingPath.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSLinearRingPath.java new file mode 100644 index 0000000000..a4423373ad --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSLinearRingPath.java @@ -0,0 +1,88 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial.locationtech.jts; + +import com.querydsl.core.types.ExpressionUtils; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathImpl; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.PathMetadataFactory; +import com.querydsl.core.types.Visitor; +import org.locationtech.jts.geom.LinearRing; + +import java.lang.reflect.AnnotatedElement; + +/** + * {@code JTSLinearRingPath} extends {@link JTSLinearRingExpression} to implement the + * {@link Path} interface + * + * @author tiwe + * + * @param + */ +public class JTSLinearRingPath extends JTSLinearRingExpression implements Path { + + private static final long serialVersionUID = 312776751843333543L; + + private final PathImpl pathMixin; + + @SuppressWarnings("unchecked") + public JTSLinearRingPath(Path parent, String property) { + this((Class) LinearRing.class, parent, property); + } + + public JTSLinearRingPath(Class type, Path parent, String property) { + this(type, PathMetadataFactory.forProperty(parent, property)); + } + + @SuppressWarnings("unchecked") + public JTSLinearRingPath(PathMetadata metadata) { + this((Class) LinearRing.class, metadata); + } + + public JTSLinearRingPath(Class type, PathMetadata metadata) { + super(ExpressionUtils.path(type, metadata)); + this.pathMixin = (PathImpl) mixin; + } + + @SuppressWarnings("unchecked") + public JTSLinearRingPath(String var) { + this((Class) LinearRing.class, PathMetadataFactory.forVariable(var)); + } + + @Override + public final R accept(Visitor v, C context) { + return v.visit(pathMixin, context); + } + + public JTSLinearRingPath(Class type, String var) { + this(type, PathMetadataFactory.forVariable(var)); + } + + @Override + public PathMetadata getMetadata() { + return pathMixin.getMetadata(); + } + + @Override + public Path getRoot() { + return pathMixin.getRoot(); + } + + @Override + public AnnotatedElement getAnnotatedElement() { + return pathMixin.getAnnotatedElement(); + } + +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSMultiCurveExpression.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSMultiCurveExpression.java new file mode 100644 index 0000000000..187e0added --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSMultiCurveExpression.java @@ -0,0 +1,71 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial.locationtech.jts; + +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.dsl.BooleanExpression; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberExpression; +import com.querydsl.spatial.SpatialOps; +import org.locationtech.jts.geom.GeometryCollection; +import org.jetbrains.annotations.Nullable; + +/** + * A MultiCurve is a 1-dimensional GeometryCollection whose elements are Curves. + * + * @author tiwe + * + * @param + */ +public abstract class JTSMultiCurveExpression extends JTSGeometryCollectionExpression { + + private static final long serialVersionUID = 6983316799469849656L; + + @Nullable + private transient volatile BooleanExpression closed; + + @Nullable + private transient volatile NumberExpression length; + + public JTSMultiCurveExpression(Expression mixin) { + super(mixin); + } + + /** + * Returns 1 (TRUE) if this MultiCurve is closed [StartPoint ( ) = EndPoint ( ) for each + * Curve in this MultiCurve]. + * + * @return closed + */ + public BooleanExpression isClosed() { + if (closed == null) { + closed = Expressions.booleanOperation(SpatialOps.IS_CLOSED, mixin); + } + return closed; + } + + /** + * The Length of this MultiCurve which is equal to the sum of the lengths of the element + * Curves. + * + * @return length + */ + public NumberExpression length() { + if (length == null) { + length = Expressions.numberOperation(Double.class, SpatialOps.LENGTH, mixin); + } + return length; + } + +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSMultiLineStringExpression.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSMultiLineStringExpression.java new file mode 100644 index 0000000000..22e9219995 --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSMultiLineStringExpression.java @@ -0,0 +1,34 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial.locationtech.jts; + +import com.querydsl.core.types.Expression; +import org.locationtech.jts.geom.MultiLineString; + +/** + * A MultiLineString is a MultiCurve whose elements are LineStrings. + * + * @author tiwe + * + * @param + */ +public abstract class JTSMultiLineStringExpression extends JTSMultiCurveExpression { + + private static final long serialVersionUID = -3103756880812584473L; + + public JTSMultiLineStringExpression(Expression mixin) { + super(mixin); + } + +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSMultiLineStringPath.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSMultiLineStringPath.java new file mode 100644 index 0000000000..8bef108164 --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSMultiLineStringPath.java @@ -0,0 +1,88 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial.locationtech.jts; + +import com.querydsl.core.types.ExpressionUtils; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathImpl; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.PathMetadataFactory; +import com.querydsl.core.types.Visitor; +import org.locationtech.jts.geom.MultiLineString; + +import java.lang.reflect.AnnotatedElement; + +/** + * {@code JTSMultiLineStringPath} extends {@link JTSMultiLineStringExpression} to implement the + * {@link Path} interface + * + * @author tiwe + * + * @param + */ +public class JTSMultiLineStringPath extends JTSMultiLineStringExpression implements Path { + + private static final long serialVersionUID = 312776751843333543L; + + private final PathImpl pathMixin; + + @SuppressWarnings("unchecked") + public JTSMultiLineStringPath(Path parent, String property) { + this((Class) MultiLineString.class, parent, property); + } + + public JTSMultiLineStringPath(Class type, Path parent, String property) { + this(type, PathMetadataFactory.forProperty(parent, property)); + } + + @SuppressWarnings("unchecked") + public JTSMultiLineStringPath(PathMetadata metadata) { + this((Class) MultiLineString.class, metadata); + } + + public JTSMultiLineStringPath(Class type, PathMetadata metadata) { + super(ExpressionUtils.path(type, metadata)); + this.pathMixin = (PathImpl) mixin; + } + + @SuppressWarnings("unchecked") + public JTSMultiLineStringPath(String var) { + this((Class) MultiLineString.class, PathMetadataFactory.forVariable(var)); + } + + @Override + public final R accept(Visitor v, C context) { + return v.visit(pathMixin, context); + } + + public JTSMultiLineStringPath(Class type, String var) { + this(type, PathMetadataFactory.forVariable(var)); + } + + @Override + public PathMetadata getMetadata() { + return pathMixin.getMetadata(); + } + + @Override + public Path getRoot() { + return pathMixin.getRoot(); + } + + @Override + public AnnotatedElement getAnnotatedElement() { + return pathMixin.getAnnotatedElement(); + } + +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSMultiPointExpression.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSMultiPointExpression.java new file mode 100644 index 0000000000..b1b870c454 --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSMultiPointExpression.java @@ -0,0 +1,36 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial.locationtech.jts; + +import com.querydsl.core.types.Expression; +import org.locationtech.jts.geom.MultiPoint; + +/** + * A MultiPoint is a 0-dimensional GeometryCollection. The elements of a MultiPoint are restricted to Points. The + * Points are not connected or ordered in any semantically important way (see the discussion at + * GeometryCollection). + * + * @author tiwe + * + * @param + */ +public abstract class JTSMultiPointExpression extends JTSGeometryCollectionExpression { + + private static final long serialVersionUID = 7221702165705045865L; + + public JTSMultiPointExpression(Expression mixin) { + super(mixin); + } + +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSMultiPointPath.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSMultiPointPath.java new file mode 100644 index 0000000000..d15d6f73bb --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSMultiPointPath.java @@ -0,0 +1,88 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial.locationtech.jts; + +import com.querydsl.core.types.ExpressionUtils; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathImpl; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.PathMetadataFactory; +import com.querydsl.core.types.Visitor; +import org.locationtech.jts.geom.MultiPoint; + +import java.lang.reflect.AnnotatedElement; + +/** + * {@code JTSMultiPointPath} extends {@link JTSMultiPointExpression} to implement the + * {@link Path} interface + * + * @author tiwe + * + * @param + */ +public class JTSMultiPointPath extends JTSMultiPointExpression implements Path { + + private static final long serialVersionUID = 312776751843333543L; + + private final PathImpl pathMixin; + + @SuppressWarnings("unchecked") + public JTSMultiPointPath(Path parent, String property) { + this((Class) MultiPoint.class, parent, property); + } + + public JTSMultiPointPath(Class type, Path parent, String property) { + this(type, PathMetadataFactory.forProperty(parent, property)); + } + + @SuppressWarnings("unchecked") + public JTSMultiPointPath(PathMetadata metadata) { + this((Class) MultiPoint.class, metadata); + } + + public JTSMultiPointPath(Class type, PathMetadata metadata) { + super(ExpressionUtils.path(type, metadata)); + this.pathMixin = (PathImpl) mixin; + } + + @SuppressWarnings("unchecked") + public JTSMultiPointPath(String var) { + this((Class) MultiPoint.class, PathMetadataFactory.forVariable(var)); + } + + @Override + public final R accept(Visitor v, C context) { + return v.visit(pathMixin, context); + } + + public JTSMultiPointPath(Class type, String var) { + this(type, PathMetadataFactory.forVariable(var)); + } + + @Override + public PathMetadata getMetadata() { + return pathMixin.getMetadata(); + } + + @Override + public Path getRoot() { + return pathMixin.getRoot(); + } + + @Override + public AnnotatedElement getAnnotatedElement() { + return pathMixin.getAnnotatedElement(); + } + +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSMultiPolygonExpression.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSMultiPolygonExpression.java new file mode 100644 index 0000000000..3afe6171c9 --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSMultiPolygonExpression.java @@ -0,0 +1,34 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial.locationtech.jts; + +import com.querydsl.core.types.Expression; +import org.locationtech.jts.geom.MultiPolygon; + +/** + * A MultiPolygon is a MultiSurface whose elements are Polygons. + * + * @author tiwe + * + * @param + */ +public abstract class JTSMultiPolygonExpression extends JTSMultiSurfaceExpression { + + private static final long serialVersionUID = -2285946852207189655L; + + public JTSMultiPolygonExpression(Expression mixin) { + super(mixin); + } + +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSMultiPolygonPath.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSMultiPolygonPath.java new file mode 100644 index 0000000000..6ba7725907 --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSMultiPolygonPath.java @@ -0,0 +1,88 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial.locationtech.jts; + +import com.querydsl.core.types.ExpressionUtils; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathImpl; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.PathMetadataFactory; +import com.querydsl.core.types.Visitor; +import org.locationtech.jts.geom.MultiPolygon; + +import java.lang.reflect.AnnotatedElement; + +/** + * {@code JTSMultiPolygonPath} extends {@link JTSMultiPolygonExpression} to implement the + * {@link Path} interface + * + * @author tiwe + * + * @param + */ +public class JTSMultiPolygonPath extends JTSMultiPolygonExpression implements Path { + + private static final long serialVersionUID = 312776751843333543L; + + private final PathImpl pathMixin; + + @SuppressWarnings("unchecked") + public JTSMultiPolygonPath(Path parent, String property) { + this((Class) MultiPolygon.class, parent, property); + } + + public JTSMultiPolygonPath(Class type, Path parent, String property) { + this(type, PathMetadataFactory.forProperty(parent, property)); + } + + @SuppressWarnings("unchecked") + public JTSMultiPolygonPath(PathMetadata metadata) { + this((Class) MultiPolygon.class, metadata); + } + + public JTSMultiPolygonPath(Class type, PathMetadata metadata) { + super(ExpressionUtils.path(type, metadata)); + this.pathMixin = (PathImpl) mixin; + } + + @SuppressWarnings("unchecked") + public JTSMultiPolygonPath(String var) { + this((Class) MultiPolygon.class, PathMetadataFactory.forVariable(var)); + } + + @Override + public final R accept(Visitor v, C context) { + return v.visit(pathMixin, context); + } + + public JTSMultiPolygonPath(Class type, String var) { + this(type, PathMetadataFactory.forVariable(var)); + } + + @Override + public PathMetadata getMetadata() { + return pathMixin.getMetadata(); + } + + @Override + public Path getRoot() { + return pathMixin.getRoot(); + } + + @Override + public AnnotatedElement getAnnotatedElement() { + return pathMixin.getAnnotatedElement(); + } + +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSMultiSurfaceExpression.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSMultiSurfaceExpression.java new file mode 100644 index 0000000000..ac757157e4 --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSMultiSurfaceExpression.java @@ -0,0 +1,86 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial.locationtech.jts; + +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberExpression; +import com.querydsl.spatial.SpatialOps; +import org.locationtech.jts.geom.GeometryCollection; +import org.locationtech.jts.geom.Point; +import org.jetbrains.annotations.Nullable; + +/** + * A MultiSurface is a 2-dimensional GeometryCollection whose elements are Surfaces, all using coordinates from + * the same coordinate reference system. The geometric interiors of any two Surfaces in a MultiSurface may not + * intersect in the full coordinate system. The boundaries of any two coplanar elements in a MultiSurface may + * intersect, at most, at a finite number of Points. If they were to meet along a curve, they could be merged into a + * single surface. + * + * @author tiwe + * + * @param + */ +public abstract class JTSMultiSurfaceExpression extends JTSGeometryCollectionExpression { + + private static final long serialVersionUID = 4133386816772862010L; + + @Nullable + private transient volatile JTSPointExpression centroid, pointOnSurface; + + @Nullable + private transient volatile NumberExpression area; + + public JTSMultiSurfaceExpression(Expression mixin) { + super(mixin); + } + + /** + * The area of this MultiSurface, as measured in the spatial reference system of this MultiSurface. + * + * @return area + */ + public NumberExpression area() { + if (area == null) { + area = Expressions.numberOperation(Double.class, SpatialOps.AREA, mixin); + } + return area; + } + + /** + * The mathematical centroid for this MultiSurface. The result is not guaranteed to be on + * this MultiSurface. + * + * @return centroid + */ + public JTSPointExpression centroid() { + if (centroid == null) { + centroid = JTSGeometryExpressions.pointOperation(SpatialOps.CENTROID, mixin); + } + return centroid; + } + + /** + * A Point guaranteed to be on this MultiSurface. + * + * @return point on surface + */ + public JTSPointExpression pointOnSurface() { + if (pointOnSurface == null) { + pointOnSurface = JTSGeometryExpressions.pointOperation(SpatialOps.POINT_ON_SURFACE, mixin); + } + return pointOnSurface; + } + +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSPointExpression.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSPointExpression.java new file mode 100644 index 0000000000..a08616f58e --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSPointExpression.java @@ -0,0 +1,90 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial.locationtech.jts; + +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberExpression; +import com.querydsl.spatial.SpatialOps; +import org.locationtech.jts.geom.Point; +import org.jetbrains.annotations.Nullable; + +/** + * A Point is a 0-dimensional geometric object and represents a single location in coordinate space. A Point has an + * x-coordinate value, a y-coordinate value. If called for by the associated Spatial Reference System, it may also + * have coordinate values for z and m. + * + * @author tiwe + * + * @param + */ +public abstract class JTSPointExpression extends JTSGeometryExpression { + + private static final long serialVersionUID = -3549448861390349654L; + + @Nullable + private transient volatile NumberExpression x, y, z, m; + + public JTSPointExpression(Expression mixin) { + super(mixin); + } + + /** + * The x-coordinate value for this Point. + * + * @return x-coordinate + */ + public NumberExpression x() { + if (x == null) { + x = Expressions.numberOperation(Double.class, SpatialOps.X, mixin); + } + return x; + } + + /** + * The y-coordinate value for this Point. + * + * @return y-coordinate + */ + public NumberExpression y() { + if (y == null) { + y = Expressions.numberOperation(Double.class, SpatialOps.Y, mixin); + } + return y; + } + + /** + * The z-coordinate value for this Point, if it has one. Returns NIL otherwise. + * + * @return z-coordinate + */ + public NumberExpression z() { + if (z == null) { + z = Expressions.numberOperation(Double.class, SpatialOps.Z, mixin); + } + return z; + } + + /** + * The m-coordinate value for this Point, if it has one. Returns NIL otherwise. + * + * @return m-coordinate + */ + public NumberExpression m() { + if (m == null) { + m = Expressions.numberOperation(Double.class, SpatialOps.M, mixin); + } + return m; + } +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSPointOperation.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSPointOperation.java new file mode 100644 index 0000000000..d0c9e3b161 --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSPointOperation.java @@ -0,0 +1,69 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial.locationtech.jts; + +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.ExpressionUtils; +import com.querydsl.core.types.Operation; +import com.querydsl.core.types.OperationImpl; +import com.querydsl.core.types.Operator; +import com.querydsl.core.types.Visitor; +import org.locationtech.jts.geom.Point; + +import java.util.Arrays; +import java.util.List; + +/** + * {@code JTSPointOperation} extends {@link JTSPointExpression} to implement the + * {@link Operation} interface + * + * @author tiwe + * + * @param + */ +public class JTSPointOperation extends JTSPointExpression implements Operation { + + private static final long serialVersionUID = 3433471874808633698L; + + private final OperationImpl opMixin; + + protected JTSPointOperation(Class type, Operator op, Expression... args) { + this(type, op, Arrays.asList(args)); + } + + protected JTSPointOperation(Class type, Operator op, List> args) { + super(ExpressionUtils.operation(type, op, args)); + this.opMixin = (OperationImpl) mixin; + } + + @Override + public final R accept(Visitor v, C context) { + return v.visit(opMixin, context); + } + + @Override + public Expression getArg(int index) { + return opMixin.getArg(index); + } + + @Override + public List> getArgs() { + return opMixin.getArgs(); + } + + @Override + public Operator getOperator() { + return opMixin.getOperator(); + } +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSPointPath.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSPointPath.java new file mode 100644 index 0000000000..50d02a11f8 --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSPointPath.java @@ -0,0 +1,88 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial.locationtech.jts; + +import com.querydsl.core.types.ExpressionUtils; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathImpl; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.PathMetadataFactory; +import com.querydsl.core.types.Visitor; +import org.locationtech.jts.geom.Point; + +import java.lang.reflect.AnnotatedElement; + +/** + * {@code JTSPointPath} extends {@link JTSPointExpression} to implement the + * {@link Path} interface + * + * @author tiwe + * + * @param + */ +public class JTSPointPath extends JTSPointExpression implements Path { + + private static final long serialVersionUID = 312776751843333543L; + + private final PathImpl pathMixin; + + @SuppressWarnings("unchecked") + public JTSPointPath(Path parent, String property) { + this((Class) Point.class, parent, property); + } + + public JTSPointPath(Class type, Path parent, String property) { + this(type, PathMetadataFactory.forProperty(parent, property)); + } + + @SuppressWarnings("unchecked") + public JTSPointPath(PathMetadata metadata) { + this((Class) Point.class, metadata); + } + + public JTSPointPath(Class type, PathMetadata metadata) { + super(ExpressionUtils.path(type, metadata)); + this.pathMixin = (PathImpl) mixin; + } + + @SuppressWarnings("unchecked") + public JTSPointPath(String var) { + this((Class) Point.class, PathMetadataFactory.forVariable(var)); + } + + @Override + public final R accept(Visitor v, C context) { + return v.visit(pathMixin, context); + } + + public JTSPointPath(Class type, String var) { + this(type, PathMetadataFactory.forVariable(var)); + } + + @Override + public PathMetadata getMetadata() { + return pathMixin.getMetadata(); + } + + @Override + public Path getRoot() { + return pathMixin.getRoot(); + } + + @Override + public AnnotatedElement getAnnotatedElement() { + return pathMixin.getAnnotatedElement(); + } + +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSPolygonExpression.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSPolygonExpression.java new file mode 100644 index 0000000000..56ecea16e2 --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSPolygonExpression.java @@ -0,0 +1,81 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial.locationtech.jts; + +import com.querydsl.core.types.ConstantImpl; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberExpression; +import com.querydsl.spatial.SpatialOps; +import org.locationtech.jts.geom.LineString; +import org.locationtech.jts.geom.Polygon; +import org.jetbrains.annotations.Nullable; + +/** + * A Polygon is a planar Surface defined by 1 exterior boundary and 0 or more interior boundaries. Each interior + * boundary defines a hole in the Polygon. A Triangle is a polygon with 3 distinct, non-collinear vertices and no + * interior boundary. + * + * @author tiwe + * + * @param + */ +public abstract class JTSPolygonExpression extends JTSSurfaceExpression { + + private static final long serialVersionUID = 7544382956232485312L; + + @Nullable + private transient volatile NumberExpression numInteriorRing; + + @Nullable + private transient volatile JTSLineStringExpression exteriorRing; + + public JTSPolygonExpression(Expression mixin) { + super(mixin); + } + + /** + * Returns the exterior ring of this Polygon. + * + * @return exterior ring + */ + public JTSLineStringExpression exteriorRing() { + if (exteriorRing == null) { + exteriorRing = JTSGeometryExpressions.lineStringOperation(SpatialOps.EXTERIOR_RING, mixin); + } + return exteriorRing; + } + + /** + * Returns the number of interior rings in this Polygon. + * + * @return number of interior rings + */ + public NumberExpression numInteriorRing() { + if (numInteriorRing == null) { + numInteriorRing = Expressions.numberOperation(Integer.class, SpatialOps.NUM_INTERIOR_RING, mixin); + } + return numInteriorRing; + } + + /** + * Returns the N th interior ring for this Polygon as a LineString. + * + * @param idx one based index + * @return interior ring at index + */ + public JTSLineStringExpression interiorRingN(int idx) { + return JTSGeometryExpressions.lineStringOperation(SpatialOps.INTERIOR_RINGN, mixin, ConstantImpl.create(idx)); + } +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSPolygonOperation.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSPolygonOperation.java new file mode 100644 index 0000000000..2087965968 --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSPolygonOperation.java @@ -0,0 +1,69 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial.locationtech.jts; + +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.ExpressionUtils; +import com.querydsl.core.types.Operation; +import com.querydsl.core.types.OperationImpl; +import com.querydsl.core.types.Operator; +import com.querydsl.core.types.Visitor; +import org.locationtech.jts.geom.Polygon; + +import java.util.Arrays; +import java.util.List; + +/** + * {@code JTSPolygonOperation} extends {@link JTSPolygonExpression} to implement the + * {@link Operation} interface + * + * @author tiwe + * + * @param + */ +public class JTSPolygonOperation extends JTSPolygonExpression implements Operation { + + private static final long serialVersionUID = 3433471874808633698L; + + private final OperationImpl opMixin; + + protected JTSPolygonOperation(Class type, Operator op, Expression... args) { + this(type, op, Arrays.asList(args)); + } + + protected JTSPolygonOperation(Class type, Operator op, List> args) { + super(ExpressionUtils.operation(type, op, args)); + this.opMixin = (OperationImpl) mixin; + } + + @Override + public final R accept(Visitor v, C context) { + return v.visit(opMixin, context); + } + + @Override + public Expression getArg(int index) { + return opMixin.getArg(index); + } + + @Override + public List> getArgs() { + return opMixin.getArgs(); + } + + @Override + public Operator getOperator() { + return opMixin.getOperator(); + } +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSPolygonPath.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSPolygonPath.java new file mode 100644 index 0000000000..9d3eb1d341 --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSPolygonPath.java @@ -0,0 +1,88 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial.locationtech.jts; + +import com.querydsl.core.types.ExpressionUtils; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathImpl; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.PathMetadataFactory; +import com.querydsl.core.types.Visitor; +import org.locationtech.jts.geom.Polygon; + +import java.lang.reflect.AnnotatedElement; + +/** + * {@code JTSPolygonPath} extends {@link JTSPolygonExpression} to implement the + * {@link Path} interface + * + * @author tiwe + * + * @param + */ +public class JTSPolygonPath extends JTSPolygonExpression implements Path { + + private static final long serialVersionUID = 312776751843333543L; + + private final PathImpl pathMixin; + + @SuppressWarnings("unchecked") + public JTSPolygonPath(Path parent, String property) { + this((Class) Polygon.class, parent, property); + } + + public JTSPolygonPath(Class type, Path parent, String property) { + this(type, PathMetadataFactory.forProperty(parent, property)); + } + + @SuppressWarnings("unchecked") + public JTSPolygonPath(PathMetadata metadata) { + this((Class) Polygon.class, metadata); + } + + public JTSPolygonPath(Class type, PathMetadata metadata) { + super(ExpressionUtils.path(type, metadata)); + this.pathMixin = (PathImpl) mixin; + } + + @SuppressWarnings("unchecked") + public JTSPolygonPath(String var) { + this((Class) Polygon.class, PathMetadataFactory.forVariable(var)); + } + + @Override + public final R accept(Visitor v, C context) { + return v.visit(pathMixin, context); + } + + public JTSPolygonPath(Class type, String var) { + this(type, PathMetadataFactory.forVariable(var)); + } + + @Override + public PathMetadata getMetadata() { + return pathMixin.getMetadata(); + } + + @Override + public Path getRoot() { + return pathMixin.getRoot(); + } + + @Override + public AnnotatedElement getAnnotatedElement() { + return pathMixin.getAnnotatedElement(); + } + +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSSurfaceExpression.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSSurfaceExpression.java new file mode 100644 index 0000000000..e0358415f9 --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/JTSSurfaceExpression.java @@ -0,0 +1,82 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.spatial.locationtech.jts; + +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberExpression; +import com.querydsl.spatial.SpatialOps; +import org.locationtech.jts.geom.Geometry; +import org.locationtech.jts.geom.Point; +import org.jetbrains.annotations.Nullable; + +/** + * A Surface is a 2-dimensional geometric object. + * + * @author tiwe + * + * @param + */ +public abstract class JTSSurfaceExpression extends JTSGeometryExpression { + + private static final long serialVersionUID = 3534197011234723698L; + + @Nullable + private transient volatile JTSPointExpression centroid, pointOnSurface; + + @Nullable + private transient volatile NumberExpression area; + + public JTSSurfaceExpression(Expression mixin) { + super(mixin); + } + + /** + * The area of this Surface, as measured in the spatial reference system of this Surface. + * + * @return area + */ + public NumberExpression area() { + if (area == null) { + area = Expressions.numberOperation(Double.class, SpatialOps.AREA, mixin); + } + return area; + } + + /** + * The mathematical centroid for this Surface as a Point. The result is not guaranteed to + * be on this Surface. + * + * @return centroid + */ + public JTSPointExpression centroid() { + if (centroid == null) { + centroid = JTSGeometryExpressions.pointOperation(SpatialOps.CENTROID, mixin); + } + return centroid; + } + + /** + * A Point guaranteed to be on this Surface. + * + * @return point on surface + */ + public JTSPointExpression pointOnSurface() { + if (pointOnSurface == null) { + pointOnSurface = JTSGeometryExpressions.pointOperation(SpatialOps.POINT_ON_SURFACE, mixin); + } + return pointOnSurface; + } + +} diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/package-info.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/package-info.java new file mode 100644 index 0000000000..758d3e3f61 --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/locationtech/jts/package-info.java @@ -0,0 +1,18 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ + +/** + * Spatial types using JTS + */ +package com.querydsl.spatial.locationtech.jts; diff --git a/querydsl-spatial/src/main/java/com/querydsl/spatial/package-info.java b/querydsl-spatial/src/main/java/com/querydsl/spatial/package-info.java new file mode 100644 index 0000000000..e1c782393e --- /dev/null +++ b/querydsl-spatial/src/main/java/com/querydsl/spatial/package-info.java @@ -0,0 +1,18 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ + +/** + * Spatial types using Geolatte + */ +package com.querydsl.spatial; diff --git a/querydsl-spatial/src/main/resources/META-INF/services/com.querydsl.codegen.Extension b/querydsl-spatial/src/main/resources/META-INF/services/com.querydsl.codegen.Extension new file mode 100644 index 0000000000..660cfe9b1a --- /dev/null +++ b/querydsl-spatial/src/main/resources/META-INF/services/com.querydsl.codegen.Extension @@ -0,0 +1 @@ +com.querydsl.spatial.apt.SpatialSupport \ No newline at end of file diff --git a/querydsl-spatial/src/test/java/com/mysema/query/spatial/HibernateSpatialSupport.java b/querydsl-spatial/src/test/java/com/mysema/query/spatial/HibernateSpatialSupport.java deleted file mode 100644 index 8ae00df5de..0000000000 --- a/querydsl-spatial/src/test/java/com/mysema/query/spatial/HibernateSpatialSupport.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2014, Mysema Ltd - * - * 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. - */ -package com.mysema.query.spatial; - -import com.google.common.collect.Maps; -import com.mysema.query.types.Operator; - -import java.util.Map; - -public class HibernateSpatialSupport { - - public static Map, String> getSpatialOps(String prefix, boolean asFunction) { - Map, String> ops = Maps.newHashMap(); - ops.put(SpatialOps.DIMENSION, "dimension({0})"); - ops.put(SpatialOps.GEOMETRY_TYPE, "geometrytype({0}, {1})"); - ops.put(SpatialOps.SRID, "srid({0})"); - ops.put(SpatialOps.ENVELOPE, "envelope({0})"); - ops.put(SpatialOps.AS_TEXT, "astext({0})"); - ops.put(SpatialOps.AS_BINARY, "asbinary({0})"); - ops.put(SpatialOps.IS_EMPTY, "isempty({0})"); - ops.put(SpatialOps.IS_SIMPLE, "issimple({0})"); - ops.put(SpatialOps.BOUNDARY, "boundary({0})"); - - ops.put(SpatialOps.EQUALS, "equals({0}, {1})"); - ops.put(SpatialOps.DISJOINT, "disjoint({0}, {1})"); - ops.put(SpatialOps.INTERSECTS, "intersects({0}, {1})"); - ops.put(SpatialOps.TOUCHES, "touches({0}, {1})"); - ops.put(SpatialOps.CROSSES, "crosses({0}, {1})"); - ops.put(SpatialOps.WITHIN, "within({0}, {1})"); - ops.put(SpatialOps.CONTAINS, "contains({0}, {1})"); - ops.put(SpatialOps.OVERLAPS, "overlaps({0}, {1})"); - ops.put(SpatialOps.RELATE, "relate({0}, {1}, {2})"); - - ops.put(SpatialOps.DISTANCE, "distance({0}, {1})"); - ops.put(SpatialOps.BUFFER, "buffer({0}, {1})"); - ops.put(SpatialOps.CONVEXHULL, "convexhull({0})"); - ops.put(SpatialOps.INTERSECTION, "intersection({0}, {1})"); - ops.put(SpatialOps.UNION, "geomunion({0}, {1})"); - ops.put(SpatialOps.DIFFERENCE, "difference({0}, {1})"); - ops.put(SpatialOps.SYMDIFFERENCE, "symdifference({0}, {1})"); - // dwithin({0}, {1}, 2) - ops.put(SpatialOps.TRANSFORM, "transform({0}, {1})"); - // extent({0}) - return ops; - } -} diff --git a/querydsl-spatial/src/test/java/com/mysema/query/spatial/path/GeometryPathTest.java b/querydsl-spatial/src/test/java/com/mysema/query/spatial/path/GeometryPathTest.java deleted file mode 100644 index d1f39c8aa0..0000000000 --- a/querydsl-spatial/src/test/java/com/mysema/query/spatial/path/GeometryPathTest.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.mysema.query.spatial.path; - -import static org.junit.Assert.assertEquals; - -import org.geolatte.geom.Geometry; -import org.geolatte.geom.GeometryCollection; -import org.geolatte.geom.LineString; -import org.geolatte.geom.LinearRing; -import org.geolatte.geom.MultiLineString; -import org.geolatte.geom.MultiPoint; -import org.geolatte.geom.MultiPolygon; -import org.geolatte.geom.Point; -import org.geolatte.geom.PolyHedralSurface; -import org.geolatte.geom.Polygon; -import org.junit.Test; - -public class GeometryPathTest { - - @Test - public void Convert() { - GeometryPath geometry = new GeometryPath("geometry"); - assertEquals(new GeometryCollectionPath("geometry"), geometry.asCollection()); - assertEquals(new LinearRingPath("geometry"), geometry.asLinearRing()); - assertEquals(new LineStringPath("geometry"), geometry.asLineString()); - assertEquals(new MultiLineStringPath("geometry"), geometry.asMultiLineString()); - assertEquals(new MultiPointPath("geometry"), geometry.asMultiPoint()); - assertEquals(new MultiPolygonPath("geometry"), geometry.asMultiPolygon()); - assertEquals(new PointPath("geometry"), geometry.asPoint()); - assertEquals(new PolygonPath("geometry"), geometry.asPolygon()); - assertEquals(new PolyhedralSurfacePath("geometry"), geometry.asPolygHedralSurface()); - } -} diff --git a/querydsl-spatial/src/test/java/com/querydsl/spatial/GeometryEntity.java b/querydsl-spatial/src/test/java/com/querydsl/spatial/GeometryEntity.java new file mode 100644 index 0000000000..2cc1e2e633 --- /dev/null +++ b/querydsl-spatial/src/test/java/com/querydsl/spatial/GeometryEntity.java @@ -0,0 +1,28 @@ +package com.querydsl.spatial; + +import org.geolatte.geom.*; + +import com.querydsl.core.annotations.QueryEntity; + +@QueryEntity +public class GeometryEntity { + + Geometry geometry; + + GeometryCollection geometryCollection; + + LinearRing linearRing; + + LineString lineString; + + MultiLineString multiLineString; + + MultiPoint multiPoint; + + MultiPolygon multiPolygon; + + Point point; + + Polygon polygon; + +} diff --git a/querydsl-spatial/src/test/java/com/querydsl/spatial/GeometryPathTest.java b/querydsl-spatial/src/test/java/com/querydsl/spatial/GeometryPathTest.java new file mode 100644 index 0000000000..6fbaea1f00 --- /dev/null +++ b/querydsl-spatial/src/test/java/com/querydsl/spatial/GeometryPathTest.java @@ -0,0 +1,22 @@ +package com.querydsl.spatial; + +import static org.junit.Assert.assertEquals; + +import org.geolatte.geom.*; +import org.junit.Test; + +public class GeometryPathTest { + + @Test + public void convert() { + GeometryPath geometry = new GeometryPath("geometry"); + assertEquals(new GeometryCollectionPath("geometry"), geometry.asCollection()); + assertEquals(new LinearRingPath("geometry"), geometry.asLinearRing()); + assertEquals(new LineStringPath("geometry"), geometry.asLineString()); + assertEquals(new MultiLineStringPath("geometry"), geometry.asMultiLineString()); + assertEquals(new MultiPointPath("geometry"), geometry.asMultiPoint()); + assertEquals(new MultiPolygonPath("geometry"), geometry.asMultiPolygon()); + assertEquals(new PointPath("geometry"), geometry.asPoint()); + assertEquals(new PolygonPath("geometry"), geometry.asPolygon()); + } +} diff --git a/querydsl-spatial/src/test/java/com/querydsl/spatial/hibernate/HibernateSpatialSupportTest.java b/querydsl-spatial/src/test/java/com/querydsl/spatial/hibernate/HibernateSpatialSupportTest.java new file mode 100644 index 0000000000..7723637660 --- /dev/null +++ b/querydsl-spatial/src/test/java/com/querydsl/spatial/hibernate/HibernateSpatialSupportTest.java @@ -0,0 +1,21 @@ +package com.querydsl.spatial.hibernate; + +import static org.junit.Assert.assertTrue; + +import java.util.Map; + +import org.junit.Test; + +import com.querydsl.core.types.Operator; +import com.querydsl.spatial.SpatialOps; + +public class HibernateSpatialSupportTest { + + @Test + public void allMapped() { + Map mapping = HibernateSpatialSupport.getSpatialOps(); + for (Operator operator : SpatialOps.values()) { + assertTrue(operator + " missing", mapping.containsKey(operator)); + } + } +} diff --git a/querydsl-spatial/src/test/java/com/querydsl/spatial/jts/JTSGeometryEntity.java b/querydsl-spatial/src/test/java/com/querydsl/spatial/jts/JTSGeometryEntity.java new file mode 100644 index 0000000000..4aa6d87ae4 --- /dev/null +++ b/querydsl-spatial/src/test/java/com/querydsl/spatial/jts/JTSGeometryEntity.java @@ -0,0 +1,27 @@ +package com.querydsl.spatial.jts; + +import com.querydsl.core.annotations.QueryEntity; +import com.vividsolutions.jts.geom.*; + +@QueryEntity +public class JTSGeometryEntity { + + Geometry geometry; + + GeometryCollection geometryCollection; + + LinearRing linearRing; + + LineString lineString; + + MultiLineString multiLineString; + + MultiPoint multiPoint; + + MultiPolygon multiPolygon; + + Point point; + + Polygon polygon; + +} diff --git a/querydsl-spatial/src/test/java/com/querydsl/spatial/jts/JTSGeometryPathTest.java b/querydsl-spatial/src/test/java/com/querydsl/spatial/jts/JTSGeometryPathTest.java new file mode 100644 index 0000000000..59894d49d1 --- /dev/null +++ b/querydsl-spatial/src/test/java/com/querydsl/spatial/jts/JTSGeometryPathTest.java @@ -0,0 +1,23 @@ +package com.querydsl.spatial.jts; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import com.vividsolutions.jts.geom.*; + +public class JTSGeometryPathTest { + + @Test + public void convert() { + JTSGeometryPath geometry = new JTSGeometryPath("geometry"); + assertEquals(new JTSGeometryCollectionPath("geometry"), geometry.asCollection()); + assertEquals(new JTSLinearRingPath("geometry"), geometry.asLinearRing()); + assertEquals(new JTSLineStringPath("geometry"), geometry.asLineString()); + assertEquals(new JTSMultiLineStringPath("geometry"), geometry.asMultiLineString()); + assertEquals(new JTSMultiPointPath("geometry"), geometry.asMultiPoint()); + assertEquals(new JTSMultiPolygonPath("geometry"), geometry.asMultiPolygon()); + assertEquals(new JTSPointPath("geometry"), geometry.asPoint()); + assertEquals(new JTSPolygonPath("geometry"), geometry.asPolygon()); + } +} diff --git a/querydsl-spatial/template.mf b/querydsl-spatial/template.mf deleted file mode 100644 index 72e7150306..0000000000 --- a/querydsl-spatial/template.mf +++ /dev/null @@ -1,9 +0,0 @@ -Bundle-SymbolicName: com.mysema.querydsl.core -Bundle-Name: Querydsl Spatial -Bundle-Vendor: Mysema -Bundle-ManifestVersion: 2 -Import-Template: - javax.annotation.*;version="0", - org.geolatte.geom.*;version="0.11", - com.mysema.query.*;version="${project.version}", - com.google.common.*;version="${guava.version}" diff --git a/querydsl-sql-codegen/pom.xml b/querydsl-sql-codegen/pom.xml index cb5cb44fe1..3f109c5084 100644 --- a/querydsl-sql-codegen/pom.xml +++ b/querydsl-sql-codegen/pom.xml @@ -1,50 +1,40 @@ - + 4.0.0 - com.mysema.querydsl + com.querydsl querydsl-root - 3.4.1.BUILD-SNAPSHOT - ../querydsl-root/pom.xml + 5.1.0 + ../pom.xml - com.mysema.querydsl + com.querydsl querydsl-sql-codegen Querydsl - SQL codegen support SQL codegen support for Querydsl jar - 1.8.1 + 1.10.12 - com.mysema.querydsl - querydsl-codegen - ${project.version} + org.jetbrains + annotations + provided - com.mysema.querydsl - querydsl-sql + com.querydsl + querydsl-codegen ${project.version} - com.mysema.querydsl - querydsl-spatial + com.querydsl + querydsl-sql ${project.version} - - - - org.slf4j - slf4j-api - - org.slf4j - slf4j-log4j12 - provided - @@ -56,7 +46,13 @@ - com.mysema.querydsl + joda-time + joda-time + ${jodatime.version} + test + + + com.querydsl querydsl-sql ${project.version} test @@ -75,6 +71,12 @@ ${derby.version} test + + org.apache.derby + derbytools + ${derby.version} + test + mysql mysql-connector-java @@ -86,30 +88,59 @@ postgresql ${postgresql.version} test + + + org.slf4j + slf4j-simple + + - com.oracle - ojdbc6 - 11.1.0.7.0 + com.oracle.database.jdbc + ojdbc8 + ${oracle.version} test - net.sourceforge.jtds - jtds - ${jtds.version} + com.microsoft.sqlserver + mssql-jdbc + ${mssql.version} test com.h2database h2 - ${h2.version} test - org.opengeo - geodb - 0.7 + org.orbisgis + h2gis + ${h2gis.version} + test + + + log4j + log4j + + + slf4j-api + org.slf4j + + + + + + javax.validation + validation-api + provided + true + + + + org.slf4j + slf4j-api + 1.7.35 test @@ -121,7 +152,7 @@ - com.mysema.querydsl + com.querydsl querydsl-core ${project.version} test @@ -139,8 +170,8 @@ - com.springsource.bundlor - com.springsource.bundlor.maven + org.apache.felix + maven-bundle-plugin @@ -149,7 +180,7 @@ src/main/assembly.xml - ../querydsl-root/target/dist + ../target/dist @@ -164,6 +195,13 @@ + + + + com.querydsl.sql.codegen + + + maven-source-plugin @@ -191,7 +229,7 @@ + + joda-time + joda-time + ${jodatime.version} + test + + + cglib + cglib + ${cglib.version} + test + + + org.hsqldb + hsqldb + ${hsqldb.version} + test + + + + com.ibm.db2 + jcc + ${db2.version} + test + + + org.apache.derby + derby + ${derby.version} + test + + + org.apache.derby + derbytools + ${derby.version} + test + + + mysql + mysql-connector-java + ${mysql.version} + test + + + org.postgresql + postgresql + ${postgresql.version} + test + + + org.slf4j + slf4j-simple + + + + + org.postgis + postgis-jdbc + 1.3.3 + compile + true + + + com.oracle.database.jdbc + ojdbc8 + ${oracle.version} + test + + + oracle + sdoapi + 11.2.0 + test + + + com.microsoft.sqlserver + mssql-jdbc + ${mssql.version} + test + + + com.h2database + h2 + test + + + org.orbisgis + h2gis + ${h2gis.version} + test + + + log4j + log4j + + + jts-core + org.locationtech.jts + + + slf4j-api + org.slf4j + + + + + + com.github.jinahya + cubrid-jdbc-driver-${cubrid.version} + 1.0.0 + test + + + org.firebirdsql.jdbc + jaybird + ${firebird.version} + test + + + + org.xerial + sqlite-jdbc + ${sqlite.version} + test + + + + com.querydsl + querydsl-core + ${project.version} + test + test-jar + + + com.querydsl + querydsl-sql + ${project.version} + test + test-jar + + + + + jdepend + jdepend + 2.9.1 + test + + + + + org.jvnet.hudson + annotation-indexer + 1.2 + true + + + + + + + org.apache.felix + maven-bundle-plugin + + + + org.apache.maven.plugins + maven-jar-plugin + + + test-jar + + test-jar + + + + + + + com.querydsl.sql.spatial + + + + + + maven-source-plugin + + + package + + test-jar + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + + derby.stream.error.file + target/derby.log + + + + + + + + + + + teradata + + + com.teradata + teradata-jdbc + ${teradata.version} + test + + + com.teradata + teradata-config + ${teradata.version} + test + + + + + java-11 + + [11,) + + + + javax.annotation + javax.annotation-api + 1.3.2 + provided + + + + + java-21 + + [21,) + + + + cglib + cglib + ${cglib.version} + test + + + org.ow2.asm + asm + + + org.ow2.asm + asm-commons + + + + + org.ow2.asm + asm + ${asm.version} + test + + + org.ow2.asm + asm-commons + ${asm.version} + test + + + + + + + + + datanucleus + https://www.datanucleus.org/downloads/maven2 + + + + diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/spatial/GeoDBTemplates.java b/querydsl-sql-spatial/src/main/java/com/querydsl/sql/spatial/GeoDBTemplates.java similarity index 75% rename from querydsl-sql/src/main/java/com/mysema/query/sql/spatial/GeoDBTemplates.java rename to querydsl-sql-spatial/src/main/java/com/querydsl/sql/spatial/GeoDBTemplates.java index ba3657e2d6..eaa504826b 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/spatial/GeoDBTemplates.java +++ b/querydsl-sql-spatial/src/main/java/com/querydsl/sql/spatial/GeoDBTemplates.java @@ -1,5 +1,5 @@ /* - * Copyright 2014, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,19 +11,22 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql.spatial; +package com.querydsl.sql.spatial; -import com.mysema.query.sql.H2Templates; -import com.mysema.query.sql.SQLTemplates; +import com.querydsl.sql.H2Templates; +import com.querydsl.sql.SQLTemplates; /** - * GeoDBTemplates is a spatial enabled SQL dialect for GeoDB + * {@code GeoDBTemplates} is a spatial enabled SQL dialect for GeoDB * * @author tiwe * */ public class GeoDBTemplates extends H2Templates { + @SuppressWarnings("FieldNameHidesFieldInSuperclass") //Intentional + public static final GeoDBTemplates DEFAULT = new GeoDBTemplates(); + public static Builder builder() { return new Builder() { @Override diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/spatial/GeoDBWkbType.java b/querydsl-sql-spatial/src/main/java/com/querydsl/sql/spatial/GeoDBWkbType.java similarity index 79% rename from querydsl-sql/src/main/java/com/mysema/query/sql/spatial/GeoDBWkbType.java rename to querydsl-sql-spatial/src/main/java/com/querydsl/sql/spatial/GeoDBWkbType.java index c426aef753..d0a8735445 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/spatial/GeoDBWkbType.java +++ b/querydsl-sql-spatial/src/main/java/com/querydsl/sql/spatial/GeoDBWkbType.java @@ -1,5 +1,5 @@ /* - * Copyright 2014, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,15 +11,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql.spatial; +package com.querydsl.sql.spatial; -import javax.annotation.Nullable; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Types; -import com.mysema.query.sql.types.AbstractType; +import org.jetbrains.annotations.Nullable; + import org.geolatte.geom.ByteBuffer; import org.geolatte.geom.ByteOrder; import org.geolatte.geom.Geometry; @@ -28,17 +28,15 @@ import org.geolatte.geom.codec.WkbEncoder; import org.geolatte.geom.codec.Wkt; -/** - * @author tiwe - * - */ -public class GeoDBWkbType extends AbstractType { +import com.querydsl.sql.types.AbstractType; + +class GeoDBWkbType extends AbstractType { public static final GeoDBWkbType DEFAULT = new GeoDBWkbType(); private final ByteOrder byteOrder = ByteOrder.NDR; - public GeoDBWkbType() { + GeoDBWkbType() { super(Types.BLOB); } @@ -59,7 +57,7 @@ public Geometry getValue(ResultSet rs, int startIndex) throws SQLException { } else { wkb = bytes; } - WkbDecoder decoder = Wkb.newWkbDecoder(Wkb.Dialect.POSTGIS_EWKB_1); + WkbDecoder decoder = Wkb.newDecoder(Wkb.Dialect.POSTGIS_EWKB_1); return decoder.decode(ByteBuffer.from(wkb)); } else { return null; @@ -68,18 +66,18 @@ public Geometry getValue(ResultSet rs, int startIndex) throws SQLException { @Override public void setValue(PreparedStatement st, int startIndex, Geometry value) throws SQLException { - WkbEncoder encoder = Wkb.newWkbEncoder(Wkb.Dialect.POSTGIS_EWKB_1); + WkbEncoder encoder = Wkb.newEncoder(Wkb.Dialect.POSTGIS_EWKB_1); ByteBuffer buffer = encoder.encode(value, byteOrder); st.setBytes(startIndex, buffer.toByteArray()); } @Override public String getLiteral(Geometry geometry) { - String str = Wkt.newWktEncoder(Wkt.Dialect.POSTGIS_EWKT_1).encode(geometry); + String str = Wkt.newEncoder(Wkt.Dialect.POSTGIS_EWKT_1).encode(geometry); if (geometry.getSRID() > -1) { return "ST_GeomFromText('" + str + "', " + geometry.getSRID() + ")"; } else { - return "ST_GeomFromText('" + str + "')"; + return "ST_GeomFromText('" + str + "', -1)"; } } diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/spatial/GeometryWkbType.java b/querydsl-sql-spatial/src/main/java/com/querydsl/sql/spatial/GeometryWkbType.java similarity index 77% rename from querydsl-sql/src/main/java/com/mysema/query/sql/spatial/GeometryWkbType.java rename to querydsl-sql-spatial/src/main/java/com/querydsl/sql/spatial/GeometryWkbType.java index f5856567a3..88e87f4ee5 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/spatial/GeometryWkbType.java +++ b/querydsl-sql-spatial/src/main/java/com/querydsl/sql/spatial/GeometryWkbType.java @@ -1,5 +1,5 @@ /* - * Copyright 2014, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,15 +11,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql.spatial; +package com.querydsl.sql.spatial; -import javax.annotation.Nullable; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Types; -import com.mysema.query.sql.types.AbstractType; +import org.jetbrains.annotations.Nullable; + import org.geolatte.geom.ByteBuffer; import org.geolatte.geom.ByteOrder; import org.geolatte.geom.Geometry; @@ -28,11 +28,9 @@ import org.geolatte.geom.codec.WkbEncoder; import org.geolatte.geom.codec.Wkt; -/** - * @author tiwe - * - */ -public class GeometryWkbType extends AbstractType { +import com.querydsl.sql.types.AbstractType; + +class GeometryWkbType extends AbstractType { public static final GeometryWkbType NDR = new GeometryWkbType(ByteOrder.NDR); @@ -40,7 +38,7 @@ public class GeometryWkbType extends AbstractType { private final ByteOrder byteOrder; - public GeometryWkbType(ByteOrder byteOrder) { + GeometryWkbType(ByteOrder byteOrder) { super(Types.OTHER); this.byteOrder = byteOrder; } @@ -55,7 +53,7 @@ public Class getReturnedClass() { public Geometry getValue(ResultSet rs, int startIndex) throws SQLException { byte[] bytes = rs.getBytes(startIndex); if (bytes != null) { - WkbDecoder decoder = Wkb.newWkbDecoder(Wkb.Dialect.POSTGIS_EWKB_1); + WkbDecoder decoder = Wkb.newDecoder(Wkb.Dialect.POSTGIS_EWKB_1); return decoder.decode(ByteBuffer.from(bytes)); } else { return null; @@ -64,15 +62,14 @@ public Geometry getValue(ResultSet rs, int startIndex) throws SQLException { @Override public void setValue(PreparedStatement st, int startIndex, Geometry value) throws SQLException { - WkbEncoder encoder = Wkb.newWkbEncoder(Wkb.Dialect.POSTGIS_EWKB_1); + WkbEncoder encoder = Wkb.newEncoder(Wkb.Dialect.POSTGIS_EWKB_1); ByteBuffer buffer = encoder.encode(value, byteOrder); st.setBytes(startIndex, buffer.toByteArray()); } @Override public String getLiteral(Geometry geometry) { - String str = Wkt.newWktEncoder(Wkt.Dialect.POSTGIS_EWKT_1).encode(geometry); - return "'" + str + "'"; + return "'" + Wkt.newEncoder(Wkt.Dialect.POSTGIS_EWKT_1).encode(geometry) + "'"; } } diff --git a/querydsl-sql-spatial/src/main/java/com/querydsl/sql/spatial/GeometryWktClobType.java b/querydsl-sql-spatial/src/main/java/com/querydsl/sql/spatial/GeometryWktClobType.java new file mode 100644 index 0000000000..c8023fe48b --- /dev/null +++ b/querydsl-sql-spatial/src/main/java/com/querydsl/sql/spatial/GeometryWktClobType.java @@ -0,0 +1,61 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.spatial; + +import java.sql.*; + +import org.jetbrains.annotations.Nullable; + +import org.geolatte.geom.Geometry; +import org.geolatte.geom.codec.Wkt; + +import com.querydsl.sql.types.AbstractType; + +class GeometryWktClobType extends AbstractType { + + public static final GeometryWktClobType DEFAULT = new GeometryWktClobType(); + + GeometryWktClobType() { + super(Types.CLOB); + } + + @Override + public Class getReturnedClass() { + return Geometry.class; + } + + @Override + @Nullable + public Geometry getValue(ResultSet rs, int startIndex) throws SQLException { + Clob clob = rs.getClob(startIndex); + String str = clob != null ? clob.getSubString(1, (int) clob.length()) : null; + if (str != null) { + return Wkt.newDecoder(Wkt.Dialect.POSTGIS_EWKT_1).decode(str); + } else { + return null; + } + } + + @Override + public void setValue(PreparedStatement st, int startIndex, Geometry value) throws SQLException { + String str = Wkt.newEncoder(Wkt.Dialect.POSTGIS_EWKT_1).encode(value); + st.setString(startIndex, str); + } + + @Override + public String getLiteral(Geometry geometry) { + return "'" + Wkt.newEncoder(Wkt.Dialect.POSTGIS_EWKT_1).encode(geometry) + "'"; + } + +} diff --git a/querydsl-sql-spatial/src/main/java/com/querydsl/sql/spatial/GeometryWktType.java b/querydsl-sql-spatial/src/main/java/com/querydsl/sql/spatial/GeometryWktType.java new file mode 100644 index 0000000000..f32bdcfd56 --- /dev/null +++ b/querydsl-sql-spatial/src/main/java/com/querydsl/sql/spatial/GeometryWktType.java @@ -0,0 +1,62 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.spatial; + +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Types; + +import org.jetbrains.annotations.Nullable; + +import org.geolatte.geom.Geometry; +import org.geolatte.geom.codec.Wkt; + +import com.querydsl.sql.types.AbstractType; + +class GeometryWktType extends AbstractType { + + public static final GeometryWktType DEFAULT = new GeometryWktType(); + + GeometryWktType() { + super(Types.VARCHAR); + } + + @Override + public Class getReturnedClass() { + return Geometry.class; + } + + @Override + @Nullable + public Geometry getValue(ResultSet rs, int startIndex) throws SQLException { + String str = rs.getString(startIndex); + if (str != null) { + return Wkt.newDecoder(Wkt.Dialect.POSTGIS_EWKT_1).decode(str); + } else { + return null; + } + } + + @Override + public void setValue(PreparedStatement st, int startIndex, Geometry value) throws SQLException { + String str = Wkt.newEncoder(Wkt.Dialect.POSTGIS_EWKT_1).encode(value); + st.setString(startIndex, str); + } + + @Override + public String getLiteral(Geometry geometry) { + return "'" + Wkt.newEncoder(Wkt.Dialect.POSTGIS_EWKT_1).encode(geometry) + "'"; + } +} diff --git a/querydsl-sql-spatial/src/main/java/com/querydsl/sql/spatial/H2GISTemplates.java b/querydsl-sql-spatial/src/main/java/com/querydsl/sql/spatial/H2GISTemplates.java new file mode 100644 index 0000000000..3e7934bd14 --- /dev/null +++ b/querydsl-sql-spatial/src/main/java/com/querydsl/sql/spatial/H2GISTemplates.java @@ -0,0 +1,53 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.spatial; + +import com.querydsl.sql.H2Templates; +import com.querydsl.sql.SQLTemplates; + +/** + * {@code GeoDBTemplates} is a spatial enabled SQL dialect for GeoDB + * + * @author tiwe + * + */ +public class H2GISTemplates extends H2Templates { + + @SuppressWarnings("FieldNameHidesFieldInSuperclass") //Intentional + public static final H2GISTemplates DEFAULT = new H2GISTemplates(); + + public static Builder builder() { + return new Builder() { + @Override + protected SQLTemplates build(char escape, boolean quote) { + return new H2GISTemplates(escape, quote); + } + }; + } + + public H2GISTemplates() { + this('\\', false); + } + + public H2GISTemplates(boolean quote) { + this('\\', quote); + } + + public H2GISTemplates(char escape, boolean quote) { + super(escape, quote); + addCustomType(H2GISWkbType.DEFAULT); + add(SpatialTemplatesSupport.getSpatialOps(true)); + } + +} \ No newline at end of file diff --git a/querydsl-sql-spatial/src/main/java/com/querydsl/sql/spatial/H2GISWkbType.java b/querydsl-sql-spatial/src/main/java/com/querydsl/sql/spatial/H2GISWkbType.java new file mode 100644 index 0000000000..0859e59e03 --- /dev/null +++ b/querydsl-sql-spatial/src/main/java/com/querydsl/sql/spatial/H2GISWkbType.java @@ -0,0 +1,82 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.spatial; + +import com.querydsl.sql.types.AbstractType; +import org.geolatte.geom.ByteBuffer; +import org.geolatte.geom.ByteOrder; +import org.geolatte.geom.Geometry; +import org.geolatte.geom.codec.Wkb; +import org.geolatte.geom.codec.WkbDecoder; +import org.geolatte.geom.codec.WkbEncoder; +import org.geolatte.geom.codec.Wkt; +import org.jetbrains.annotations.Nullable; + +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Types; + +class H2GISWkbType extends AbstractType { + + public static final H2GISWkbType DEFAULT = new H2GISWkbType(); + + private final ByteOrder byteOrder = ByteOrder.NDR; + + H2GISWkbType() { + super(Types.BLOB); + } + + @Override + public Class getReturnedClass() { + return Geometry.class; + } + + @Override + @Nullable + public Geometry getValue(ResultSet rs, int startIndex) throws SQLException { + byte[] bytes = rs.getBytes(startIndex); + if (bytes != null) { + byte[] wkb; + if (bytes[0] != 0 && bytes[0] != 1) { // decodes EWKB + wkb = new byte[bytes.length - 32]; + System.arraycopy(bytes, 32, wkb, 0, wkb.length); + } else { + wkb = bytes; + } + WkbDecoder decoder = Wkb.newDecoder(Wkb.Dialect.POSTGIS_EWKB_1); + return decoder.decode(ByteBuffer.from(wkb)); + } else { + return null; + } + } + + @Override + public void setValue(PreparedStatement st, int startIndex, Geometry value) throws SQLException { + WkbEncoder encoder = Wkb.newEncoder(Wkb.Dialect.POSTGIS_EWKB_1); + ByteBuffer buffer = encoder.encode(value, byteOrder); + st.setBytes(startIndex, buffer.toByteArray()); + } + + @Override + public String getLiteral(Geometry geometry) { + String str = Wkt.newEncoder(Wkt.Dialect.POSTGIS_EWKT_1).encode(geometry); + if (geometry.getSRID() > -1) { + return "ST_GeomFromText('" + str + "', " + geometry.getSRID() + ")"; + } else { + return "ST_GeomFromText('" + str + "', -1)"; + } + } + +} diff --git a/querydsl-sql-spatial/src/main/java/com/querydsl/sql/spatial/MySQLSpatialTemplates.java b/querydsl-sql-spatial/src/main/java/com/querydsl/sql/spatial/MySQLSpatialTemplates.java new file mode 100644 index 0000000000..b75622566a --- /dev/null +++ b/querydsl-sql-spatial/src/main/java/com/querydsl/sql/spatial/MySQLSpatialTemplates.java @@ -0,0 +1,55 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.spatial; + +import com.querydsl.spatial.SpatialOps; +import com.querydsl.sql.MySQLTemplates; +import com.querydsl.sql.SQLTemplates; + +/** + * {@code MySQLSpatialTemplates} is a spatial enabled SQL dialect for MySQL + * + * @author tiwe + * + */ +public class MySQLSpatialTemplates extends MySQLTemplates { + + @SuppressWarnings("FieldNameHidesFieldInSuperclass") //Intentional + public static final MySQLSpatialTemplates DEFAULT = new MySQLSpatialTemplates(); + + public static Builder builder() { + return new Builder() { + @Override + protected SQLTemplates build(char escape, boolean quote) { + return new MySQLSpatialTemplates(escape, quote); + } + }; + } + + public MySQLSpatialTemplates() { + this('\\', false); + } + + public MySQLSpatialTemplates(boolean quote) { + this('\\', quote); + } + + public MySQLSpatialTemplates(char escape, boolean quote) { + super(escape, quote); + addCustomType(MySQLWkbType.DEFAULT); + add(SpatialTemplatesSupport.getSpatialOps("", true)); + add(SpatialOps.NUM_INTERIOR_RING, "NumInteriorRings({0})"); + } + +} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/spatial/MySQLWkbType.java b/querydsl-sql-spatial/src/main/java/com/querydsl/sql/spatial/MySQLWkbType.java similarity index 84% rename from querydsl-sql/src/main/java/com/mysema/query/sql/spatial/MySQLWkbType.java rename to querydsl-sql-spatial/src/main/java/com/querydsl/sql/spatial/MySQLWkbType.java index 8f19c6cbbe..8a91fd5406 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/spatial/MySQLWkbType.java +++ b/querydsl-sql-spatial/src/main/java/com/querydsl/sql/spatial/MySQLWkbType.java @@ -1,5 +1,5 @@ /* - * Copyright 2014, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,15 +11,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql.spatial; +package com.querydsl.sql.spatial; -import javax.annotation.Nullable; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Types; -import com.mysema.query.sql.types.AbstractType; +import org.jetbrains.annotations.Nullable; + import org.geolatte.geom.ByteBuffer; import org.geolatte.geom.ByteOrder; import org.geolatte.geom.Geometry; @@ -28,17 +28,15 @@ import org.geolatte.geom.codec.WkbEncoder; import org.geolatte.geom.codec.Wkt; -/** - * @author tiwe - * - */ -public class MySQLWkbType extends AbstractType { +import com.querydsl.sql.types.AbstractType; + +class MySQLWkbType extends AbstractType { public static final MySQLWkbType DEFAULT = new MySQLWkbType(); private final ByteOrder byteOrder = ByteOrder.NDR; - public MySQLWkbType() { + MySQLWkbType() { super(Types.BLOB); } @@ -56,7 +54,7 @@ public Geometry getValue(ResultSet rs, int startIndex) throws SQLException { System.arraycopy(bytes, 4, wkb, 0, wkb.length); int srid = bytes[3] << 24 | (bytes[2] & 0xff) << 16 | (bytes[1] & 0xff) << 8 | (bytes[0] & 0xff); // TODO make sure srid is set - WkbDecoder decoder = Wkb.newWkbDecoder(Wkb.Dialect.POSTGIS_EWKB_1); + WkbDecoder decoder = Wkb.newDecoder(Wkb.Dialect.POSTGIS_EWKB_1); return decoder.decode(ByteBuffer.from(wkb)); } else { return null; @@ -65,7 +63,7 @@ public Geometry getValue(ResultSet rs, int startIndex) throws SQLException { @Override public void setValue(PreparedStatement st, int startIndex, Geometry value) throws SQLException { - WkbEncoder encoder = Wkb.newWkbEncoder(Wkb.Dialect.POSTGIS_EWKB_1); + WkbEncoder encoder = Wkb.newEncoder(Wkb.Dialect.POSTGIS_EWKB_1); ByteBuffer buffer = encoder.encode(value, byteOrder); int srid = value.getSRID(); @@ -83,7 +81,7 @@ public void setValue(PreparedStatement st, int startIndex, Geometry value) throw @Override public String getLiteral(Geometry geometry) { - String str = Wkt.newWktEncoder(Wkt.Dialect.POSTGIS_EWKT_1).encode(geometry); + String str = Wkt.newEncoder(Wkt.Dialect.POSTGIS_EWKT_1).encode(geometry); if (geometry.getSRID() > -1) { return "GeomFromText('" + str + "', " + geometry.getSRID() + ")"; } else { diff --git a/querydsl-sql-spatial/src/main/java/com/querydsl/sql/spatial/OracleSpatialTemplates.java b/querydsl-sql-spatial/src/main/java/com/querydsl/sql/spatial/OracleSpatialTemplates.java new file mode 100644 index 0000000000..3cc259889b --- /dev/null +++ b/querydsl-sql-spatial/src/main/java/com/querydsl/sql/spatial/OracleSpatialTemplates.java @@ -0,0 +1,53 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.spatial; + +import com.querydsl.sql.OracleTemplates; +import com.querydsl.sql.SQLTemplates; + +/** + * {@code OracleSpatialTemplates} is a spatial enabled SQL dialect for Oracle + * + * @author tiwe + * + */ +public class OracleSpatialTemplates extends OracleTemplates { + + @SuppressWarnings("FieldNameHidesFieldInSuperclass") //Intentional + public static final OracleSpatialTemplates DEFAULT = new OracleSpatialTemplates(); + + public static Builder builder() { + return new Builder() { + @Override + protected SQLTemplates build(char escape, boolean quote) { + return new OracleSpatialTemplates(escape, quote); + } + }; + } + + public OracleSpatialTemplates() { + this('\\', false); + } + + public OracleSpatialTemplates(boolean quote) { + this('\\', quote); + } + + public OracleSpatialTemplates(char escape, boolean quote) { + super(escape, quote); + addCustomType(SDOGeometryType.DEFAULT); + // TODO + } + +} diff --git a/querydsl-sql-spatial/src/main/java/com/querydsl/sql/spatial/PGgeometryType.java b/querydsl-sql-spatial/src/main/java/com/querydsl/sql/spatial/PGgeometryType.java new file mode 100644 index 0000000000..d069d8f660 --- /dev/null +++ b/querydsl-sql-spatial/src/main/java/com/querydsl/sql/spatial/PGgeometryType.java @@ -0,0 +1,64 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.spatial; + +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Types; + +import org.jetbrains.annotations.Nullable; + +import org.geolatte.geom.Geometry; +import org.geolatte.geom.codec.Wkt; +import org.postgis.PGgeometry; + +import com.querydsl.sql.types.AbstractType; + +class PGgeometryType extends AbstractType { + + public static final PGgeometryType DEFAULT = new PGgeometryType(); + + PGgeometryType() { + super(Types.STRUCT); + } + + @Override + public Class getReturnedClass() { + return Geometry.class; + } + + @Override + @Nullable + public Geometry getValue(ResultSet rs, int startIndex) throws SQLException { + PGgeometry obj = (PGgeometry) rs.getObject(startIndex); + if (obj == null) { + return null; + } + return Wkt.newDecoder(Wkt.Dialect.POSTGIS_EWKT_1).decode(obj.getValue()); + } + + @Override + public void setValue(PreparedStatement st, int startIndex, Geometry value) throws SQLException { + final String encode = Wkt.newEncoder(Wkt.Dialect.POSTGIS_EWKT_1).encode(value); + PGgeometry geometry = new PGgeometry(encode); + st.setObject(startIndex, geometry); + } + + @Override + public String getLiteral(Geometry geometry) { + return "'" + Wkt.newEncoder(Wkt.Dialect.POSTGIS_EWKT_1).encode(geometry) + "'"; + } + +} diff --git a/querydsl-sql-spatial/src/main/java/com/querydsl/sql/spatial/PostGISTemplates.java b/querydsl-sql-spatial/src/main/java/com/querydsl/sql/spatial/PostGISTemplates.java new file mode 100644 index 0000000000..a2a936fefc --- /dev/null +++ b/querydsl-sql-spatial/src/main/java/com/querydsl/sql/spatial/PostGISTemplates.java @@ -0,0 +1,56 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.spatial; + +import com.querydsl.spatial.SpatialOps; +import com.querydsl.sql.PostgreSQLTemplates; +import com.querydsl.sql.SQLTemplates; + +/** + * {@code PostGISTemplates} is a spatial enabled SQL dialect for PostGIS + * + * @author tiwe + * + */ +public class PostGISTemplates extends PostgreSQLTemplates { + + @SuppressWarnings("FieldNameHidesFieldInSuperclass") //Intentional + public static final PostGISTemplates DEFAULT = new PostGISTemplates(); + + public static Builder builder() { + return new Builder() { + @Override + protected SQLTemplates build(char escape, boolean quote) { + return new PostGISTemplates(escape, quote); + } + }; + } + + public PostGISTemplates() { + this('\\', false); + } + + public PostGISTemplates(boolean quote) { + this('\\', quote); + } + + public PostGISTemplates(char escape, boolean quote) { + super(escape, quote); + addCustomType(PGgeometryType.DEFAULT); + add(SpatialTemplatesSupport.getSpatialOps(true)); + add(SpatialOps.DISTANCE_SPHERE, "ST_Distance_Sphere({0}, {1})"); + add(SpatialOps.DISTANCE_SPHEROID, "ST_Distance_Spheroid({0}, {1})"); + } + +} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/spatial/QSpatialRefSys.java b/querydsl-sql-spatial/src/main/java/com/querydsl/sql/spatial/QSpatialRefSys.java similarity index 77% rename from querydsl-sql/src/main/java/com/mysema/query/sql/spatial/QSpatialRefSys.java rename to querydsl-sql-spatial/src/main/java/com/querydsl/sql/spatial/QSpatialRefSys.java index 29e41d6980..82ac5ade68 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/spatial/QSpatialRefSys.java +++ b/querydsl-sql-spatial/src/main/java/com/querydsl/sql/spatial/QSpatialRefSys.java @@ -1,5 +1,5 @@ /* - * Copyright 2014, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,24 +11,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql.spatial; - -import static com.mysema.query.types.PathMetadataFactory.forVariable; - -import javax.annotation.Generated; - -import com.mysema.query.sql.ColumnMetadata; -import com.mysema.query.types.Path; -import com.mysema.query.types.PathMetadata; -import com.mysema.query.types.path.NumberPath; -import com.mysema.query.types.path.StringPath; +package com.querydsl.sql.spatial; +import static com.querydsl.core.types.PathMetadataFactory.forVariable; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.StringPath; +import com.querydsl.sql.ColumnMetadata; /** * QSpatialRefSys is a Querydsl query type for SpatialRefSys */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") public class QSpatialRefSys extends RelationalPathSpatial { private static final long serialVersionUID = 1681874658; @@ -43,7 +38,7 @@ public class QSpatialRefSys extends RelationalPathSpatial { public final StringPath srtext = createString("srtext"); - public final com.mysema.query.sql.PrimaryKey spatialRefSysPkey = createPrimaryKey(srid); + public final com.querydsl.sql.PrimaryKey spatialRefSysPkey = createPrimaryKey(srid); public QSpatialRefSys(String variable) { super(SpatialRefSys.class, forVariable(variable), "public", "spatial_ref_sys"); @@ -60,7 +55,7 @@ public QSpatialRefSys(Path path) { addMetadata(); } - public QSpatialRefSys(PathMetadata metadata) { + public QSpatialRefSys(PathMetadata metadata) { super(SpatialRefSys.class, metadata, "public", "spatial_ref_sys"); addMetadata(); } diff --git a/querydsl-sql-spatial/src/main/java/com/querydsl/sql/spatial/RelationalPathSpatial.java b/querydsl-sql-spatial/src/main/java/com/querydsl/sql/spatial/RelationalPathSpatial.java new file mode 100644 index 0000000000..fdec6b56bd --- /dev/null +++ b/querydsl-sql-spatial/src/main/java/com/querydsl/sql/spatial/RelationalPathSpatial.java @@ -0,0 +1,95 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.spatial; + +import org.geolatte.geom.*; + +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.PathMetadataFactory; +import com.querydsl.spatial.*; +import com.querydsl.sql.RelationalPathBase; + +/** + * {@code RelationalPathSpatial} extends {@link RelationalPathBase} to provide factory methods + * for spatial path creation + * + * @author tiwe + * + * @param + */ +public class RelationalPathSpatial extends RelationalPathBase implements GeometryPaths { + + private static final long serialVersionUID = -7176236689794620277L; + + public RelationalPathSpatial(Class type, String variable, String schema, String table) { + this(type, PathMetadataFactory.forVariable(variable), schema, table); + } + + public RelationalPathSpatial(Class type, PathMetadata metadata, String schema, String table) { + super(type, metadata, schema, table); + } + + @Override + public GeometryCollectionPath createGeometryCollection( + String property, Class type) { + return add(new GeometryCollectionPath(type, forProperty(property))); + } + + @Override + public GeometryPath createGeometry(String property, + Class type) { + return add(new GeometryPath(type, forProperty(property))); + } + + @Override + public LinearRingPath createLinearRing(String property, + Class type) { + return add(new LinearRingPath(type, forProperty(property))); + } + + @Override + public LineStringPath createLineString(String property, + Class type) { + return add(new LineStringPath(type, forProperty(property))); + } + + @Override + public MultiLineStringPath createMultiLineString( + String property, Class type) { + return add(new MultiLineStringPath(type, forProperty(property))); + } + + @Override + public MultiPointPath createMultiPoint(String property, + Class type) { + return add(new MultiPointPath(type, forProperty(property))); + } + + @Override + public MultiPolygonPath createMultiPolygon(String property, + Class type) { + return add(new MultiPolygonPath(type, forProperty(property))); + } + + @Override + public PointPath createPoint(String property, Class type) { + return add(new PointPath(type, forProperty(property))); + } + + @Override + public PolygonPath createPolygon(String property, Class type) { + return add(new PolygonPath(type, forProperty(property))); + } + +} diff --git a/querydsl-sql-spatial/src/main/java/com/querydsl/sql/spatial/SDOGeometryType.java b/querydsl-sql-spatial/src/main/java/com/querydsl/sql/spatial/SDOGeometryType.java new file mode 100644 index 0000000000..9f5bb87985 --- /dev/null +++ b/querydsl-sql-spatial/src/main/java/com/querydsl/sql/spatial/SDOGeometryType.java @@ -0,0 +1,69 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.spatial; + +import com.querydsl.sql.types.AbstractType; +import org.geolatte.geom.Geometry; +import org.geolatte.geom.codec.db.oracle.Decoders; +import org.geolatte.geom.codec.db.oracle.DefaultConnectionFinder; +import org.geolatte.geom.codec.db.oracle.Encoders; +import org.geolatte.geom.codec.db.oracle.OracleJDBCTypeFactory; +import org.jetbrains.annotations.Nullable; + +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Struct; +import java.sql.Types; + +class SDOGeometryType extends AbstractType { + + public static final SDOGeometryType DEFAULT = new SDOGeometryType(); + + SDOGeometryType() { + super(Types.OTHER); + } + + @Override + public Class getReturnedClass() { + return Geometry.class; + } + + @Override + @Nullable + public Geometry getValue(ResultSet rs, int startIndex) throws SQLException { + byte[] bytes = rs.getBytes(startIndex); + if (bytes != null) { + try { + final Struct object = rs.getObject(startIndex, Struct.class); + return Decoders.decode(object); + } catch (Exception e) { + throw new SQLException(e); + } + } else { + return null; + } + } + + @Override + public void setValue(PreparedStatement st, int startIndex, Geometry value) throws SQLException { + try { + final Struct struct = Encoders.encode(value, st.getConnection(), new OracleJDBCTypeFactory(new DefaultConnectionFinder())); + st.setObject(startIndex, struct); + } catch (Exception e) { + throw new SQLException(e); + } + } + +} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/spatial/SQLServer2008SpatialTemplates.java b/querydsl-sql-spatial/src/main/java/com/querydsl/sql/spatial/SQLServer2008SpatialTemplates.java similarity index 75% rename from querydsl-sql/src/main/java/com/mysema/query/sql/spatial/SQLServer2008SpatialTemplates.java rename to querydsl-sql-spatial/src/main/java/com/querydsl/sql/spatial/SQLServer2008SpatialTemplates.java index 7c9c9dd7dc..4abd3769d9 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/spatial/SQLServer2008SpatialTemplates.java +++ b/querydsl-sql-spatial/src/main/java/com/querydsl/sql/spatial/SQLServer2008SpatialTemplates.java @@ -1,5 +1,5 @@ /* - * Copyright 2014, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,20 +11,23 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql.spatial; +package com.querydsl.sql.spatial; -import com.mysema.query.spatial.SpatialOps; -import com.mysema.query.sql.SQLServer2008Templates; -import com.mysema.query.sql.SQLTemplates; +import com.querydsl.spatial.SpatialOps; +import com.querydsl.sql.SQLServer2008Templates; +import com.querydsl.sql.SQLTemplates; /** - * SQLServer2008SpatialTemplates is a spatial enabled SQL dialect for SQL Server 2008 + * {@code SQLServer2008SpatialTemplates} is a spatial enabled SQL dialect for SQL Server 2008 * * @author tiwe * */ public class SQLServer2008SpatialTemplates extends SQLServer2008Templates { + @SuppressWarnings("FieldNameHidesFieldInSuperclass") //Intentional + public static final SQLServer2008SpatialTemplates DEFAULT = new SQLServer2008SpatialTemplates(); + public static Builder builder() { return new Builder() { @Override diff --git a/querydsl-sql-spatial/src/main/java/com/querydsl/sql/spatial/SQLServerGeometryType.java b/querydsl-sql-spatial/src/main/java/com/querydsl/sql/spatial/SQLServerGeometryType.java new file mode 100644 index 0000000000..0a2169592f --- /dev/null +++ b/querydsl-sql-spatial/src/main/java/com/querydsl/sql/spatial/SQLServerGeometryType.java @@ -0,0 +1,72 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.spatial; + +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Types; + +import org.geolatte.geom.codec.db.sqlserver.Decoders; +import org.geolatte.geom.codec.db.sqlserver.Encoders; +import org.jetbrains.annotations.Nullable; + +import org.geolatte.geom.Geometry; +import org.geolatte.geom.codec.Wkt; + +import com.querydsl.sql.types.AbstractType; + +class SQLServerGeometryType extends AbstractType { + + public static final SQLServerGeometryType DEFAULT = new SQLServerGeometryType(); + + private static final int DEFAULT_SRID = 4326; + + SQLServerGeometryType() { + super(Types.BLOB); + } + + @Override + public Class getReturnedClass() { + return Geometry.class; + } + + @Override + @Nullable + public Geometry getValue(ResultSet rs, int startIndex) throws SQLException { + byte[] bytes = rs.getBytes(startIndex); + if (bytes != null) { + return Decoders.decode(bytes); + } else { + return null; + } + } + + @Override + public void setValue(PreparedStatement st, int startIndex, Geometry value) throws SQLException { + byte[] bytes = Encoders.encode(value); + st.setBytes(startIndex, bytes); + } + + @Override + public String getLiteral(Geometry geometry) { + String str = Wkt.newEncoder(Wkt.Dialect.POSTGIS_EWKT_1).encode(geometry); + if (geometry.getSRID() > -1) { + return "geometry::STGeomFromText('" + str + "', " + geometry.getSRID() + ")"; + } else { + return "geometry::STGeomFromText('" + str + "', " + DEFAULT_SRID + ")"; + } + } + +} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/spatial/SpatialRefSys.java b/querydsl-sql-spatial/src/main/java/com/querydsl/sql/spatial/SpatialRefSys.java similarity index 89% rename from querydsl-sql/src/main/java/com/mysema/query/sql/spatial/SpatialRefSys.java rename to querydsl-sql-spatial/src/main/java/com/querydsl/sql/spatial/SpatialRefSys.java index 3bff433b98..7ba3eac477 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/spatial/SpatialRefSys.java +++ b/querydsl-sql-spatial/src/main/java/com/querydsl/sql/spatial/SpatialRefSys.java @@ -1,5 +1,5 @@ /* - * Copyright 2014, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,14 +11,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql.spatial; - -import javax.annotation.Generated; +package com.querydsl.sql.spatial; /** * SpatialRefSys is a Querydsl bean type */ -@Generated("com.mysema.query.codegen.BeanSerializer") public class SpatialRefSys { private String authName; diff --git a/querydsl-sql-spatial/src/main/java/com/querydsl/sql/spatial/SpatialSupport.java b/querydsl-sql-spatial/src/main/java/com/querydsl/sql/spatial/SpatialSupport.java new file mode 100644 index 0000000000..73618cfb53 --- /dev/null +++ b/querydsl-sql-spatial/src/main/java/com/querydsl/sql/spatial/SpatialSupport.java @@ -0,0 +1,61 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.spatial; + +import com.querydsl.codegen.AbstractModule; +import com.querydsl.codegen.Extension; +import com.querydsl.sql.Configuration; +import com.querydsl.sql.codegen.SQLCodegenModule; +import org.geolatte.geom.Geometry; +import org.geolatte.geom.GeometryCollection; +import org.geolatte.geom.LineString; +import org.geolatte.geom.MultiLineString; +import org.geolatte.geom.MultiPoint; +import org.geolatte.geom.MultiPolygon; +import org.geolatte.geom.Point; +import org.geolatte.geom.Polygon; + +/** + * {@code SpatialSupport} provides support for spatial types in code generation + * + * @author tiwe + * + */ +public final class SpatialSupport implements Extension { + + private static void registerTypes(Configuration configuration) { + // mysql & postgresql + configuration.registerType("geometry", Geometry.class); + configuration.registerType("point", Point.class); + configuration.registerType("linestring", LineString.class); + configuration.registerType("polygon", Polygon.class); + configuration.registerType("multipoint", MultiPoint.class); + configuration.registerType("multilinestring", MultiLineString.class); + configuration.registerType("multipolygon", MultiPolygon.class); + configuration.registerType("geometrycollection", GeometryCollection.class); + // teradata + configuration.registerType("sysudtlib.st_geometry", Geometry.class); + } + + /** + * Register spatial types to the given codegen module + * + * @param module module to be customized for spatial support + */ + public void addSupport(AbstractModule module) { + module.bindInstance(SQLCodegenModule.ENTITYPATH_TYPE, RelationalPathSpatial.class); + registerTypes(module.get(Configuration.class)); + } + +} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/spatial/SpatialTemplatesSupport.java b/querydsl-sql-spatial/src/main/java/com/querydsl/sql/spatial/SpatialTemplatesSupport.java similarity index 80% rename from querydsl-sql/src/main/java/com/mysema/query/sql/spatial/SpatialTemplatesSupport.java rename to querydsl-sql-spatial/src/main/java/com/querydsl/sql/spatial/SpatialTemplatesSupport.java index a3e5d43a49..4926ad374b 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/spatial/SpatialTemplatesSupport.java +++ b/querydsl-sql-spatial/src/main/java/com/querydsl/sql/spatial/SpatialTemplatesSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2014, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,13 +11,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql.spatial; +package com.querydsl.sql.spatial; +import java.util.HashMap; import java.util.Map; -import com.google.common.collect.Maps; -import com.mysema.query.spatial.SpatialOps; -import com.mysema.query.types.Operator; +import com.querydsl.core.types.Operator; +import com.querydsl.spatial.SpatialOps; /** * Static factory methods for spatial enabled SQLTemplates subclasses @@ -27,6 +27,8 @@ */ public final class SpatialTemplatesSupport { + private SpatialTemplatesSupport() { } + private static String createSpatial(String name, int args, boolean asFunction) { StringBuilder result = new StringBuilder(); if (!asFunction) { @@ -39,18 +41,18 @@ private static String createSpatial(String name, int args, boolean asFunction) { if (i > start) { result.append(", "); } - result.append("{" + i + "}"); + result.append("{").append(i).append("}"); } result.append(")"); return result.toString(); } - public static Map, String> getSpatialOps(boolean asFunction) { + public static Map getSpatialOps(boolean asFunction) { return getSpatialOps("ST_", asFunction); } - public static Map, String> getSpatialOps(String prefix, boolean asFunction) { - Map, String> ops = Maps.newHashMap(); + public static Map getSpatialOps(String prefix, boolean asFunction) { + Map ops = new HashMap<>(); ops.put(SpatialOps.AREA, createSpatial(prefix + "Area", 1, asFunction)); ops.put(SpatialOps.AREA2, createSpatial(prefix + "Area", 2, asFunction)); ops.put(SpatialOps.AS_BINARY, createSpatial(prefix + "AsBinary", 1, asFunction)); @@ -113,6 +115,22 @@ public static Map, String> getSpatialOps(String prefix, boolean asFu ops.put(SpatialOps.Y2, createSpatial(prefix + "Y", 2, asFunction)); ops.put(SpatialOps.Z, createSpatial(prefix + "Z", 1, asFunction)); ops.put(SpatialOps.Z2, createSpatial(prefix + "Z", 2, asFunction)); + + // extensions + ops.put(SpatialOps.AS_EWKT, createSpatial(prefix + "AsEWKT", 1, asFunction)); + ops.put(SpatialOps.GEOM_FROM_TEXT, createSpatial(prefix + "GeomFromText", 1, asFunction)); + ops.put(SpatialOps.SET_SRID, createSpatial(prefix + "SetSRID", 2, asFunction)); + ops.put(SpatialOps.XMIN, createSpatial(prefix + "XMin", 1, asFunction)); + ops.put(SpatialOps.XMAX, createSpatial(prefix + "XMax", 1, asFunction)); + ops.put(SpatialOps.YMIN, createSpatial(prefix + "YMin", 1, asFunction)); + ops.put(SpatialOps.YMAX, createSpatial(prefix + "YMax", 1, asFunction)); + ops.put(SpatialOps.DWITHIN, createSpatial(prefix + "DWithin", 3, asFunction)); + ops.put(SpatialOps.EXTENT, createSpatial(prefix + "Extent", 1, asFunction)); + ops.put(SpatialOps.COLLECT, createSpatial(prefix + "Collect", 1, asFunction)); + ops.put(SpatialOps.COLLECT2, createSpatial(prefix + "Collect", 2, asFunction)); + ops.put(SpatialOps.TRANSLATE, createSpatial(prefix + "Translate", 3, asFunction)); + ops.put(SpatialOps.TRANSLATE2, createSpatial(prefix + "Translate", 4, asFunction)); + return ops; } diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/spatial/TeradataSpatialTemplates.java b/querydsl-sql-spatial/src/main/java/com/querydsl/sql/spatial/TeradataSpatialTemplates.java similarity index 76% rename from querydsl-sql/src/main/java/com/mysema/query/sql/spatial/TeradataSpatialTemplates.java rename to querydsl-sql-spatial/src/main/java/com/querydsl/sql/spatial/TeradataSpatialTemplates.java index b64dc6faea..2fe934d5c7 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/spatial/TeradataSpatialTemplates.java +++ b/querydsl-sql-spatial/src/main/java/com/querydsl/sql/spatial/TeradataSpatialTemplates.java @@ -1,5 +1,5 @@ /* - * Copyright 2014, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,22 +11,25 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql.spatial; +package com.querydsl.sql.spatial; -import com.mysema.query.spatial.SpatialOps; -import com.mysema.query.sql.SQLTemplates; -import com.mysema.query.sql.SchemaAndTable; -import com.mysema.query.sql.TeradataTemplates; -import com.mysema.query.sql.types.StringAsObjectType; +import com.querydsl.spatial.SpatialOps; +import com.querydsl.sql.SQLTemplates; +import com.querydsl.sql.SchemaAndTable; +import com.querydsl.sql.TeradataTemplates; +import com.querydsl.sql.types.StringAsObjectType; /** - * TeradataSpatialTemplates is a spatial enabled SQL dialect for Teradata + * {@code TeradataSpatialTemplates} is a spatial enabled SQL dialect for Teradata * * @author tiwe * */ public class TeradataSpatialTemplates extends TeradataTemplates { + @SuppressWarnings("FieldNameHidesFieldInSuperclass") //Intentional + public static final TeradataSpatialTemplates DEFAULT = new TeradataSpatialTemplates(); + public static Builder builder() { return new Builder() { @Override diff --git a/querydsl-sql-spatial/src/main/java/com/querydsl/sql/spatial/package-info.java b/querydsl-sql-spatial/src/main/java/com/querydsl/sql/spatial/package-info.java new file mode 100644 index 0000000000..82f00ef0b5 --- /dev/null +++ b/querydsl-sql-spatial/src/main/java/com/querydsl/sql/spatial/package-info.java @@ -0,0 +1,18 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ + +/** + * Spatial support + */ +package com.querydsl.sql.spatial; diff --git a/querydsl-sql-spatial/src/main/resources/META-INF/services/com.querydsl.codegen.Extension b/querydsl-sql-spatial/src/main/resources/META-INF/services/com.querydsl.codegen.Extension new file mode 100644 index 0000000000..0389ec47c6 --- /dev/null +++ b/querydsl-sql-spatial/src/main/resources/META-INF/services/com.querydsl.codegen.Extension @@ -0,0 +1 @@ +com.querydsl.sql.spatial.SpatialSupport \ No newline at end of file diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/spatial/GeoDBTemplatesTest.java b/querydsl-sql-spatial/src/test/java/com/querydsl/sql/spatial/GeoDBTemplatesTest.java similarity index 81% rename from querydsl-sql/src/test/java/com/mysema/query/sql/spatial/GeoDBTemplatesTest.java rename to querydsl-sql-spatial/src/test/java/com/querydsl/sql/spatial/GeoDBTemplatesTest.java index e64484e686..a02c4e82f7 100644 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/spatial/GeoDBTemplatesTest.java +++ b/querydsl-sql-spatial/src/test/java/com/querydsl/sql/spatial/GeoDBTemplatesTest.java @@ -1,8 +1,9 @@ -package com.mysema.query.sql.spatial; +package com.querydsl.sql.spatial; -import com.mysema.query.sql.SQLTemplates; import org.junit.Test; +import com.querydsl.sql.SQLTemplates; + public class GeoDBTemplatesTest { @Test diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/spatial/MySQLSpatialTemplatesTest.java b/querydsl-sql-spatial/src/test/java/com/querydsl/sql/spatial/MySQLSpatialTemplatesTest.java similarity index 81% rename from querydsl-sql/src/test/java/com/mysema/query/sql/spatial/MySQLSpatialTemplatesTest.java rename to querydsl-sql-spatial/src/test/java/com/querydsl/sql/spatial/MySQLSpatialTemplatesTest.java index dd7f158752..c459fae55d 100644 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/spatial/MySQLSpatialTemplatesTest.java +++ b/querydsl-sql-spatial/src/test/java/com/querydsl/sql/spatial/MySQLSpatialTemplatesTest.java @@ -1,8 +1,9 @@ -package com.mysema.query.sql.spatial; +package com.querydsl.sql.spatial; -import com.mysema.query.sql.SQLTemplates; import org.junit.Test; +import com.querydsl.sql.SQLTemplates; + public class MySQLSpatialTemplatesTest { @Test diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/spatial/PostGISTemplatesTest.java b/querydsl-sql-spatial/src/test/java/com/querydsl/sql/spatial/PostGISTemplatesTest.java similarity index 79% rename from querydsl-sql/src/test/java/com/mysema/query/sql/spatial/PostGISTemplatesTest.java rename to querydsl-sql-spatial/src/test/java/com/querydsl/sql/spatial/PostGISTemplatesTest.java index b358689523..1870c80e50 100644 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/spatial/PostGISTemplatesTest.java +++ b/querydsl-sql-spatial/src/test/java/com/querydsl/sql/spatial/PostGISTemplatesTest.java @@ -1,8 +1,9 @@ -package com.mysema.query.sql.spatial; +package com.querydsl.sql.spatial; -import com.mysema.query.sql.SQLTemplates; import org.junit.Test; +import com.querydsl.sql.SQLTemplates; + public class PostGISTemplatesTest { @Test diff --git a/querydsl-sql-spatial/src/test/java/com/querydsl/sql/spatial/QShapes.java b/querydsl-sql-spatial/src/test/java/com/querydsl/sql/spatial/QShapes.java new file mode 100644 index 0000000000..71c73a102e --- /dev/null +++ b/querydsl-sql-spatial/src/test/java/com/querydsl/sql/spatial/QShapes.java @@ -0,0 +1,57 @@ +package com.querydsl.sql.spatial; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import org.geolatte.geom.Geometry; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.spatial.GeometryPath; +import com.querydsl.sql.ColumnMetadata; + +/** + * QShapes is a Querydsl query type for QShapes + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class QShapes extends RelationalPathSpatial { + + private static final long serialVersionUID = 563213127; + + public static final QShapes shapes = new QShapes("SHAPES"); + + public final GeometryPath geometry = createGeometry("geometry", Geometry.class); + + public final NumberPath id = createNumber("id", Integer.class); + + public final com.querydsl.sql.PrimaryKey shapesPkey = createPrimaryKey(id); + + public QShapes(String variable) { + super(Shapes.class, forVariable(variable), "PUBLIC", "SHAPES"); + addMetadata(); + } + + public QShapes(String variable, String schema, String table) { + super(Shapes.class, forVariable(variable), schema, table); + addMetadata(); + } + + public QShapes(Path path) { + super(path.getType(), path.getMetadata(), "PUBLIC", "SHAPES"); + addMetadata(); + } + + public QShapes(PathMetadata metadata) { + super(Shapes.class, metadata, "PUBLIC", "SHAPES"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(geometry, ColumnMetadata.named("GEOMETRY").ofType(1111).withSize(2147483647)); + addMetadata(id, ColumnMetadata.named("ID").ofType(4).withSize(10).notNull()); + } + +} + diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/spatial/SQLServer2008SpatialTemplatesTest.java b/querydsl-sql-spatial/src/test/java/com/querydsl/sql/spatial/SQLServer2008SpatialTemplatesTest.java similarity index 82% rename from querydsl-sql/src/test/java/com/mysema/query/sql/spatial/SQLServer2008SpatialTemplatesTest.java rename to querydsl-sql-spatial/src/test/java/com/querydsl/sql/spatial/SQLServer2008SpatialTemplatesTest.java index a8acd6b523..a568360231 100644 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/spatial/SQLServer2008SpatialTemplatesTest.java +++ b/querydsl-sql-spatial/src/test/java/com/querydsl/sql/spatial/SQLServer2008SpatialTemplatesTest.java @@ -1,8 +1,9 @@ -package com.mysema.query.sql.spatial; +package com.querydsl.sql.spatial; -import com.mysema.query.sql.SQLTemplates; import org.junit.Test; +import com.querydsl.sql.SQLTemplates; + public class SQLServer2008SpatialTemplatesTest { @Test diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/spatial/Shapes.java b/querydsl-sql-spatial/src/test/java/com/querydsl/sql/spatial/Shapes.java similarity index 91% rename from querydsl-sql/src/test/java/com/mysema/query/sql/spatial/Shapes.java rename to querydsl-sql-spatial/src/test/java/com/querydsl/sql/spatial/Shapes.java index f46aebddf8..117044a4f8 100644 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/spatial/Shapes.java +++ b/querydsl-sql-spatial/src/test/java/com/querydsl/sql/spatial/Shapes.java @@ -1,4 +1,4 @@ -package com.mysema.query.sql.spatial; +package com.querydsl.sql.spatial; import org.geolatte.geom.Geometry; diff --git a/querydsl-sql-spatial/src/test/java/com/querydsl/sql/spatial/SpatialBase.java b/querydsl-sql-spatial/src/test/java/com/querydsl/sql/spatial/SpatialBase.java new file mode 100644 index 0000000000..ebf75c6c5d --- /dev/null +++ b/querydsl-sql-spatial/src/test/java/com/querydsl/sql/spatial/SpatialBase.java @@ -0,0 +1,450 @@ + +package com.querydsl.sql.spatial; + +import static com.querydsl.core.Target.*; +import static org.junit.Assert.*; + +import java.util.ArrayList; +import java.util.List; + +import org.geolatte.geom.*; +import org.geolatte.geom.codec.Wkt; +import org.junit.Test; + +import com.querydsl.core.Target; +import com.querydsl.core.Tuple; +import com.querydsl.core.testutil.ExcludeIn; +import com.querydsl.core.testutil.IncludeIn; +import com.querydsl.core.types.ConstantImpl; +import com.querydsl.core.types.Expression; +import com.querydsl.spatial.*; +import com.querydsl.sql.AbstractBaseTest; +import com.querydsl.sql.SQLQuery; + +public class SpatialBase extends AbstractBaseTest { + + private static final QShapes shapes = QShapes.shapes; + + // point 1-5 + // linestring 6-7 + // polygon 8-9 + // multipoint 10-11 + // multilinestring 12-13 + // multipolygon 14-15 + + private SQLQuery withPoints() { + return query().from(shapes).where(shapes.id.between(1, 5)); + } + + private SQLQuery withLineStrings() { + return query().from(shapes).where(shapes.id.between(6, 7)); + } + + private SQLQuery withPolygons() { + return query().from(shapes).where(shapes.id.between(8, 9)); + } + + private SQLQuery withMultipoints() { + return query().from(shapes).where(shapes.id.between(10, 11)); + } + + private SQLQuery withMultiLineStrings() { + return query().from(shapes).where(shapes.id.between(12, 13)); + } + + private SQLQuery withMultiPolygons() { + return query().from(shapes).where(shapes.id.between(14, 15)); + } + + @Test + @IncludeIn(POSTGRESQL) + public void spatialRefSys() { + QSpatialRefSys spatialRefSys = QSpatialRefSys.spatialRefSys; + query().from(spatialRefSys).select(spatialRefSys).fetch(); + } + + private String normalize(String s) { + String normalized = s.replace(" ", "").replace("ST_", "").replace("_", ""); + normalized = normalized.substring(normalized.indexOf(';') + 1); + return normalized.toUpperCase(); + } + + @Test // FIXME, maybe use enum as the type ?!? + @ExcludeIn(H2) + public void geometryType() { + List results = query().from(shapes).select(shapes.geometry, shapes.geometry.geometryType()).fetch(); + assertFalse(results.isEmpty()); + for (Tuple row : results) { + assertEquals( + normalize(row.get(shapes.geometry).getGeometryType().name()), + normalize(row.get(shapes.geometry.geometryType()))); + } + } + + @Test + public void asText() { + List results = query().from(shapes).select(shapes.geometry, shapes.geometry.asText()).fetch(); + assertFalse(results.isEmpty()); + for (Tuple row : results) { + if (!(row.get(shapes.geometry) instanceof MultiPoint)) { + assertEquals( + normalize(Wkt.toWkt(row.get(shapes.geometry))), + normalize(row.get(shapes.geometry.asText()))); + } + } + } + + @Test + @ExcludeIn(H2) + public void point_x_y() { + PointPath point = shapes.geometry.asPoint(); + List results = withPoints().select(point, point.x(), point.y()).fetch(); + assertFalse(results.isEmpty()); + for (Tuple row : results) { + assertEquals(Double.valueOf(row.get(point).getPosition().getCoordinate(0)), row.get(point.x())); + assertEquals(Double.valueOf(row.get(point).getPosition().getCoordinate(1)), row.get(point.y())); + } + } + + @Test + @ExcludeIn(MYSQL) + public void point_distance() { + QShapes shapes1 = QShapes.shapes; + QShapes shapes2 = new QShapes("shapes2"); + for (Tuple tuple : query().from(shapes1, shapes2) + .where(shapes1.id.loe(5), shapes2.id.loe(5)) + .select(shapes1.geometry.asPoint(), + shapes2.geometry.asPoint(), + shapes1.geometry.distance(shapes2.geometry)).fetch()) { + Point point1 = tuple.get(shapes1.geometry.asPoint()); + Point point2 = tuple.get(shapes2.geometry.asPoint()); + Double distance = tuple.get(shapes1.geometry.distance(shapes2.geometry)); + assertEquals(JTSGeometryOperations.Default.distance(point1, point2), distance, 0.0001); + } + } + + @Test + public void point_instances() { + List results = withPoints().select(shapes).fetch(); + assertEquals(5, results.size()); + for (Shapes row : results) { + assertNotNull(row.getId()); + assertNotNull(row.getGeometry()); + assertTrue(row.getGeometry() instanceof Point); + } + } + + @Test + public void lineString_instances() { + List results = withLineStrings().select(shapes.geometry).fetch(); + assertFalse(results.isEmpty()); + for (Geometry row : results) { + assertNotNull(row); + assertTrue(row instanceof LineString); + } + } + + @Test + public void polygon_instances() { + List results = withPolygons().select(shapes.geometry).fetch(); + assertFalse(results.isEmpty()); + for (Geometry row : results) { + assertNotNull(row); + assertTrue(row instanceof Polygon); + } + } + + @Test + public void multiPoint_instances() { + List results = withMultipoints().select(shapes.geometry).fetch(); + assertFalse(results.isEmpty()); + for (Geometry row : results) { + assertNotNull(row); + assertTrue(row instanceof MultiPoint); + } + } + + @Test + public void multiLineString_instances() { + List results = withMultiLineStrings().select(shapes.geometry).fetch(); + assertFalse(results.isEmpty()); + for (Geometry row : results) { + assertNotNull(row); + assertTrue(row instanceof MultiLineString); + } + } + + @Test + public void multiPolygon_instances() { + List results = withMultiPolygons().select(shapes.geometry).fetch(); + assertFalse(results.isEmpty()); + for (Geometry row : results) { + assertNotNull(row); + assertTrue(row instanceof MultiPolygon); + } + } + + @Test + public void point_methods() { + PointPath point = shapes.geometry.asPoint(); + + List> expressions = new ArrayList<>(); + add(expressions, point.asBinary(), H2); + add(expressions, point.asText()); + add(expressions, point.boundary(), H2, MYSQL); + add(expressions, point.convexHull(), H2, MYSQL); + add(expressions, point.dimension()); + add(expressions, point.envelope(), H2); + add(expressions, point.geometryType(), H2); + add(expressions, point.isEmpty()); + add(expressions, point.isSimple()); + add(expressions, point.m(), MYSQL, TERADATA, H2); + add(expressions, point.srid()); + // TODO add emulations + add(expressions, point.transform(26986), MYSQL, POSTGRESQL, SQLSERVER, TERADATA, H2); + // point specific + add(expressions, point.x(), H2); + add(expressions, point.y(), H2); + add(expressions, point.z(), MYSQL, TERADATA, H2); + + for (Expression expr : expressions) { + boolean logged = false; + for (Object row : withPoints().select(expr).fetch()) { + if (row == null && !logged) { + System.err.println(expr.toString()); + logged = true; + } + } + } + } + + private List> createExpressions(PointExpression point1, Expression point2) { + List> expressions = new ArrayList<>(); + add(expressions, point1.contains(point2)); + add(expressions, point1.crosses(point2)); + add(expressions, point1.difference(point2), H2, MYSQL); + add(expressions, point1.disjoint(point2)); + add(expressions, point1.distance(point2), MYSQL); + add(expressions, point1.distanceSphere(point2), H2, MYSQL, SQLSERVER); + add(expressions, point1.distanceSpheroid(point2), H2, MYSQL, POSTGRESQL, SQLSERVER); + add(expressions, point1.eq(point2)); + add(expressions, point1.intersection(point2), H2, MYSQL); + add(expressions, point1.intersects(point2)); + add(expressions, point1.overlaps(point2)); + add(expressions, point1.symDifference(point2), H2, MYSQL); + add(expressions, point1.touches(point2)); + add(expressions, point1.union(point2), H2, MYSQL); + add(expressions, point1.within(point2)); + return expressions; + } + + @Test + public void point_methods2() { + QShapes shapes1 = QShapes.shapes; + QShapes shapes2 = new QShapes("shapes2"); + + List> expressions = new ArrayList<>(); + expressions.addAll(createExpressions(shapes1.geometry.asPoint(), shapes2.geometry.asPoint())); + expressions.addAll(createExpressions(shapes1.geometry.asPoint(), ConstantImpl.create((Point) Wkt.fromWkt("Point(2 2)")))); + + for (Expression expr : expressions) { + boolean logged = false; + for (Object row : query().from(shapes1, shapes2) + .where(shapes1.id.loe(5), shapes2.id.loe(5)).select(expr).fetch()) { + if (row == null && !logged) { + System.err.println(expr.toString()); + logged = true; + } + } + } + } + + @Test + public void lineString_methods() { + LineStringPath lineString = shapes.geometry.asLineString(); + + List> expressions = new ArrayList<>(); + add(expressions, lineString.asBinary(), H2); + add(expressions, lineString.asText()); + add(expressions, lineString.boundary(), H2, MYSQL); + add(expressions, lineString.convexHull(), H2, MYSQL); + add(expressions, lineString.dimension()); + add(expressions, lineString.envelope(), H2); + add(expressions, lineString.geometryType(), H2); + add(expressions, lineString.isEmpty()); + add(expressions, lineString.isSimple()); + // curve specific + add(expressions, lineString.length(), H2); + add(expressions, lineString.startPoint(), H2); + add(expressions, lineString.endPoint(), H2); + add(expressions, lineString.isClosed(), H2); + add(expressions, lineString.isRing(), H2, MYSQL); + // linestring specific + add(expressions, lineString.numPoints(), H2); + add(expressions, lineString.pointN(1), H2); + + for (Expression expr : expressions) { + boolean logged = false; + for (Object row : withLineStrings().select(expr).fetch()) { + if (row == null && !logged) { + System.err.println(expr.toString()); + logged = true; + } + } + } + } + + @Test + public void polygon_methods() { + PolygonPath polygon = shapes.geometry.asPolygon(); + + List> expressions = new ArrayList<>(); + add(expressions, polygon.asBinary(), H2); + add(expressions, polygon.asText()); + add(expressions, polygon.boundary(), H2, MYSQL); + add(expressions, polygon.convexHull(), H2, MYSQL); + add(expressions, polygon.dimension()); + add(expressions, polygon.envelope(), H2); + add(expressions, polygon.geometryType(), H2); + add(expressions, polygon.isEmpty()); + add(expressions, polygon.isSimple()); + // surface specific + add(expressions, polygon.area()); + add(expressions, polygon.centroid()); + add(expressions, polygon.pointOnSurface(), H2, MYSQL); + // polygon specific + add(expressions, polygon.exteriorRing(), H2); + add(expressions, polygon.numInteriorRing(), H2); + add(expressions, polygon.interiorRingN(1), H2); + + for (Expression expr : expressions) { + boolean logged = false; + for (Object row : withPolygons().select(expr).fetch()) { + if (row == null && !logged) { + System.err.println(expr.toString()); + logged = true; + } + } + } + } + + @Test + public void multiPoint_methods() { + MultiPointPath multipoint = shapes.geometry.asMultiPoint(); + + List> expressions = new ArrayList<>(); + add(expressions, multipoint.asBinary(), H2); + add(expressions, multipoint.asText()); + add(expressions, multipoint.boundary(), H2, MYSQL); + add(expressions, multipoint.convexHull(), H2, MYSQL); + add(expressions, multipoint.dimension()); + add(expressions, multipoint.envelope(), H2); + add(expressions, multipoint.geometryType(), H2); + add(expressions, multipoint.isEmpty()); + add(expressions, multipoint.isSimple()); + // multipoint specific + add(expressions, multipoint.numGeometries(), H2); + add(expressions, multipoint.geometryN(1), H2); + + for (Expression expr : expressions) { + boolean logged = false; + for (Object row : withMultipoints().select(expr).fetch()) { + if (row == null && !logged) { + System.err.println(expr.toString()); + logged = true; + } + } + } + } + + @Test + public void multiLineString_methods() { + MultiLineStringPath multilinestring = shapes.geometry.asMultiLineString(); + + List> expressions = new ArrayList<>(); + add(expressions, multilinestring.asBinary(), H2); + add(expressions, multilinestring.asText()); + add(expressions, multilinestring.boundary(), H2, MYSQL); + add(expressions, multilinestring.convexHull(), H2, MYSQL); + add(expressions, multilinestring.dimension()); + add(expressions, multilinestring.envelope(), H2); + add(expressions, multilinestring.geometryType(), H2); + add(expressions, multilinestring.isEmpty()); + add(expressions, multilinestring.isSimple()); + // multicurve specific + add(expressions, multilinestring.isClosed(), H2); + add(expressions, multilinestring.length(), H2); + // multilinestring specific + add(expressions, multilinestring.numGeometries(), H2); + add(expressions, multilinestring.geometryN(1), H2); + + for (Expression expr : expressions) { + boolean logged = false; + for (Object row : withMultiLineStrings().select(expr).fetch()) { + if (row == null && !logged) { + System.err.println(expr.toString()); + logged = true; + } + } + } + } + + @Test + public void multiPolygon_methods() { + MultiPolygonPath multipolygon = shapes.geometry.asMultiPolygon(); + + List> expressions = new ArrayList<>(); + add(expressions, multipolygon.asBinary(), H2); + add(expressions, multipolygon.asText()); + add(expressions, multipolygon.boundary(), H2, MYSQL); + add(expressions, multipolygon.convexHull(), H2, MYSQL); + add(expressions, multipolygon.dimension()); + add(expressions, multipolygon.envelope(), H2); + add(expressions, multipolygon.geometryType(), H2); + add(expressions, multipolygon.isEmpty()); + add(expressions, multipolygon.isSimple()); + // multipolygon specific + add(expressions, multipolygon.numGeometries(), H2); + add(expressions, multipolygon.geometryN(1), H2); + + for (Expression expr : expressions) { + boolean logged = false; + for (Object row : withMultiPolygons().select(expr).fetch()) { + if (row == null && !logged) { + System.err.println(expr.toString()); + logged = true; + } + } + } + } + + @Test + @IncludeIn(Target.POSTGRESQL) + public void extensions() { + List> expressions = new ArrayList<>(); + GeometryExpression expr1 = shapes.geometry; + + expressions.add(GeometryExpressions.asEWKT(expr1)); + expressions.add(GeometryExpressions.fromText(expr1.asText())); + expressions.add(GeometryExpressions.setSRID(expr1, 4326)); + expressions.add(GeometryExpressions.xmin(expr1)); + expressions.add(GeometryExpressions.xmax(expr1)); + expressions.add(GeometryExpressions.ymin(expr1)); + expressions.add(GeometryExpressions.ymax(expr1)); + expressions.add(GeometryExpressions.dwithin(expr1, expr1, 1)); + expressions.add(GeometryExpressions.collect(expr1, expr1)); + expressions.add(GeometryExpressions.translate(expr1, 1, 1)); + + for (Expression expr : expressions) { + boolean logged = false; + for (Object row : withPoints().select(expr).fetch()) { + if (row == null && !logged) { + System.err.println(expr.toString()); + logged = true; + } + } + } + } + + +} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/spatial/TeradataSpatialTemplatesTest.java b/querydsl-sql-spatial/src/test/java/com/querydsl/sql/spatial/TeradataSpatialTemplatesTest.java similarity index 80% rename from querydsl-sql/src/test/java/com/mysema/query/sql/spatial/TeradataSpatialTemplatesTest.java rename to querydsl-sql-spatial/src/test/java/com/querydsl/sql/spatial/TeradataSpatialTemplatesTest.java index aaa1d99bc6..484199286c 100644 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/spatial/TeradataSpatialTemplatesTest.java +++ b/querydsl-sql-spatial/src/test/java/com/querydsl/sql/spatial/TeradataSpatialTemplatesTest.java @@ -1,8 +1,9 @@ -package com.mysema.query.sql.spatial; +package com.querydsl.sql.spatial; -import com.mysema.query.sql.SQLTemplates; import org.junit.Test; +import com.querydsl.sql.SQLTemplates; + public class TeradataSpatialTemplatesTest { @Test diff --git a/querydsl-sql-spatial/src/test/java/com/querydsl/sql/spatial/suites/H2LiteralsSuiteTest.java b/querydsl-sql-spatial/src/test/java/com/querydsl/sql/spatial/suites/H2LiteralsSuiteTest.java new file mode 100644 index 0000000000..cb1b41be9b --- /dev/null +++ b/querydsl-sql-spatial/src/test/java/com/querydsl/sql/spatial/suites/H2LiteralsSuiteTest.java @@ -0,0 +1,24 @@ +package com.querydsl.sql.spatial.suites; + +import com.querydsl.sql.spatial.H2GISTemplates; +import org.junit.BeforeClass; +import org.junit.experimental.categories.Category; + +import com.querydsl.core.testutil.H2; +import com.querydsl.sql.Connections; +import com.querydsl.sql.spatial.SpatialBase; +import com.querydsl.sql.suites.AbstractSuite; + +@Category(H2.class) +public class H2LiteralsSuiteTest extends AbstractSuite { + + public static class Spatial extends SpatialBase { } + + @BeforeClass + public static void setUp() throws Exception { + Connections.initH2(); + Connections.initConfiguration(H2GISTemplates.builder().newLineToSingleSpace().build()); + Connections.getConfiguration().setUseLiterals(true); + } + +} diff --git a/querydsl-sql-spatial/src/test/java/com/querydsl/sql/spatial/suites/H2SuiteTest.java b/querydsl-sql-spatial/src/test/java/com/querydsl/sql/spatial/suites/H2SuiteTest.java new file mode 100644 index 0000000000..88d8604779 --- /dev/null +++ b/querydsl-sql-spatial/src/test/java/com/querydsl/sql/spatial/suites/H2SuiteTest.java @@ -0,0 +1,23 @@ +package com.querydsl.sql.spatial.suites; + +import com.querydsl.sql.spatial.H2GISTemplates; +import org.junit.BeforeClass; +import org.junit.experimental.categories.Category; + +import com.querydsl.core.testutil.H2; +import com.querydsl.sql.Connections; +import com.querydsl.sql.spatial.SpatialBase; +import com.querydsl.sql.suites.AbstractSuite; + +@Category(H2.class) +public class H2SuiteTest extends AbstractSuite { + + public static class Spatial extends SpatialBase { } + + @BeforeClass + public static void setUp() throws Exception { + Connections.initH2(); + Connections.initConfiguration(H2GISTemplates.builder().newLineToSingleSpace().build()); + } + +} diff --git a/querydsl-sql-spatial/src/test/java/com/querydsl/sql/spatial/suites/MSSQLLiteralsSuiteTest.java b/querydsl-sql-spatial/src/test/java/com/querydsl/sql/spatial/suites/MSSQLLiteralsSuiteTest.java new file mode 100644 index 0000000000..4d2254489b --- /dev/null +++ b/querydsl-sql-spatial/src/test/java/com/querydsl/sql/spatial/suites/MSSQLLiteralsSuiteTest.java @@ -0,0 +1,24 @@ +package com.querydsl.sql.spatial.suites; + +import org.junit.BeforeClass; +import org.junit.experimental.categories.Category; + +import com.querydsl.core.testutil.SQLServer; +import com.querydsl.sql.Connections; +import com.querydsl.sql.spatial.SQLServer2008SpatialTemplates; +import com.querydsl.sql.spatial.SpatialBase; +import com.querydsl.sql.suites.AbstractSuite; + +@Category(SQLServer.class) +public class MSSQLLiteralsSuiteTest extends AbstractSuite { + + public static class Spatial extends SpatialBase { } + + @BeforeClass + public static void setUp() throws Exception { + Connections.initSQLServer(); + Connections.initConfiguration(SQLServer2008SpatialTemplates.builder().newLineToSingleSpace().build()); + Connections.getConfiguration().setUseLiterals(true); + } + +} diff --git a/querydsl-sql-spatial/src/test/java/com/querydsl/sql/spatial/suites/MSSQLSuiteTest.java b/querydsl-sql-spatial/src/test/java/com/querydsl/sql/spatial/suites/MSSQLSuiteTest.java new file mode 100644 index 0000000000..9040296ac7 --- /dev/null +++ b/querydsl-sql-spatial/src/test/java/com/querydsl/sql/spatial/suites/MSSQLSuiteTest.java @@ -0,0 +1,23 @@ +package com.querydsl.sql.spatial.suites; + +import org.junit.BeforeClass; +import org.junit.experimental.categories.Category; + +import com.querydsl.core.testutil.SQLServer; +import com.querydsl.sql.Connections; +import com.querydsl.sql.spatial.SQLServer2008SpatialTemplates; +import com.querydsl.sql.spatial.SpatialBase; +import com.querydsl.sql.suites.AbstractSuite; + +@Category(SQLServer.class) +public class MSSQLSuiteTest extends AbstractSuite { + + public static class Spatial extends SpatialBase { } + + @BeforeClass + public static void setUp() throws Exception { + Connections.initSQLServer(); + Connections.initConfiguration(SQLServer2008SpatialTemplates.builder().newLineToSingleSpace().build()); + } + +} diff --git a/querydsl-sql-spatial/src/test/java/com/querydsl/sql/spatial/suites/MySQLLiteralsSuiteTest.java b/querydsl-sql-spatial/src/test/java/com/querydsl/sql/spatial/suites/MySQLLiteralsSuiteTest.java new file mode 100644 index 0000000000..c3c9c8f508 --- /dev/null +++ b/querydsl-sql-spatial/src/test/java/com/querydsl/sql/spatial/suites/MySQLLiteralsSuiteTest.java @@ -0,0 +1,24 @@ +package com.querydsl.sql.spatial.suites; + +import org.junit.BeforeClass; +import org.junit.experimental.categories.Category; + +import com.querydsl.core.testutil.MySQL; +import com.querydsl.sql.Connections; +import com.querydsl.sql.spatial.MySQLSpatialTemplates; +import com.querydsl.sql.spatial.SpatialBase; +import com.querydsl.sql.suites.AbstractSuite; + +@Category(MySQL.class) +public class MySQLLiteralsSuiteTest extends AbstractSuite { + + public static class Spatial extends SpatialBase { } + + @BeforeClass + public static void setUp() throws Exception { + Connections.initMySQL(); + Connections.initConfiguration(MySQLSpatialTemplates.builder().newLineToSingleSpace().build()); + Connections.getConfiguration().setUseLiterals(true); + } + +} diff --git a/querydsl-sql-spatial/src/test/java/com/querydsl/sql/spatial/suites/MySQLSuiteTest.java b/querydsl-sql-spatial/src/test/java/com/querydsl/sql/spatial/suites/MySQLSuiteTest.java new file mode 100644 index 0000000000..1d355777da --- /dev/null +++ b/querydsl-sql-spatial/src/test/java/com/querydsl/sql/spatial/suites/MySQLSuiteTest.java @@ -0,0 +1,23 @@ +package com.querydsl.sql.spatial.suites; + +import org.junit.BeforeClass; +import org.junit.experimental.categories.Category; + +import com.querydsl.core.testutil.MySQL; +import com.querydsl.sql.Connections; +import com.querydsl.sql.spatial.MySQLSpatialTemplates; +import com.querydsl.sql.spatial.SpatialBase; +import com.querydsl.sql.suites.AbstractSuite; + +@Category(MySQL.class) +public class MySQLSuiteTest extends AbstractSuite { + + public static class Spatial extends SpatialBase { } + + @BeforeClass + public static void setUp() throws Exception { + Connections.initMySQL(); + Connections.initConfiguration(MySQLSpatialTemplates.builder().newLineToSingleSpace().build()); + } + +} diff --git a/querydsl-sql-spatial/src/test/java/com/querydsl/sql/spatial/suites/PostgreSQLLiteralsSuiteTest.java b/querydsl-sql-spatial/src/test/java/com/querydsl/sql/spatial/suites/PostgreSQLLiteralsSuiteTest.java new file mode 100644 index 0000000000..ad03e6a57e --- /dev/null +++ b/querydsl-sql-spatial/src/test/java/com/querydsl/sql/spatial/suites/PostgreSQLLiteralsSuiteTest.java @@ -0,0 +1,24 @@ +package com.querydsl.sql.spatial.suites; + +import org.junit.BeforeClass; +import org.junit.experimental.categories.Category; + +import com.querydsl.core.testutil.PostgreSQL; +import com.querydsl.sql.Connections; +import com.querydsl.sql.spatial.PostGISTemplates; +import com.querydsl.sql.spatial.SpatialBase; +import com.querydsl.sql.suites.AbstractSuite; + +@Category(PostgreSQL.class) +public class PostgreSQLLiteralsSuiteTest extends AbstractSuite { + + public static class Spatial extends SpatialBase { } + + @BeforeClass + public static void setUp() throws Exception { + Connections.initPostgreSQL(); + Connections.initConfiguration(PostGISTemplates.builder().quote().newLineToSingleSpace().build()); + Connections.getConfiguration().setUseLiterals(true); + } + +} diff --git a/querydsl-sql-spatial/src/test/java/com/querydsl/sql/spatial/suites/PostgreSQLSuiteTest.java b/querydsl-sql-spatial/src/test/java/com/querydsl/sql/spatial/suites/PostgreSQLSuiteTest.java new file mode 100644 index 0000000000..d0a7b2cf90 --- /dev/null +++ b/querydsl-sql-spatial/src/test/java/com/querydsl/sql/spatial/suites/PostgreSQLSuiteTest.java @@ -0,0 +1,23 @@ +package com.querydsl.sql.spatial.suites; + +import org.junit.BeforeClass; +import org.junit.experimental.categories.Category; + +import com.querydsl.core.testutil.PostgreSQL; +import com.querydsl.sql.Connections; +import com.querydsl.sql.spatial.PostGISTemplates; +import com.querydsl.sql.spatial.SpatialBase; +import com.querydsl.sql.suites.AbstractSuite; + +@Category(PostgreSQL.class) +public class PostgreSQLSuiteTest extends AbstractSuite { + + public static class Spatial extends SpatialBase { } + + @BeforeClass + public static void setUp() throws Exception { + Connections.initPostgreSQL(); + Connections.initConfiguration(PostGISTemplates.builder().quote().newLineToSingleSpace().build()); + } + +} diff --git a/querydsl-sql-spatial/src/test/java/com/querydsl/sql/spatial/suites/SpatialTest.java b/querydsl-sql-spatial/src/test/java/com/querydsl/sql/spatial/suites/SpatialTest.java new file mode 100644 index 0000000000..34ccdcb3f9 --- /dev/null +++ b/querydsl-sql-spatial/src/test/java/com/querydsl/sql/spatial/suites/SpatialTest.java @@ -0,0 +1,54 @@ +package com.querydsl.sql.spatial.suites; + +import java.sql.*; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +import com.querydsl.core.testutil.H2; +import com.querydsl.sql.Connections; + +@Category(H2.class) +public class SpatialTest { + + @Before + public void setUp() throws ClassNotFoundException, SQLException { + Connections.initH2(); +// Connections.initMySQL(); +// Connections.initPostgreSQL(); +// Connections.initTeradata(); + } + + @After + public void tearDown() throws SQLException { + Connections.close(); + } + + @Test + public void test() throws SQLException { + Statement stmt = Connections.getStatement(); + try (ResultSet rs = stmt.executeQuery("select \"GEOMETRY\" from \"SHAPES\"")) { + while (rs.next()) { + System.err.println(rs.getObject(1).getClass().getName()); + System.err.println(rs.getString(1)); +// Clob clob = rs.getClob(1); +// System.err.println(clob.getSubString(1, (int) clob.length())); + } + } + } + + @Test + public void metadata() throws SQLException { + Connection conn = Connections.getConnection(); + DatabaseMetaData md = conn.getMetaData(); + try (ResultSet rs = md.getColumns(null, null, "SHAPES", "GEOMETRY")) { + rs.next(); + int type = rs.getInt("DATA_TYPE"); + String typeName = rs.getString("TYPE_NAME"); + System.err.println(type + " " + typeName); + } + } + +} diff --git a/querydsl-sql-spring/pom.xml b/querydsl-sql-spring/pom.xml new file mode 100644 index 0000000000..8731ecc684 --- /dev/null +++ b/querydsl-sql-spring/pom.xml @@ -0,0 +1,50 @@ + + + 4.0.0 + + + com.querydsl + querydsl-root + 5.1.0 + ../pom.xml + + + com.querydsl + querydsl-sql-spring + Querydsl - SQL Spring support + SQL Spring support for Querydsl + + + + 5.3.26 + + + + + org.jetbrains + annotations + provided + + + com.querydsl + querydsl-sql + ${project.version} + + + org.springframework + spring-jdbc + ${spring.version} + provided + + + + + + + org.apache.felix + maven-bundle-plugin + + + + + diff --git a/querydsl-sql-spring/src/main/java/com/querydsl/sql/spring/SpringConnectionProvider.java b/querydsl-sql-spring/src/main/java/com/querydsl/sql/spring/SpringConnectionProvider.java new file mode 100644 index 0000000000..90f087f394 --- /dev/null +++ b/querydsl-sql-spring/src/main/java/com/querydsl/sql/spring/SpringConnectionProvider.java @@ -0,0 +1,51 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.spring; + +import java.sql.Connection; +import java.util.function.Supplier; + +import javax.sql.DataSource; + +import org.springframework.jdbc.datasource.DataSourceUtils; + +/** + * {@code SpringConnectionProvider} is a Provider implementation which provides a transactionally bound connection + * + *

Usage example

+ *
+ * {@code
+ * Provider provider = new SpringConnectionProvider(dataSource());
+ * SQLQueryFactory queryFactory = SQLQueryFactory(configuration, provider);
+ * }
+ * 
+ */ +public class SpringConnectionProvider implements Supplier { + + private final DataSource dataSource; + + public SpringConnectionProvider(DataSource dataSource) { + this.dataSource = dataSource; + } + + @Override + public Connection get() { + Connection connection = DataSourceUtils.getConnection(dataSource); + if (!DataSourceUtils.isConnectionTransactional(connection, dataSource)) { + throw new IllegalStateException("Connection is not transactional"); + } + return connection; + } + +} \ No newline at end of file diff --git a/querydsl-sql-spring/src/main/java/com/querydsl/sql/spring/SpringExceptionTranslator.java b/querydsl-sql-spring/src/main/java/com/querydsl/sql/spring/SpringExceptionTranslator.java new file mode 100644 index 0000000000..88caff976d --- /dev/null +++ b/querydsl-sql-spring/src/main/java/com/querydsl/sql/spring/SpringExceptionTranslator.java @@ -0,0 +1,57 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.spring; + +import java.sql.SQLException; +import java.util.List; + +import org.springframework.jdbc.support.SQLExceptionTranslator; +import org.springframework.jdbc.support.SQLStateSQLExceptionTranslator; + +/** + * {@code SpringExceptionTranslator} is an {@link SQLExceptionTranslator} implementation which uses Spring's + * exception translation functionality internally + * + *

Usage example

+ *
+ * {@code
+ * Configuration configuration = new Configuration(templates);
+ * configuration.setExceptionTranslator(new SpringExceptionTranslator());
+ * }
+ * 
+ * + */ +public class SpringExceptionTranslator implements com.querydsl.sql.SQLExceptionTranslator { + + private final SQLExceptionTranslator translator; + + public SpringExceptionTranslator() { + this.translator = new SQLStateSQLExceptionTranslator(); + } + + public SpringExceptionTranslator(SQLExceptionTranslator translator) { + this.translator = translator; + } + + @Override + public RuntimeException translate(String sql, List bindings, SQLException e) { + return translator.translate(null, sql, e); + } + + @Override + public RuntimeException translate(SQLException e) { + return translator.translate(null, null, e); + } + +} \ No newline at end of file diff --git a/querydsl-sql-spring/src/main/java/com/querydsl/sql/spring/package-info.java b/querydsl-sql-spring/src/main/java/com/querydsl/sql/spring/package-info.java new file mode 100644 index 0000000000..628b475f46 --- /dev/null +++ b/querydsl-sql-spring/src/main/java/com/querydsl/sql/spring/package-info.java @@ -0,0 +1,18 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ + +/** + * Spring support + */ +package com.querydsl.sql.spring; diff --git a/querydsl-sql/README.md b/querydsl-sql/README.md index ddb7938ece..51b21d18c4 100644 --- a/querydsl-sql/README.md +++ b/querydsl-sql/README.md @@ -6,60 +6,68 @@ The SQL module provides integration with the JDBC API. Add the following dependencies to your Maven project : - - com.mysema.querydsl - querydsl-sql - ${querydsl.version} - - - - org.slf4j - slf4j-log4j12 - 1.6.1 - +```XML + + com.querydsl + querydsl-sql + ${querydsl.version} + +``` **Code generation via Maven** This functionality is also available as a Maven plugin. The presented example can be declared like this in the POM : - - - com.mysema.querydsl - querydsl-maven-plugin - ${querydsl.version} - - - - export - - - - - org.apache.derby.jdbc.EmbeddedDriver - jdbc:derby:target/demoDB;create=true - com.myproject.domain - ${project.basedir}/target/generated-sources/java - - - - org.apache.derby - derby - ${derby.version} - - - + +```XML + + + + ... + + com.querydsl + querydsl-maven-plugin + ${querydsl.version} + + + + export + + + + + org.apache.derby.jdbc.EmbeddedDriver + jdbc:derby:target/demoDB;create=true + com.myproject.domain + ${project.basedir}/target/generated-sources/java + + + + org.apache.derby + derby + ${derby.version} + + + + ... + + + +``` Use the goal test-export to add the targetFolder as a test compile source root instead of a compile source root. **Querying** Querying with Querydsl SQL is as simple as this : - - QCustomer customer = new QCustomer("c"); - SQLTemplates dialect = new HSQLDBTemplates(); // SQL-dialect - SQLQuery query = new SQLQuery(connection, dialect); - List lastNames = query.from(customer) - .where(customer.firstName.eq("Bob")) - .list(customer.lastName); - +```JAVA +QCustomer customer = new QCustomer("c"); + +SQLTemplates dialect = new HSQLDBTemplates(); // SQL-dialect +SQLQuery query = new SQLQuery(connection, dialect); +List lastNames = query.select(customer.lastName) + .from(customer) + .where(customer.firstName.eq("Bob")) + .fetch(); +``` For more information on the Querydsl SQL module visit the reference documentation http://www.querydsl.com/static/querydsl/latest/reference/html/ch02s03.html diff --git a/querydsl-sql/pom.xml b/querydsl-sql/pom.xml index 2c8dd34043..2a7437dc6b 100644 --- a/querydsl-sql/pom.xml +++ b/querydsl-sql/pom.xml @@ -1,70 +1,67 @@ - + 4.0.0 - com.mysema.querydsl + com.querydsl querydsl-root - 3.4.1.BUILD-SNAPSHOT - ../querydsl-root/pom.xml + 5.1.0 + ../pom.xml - com.mysema.querydsl + com.querydsl querydsl-sql Querydsl - SQL support SQL support for Querydsl jar - 1.11 + + org.joda.time.*;version="[1.6,3)", + ${osgi.import.package.root} + + -Xms256m -Xmx512m -Duser.timezone=UTC - com.mysema.querydsl - querydsl-core - ${project.version} - - - com.mysema.querydsl - querydsl-spatial - ${project.version} + org.jetbrains + annotations provided + - com.vividsolutions - jts - 1.10 - provided + com.querydsl + querydsl-core + ${project.version} + joda-time joda-time - 1.6 - + ${jodatime.version} + provided + true + javax.validation validation-api - 1.0.0.GA + test - + + - org.slf4j - slf4j-api + com.ibm.db2 + jcc + ${db2.version} + test - org.slf4j - slf4j-log4j12 - provided - - - - javax.inject - javax.inject - 1 - - - + cglib + cglib + ${cglib.version} + test + org.hsqldb hsqldb @@ -78,6 +75,12 @@ ${derby.version} test + + org.apache.derby + derbytools + ${derby.version} + test + mysql mysql-connector-java @@ -88,51 +91,76 @@ org.postgresql postgresql ${postgresql.version} - provided + test + + + org.slf4j + slf4j-simple + + org.postgis postgis-jdbc 1.3.3 - provided + test - com.oracle - ojdbc6 + com.oracle.database.jdbc + ojdbc8 ${oracle.version} - provided + test oracle sdoapi 11.2.0 - provided + test - net.sourceforge.jtds - jtds - ${jtds.version} + com.microsoft.sqlserver + mssql-jdbc + ${mssql.version} test com.h2database h2 - ${h2.version} test - org.opengeo - geodb - 0.7 + org.orbisgis + h2gis + ${h2gis.version} + test + + + log4j + log4j + + + jts-core + org.locationtech.jts + + + slf4j-api + org.slf4j + + + + + + com.github.jinahya + cubrid-jdbc-driver-${cubrid.version} + 1.0.0 test - - cubrid - cubrid-jdbc - ${cubrid.version} + org.firebirdsql.jdbc + jaybird + ${firebird.version} test - + org.xerial @@ -142,13 +170,24 @@ - com.mysema.querydsl + com.querydsl querydsl-core ${project.version} test test-jar - - + + + io.github.classgraph + classgraph + test + + + com.querydsl + querydsl-spatial + ${project.version} + test + + jdepend jdepend @@ -156,63 +195,34 @@ test - - com.infradna.tool - bridge-method-annotation - ${bridge-method.version} - - - org.jenkins-ci - annotation-indexer - - + org.openjdk.jmh + jmh-core + ${jmh.version} + test + + + + org.openjdk.jmh + jmh-generator-annprocess + ${jmh.version} + test + + org.jvnet.hudson annotation-indexer 1.2 true - - com.infradna.tool - bridge-method-injector - ${bridge-method.version} - - - - process - - - - - - com.infradna.tool - bridge-method-annotation - ${bridge-method.version} - true - - - org.jenkins-ci - annotation-indexer - - - - - org.jvnet.hudson - annotation-indexer - 1.2 - - - - - com.springsource.bundlor - com.springsource.bundlor.maven + org.apache.felix + maven-bundle-plugin @@ -226,6 +236,13 @@ + + + + com.querydsl.sql + + + maven-source-plugin @@ -249,11 +266,18 @@ - - + + + + org.apache.maven.plugins + maven-compiler-plugin + + -proc:none + + - - - CUBRID - http://maven.cubrid.org - - datanucleus - http://www.datanucleus.org/downloads/maven2 + https://www.datanucleus.org/downloads/maven2 - - + + diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/AbstractSQLQuery.java b/querydsl-sql/src/main/java/com/mysema/query/sql/AbstractSQLQuery.java deleted file mode 100644 index 293a52a5f1..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/AbstractSQLQuery.java +++ /dev/null @@ -1,435 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import java.lang.reflect.InvocationTargetException; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import javax.annotation.Nullable; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.mysema.commons.lang.CloseableIterator; -import com.mysema.query.DefaultQueryMetadata; -import com.mysema.query.QueryException; -import com.mysema.query.QueryFlag; -import com.mysema.query.QueryMetadata; -import com.mysema.query.QueryModifiers; -import com.mysema.query.SearchResults; -import com.mysema.query.support.QueryMixin; -import com.mysema.query.types.Expression; -import com.mysema.query.types.FactoryExpression; -import com.mysema.query.types.ParamExpression; -import com.mysema.query.types.ParamNotSetException; -import com.mysema.query.types.Path; -import com.mysema.util.ResultSetAdapter; - -/** - * AbstractSQLQuery is the base type for SQL query implementations - * - * @author tiwe - * - * @param concrete subtype - */ -public abstract class AbstractSQLQuery> extends ProjectableSQLQuery { - - private static final Logger logger = LoggerFactory.getLogger(AbstractSQLQuery.class); - - private static final QueryFlag rowCountFlag = new QueryFlag(QueryFlag.Position.AFTER_PROJECTION, ", count(*) over() "); - - @Nullable - private final Connection conn; - - protected SQLListeners listeners; - - protected boolean useLiterals; - - private boolean getLastCell; - - private Object lastCell; - - public AbstractSQLQuery(@Nullable Connection conn, Configuration configuration) { - this(conn, configuration, new DefaultQueryMetadata().noValidate()); - } - - public AbstractSQLQuery(@Nullable Connection conn, Configuration configuration, QueryMetadata metadata) { - super(new QueryMixin(metadata, false), configuration); - this.conn = conn; - this.listeners = new SQLListeners(configuration.getListeners()); - this.useLiterals = configuration.getUseLiterals(); - } - - /** - * @param listener - */ - public void addListener(SQLListener listener) { - listeners.add(listener); - } - - @Override - public long count() { - try { - return unsafeCount(); - } catch (SQLException e) { - String error = "Caught " + e.getClass().getName(); - logger.error(error, e); - throw configuration.translate(e); - } - } - - /** - * If you use forUpdate() with a backend that uses page or row locks, rows examined by the - * query are write-locked until the end of the current transaction. - * - * Not supported for SQLite and CUBRID - * - * @return - */ - public Q forUpdate() { - return addFlag(SQLOps.FOR_UPDATE_FLAG); - } - - protected SQLSerializer createSerializer() { - SQLSerializer serializer = new SQLSerializer(configuration); - serializer.setUseLiterals(useLiterals); - return serializer; - } - - @Nullable - private T get(ResultSet rs, Expression expr, int i, Class type) throws SQLException { - return configuration.get(rs, expr instanceof Path ? (Path)expr : null, i, type); - } - - private void set(PreparedStatement stmt, Path path, int i, Object value) throws SQLException{ - configuration.set(stmt, path, i, value); - } - - /** - * Get the results as an JDBC result set - * - * @param args - * @return - */ - public ResultSet getResults(Expression... exprs) { - queryMixin.addProjection(exprs); - SQLSerializer serializer = serialize(false); - String queryString = serializer.toString(); - if (logger.isDebugEnabled()) { - logger.debug("query : {}", queryString); - } - listeners.notifyQuery(queryMixin.getMetadata()); - - List constants = serializer.getConstants(); - try { - final PreparedStatement stmt = conn.prepareStatement(queryString); - setParameters(stmt, constants, serializer.getConstantPaths(), getMetadata().getParams()); - final ResultSet rs = stmt.executeQuery(); - - return new ResultSetAdapter(rs) { - @Override - public void close() throws SQLException { - try { - super.close(); - } finally { - stmt.close(); - } - } - }; - } catch (SQLException e) { - throw configuration.translate(queryString, constants, e); - } finally { - reset(); - } - } - - protected Configuration getConfiguration() { - return configuration; - } - - @Override - public CloseableIterator iterate(Expression expr) { - expr = queryMixin.addProjection(expr); - return iterateSingle(queryMixin.getMetadata(), expr); - } - - @SuppressWarnings("unchecked") - private CloseableIterator iterateSingle(QueryMetadata metadata, @Nullable final Expression expr) { - SQLSerializer serializer = serialize(false); - final String queryString = serializer.toString(); - if (logger.isDebugEnabled()) { - logger.debug("query : {}", queryString); - } - listeners.notifyQuery(queryMixin.getMetadata()); - List constants = serializer.getConstants(); - try { - final PreparedStatement stmt = conn.prepareStatement(queryString); - setParameters(stmt, constants, serializer.getConstantPaths(), metadata.getParams()); - final ResultSet rs = stmt.executeQuery(); - - if (expr == null) { - return new SQLResultIterator(configuration, stmt, rs) { - @Override - public RT produceNext(ResultSet rs) throws Exception { - return (RT) rs.getObject(1); - } - }; - } else if (expr instanceof FactoryExpression) { - return new SQLResultIterator(configuration, stmt, rs) { - @Override - public RT produceNext(ResultSet rs) throws Exception { - return newInstance((FactoryExpression) expr, rs, 0); - } - }; - } else if (expr.getType().isArray()) { - return new SQLResultIterator(configuration, stmt, rs) { - @Override - public RT produceNext(ResultSet rs) throws Exception { - Object[] rv = new Object[rs.getMetaData().getColumnCount()]; - for (int i = 0; i < rv.length; i++) { - rv[i] = rs.getObject(i+1); - } - return (RT) rv; - } - }; - } else { - return new SQLResultIterator(configuration, stmt, rs) { - @Override - public RT produceNext(ResultSet rs) throws Exception { - return get(rs, expr, 1, expr.getType()); - } - }; - } - - } catch (SQLException e) { - throw configuration.translate(queryString, constants, e); - } finally { - reset(); - } - } - - @SuppressWarnings("unchecked") - @Override - public List list(Expression expr) { - expr = queryMixin.addProjection(expr); - SQLSerializer serializer = serialize(false); - final String queryString = serializer.toString(); - if (logger.isDebugEnabled()) { - logger.debug("query : {}", queryString); - } - listeners.notifyQuery(queryMixin.getMetadata()); - List constants = serializer.getConstants(); - try { - final PreparedStatement stmt = conn.prepareStatement(queryString); - try { - setParameters(stmt, constants, serializer.getConstantPaths(), queryMixin.getMetadata().getParams()); - final ResultSet rs = stmt.executeQuery(); - try { - lastCell = null; - final List rv = new ArrayList(); - if (expr instanceof FactoryExpression) { - FactoryExpression fe = (FactoryExpression)expr; - while (rs.next()) { - if (getLastCell) { - lastCell = rs.getObject(fe.getArgs().size() + 1); - getLastCell = false; - } - rv.add(newInstance(fe, rs, 0)); - } - } else if (expr.getType().isArray()) { - while (rs.next()) { - Object[] row = new Object[rs.getMetaData().getColumnCount()]; - if (getLastCell) { - lastCell = rs.getObject(row.length); - getLastCell = false; - } - for (int i = 0; i < row.length; i++) { - row[i] = rs.getObject(i+1); - } - rv.add((RT)row); - } - } else { - while (rs.next()) { - if (getLastCell) { - lastCell = rs.getObject(2); - getLastCell = false; - } - rv.add(get(rs, expr, 1, expr.getType())); - } - } - return rv; - } catch (IllegalAccessException e) { - throw new QueryException(e); - } catch (InvocationTargetException e) { - throw new QueryException(e); - } catch (InstantiationException e) { - throw new QueryException(e); - } catch (SQLException e) { - throw configuration.translate(queryString, constants, e); - } finally { - rs.close(); - } - } finally { - stmt.close(); - } - } catch (SQLException e) { - throw configuration.translate(queryString, constants, e); - } finally { - reset(); - } - } - - @Override - public SearchResults listResults(Expression expr) { - try { - if (configuration.getTemplates().isCountViaAnalytics()) { - List results; - try { - queryMixin.addFlag(rowCountFlag); - getLastCell = true; - results = list(expr); - } finally { - queryMixin.removeFlag(rowCountFlag); - } - long total; - if (!results.isEmpty()) { - if (lastCell instanceof Number) { - total = ((Number)lastCell).longValue(); - } else { - throw new IllegalStateException("Unsupported lastCell instance " + lastCell); - } - } else { - total = count(); - } - QueryModifiers modifiers = queryMixin.getMetadata().getModifiers(); - return new SearchResults(results, modifiers, total); - - } else { - queryMixin.addProjection(expr); - long total = count(); - if (total > 0) { - queryMixin.getMetadata().clearProjection(); - QueryModifiers modifiers = queryMixin.getMetadata().getModifiers(); - return new SearchResults(list(expr), modifiers, total); - } else { - return SearchResults.emptyResults(); - } - } - - } finally { - getLastCell = false; - reset(); - } - } - - private RT newInstance(FactoryExpression c, ResultSet rs, int offset) - throws InstantiationException, IllegalAccessException, InvocationTargetException, SQLException{ - Object[] args = new Object[c.getArgs().size()]; - for (int i = 0; i < args.length; i++) { - args[i] = get(rs, c.getArgs().get(i), offset + i + 1, c.getArgs().get(i).getType()); - } - return c.newInstance(args); - } - - private void reset() { - queryMixin.getMetadata().reset(); - } - - protected void setParameters(PreparedStatement stmt, List objects, List> constantPaths, - Map, ?> params) { - if (objects.size() != constantPaths.size()) { - throw new IllegalArgumentException("Expected " + objects.size() + - " paths, but got " + constantPaths.size()); - } - for (int i = 0; i < objects.size(); i++) { - Object o = objects.get(i); - try { - if (o instanceof ParamExpression) { - if (!params.containsKey(o)) { - throw new ParamNotSetException((ParamExpression) o); - } - o = params.get(o); - } - set(stmt, constantPaths.get(i), i+1, o); - } catch (SQLException e) { - throw configuration.translate(e); - } - } - } - - @Override - public RT uniqueResult(Expression expr) { - if (getMetadata().getModifiers().getLimit() == null - && !expr.toString().contains("count(")) { - limit(2); - } - CloseableIterator iterator = iterate(expr); - return uniqueResult(iterator); - } - - private long unsafeCount() throws SQLException { - SQLSerializer serializer = serialize(true); - final String queryString = serializer.toString(); - if (logger.isDebugEnabled()) { - logger.debug("query : {}", queryString); - } - List constants = serializer.getConstants(); - PreparedStatement stmt = null; - ResultSet rs = null; - try { - stmt = conn.prepareStatement(queryString); - setParameters(stmt, constants, serializer.getConstantPaths(), getMetadata().getParams()); - rs = stmt.executeQuery(); - rs.next(); - return rs.getLong(1); - } catch (SQLException e) { - throw configuration.translate(queryString, constants, e); - } finally { - try { - if (rs != null) { - rs.close(); - } - } finally { - if (stmt != null) { - stmt.close(); - } - } - } - } - - public void setUseLiterals(boolean useLiterals) { - this.useLiterals = useLiterals; - } - - @Override - protected void clone(Q query) { - super.clone(query); - this.useLiterals = query.useLiterals; - this.listeners = new SQLListeners(query.listeners); - } - - @Override - public Q clone() { - return this.clone(this.conn); - } - - public abstract Q clone(Connection connection); - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/AbstractSQLQueryFactory.java b/querydsl-sql/src/main/java/com/mysema/query/sql/AbstractSQLQueryFactory.java deleted file mode 100644 index dd045ae178..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/AbstractSQLQueryFactory.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import java.sql.Connection; - -import javax.inject.Provider; - -import com.infradna.tool.bridge_method_injector.WithBridgeMethods; -import com.mysema.query.sql.dml.SQLDeleteClause; -import com.mysema.query.sql.dml.SQLInsertClause; -import com.mysema.query.sql.dml.SQLMergeClause; -import com.mysema.query.sql.dml.SQLUpdateClause; -import com.mysema.query.types.Expression; -import com.mysema.query.types.Path; -import com.mysema.query.types.SubQueryExpression; - -/** - * AbstractSQLQueryFactory is the base class for {@link SQLCommonQueryFactory} implementations - * - * @author tiwe - * - */ -public abstract class AbstractSQLQueryFactory, SQ extends AbstractSQLSubQuery> implements SQLCommonQueryFactory { - - protected final Configuration configuration; - - protected final Provider connection; - - public AbstractSQLQueryFactory(Configuration configuration, Provider connection) { - this.configuration = configuration; - this.connection = connection; - } - - @Override - public final SQLDeleteClause delete(RelationalPath path) { - return new SQLDeleteClause(connection.get(), configuration, path); - } - - @Override - public final Q from(Expression from) { - return (Q) query().from(from); - } - - public final Q from(Expression... args) { - return (Q) query().from(args); - } - - public final Q from(SubQueryExpression subQuery, Path alias) { - return (Q) query().from(subQuery, alias); - } - - @Override - public final SQLInsertClause insert(RelationalPath path) { - return new SQLInsertClause(connection.get(), configuration, path); - } - - @Override - public final SQLMergeClause merge(RelationalPath path) { - return new SQLMergeClause(connection.get(), configuration, path); - } - - @Override - public final SQLUpdateClause update(RelationalPath path) { - return new SQLUpdateClause(connection.get(), configuration, path); - } - - @SuppressWarnings("unchecked") - @Override - @WithBridgeMethods(value=SQLSubQuery.class, castRequired=true) - public SQ subQuery() { - return (SQ) new SQLSubQuery(); - } - - @Override - @WithBridgeMethods(value=SQLSubQuery.class, castRequired=true) - public final SQ subQuery(Expression from) { - return subQuery().from(from); - } - - public final Configuration getConfiguration() { - return configuration; - } - - public final Connection getConnection() { - return connection.get(); - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/AbstractSQLSubQuery.java b/querydsl-sql/src/main/java/com/mysema/query/sql/AbstractSQLSubQuery.java deleted file mode 100644 index e31337e294..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/AbstractSQLSubQuery.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import com.mysema.query.QueryMetadata; - -/** - * Abstract superclass for SubQuery implementations - * - * @author tiwe - * - */ -public abstract class AbstractSQLSubQuery> extends DetachableSQLQuery -{ - - public AbstractSQLSubQuery() - { - super(); - } - - public AbstractSQLSubQuery(QueryMetadata metadata) - { - super(metadata); - } - - public AbstractSQLSubQuery(Configuration configuration, QueryMetadata metadata) - { - super(configuration, metadata); - } - - protected SQLSerializer createSerializer() - { - return new SQLSerializer(configuration); - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/CUBRIDTemplates.java b/querydsl-sql/src/main/java/com/mysema/query/sql/CUBRIDTemplates.java deleted file mode 100644 index b1daa48dff..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/CUBRIDTemplates.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright 2012, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import com.mysema.query.QueryMetadata; -import com.mysema.query.QueryModifiers; -import com.mysema.query.types.Ops; - -/** - * CUBRIDTemplates is a SQL dialect for CUBRID - * - * @author tiwe - * - */ -public class CUBRIDTemplates extends SQLTemplates { - - public static Builder builder() { - return new Builder() { - @Override - protected SQLTemplates build(char escape, boolean quote) { - return new CUBRIDTemplates(escape, quote); - } - }; - } - - private String limitTemplate = "\nlimit {0}"; - - private String offsetLimitTemplate = "\nlimit {0}, {1}"; - - public CUBRIDTemplates() { - this('\\', false); - } - - public CUBRIDTemplates(boolean quote) { - this('\\',quote); - } - - public CUBRIDTemplates(char escape, boolean quote) { - super("\"", escape, quote); - setDummyTable(null); - setParameterMetadataAvailable(false); - setNullsFirst(null); - setNullsLast(null); - setDefaultValues("\ndefault values"); - - add(Ops.DateTimeOps.DAY_OF_YEAR, "dayofyear({0})"); - add(Ops.DateTimeOps.DAY_OF_WEEK, "dayofweek({0})"); - add(Ops.DateTimeOps.YEAR_WEEK, "(year({0}) * 100 + week({0}))"); - - add(Ops.DateTimeOps.ADD_YEARS, "date_add({0}, interval {1s} year)"); - add(Ops.DateTimeOps.ADD_MONTHS, "date_add({0}, interval {1s} month)"); - add(Ops.DateTimeOps.ADD_WEEKS, "date_add({0}, interval {1s} week)"); - add(Ops.DateTimeOps.ADD_DAYS, "date_add({0}, interval {1s} day)"); - add(Ops.DateTimeOps.ADD_HOURS, "date_add({0}, interval {1s} hour)"); - add(Ops.DateTimeOps.ADD_MINUTES, "date_add({0}, interval {1s} minute)"); - add(Ops.DateTimeOps.ADD_SECONDS, "date_add({0}, interval {1s} second)"); - - add(Ops.MathOps.LN, "ln({0})"); - add(Ops.MathOps.LOG, "(ln({0}) / ln({1}))"); - add(Ops.MathOps.COSH, "(exp({0}) + exp({0} * -1)) / 2"); - add(Ops.MathOps.COTH, "(exp({0} * 2) + 1) / (exp({0} * 2) - 1)"); - add(Ops.MathOps.SINH, "(exp({0}) - exp({0} * -1)) / 2"); - add(Ops.MathOps.TANH, "(exp({0} * 2) - 1) / (exp({0} * 2) + 1)"); - } - - @Override - protected void serializeModifiers(QueryMetadata metadata, SQLSerializer context) { - QueryModifiers mod = metadata.getModifiers(); - if (mod.getLimit() != null) { - if (mod.getOffset() != null) { - context.handle(offsetLimitTemplate, mod.getOffset(), mod.getLimit()); - } else { - context.handle(limitTemplate, mod.getLimit()); - } - } else if (mod.getOffset() != null) { - context.handle(offsetLimitTemplate, mod.getOffset(), Integer.MAX_VALUE); - } - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/Configuration.java b/querydsl-sql/src/main/java/com/mysema/query/sql/Configuration.java deleted file mode 100644 index 85f00ed6cc..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/Configuration.java +++ /dev/null @@ -1,472 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Types; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.annotation.Nullable; - -import com.google.common.collect.Maps; -import com.mysema.query.sql.types.Null; -import com.mysema.query.sql.types.Type; -import com.mysema.query.types.Path; - -/** - * Configuration for SQLQuery instances - * - * @author tiwe - * - */ -public final class Configuration { - - public static final Configuration DEFAULT = new Configuration(SQLTemplates.DEFAULT); - - private final JDBCTypeMapping jdbcTypeMapping = new JDBCTypeMapping(); - - private final JavaTypeMapping javaTypeMapping = new JavaTypeMapping(); - - private final Map schemaTables = Maps.newHashMap(); - - private final Map schemas = Maps.newHashMap(); - - private final Map tables = Maps.newHashMap(); - - private final Map> schemaTableColumns = Maps.newHashMap(); - - private final Map> tableColumns = Maps.newHashMap(); - - private final Map> typeToName = Maps.newHashMap(); - - private final SQLTemplates templates; - - private SQLExceptionTranslator exceptionTranslator = DefaultSQLExceptionTranslator.DEFAULT; - - private final SQLListeners listeners = new SQLListeners(); - - private boolean hasTableColumnTypes = false; - - private boolean useLiterals = false; - - /** - * Create a new Configuration instance - * - * @param templates - */ - public Configuration(SQLTemplates templates) { - this.templates = templates; - for (Type customType : templates.getCustomTypes()) { - javaTypeMapping.register(customType); - } - for (Map.Entry entry : templates.getTableOverrides().entrySet()) { - schemaTables.put(entry.getKey(), entry.getValue()); - } - } - - /** - * Get the literal representation of the given constant - * - * @param o - * @return - */ - public String asLiteral(Object o) { - Type type = javaTypeMapping.getType(o.getClass()); - if (type != null) { - return templates.serialize(type.getLiteral(o), type.getSQLTypes()[0]); - } else { - throw new IllegalArgumentException("Unsupported literal type " + o.getClass().getName()); - } - } - - public SQLTemplates getTemplates() { - return templates; - } - - /** - * Use the other getJavaType method instead - * - * @param sqlType - * @param size - * @param digits - * @param tableName - * @param columnName - * @return - */ - @Deprecated - public Class getJavaType(int sqlType, int size, int digits, String tableName, String columnName) { - return getJavaType(sqlType, null, size, digits, tableName, columnName); - } - - /** - * Get the java type for the given jdbc type, table name and column name - * - * @param sqlType - * @param typeName - * @param size - * @param digits - * @param tableName - * @param columnName - * @return - */ - public Class getJavaType(int sqlType, String typeName, int size, int digits, String tableName, String columnName) { - // table.column mapped class - Type type = javaTypeMapping.getType(tableName, columnName); - if (type != null) { - return type.getReturnedClass(); - } else if (typeName != null && !typeToName.isEmpty()) { - // typename mapped class - Class clazz = typeToName.get(typeName.toLowerCase()); - if (clazz != null) { - return clazz; - } - } - // sql type mapped class - return jdbcTypeMapping.get(sqlType, size, digits); - } - - /** - * @param - * @param rs - * @param path - * @param i - * @param clazz - * @return - * @throws SQLException - */ - @Nullable - public T get(ResultSet rs, @Nullable Path path, int i, Class clazz) throws SQLException { - return getType(path, clazz).getValue(rs, i); - } - - /** - * Use getOverride instead - * - * @param schema - * @return - */ - @Deprecated - public String getSchema(String schema) { - return schemas.get(schema); - } - - /** - * Use getOverride instead - * - * @param schema - * @param table - * @return - */ - @Deprecated - public String getTable(String schema, String table) { - return getOverride(new SchemaAndTable(schema, table)).getTable(); - } - - /** - * Get the schema/table override - * - * @param schema - * @param table - * @return - */ - @Nullable - public SchemaAndTable getOverride(SchemaAndTable key) { - if (!schemaTables.isEmpty() && key.getSchema() != null) { - if (schemaTables.containsKey(key)) { - return schemaTables.get(key); - } - } - String schema = key.getSchema(), table = key.getTable(); - boolean changed = false; - if (schemas.containsKey(key.getSchema())) { - schema = schemas.get(key.getSchema()); - changed = true; - } - - if (tables.containsKey(key.getTable())) { - table = tables.get(key.getTable()); - changed = true; - } - return changed ? new SchemaAndTable(schema, table) : key; - } - - /** - * Get the column override - * - * @param key - * @param column - * @return - */ - public String getColumnOverride(SchemaAndTable key, String column) { - Map columnOverrides; - String newColumn = null; - columnOverrides = schemaTableColumns.get(key); - if (columnOverrides != null && (newColumn = columnOverrides.get(column)) != null) { - return newColumn; - } - columnOverrides = tableColumns.get(key.getTable()); - if (columnOverrides != null && (newColumn = columnOverrides.get(column)) != null) { - return newColumn; - } - return column; - - } - - /** - * @param - * @param stmt - * @param path - * @param i - * @param value - * @return - * @throws SQLException - */ - @SuppressWarnings({ "unchecked", "rawtypes" }) - public void set(PreparedStatement stmt, Path path, int i, T value) throws SQLException { - if (Null.class.isInstance(value)) { - Integer sqlType = path != null ? jdbcTypeMapping.get(path.getType()) : null; - if (sqlType != null) { - stmt.setNull(i, sqlType); - } else { - stmt.setNull(i, Types.NULL); - } - } else { - getType(path, (Class)value.getClass()).setValue(stmt, i, value); - } - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - private Type getType(@Nullable Path path, Class clazz) { - if (hasTableColumnTypes && path != null && !clazz.equals(Null.class) - && path.getMetadata().getParent() instanceof RelationalPath) { - String table = ((RelationalPath)path.getMetadata().getParent()).getTableName(); - String column = ColumnMetadata.getName(path); - Type type = (Type)javaTypeMapping.getType(table, column); - if (type != null) { - return type; - } - } - return javaTypeMapping.getType(clazz); - } - - /** - * Register a schema override - * - * @param oldSchema - * @param newSchema - * @return - */ - public String registerSchemaOverride(String oldSchema, String newSchema) { - return schemas.put(oldSchema, newSchema); - } - - /** - * Register a table override - * - * @param oldTable - * @param newTable - * @return - */ - public String registerTableOverride(String oldTable, String newTable) { - return tables.put(oldTable, newTable); - } - - /** - * Register a schema specific table override - * - * @param schema - * @param oldTable - * @param newTable - * @return - */ - public String registerTableOverride(String schema, String oldTable, String newTable) { - SchemaAndTable st = registerTableOverride(schema, oldTable, schema, newTable); - return st != null ? st.getTable() : null; - } - - /** - * Register a schema specific table override - * - * @param schema - * @param oldTable - * @param newSchema - * @param newTable - * @return - */ - public SchemaAndTable registerTableOverride(String schema, String oldTable, String newSchema, String newTable) { - return registerTableOverride(new SchemaAndTable(schema, oldTable), new SchemaAndTable(newSchema, newTable)); - } - - /** - * Register a schema specific table override - * - * @param from - * @param to - * @return - */ - public SchemaAndTable registerTableOverride(SchemaAndTable from, SchemaAndTable to) { - return schemaTables.put(from, to); - } - - /** - * Register a column override - * - * @param schema - * @param table - * @param oldColumn - * @param newColumn - * @return - */ - public String registerColumnOverride(String schema, String table, String oldColumn, String newColumn) { - SchemaAndTable key = new SchemaAndTable(schema, table); - Map columnOverrides = schemaTableColumns.get(key); - if (columnOverrides == null) { - columnOverrides = new HashMap(); - schemaTableColumns.put(key, columnOverrides); - } - return columnOverrides.put(oldColumn, newColumn); - } - - /** - * Register a column override - * - * @param table - * @param oldColumn - * @param newColumn - * @return - */ - public String registerColumnOverride(String table, String oldColumn, String newColumn) { - Map columnOverrides = tableColumns.get(table); - if (columnOverrides == null) { - columnOverrides = new HashMap(); - tableColumns.put(table, columnOverrides); - } - return columnOverrides.put(oldColumn, newColumn); - } - - /** - * Register the given {@link Type} converter - * - * @param type - */ - public void register(Type type) { - jdbcTypeMapping.register(type.getSQLTypes()[0], type.getReturnedClass()); - javaTypeMapping.register(type); - } - - /** - * Register a typeName to Class mapping - * - * @param typeName - * @param clazz - */ - public void registerType(String typeName, Class clazz) { - typeToName.put(typeName.toLowerCase(), clazz); - } - - /** - * Override the binding for the given NUMERIC type - * - * @param total total amount of digits - * @param decimal amount of fractional digits - * @param javaType - */ - public void registerNumeric(int total, int decimal, Class javaType) { - jdbcTypeMapping.registerNumeric(total, decimal, javaType); - } - - /** - * Register the given javaType for the given table and column - * - * @param table - * @param column - * @param javaType - */ - public void register(String table, String column, Class javaType) { - register(table, column, javaTypeMapping.getType(javaType)); - } - - /** - * Register the given {@link Type} converter for the given table and column - * - * @param table - * @param column - * @param type - */ - public void register(String table, String column, Type type) { - javaTypeMapping.setType(table, column, type); - hasTableColumnTypes = true; - } - - /** - * Translate the given SQLException - * - * @param ex - * @return - */ - public RuntimeException translate(SQLException ex) { - return exceptionTranslator.translate(ex); - } - - /** - * Translate the given SQLException - * - * @param sql - * @param ex - * @return - */ - public RuntimeException translate(String sql, List bindings, SQLException ex) { - return exceptionTranslator.translate(sql, bindings, ex); - } - - /** - * @param listeners - */ - public void addListener(SQLListener listener) { - listeners.add(listener); - } - - /** - * @return - */ - public SQLListeners getListeners() { - return listeners; - } - - /** - * @return - */ - public boolean getUseLiterals() { - return useLiterals; - } - - /** - * @param useLiterals - */ - public void setUseLiterals(boolean useLiterals) { - this.useLiterals = useLiterals; - } - - /** - * @param exceptionTranslator - */ - public void setExceptionTranslator(SQLExceptionTranslator exceptionTranslator) { - this.exceptionTranslator = exceptionTranslator; - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/DefaultSQLExceptionTranslator.java b/querydsl-sql/src/main/java/com/mysema/query/sql/DefaultSQLExceptionTranslator.java deleted file mode 100644 index e299de94bc..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/DefaultSQLExceptionTranslator.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2014, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import java.sql.SQLException; -import java.util.List; - -import com.mysema.query.QueryException; - -/** - * Default implementation of the SQLExceptionTranslator interface - * - * @author tiwe - * - */ -public final class DefaultSQLExceptionTranslator implements SQLExceptionTranslator { - - public static final SQLExceptionTranslator DEFAULT = new DefaultSQLExceptionTranslator(); - - @Override - public RuntimeException translate(SQLException e) { - return new QueryException(e); - } - - @Override - public RuntimeException translate(String sql, List bindings, SQLException e) { - return new QueryException("Caught " + e.getClass().getSimpleName() + " for " + sql, e); - } - - private DefaultSQLExceptionTranslator() {} -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/DerbyTemplates.java b/querydsl-sql/src/main/java/com/mysema/query/sql/DerbyTemplates.java deleted file mode 100644 index 17c53fd73a..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/DerbyTemplates.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import com.mysema.query.QueryMetadata; -import com.mysema.query.QueryModifiers; -import com.mysema.query.types.Ops; - -import java.sql.Types; - -/** - * DerbyTemplates is an SQL dialect for Derby - * - * @author tiwe - * - */ -public class DerbyTemplates extends SQLTemplates { - - private String limitOffsetTemplate = "\noffset {1s} rows fetch next {0s} rows only"; - - private String limitTemplate = "\nfetch first {0s} rows only"; - - private String offsetTemplate = "\noffset {0s} rows"; - - public static Builder builder() { - return new Builder() { - @Override - protected SQLTemplates build(char escape, boolean quote) { - return new DerbyTemplates(escape, quote); - } - }; - } - - public DerbyTemplates() { - this('\\',false); - } - - public DerbyTemplates(boolean quote) { - this('\\',quote); - } - - public DerbyTemplates(char escape, boolean quote) { - super("\"", escape, quote); - setDummyTable("sysibm.sysdummy1"); - addClass2TypeMappings("smallint", Byte.class); - setAutoIncrement(" generated always as identity"); - setFunctionJoinsWrapped(true); - setDefaultValues("\nvalues (default)"); - - add(Ops.CONCAT, "varchar({0} || {1})"); - add(Ops.DateTimeOps.DAY_OF_MONTH, "day({0})"); - - add(SQLOps.NEXTVAL, "next value for {0s}"); - - // case for eq - add(Ops.CASE_EQ, "case {1} end"); - add(Ops.CASE_EQ_WHEN, "when {0} = {1} then {2} {3}"); - add(Ops.CASE_EQ_ELSE, "else {0}"); - - add(Ops.MathOps.RANDOM, "random()"); - add(Ops.MathOps.ROUND, "floor({0})"); // FIXME - add(Ops.MathOps.POWER, "exp({1} * log({0}))"); - add(Ops.MathOps.LN, "log({0})"); - add(Ops.MathOps.LOG, "(log({0}) / log({1}))"); - add(Ops.MathOps.COTH, "(exp({0} * 2) + 1) / (exp({0} * 2) - 1)"); - - // overrides of the SQL standard functions - add(Ops.DateTimeOps.SECOND, "second({0})"); - add(Ops.DateTimeOps.MINUTE, "minute({0})"); - add(Ops.DateTimeOps.HOUR, "hour({0})"); - add(Ops.DateTimeOps.WEEK, "week({0})"); - add(Ops.DateTimeOps.MONTH, "month({0})"); - add(Ops.DateTimeOps.YEAR, "year({0})"); - add(Ops.DateTimeOps.YEAR_MONTH, "(year({0}) * 100 + month({0}))"); - add(Ops.DateTimeOps.YEAR_WEEK, "(year({0}) * 100 + week({0}))"); - add(Ops.DateTimeOps.DAY_OF_WEEK, "dayofweek({0})"); - add(Ops.DateTimeOps.DAY_OF_MONTH, "day({0})"); - add(Ops.DateTimeOps.DAY_OF_YEAR, "dayofyear({0})"); - - add(Ops.DateTimeOps.ADD_YEARS, "{fn timestampadd(SQL_TSI_YEAR, {1}, {0})}"); - add(Ops.DateTimeOps.ADD_MONTHS, "{fn timestampadd(SQL_TSI_MONTH, {1}, {0})}"); - add(Ops.DateTimeOps.ADD_WEEKS, "{fn timestampadd(SQL_TSI_WEEK, {1}, {0})}"); - add(Ops.DateTimeOps.ADD_DAYS, "{fn timestampadd(SQL_TSI_DAY, {1}, {0})}"); - add(Ops.DateTimeOps.ADD_HOURS, "{fn timestampadd(SQL_TSI_HOUR, {1}, {0})}"); - add(Ops.DateTimeOps.ADD_MINUTES, "{fn timestampadd(SQL_TSI_MINUTE, {1}, {0})}"); - add(Ops.DateTimeOps.ADD_SECONDS, "{fn timestampadd(SQL_TSI_SECOND, {1}, {0})}"); - - add(Ops.DateTimeOps.DIFF_YEARS, "{fn timestampdiff(SQL_TSI_YEAR, {0}, {1})}"); - add(Ops.DateTimeOps.DIFF_MONTHS, "{fn timestampdiff(SQL_TSI_MONTH, {0}, {1})}"); - add(Ops.DateTimeOps.DIFF_WEEKS, "{fn timestampdiff(SQL_TSI_WEEK, {0}, {1})}"); - add(Ops.DateTimeOps.DIFF_DAYS, "{fn timestampdiff(SQL_TSI_DAY, {0}, {1})}"); - add(Ops.DateTimeOps.DIFF_HOURS, "{fn timestampdiff(SQL_TSI_HOUR, {0}, {1})}"); - add(Ops.DateTimeOps.DIFF_MINUTES, "{fn timestampdiff(SQL_TSI_MINUTE, {0}, {1})}"); - add(Ops.DateTimeOps.DIFF_SECONDS, "{fn timestampdiff(SQL_TSI_SECOND, {0}, {1})}"); - - // left via substr - add(Ops.StringOps.LEFT, "substr({0},1,{1})"); - } - - @Override - public String serialize(String literal, int jdbcType) { - if (jdbcType == Types.TIMESTAMP) { - return "{ts '" + literal + "'}"; - } else if (jdbcType == Types.DATE) { - return "{d '" + literal + "'}"; - } else if (jdbcType == Types.TIME) { - return "{t '" + literal + "'}"; - } else { - return super.serialize(literal, jdbcType); - } - } - - @Override - protected void serializeModifiers(QueryMetadata metadata, SQLSerializer context) { - QueryModifiers mod = metadata.getModifiers(); - if (mod.getLimit() == null) { - context.handle(offsetTemplate, mod.getOffset()); - } else if (mod.getOffset() == null) { - context.handle(limitTemplate, mod.getLimit()); - } else { - context.handle(limitOffsetTemplate, mod.getLimit(), mod.getOffset()); - } - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/DetachableSQLQuery.java b/querydsl-sql/src/main/java/com/mysema/query/sql/DetachableSQLQuery.java deleted file mode 100644 index 5cdf8bc70e..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/DetachableSQLQuery.java +++ /dev/null @@ -1,434 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import java.util.Arrays; -import java.util.List; -import java.util.Map; - -import com.google.common.collect.ImmutableList; -import com.infradna.tool.bridge_method_injector.WithBridgeMethods; -import com.mysema.query.DefaultQueryMetadata; -import com.mysema.query.JoinFlag; -import com.mysema.query.QueryFlag; -import com.mysema.query.QueryFlag.Position; -import com.mysema.query.QueryMetadata; -import com.mysema.query.support.DetachableQuery; -import com.mysema.query.support.Expressions; -import com.mysema.query.support.QueryMixin; -import com.mysema.query.types.CollectionExpression; -import com.mysema.query.types.EntityPath; -import com.mysema.query.types.Expression; -import com.mysema.query.types.ExpressionUtils; -import com.mysema.query.types.OperationImpl; -import com.mysema.query.types.Operator; -import com.mysema.query.types.ParamExpression; -import com.mysema.query.types.ParamNotSetException; -import com.mysema.query.types.Path; -import com.mysema.query.types.Predicate; -import com.mysema.query.types.SubQueryExpression; -import com.mysema.query.types.TemplateExpressionImpl; -import com.mysema.query.types.expr.BooleanExpression; -import com.mysema.query.types.expr.CollectionExpressionBase; -import com.mysema.query.types.expr.CollectionOperation; -import com.mysema.query.types.query.ListSubQuery; -import com.mysema.query.types.template.NumberTemplate; - -/** - * Abstract superclass for SubQuery implementations - * - * @author tiwe - * - */ -public abstract class DetachableSQLQuery> extends DetachableQuery implements SQLCommonQuery { - - protected final Configuration configuration; - - public DetachableSQLQuery() { - this(new DefaultQueryMetadata().noValidate()); - } - - public DetachableSQLQuery(QueryMetadata metadata) { - this(Configuration.DEFAULT, metadata); - } - - @SuppressWarnings("unchecked") - public DetachableSQLQuery(Configuration configuration, QueryMetadata metadata) { - super(new QueryMixin(metadata)); - this.queryMixin.setSelf((Q)this); - this.configuration = configuration; - } - - /** - * Add the given prefix and expression as a general query flag - * - * @param position position of the flag - * @param prefix prefix for the flag - * @param expr expression of the flag - * @return - */ - @Override - @WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true) - public Q addFlag(Position position, String prefix, Expression expr) { - Expression flag = TemplateExpressionImpl.create(expr.getType(), prefix + "{0}", expr); - return queryMixin.addFlag(new QueryFlag(position, flag)); - } - - /** - * Add the given String literal as a query flag - * - * @param position - * @param flag - * @return - */ - @Override - @WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true) - public Q addFlag(Position position, String flag) { - return queryMixin.addFlag(new QueryFlag(position, flag)); - } - - /** - * Add the given Expression as a query flag - * - * @param position - * @param flag - * @return - */ - @Override - @WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true) - public Q addFlag(Position position, Expression flag) { - return queryMixin.addFlag(new QueryFlag(position, flag)); - } - - /** - * Add the given String literal as a join flag to the last added join with the - * position BEFORE_TARGET - * - * @param flag - * @return - */ - @Override - @WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true) - public Q addJoinFlag(String flag) { - return addJoinFlag(flag, JoinFlag.Position.BEFORE_TARGET); - } - - /** - * Add the given String literal as a join flag to the last added join - * - * @param flag - * @param position - * @return - */ - @Override - @WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true) - @SuppressWarnings("unchecked") - public Q addJoinFlag(String flag, JoinFlag.Position position) { - queryMixin.addJoinFlag(new JoinFlag(flag, position)); - return (Q)this; - } - - @Override - public BooleanExpression exists() { - return unique(NumberTemplate.ONE).exists(); - } - - @Override - public BooleanExpression notExists() { - return exists().not(); - } - - @WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true) - public Q from(Expression arg) { - return queryMixin.from(arg); - } - - @Override - @WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true) - public Q from(Expression... args) { - return queryMixin.from(args); - } - - @Override - @WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true) - @SuppressWarnings({ "unchecked", "rawtypes" }) - public Q from(SubQueryExpression subQuery, Path alias) { - return queryMixin.from(ExpressionUtils.as((Expression)subQuery, alias)); - } - - @Override - @WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true) - public Q fullJoin(EntityPath target) { - return queryMixin.fullJoin(target); - } - - @Override - @WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true) - public Q fullJoin(RelationalFunctionCall target, Path alias) { - return queryMixin.fullJoin(target, alias); - } - - @Override - @WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true) - public Q fullJoin(ForeignKey key, RelationalPath entity) { - return queryMixin.fullJoin(entity).on(key.on(entity)); - } - - @Override - @WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true) - public Q fullJoin(SubQueryExpression target, Path alias) { - return queryMixin.fullJoin(target, alias); - } - - @Override - @WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true) - public Q innerJoin(EntityPath target) { - return queryMixin.innerJoin(target); - } - - @Override - @WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true) - public Q innerJoin(RelationalFunctionCall target, Path alias) { - return queryMixin.innerJoin(target, alias); - } - - @Override - @WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true) - public Q innerJoin(ForeignKey key, RelationalPath entity) { - return queryMixin.innerJoin(entity).on(key.on(entity)); - } - - @Override - @WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true) - public Q innerJoin(SubQueryExpression target, Path alias) { - return queryMixin.innerJoin(target, alias); - } - - @Override - @WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true) - public Q join(EntityPath target) { - return queryMixin.join(target); - } - - @Override - @WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true) - public Q join(RelationalFunctionCall target, Path alias) { - return queryMixin.join(target, alias); - } - - @Override - @WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true) - public Q join(ForeignKey key, RelationalPath entity) { - return queryMixin.join(entity).on(key.on(entity)); - } - - @Override - @WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true) - public Q join(SubQueryExpression target, Path alias) { - return queryMixin.join(target, alias); - } - - @Override - @WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true) - public Q leftJoin(EntityPath target) { - return queryMixin.leftJoin(target); - } - - @Override - @WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true) - public Q leftJoin(RelationalFunctionCall target, Path alias) { - return queryMixin.leftJoin(target, alias); - } - - @Override - @WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true) - public Q leftJoin(ForeignKey key, RelationalPath entity) { - return queryMixin.leftJoin(entity).on(key.on(entity)); - } - - @Override - @WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true) - public Q leftJoin(SubQueryExpression target, Path alias) { - return queryMixin.leftJoin(target, alias); - } - - @WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true) - public Q on(Predicate condition) { - return queryMixin.on(condition); - } - - @Override - @WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true) - public Q on(Predicate... conditions) { - return queryMixin.on(conditions); - } - - @Override - @WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true) - public Q rightJoin(EntityPath target) { - return queryMixin.rightJoin(target); - } - - @Override - @WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true) - public Q rightJoin(RelationalFunctionCall target, Path alias) { - return queryMixin.fullJoin(target, alias); - } - - @Override - @WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true) - public Q rightJoin(ForeignKey key, RelationalPath entity) { - return queryMixin.rightJoin(entity).on(key.on(entity)); - } - - @Override - @WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true) - public Q rightJoin(SubQueryExpression target, Path alias) { - return queryMixin.rightJoin(target, alias); - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - private CollectionExpressionBase union(Operator op, List> sq) { - Expression rv = sq.get(0); - if (sq.size() == 1 && !CollectionExpression.class.isInstance(rv)) { - return new ListSubQuery(rv.getType(), sq.get(0).getMetadata()); - } else { - Class elementType = sq.get(0).getType(); - if (rv instanceof CollectionExpression) { - elementType = ((CollectionExpression)rv).getParameter(0); - } - for (int i = 1; i < sq.size(); i++) { - rv = CollectionOperation.create(op, (Class)elementType, rv, sq.get(i)); - } - return (CollectionExpressionBase)rv; - } - } - - public CollectionExpressionBase union(List> sq) { - return union(SQLOps.UNION, sq); - } - - public CollectionExpressionBase union(ListSubQuery... sq) { - return union(SQLOps.UNION, Arrays.asList(sq)); - } - - public CollectionExpressionBase union(SubQueryExpression... sq) { - return union(SQLOps.UNION, Arrays.asList(sq)); - } - - public CollectionExpressionBase unionAll(List> sq) { - return union(SQLOps.UNION_ALL, sq); - } - - public CollectionExpressionBase unionAll(ListSubQuery... sq) { - return union(SQLOps.UNION_ALL, Arrays.asList(sq)); - } - - public CollectionExpressionBase unionAll(SubQueryExpression... sq) { - return union(SQLOps.UNION_ALL, Arrays.asList(sq)); - } - - @Override - @WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true) - public Q withRecursive(Path alias, SubQueryExpression query) { - queryMixin.addFlag(new QueryFlag(QueryFlag.Position.WITH, SQLTemplates.RECURSIVE)); - return with(alias, query); - } - - @Override - @WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true) - public Q withRecursive(Path alias, Expression query) { - queryMixin.addFlag(new QueryFlag(QueryFlag.Position.WITH, SQLTemplates.RECURSIVE)); - return with(alias, query); - } - - @Override - @WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true) - public WithBuilder withRecursive(Path alias, Path... columns) { - queryMixin.addFlag(new QueryFlag(QueryFlag.Position.WITH, SQLTemplates.RECURSIVE)); - return with(alias, columns); - } - - @Override - @WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true) - public Q with(Path alias, SubQueryExpression target) { - Expression expr = OperationImpl.create(alias.getType(), SQLOps.WITH_ALIAS, alias, target); - return queryMixin.addFlag(new QueryFlag(QueryFlag.Position.WITH, expr)); - } - - @Override - @WithBridgeMethods(value=AbstractSQLSubQuery.class, castRequired=true) - public Q with(Path alias, Expression query) { - Expression expr = OperationImpl.create(alias.getType(), SQLOps.WITH_ALIAS, alias, query); - return queryMixin.addFlag(new QueryFlag(QueryFlag.Position.WITH, expr)); - } - - @Override - public WithBuilder with(Path alias, Path... columns) { - Expression columnsCombined = ExpressionUtils.list(Object.class, columns); - Expression aliasCombined = Expressions.operation(alias.getType(), SQLOps.WITH_COLUMNS, alias, columnsCombined); - return new WithBuilder(queryMixin, aliasCombined); - } - - public QueryMetadata getMetadata() { - return queryMixin.getMetadata(); - } - - - @Override - public abstract Q clone(); - - protected abstract SQLSerializer createSerializer(); - - protected SQLSerializer serialize(boolean forCountRow) { - SQLSerializer serializer = createSerializer(); - serializer.setStrict(false); - serializer.serialize(queryMixin.getMetadata(), forCountRow); - return serializer; - } - - /** - * Get the query as an SQL query string and bindings - * - * @param exprs - * @return - */ - public SQLBindings getSQL(Expression... exprs) { - queryMixin.addProjection(exprs); - SQLSerializer serializer = serialize(false); - ImmutableList.Builder args = ImmutableList.builder(); - Map, Object> params = getMetadata().getParams(); - for (Object o : serializer.getConstants()) { - if (o instanceof ParamExpression) { - if (!params.containsKey(o)) { - throw new ParamNotSetException((ParamExpression) o); - } - o = queryMixin.getMetadata().getParams().get(o); - } - args.add(o); - } - return new SQLBindings(serializer.toString(), args.build()); - } - - @Override - public String toString() { - if (!getMetadata().getJoins().isEmpty()) { - SQLSerializer serializer = serialize(false); - return serializer.toString().trim(); - } else { - return super.toString(); - } - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/ForeignKey.java b/querydsl-sql/src/main/java/com/mysema/query/sql/ForeignKey.java deleted file mode 100644 index b8b813403a..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/ForeignKey.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import java.io.Serializable; -import java.util.List; - -import javax.annotation.Nullable; -import javax.annotation.concurrent.Immutable; - -import com.google.common.collect.ImmutableList; -import com.mysema.query.BooleanBuilder; -import com.mysema.query.Tuple; -import com.mysema.query.types.CollectionExpression; -import com.mysema.query.types.Expression; -import com.mysema.query.types.ExpressionUtils; -import com.mysema.query.types.Ops; -import com.mysema.query.types.Path; -import com.mysema.query.types.PathImpl; -import com.mysema.query.types.Predicate; -import com.mysema.query.types.ProjectionRole; -import com.mysema.query.types.expr.BooleanExpression; -import com.mysema.query.types.expr.BooleanOperation; - -/** - * ForeignKey defines a foreign key on a table to another table - * - * @author tiwe - * - * @param - */ -@Immutable -public final class ForeignKey implements Serializable, ProjectionRole { - - private static final long serialVersionUID = 2260578033772289023L; - - private final RelationalPath entity; - - private final ImmutableList> localColumns; - - private final ImmutableList foreignColumns; - - @Nullable - private volatile Expression mixin; - - public ForeignKey(RelationalPath entity, Path localColumn, String foreignColumn) { - this(entity, ImmutableList.of(localColumn), ImmutableList.of(foreignColumn)); - } - - public ForeignKey(RelationalPath entity, ImmutableList> localColumns, - ImmutableList foreignColumns) { - this.entity = entity; - this.localColumns = localColumns; - this.foreignColumns = foreignColumns; - } - - public RelationalPath getEntity() { - return entity; - } - - public List> getLocalColumns() { - return localColumns; - } - - public List getForeignColumns() { - return foreignColumns; - } - - @SuppressWarnings("unchecked") - public Predicate on(RelationalPath entity) { - BooleanBuilder builder = new BooleanBuilder(); - for (int i = 0; i < localColumns.size(); i++) { - Expression local = (Expression)localColumns.get(i); - Expression foreign = new PathImpl(local.getType(), entity, foreignColumns.get(i)); - builder.and(ExpressionUtils.eq(local,foreign)); - } - return builder.getValue(); - } - - public BooleanExpression in(CollectionExpression coll) { - return BooleanOperation.create(Ops.IN, getProjection(), coll); - } - - @Override - public Expression getProjection() { - if (mixin == null) { - mixin = ExpressionUtils.list(Tuple.class, localColumns); - } - return mixin; - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/H2Templates.java b/querydsl-sql/src/main/java/com/mysema/query/sql/H2Templates.java deleted file mode 100644 index 9e72a896fa..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/H2Templates.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import com.mysema.query.types.Ops; - -/** - * H2Templates is an SQL dialect for H2 - * - * @author tiwe - * - */ -public class H2Templates extends SQLTemplates { - - public static Builder builder() { - return new Builder() { - @Override - protected SQLTemplates build(char escape, boolean quote) { - return new H2Templates(escape, quote); - } - }; - } - - public H2Templates() { - this('\\', false); - } - - public H2Templates(boolean quote) { - this('\\', quote); - } - - public H2Templates(char escape, boolean quote) { - super("\"", escape, quote); - setNativeMerge(true); - setLimitRequired(true); - setCountDistinctMultipleColumns(true); - - add(Ops.MathOps.ROUND, "round({0},0)"); - add(Ops.TRIM, "trim(both from {0})"); - - add(Ops.DateTimeOps.DAY_OF_WEEK, "day_of_week({0})"); - - add(Ops.MathOps.LN, "log({0})"); - add(Ops.MathOps.LOG, "(log({0}) / log({1}))"); - add(Ops.MathOps.COTH, "(cosh({0}) / sinh({0}))"); - - add(Ops.DateTimeOps.DATE, "convert({0}, date)"); - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/HSQLDBTemplates.java b/querydsl-sql/src/main/java/com/mysema/query/sql/HSQLDBTemplates.java deleted file mode 100644 index c164e75f0f..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/HSQLDBTemplates.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import com.mysema.query.types.Ops; - -/** - * HSQLDBTemplates is an SQL dialect for HSQLDB - * - * @author tiwe - * - */ -public class HSQLDBTemplates extends SQLTemplates { - - public static Builder builder() { - return new Builder() { - @Override - protected SQLTemplates build(char escape, boolean quote) { - return new HSQLDBTemplates(escape, quote); - } - }; - } - - public HSQLDBTemplates() { - this('\\', false); - } - - public HSQLDBTemplates(boolean quote) { - this('\\', quote); - } - - public HSQLDBTemplates(char escape, boolean quote) { - super("\"", escape, quote); - setLimitRequired(true); - setAutoIncrement(" identity"); - setDefaultValues("\ndefault values"); - add(Ops.TRIM, "trim(both from {0})"); - add(Ops.NEGATE, "{0} * -1", 7); - - add(SQLOps.NEXTVAL, "next value for {0s}"); - - add(Ops.MathOps.ROUND, "round({0},0)"); - add(Ops.MathOps.LN, "log({0})"); - add(Ops.MathOps.LOG, "(log({0}) / log({1}))"); - add(Ops.MathOps.COSH, "(exp({0}) + exp({0} * -1)) / 2"); - add(Ops.MathOps.COTH, "(exp({0} * 2) + 1) / (exp({0} * 2) - 1)"); - add(Ops.MathOps.SINH, "(exp({0}) - exp({0} * -1)) / 2"); - add(Ops.MathOps.TANH, "(exp({0} * 2) - 1) / (exp({0} * 2) + 1)"); - - add(Ops.DateTimeOps.WEEK, "extract(week_of_year from {0})"); - add(Ops.DateTimeOps.YEAR_WEEK, "(extract(year from {0}) * 100 + extract(week_of_year from {0}))"); - - add(Ops.DateTimeOps.ADD_YEARS, "dateadd('yy', {1s}, {0})"); - add(Ops.DateTimeOps.ADD_MONTHS, "dateadd('mm', {1s}, {0})"); - add(Ops.DateTimeOps.ADD_WEEKS, "dateadd('week', {1s}, {0})"); - add(Ops.DateTimeOps.ADD_DAYS, "dateadd('dd', {1s}, {0})"); - add(Ops.DateTimeOps.ADD_HOURS, "dateadd('hh', {1s}, {0})"); - add(Ops.DateTimeOps.ADD_MINUTES, "dateadd('mi', {1s}, {0})"); - add(Ops.DateTimeOps.ADD_SECONDS, "dateadd('ss', {1s}, {0})"); - - add(Ops.DateTimeOps.DIFF_YEARS, "datediff('yy', {0}, {1})"); - add(Ops.DateTimeOps.DIFF_MONTHS, "datediff('mm', {0}, {1})"); - add(Ops.DateTimeOps.DIFF_WEEKS, "trunc(datediff('dd', {0}, {1}) / 7)"); - add(Ops.DateTimeOps.DIFF_DAYS, "datediff('dd', {0}, {1})"); - add(Ops.DateTimeOps.DIFF_HOURS, "datediff('hh', {0}, {1})"); - add(Ops.DateTimeOps.DIFF_MINUTES, "datediff('mi', {0}, {1})"); - add(Ops.DateTimeOps.DIFF_SECONDS, "datediff('ss', {0}, {1})"); - - add(Ops.DateTimeOps.DATE, "convert({0}, date)"); - } - - @Override - public String getTypeForCast(Class cl) { - return (cl.equals(String.class)) ? "varchar(10)" : getTypeForClass(cl); - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/JDBCTypeMapping.java b/querydsl-sql/src/main/java/com/mysema/query/sql/JDBCTypeMapping.java deleted file mode 100644 index c31dac07c3..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/JDBCTypeMapping.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import javax.annotation.Nullable; -import java.math.BigDecimal; -import java.math.BigInteger; -import java.sql.Blob; -import java.sql.Types; -import java.util.HashMap; -import java.util.Map; - -import com.mysema.commons.lang.Pair; -import com.mysema.query.sql.types.Null; - -/** - * JDBCTypeMapping defines a mapping from JDBC types to Java classes. - * - * @author tiwe - * - */ -public final class JDBCTypeMapping { - - private static final Map> defaultTypes = new HashMap>(); - - private static final Map, Integer> defaultSqlTypes = new HashMap, Integer>(); - - static{ - registerDefault(-101, Object.class); - registerDefault(-102, java.sql.Timestamp.class); // Oracle: TIMESTAMP(6) WITH LOCAL TIME ZONE - - // BOOLEAN - registerDefault(Types.BIT, Boolean.class); - registerDefault(Types.BOOLEAN, Boolean.class); - - // NUMERIC - registerDefault(Types.BIGINT, Long.class); - registerDefault(Types.DECIMAL, BigDecimal.class); - registerDefault(Types.DOUBLE, Double.class); - registerDefault(Types.FLOAT, Float.class); - registerDefault(Types.INTEGER, Integer.class); - registerDefault(Types.NUMERIC, BigDecimal.class); - registerDefault(Types.REAL, Float.class); - registerDefault(Types.SMALLINT, Short.class); - registerDefault(Types.TINYINT, Byte.class); - - // DATE and TIME - registerDefault(Types.DATE, java.sql.Date.class); - registerDefault(Types.TIME, java.sql.Time.class); - registerDefault(Types.TIMESTAMP, java.sql.Timestamp.class); - - // TEXT - registerDefault(Types.NCHAR, String.class); - registerDefault(Types.CHAR, String.class); - registerDefault(Types.NCLOB, String.class); - registerDefault(Types.CLOB, String.class); - registerDefault(Types.LONGNVARCHAR, String.class); - registerDefault(Types.LONGVARCHAR, String.class); - registerDefault(Types.SQLXML, String.class); - registerDefault(Types.NVARCHAR, String.class); - registerDefault(Types.VARCHAR, String.class); - - // byte[] - registerDefault(Types.BINARY, byte[].class); - registerDefault(Types.LONGVARBINARY, byte[].class); - registerDefault(Types.VARBINARY, byte[].class); - - // BLOB - registerDefault(Types.BLOB, Blob.class); - - // OTHER - registerDefault(Types.ARRAY, Object[].class); - registerDefault(Types.DISTINCT, Object.class); - registerDefault(Types.DATALINK, Object.class); - registerDefault(Types.JAVA_OBJECT, Object.class); - registerDefault(Types.NULL, Null.class); - registerDefault(Types.OTHER, Object.class); - registerDefault(Types.REF, Object.class); - registerDefault(Types.ROWID, Object.class); - registerDefault(Types.STRUCT, Object.class); - } - - private static void registerDefault(int sqlType, Class javaType) { - defaultTypes.put(sqlType, javaType); - defaultSqlTypes.put(javaType, sqlType); - } - - private final Map> types = new HashMap>(); - - private final Map, Integer> sqlTypes = new HashMap, Integer>(); - - private final Map, Class> numericTypes = new HashMap, Class>(); - - public void register(int sqlType, Class javaType) { - types.put(sqlType, javaType); - sqlTypes.put(javaType, sqlType); - } - - public void registerNumeric(int total, int decimal, Class javaType) { - numericTypes.put(Pair.of(total, decimal), javaType); - } - - private Class getNumericClass(int total, int decimal) { - Pair key = Pair.of(total, decimal); - if (numericTypes.containsKey(key)) { - return numericTypes.get(key); - } else if (decimal <= 0) { - if (total > 18 || total == 0) { - return BigInteger.class; - } else if (total > 9 || total == 0) { - return Long.class; - } else if (total > 4) { - return Integer.class; - } else if (total > 2) { - return Short.class; - } else if (total > 0) { - return Byte.class; - } else { - return Boolean.class; - } - } else { - if (total > 16) { - return BigDecimal.class; - } else { - return Double.class; - } - } - } - - @Nullable - public Class get(int sqlType, int total, int decimal) { - if (sqlType == Types.NUMERIC || sqlType == Types.DECIMAL) { - return getNumericClass(total, decimal); - } else if (types.containsKey(sqlType)) { - return types.get(sqlType); - } else { - return defaultTypes.get(sqlType); - } - } - - @Nullable - public Integer get(Class clazz) { - if (sqlTypes.containsKey(clazz)) { - return sqlTypes.get(clazz); - } else { - return defaultSqlTypes.get(clazz); - } - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/JavaTypeMapping.java b/querydsl-sql/src/main/java/com/mysema/query/sql/JavaTypeMapping.java deleted file mode 100644 index f87ad72bff..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/JavaTypeMapping.java +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import java.util.HashMap; -import java.util.Map; -import java.util.Set; - -import javax.annotation.Nullable; - -import com.google.common.primitives.Primitives; -import com.mysema.query.sql.types.BigDecimalType; -import com.mysema.query.sql.types.BigIntegerType; -import com.mysema.query.sql.types.BlobType; -import com.mysema.query.sql.types.BooleanType; -import com.mysema.query.sql.types.ByteType; -import com.mysema.query.sql.types.BytesType; -import com.mysema.query.sql.types.CalendarType; -import com.mysema.query.sql.types.CharacterType; -import com.mysema.query.sql.types.ClobType; -import com.mysema.query.sql.types.CurrencyType; -import com.mysema.query.sql.types.DateType; -import com.mysema.query.sql.types.DoubleType; -import com.mysema.query.sql.types.FloatType; -import com.mysema.query.sql.types.IntegerType; -import com.mysema.query.sql.types.LocaleType; -import com.mysema.query.sql.types.LongType; -import com.mysema.query.sql.types.ObjectType; -import com.mysema.query.sql.types.ShortType; -import com.mysema.query.sql.types.StringType; -import com.mysema.query.sql.types.TimeType; -import com.mysema.query.sql.types.TimestampType; -import com.mysema.query.sql.types.Type; -import com.mysema.query.sql.types.URLType; -import com.mysema.query.sql.types.UtilDateType; -import com.mysema.util.ReflectionUtils; - -/** - * JavaTypeMapping provides a mapping from Class to Type instances - * - * @author tiwe - * - */ -public class JavaTypeMapping { - - private static final Map,Type> defaultTypes = new HashMap,Type>(); - - static{ - registerDefault(new BigIntegerType()); - registerDefault(new BigDecimalType()); - registerDefault(new BlobType()); - registerDefault(new BooleanType()); - registerDefault(new BytesType()); - registerDefault(new ByteType()); - registerDefault(new CharacterType()); - registerDefault(new CalendarType()); - registerDefault(new ClobType()); - registerDefault(new CurrencyType()); - registerDefault(new DateType()); - registerDefault(new DoubleType()); - registerDefault(new FloatType()); - registerDefault(new IntegerType()); - registerDefault(new LocaleType()); - registerDefault(new LongType()); - registerDefault(new ObjectType()); - registerDefault(new ShortType()); - registerDefault(new StringType()); - registerDefault(new TimestampType()); - registerDefault(new TimeType()); - registerDefault(new URLType()); - registerDefault(new UtilDateType()); - - // initialize joda time converters only if joda time is available - try { - Class.forName("org.joda.time.DateTime"); - registerDefault((Type)Class.forName("com.mysema.query.sql.types.DateTimeType").newInstance()); - registerDefault((Type)Class.forName("com.mysema.query.sql.types.LocalDateTimeType").newInstance()); - registerDefault((Type)Class.forName("com.mysema.query.sql.types.LocalDateType").newInstance()); - registerDefault((Type)Class.forName("com.mysema.query.sql.types.LocalTimeType").newInstance()); - } catch (ClassNotFoundException e) { - // converters for joda.time are not loaded - } catch (InstantiationException e) { - throw new RuntimeException(e); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } - - } - - private static void registerDefault(Type type) { - defaultTypes.put(type.getReturnedClass(), type); - Class primitive = Primitives.unwrap(type.getReturnedClass()); - if (primitive != null) { - defaultTypes.put(primitive, type); - } - } - - private final Map,Type> typeByClass = new HashMap,Type>(); - - private final Map,Type> resolvedTypesByClass = new HashMap,Type>(); - - private final Map>> typeByColumn = new HashMap>>(); - - @Nullable - public Type getType(String table, String column) { - Map> columns = typeByColumn.get(table); - if (columns != null) { - return columns.get(column); - } else { - return null; - } - } - - @SuppressWarnings("unchecked") - public Type getType(Class clazz) { - Type resolvedType = resolvedTypesByClass.get(clazz); - if (resolvedType == null) { - resolvedType = findType(clazz); - if (resolvedType != null) { - resolvedTypesByClass.put(clazz, resolvedType); - } else { - throw new IllegalArgumentException("Found no type for " + clazz.getName()); - } - } - return (Type) resolvedType; - } - - @Nullable - private Type findType(Class clazz) { - //Look for a registered type in the class hierarchy - Class cl = clazz; - do{ - if (typeByClass.containsKey(cl)) { - return typeByClass.get(cl); - } else if (defaultTypes.containsKey(cl)) { - return defaultTypes.get(cl); - } - cl = cl.getSuperclass(); - } while(!cl.equals(Object.class)); - - //Look for a registered type in any implemented interfaces - Set> interfaces = ReflectionUtils.getImplementedInterfaces(clazz); - for (Class itf : interfaces) { - if (typeByClass.containsKey(itf)) { - return typeByClass.get(itf); - } else if (defaultTypes.containsKey(itf)) { - return defaultTypes.get(itf); - } - } - return null; - } - - public void register(Type type) { - typeByClass.put(type.getReturnedClass(), type); - Class primitive = Primitives.unwrap(type.getReturnedClass()); - if (primitive != null) { - typeByClass.put(primitive, type); - } - // Clear previous resolved types, so they won't impact future lookups - resolvedTypesByClass.clear(); - } - - public void setType(String table, String column, Type type) { - Map> columns = typeByColumn.get(table); - if (columns == null) { - columns = new HashMap>(); - typeByColumn.put(table, columns); - } - columns.put(column, type); - } - -} \ No newline at end of file diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/MySQLTemplates.java b/querydsl-sql/src/main/java/com/mysema/query/sql/MySQLTemplates.java deleted file mode 100644 index ddda7f7bbe..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/MySQLTemplates.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import java.math.BigDecimal; - -import com.mysema.query.types.Ops; - -/** - * MySQLTemplates is an SQL dialect for MySQL - * - *

tested with MySQL CE 5.1 and 5.5

- * - * @author tiwe - * - */ -public class MySQLTemplates extends SQLTemplates { - - public static Builder builder() { - return new Builder() { - @Override - protected SQLTemplates build(char escape, boolean quote) { - return new MySQLTemplates(escape, quote); - } - }; - } - - public MySQLTemplates() { - this('\\', false); - } - - public MySQLTemplates(boolean quote) { - this('\\', quote); - } - - public MySQLTemplates(char escape, boolean quote) { - super("`", escape, quote); - setParameterMetadataAvailable(false); - setLimitRequired(true); - setNullsFirst(null); - setNullsLast(null); - - addClass2TypeMappings("bool", Boolean.class); - addClass2TypeMappings("int", Integer.class); - - addClass2TypeMappings("decimal", - Double.class, - Float.class, - BigDecimal.class); - addClass2TypeMappings("char", String.class); - - add(Ops.CONCAT, "concat({0}, {1})",0); - - add(Ops.StringOps.LPAD, "lpad({0},{1},' ')"); - add(Ops.StringOps.RPAD, "rpad({0},{1},' ')"); - - // like without escape - if (escape == '\\') { - add(Ops.LIKE, "{0} like {1}"); - add(Ops.ENDS_WITH, "{0} like {%1}"); - add(Ops.ENDS_WITH_IC, "{0l} like {%%1}"); - add(Ops.STARTS_WITH, "{0} like {1%}"); - add(Ops.STARTS_WITH_IC, "{0l} like {1%%}"); - add(Ops.STRING_CONTAINS, "{0} like {%1%}"); - add(Ops.STRING_CONTAINS_IC, "{0l} like {%%1%%}"); - } - - add(Ops.MathOps.LOG, "log({1},{0})"); - add(Ops.MathOps.COSH, "(exp({0}) + exp({0} * -1)) / 2"); - add(Ops.MathOps.COTH, "(exp({0} * 2) + 1) / (exp({0} * 2) - 1)"); - add(Ops.MathOps.SINH, "(exp({0}) - exp({0} * -1)) / 2"); - add(Ops.MathOps.TANH, "(exp({0} * 2) - 1) / (exp({0} * 2) + 1)"); - - add(Ops.AggOps.BOOLEAN_ANY, "bit_or({0})", 0); - add(Ops.AggOps.BOOLEAN_ALL, "bit_and({0})", 0); - - add(Ops.DateTimeOps.DAY_OF_WEEK, "dayofweek({0})"); - add(Ops.DateTimeOps.DAY_OF_YEAR, "dayofyear({0})"); - add(Ops.DateTimeOps.YEAR_MONTH, "extract(year_month from {0})"); - add(Ops.DateTimeOps.YEAR_WEEK, "yearweek({0})"); - - add(Ops.DateTimeOps.ADD_YEARS, "date_add({0}, interval {1s} year)"); - add(Ops.DateTimeOps.ADD_MONTHS, "date_add({0}, interval {1s} month)"); - add(Ops.DateTimeOps.ADD_WEEKS, "date_add({0}, interval {1s} week)"); - add(Ops.DateTimeOps.ADD_DAYS, "date_add({0}, interval {1s} day)"); - add(Ops.DateTimeOps.ADD_HOURS, "date_add({0}, interval {1s} hour)"); - add(Ops.DateTimeOps.ADD_MINUTES, "date_add({0}, interval {1s} minute)"); - add(Ops.DateTimeOps.ADD_SECONDS, "date_add({0}, interval {1s} second)"); - - add(Ops.DateTimeOps.DIFF_YEARS, "timestampdiff(year,{0},{1})"); - add(Ops.DateTimeOps.DIFF_MONTHS, "timestampdiff(month,{0},{1})"); - add(Ops.DateTimeOps.DIFF_WEEKS, "timestampdiff(week,{0},{1})"); - add(Ops.DateTimeOps.DIFF_DAYS, "timestampdiff(day,{0},{1})"); - add(Ops.DateTimeOps.DIFF_HOURS, "timestampdiff(hour,{0},{1})"); - add(Ops.DateTimeOps.DIFF_MINUTES, "timestampdiff(minute,{0},{1})"); - add(Ops.DateTimeOps.DIFF_SECONDS, "timestampdiff(second,{0},{1})"); - } - - @Override - public String escapeLiteral(String str) { - StringBuilder builder = new StringBuilder(); - for (char ch : super.escapeLiteral(str).toCharArray()) { - if (ch == '\\') { - builder.append("\\"); - } - builder.append(ch); - } - return builder.toString(); - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/OracleTemplates.java b/querydsl-sql/src/main/java/com/mysema/query/sql/OracleTemplates.java deleted file mode 100644 index 693b8813f7..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/OracleTemplates.java +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import java.math.BigInteger; -import java.sql.Types; -import java.util.List; - -import com.mysema.commons.lang.Pair; -import com.mysema.query.QueryFlag.Position; -import com.mysema.query.QueryMetadata; -import com.mysema.query.QueryModifiers; -import com.mysema.query.types.Expression; -import com.mysema.query.types.Ops; -import com.mysema.query.types.Path; - -/** - * OracleTemplates is an SQL dialect for Oracle - * - *

tested with Oracle 10g XE

- * - * @author tiwe - */ -public class OracleTemplates extends SQLTemplates { - - public static Builder builder() { - return new Builder() { - @Override - protected SQLTemplates build(char escape, boolean quote) { - return new OracleTemplates(escape, quote); - } - }; - } - - private String outerQueryStart = "select * from (\n select a.*, rownum rn from (\n "; - - private String outerQueryEnd = "\n ) a) where "; - - private String limitQueryStart = "select * from (\n "; - - private String limitQueryEnd = "\n) where rownum <= {0}"; - - private String limitOffsetTemplate = "rn > {0s} and rownum <= {1s}"; - - private String offsetTemplate = "rn > {0}"; - - public OracleTemplates() { - this('\\', false); - } - - public OracleTemplates(boolean quote) { - this('\\',quote); - } - - public OracleTemplates(char escape, boolean quote) { - super("\"", escape, quote); - setParameterMetadataAvailable(false); - setBatchCountViaGetUpdateCount(true); - setWithRecursive("with "); - setCountViaAnalytics(true); - - // type mappings - addClass2TypeMappings("number(3,0)", Byte.class); - addClass2TypeMappings("number(1,0)", Boolean.class); - addClass2TypeMappings("number(19,0)", BigInteger.class, Long.class); - addClass2TypeMappings("number(5,0)", Short.class); - addClass2TypeMappings("number(10,0)", Integer.class); - addClass2TypeMappings("double precision", Double.class); - addClass2TypeMappings("varchar(4000 char)", String.class); - - add(Ops.ALIAS, "{0} {1}"); - add(SQLOps.NEXTVAL, "{0s}.nextval"); - - // String - add(Ops.INDEX_OF, "instrb({0},{1})-1"); - add(Ops.INDEX_OF_2ARGS, "instrb({0},{1},{2}+1)-1"); - add(Ops.MATCHES, "regexp_like({0},{1})"); - add(Ops.StringOps.LOCATE, "instr({1},{0})"); - add(Ops.StringOps.LOCATE2, "instr({1},{0},{2s})"); - add(Ops.StringOps.LEFT, "substr({0},1,{1})"); - add(Ops.StringOps.RIGHT, "substr({0},-{1s},length({0}))"); - - // Number - add(Ops.MathOps.CEIL, "ceil({0})"); - add(Ops.MathOps.RANDOM, "dbms_random.value"); - add(Ops.MathOps.LN, "ln({0})"); - add(Ops.MathOps.LOG, "log({1},{0})"); - add(Ops.MathOps.COT, "(cos({0}) / sin({0}))"); - add(Ops.MathOps.COTH, "(exp({0} * 2) + 1) / (exp({0} * 2) - 1)"); - add(Ops.MathOps.DEG, "({0} * 180 / "+Math.PI+")"); - add(Ops.MathOps.RAD, "({0} * "+Math.PI+" / 180)"); - - // Date / time - add(Ops.DateTimeOps.DATE, "trunc({0})"); - - add(Ops.DateTimeOps.WEEK, "to_number(to_char({0},'WW'))"); - add(Ops.DateTimeOps.DAY_OF_WEEK, "to_number(to_char({0},'D')) + 1"); - add(Ops.DateTimeOps.DAY_OF_YEAR, "to_number(to_char({0},'DDD'))"); - add(Ops.DateTimeOps.YEAR_WEEK, "to_number(to_char({0},'IYYY') || to_char({0},'IW'))"); - - add(Ops.DateTimeOps.ADD_YEARS, "{0} + interval '{1s}' year"); - add(Ops.DateTimeOps.ADD_MONTHS, "{0} + interval '{1s}' month"); - add(Ops.DateTimeOps.ADD_WEEKS, "{0} + interval '{1s}' week"); - add(Ops.DateTimeOps.ADD_DAYS, "{0} + interval '{1s}' day"); - add(Ops.DateTimeOps.ADD_HOURS, "{0} + interval '{1s}' hour"); - add(Ops.DateTimeOps.ADD_MINUTES, "{0} + interval '{1s}' minute"); - add(Ops.DateTimeOps.ADD_SECONDS, "{0} + interval '{1s}' second"); - - add(Ops.DateTimeOps.DIFF_YEARS, "trunc(months_between({1}, {0}) / 12)"); - add(Ops.DateTimeOps.DIFF_MONTHS, "trunc(months_between({1}, {0}))"); - add(Ops.DateTimeOps.DIFF_WEEKS, "round(({1} - {0}) / 7)"); - add(Ops.DateTimeOps.DIFF_DAYS, "round({1} - {0})"); - add(Ops.DateTimeOps.DIFF_HOURS, "round(({1} - {0}) * 24)"); - add(Ops.DateTimeOps.DIFF_MINUTES, "round(({1} - {0}) * 1440)"); - add(Ops.DateTimeOps.DIFF_SECONDS, "round(({1} - {0}) * 86400)"); - - add(Ops.DateTimeOps.TRUNC_YEAR, "trunc({0}, 'year')"); - add(Ops.DateTimeOps.TRUNC_MONTH, "trunc({0}, 'month')"); - add(Ops.DateTimeOps.TRUNC_WEEK, "trunc({0}, 'w')"); - add(Ops.DateTimeOps.TRUNC_DAY, "trunc({0}, 'day')"); - add(Ops.DateTimeOps.TRUNC_HOUR, "trunc({0}, 'hh')"); - add(Ops.DateTimeOps.TRUNC_MINUTE, "trunc({0}, 'mi')"); - add(Ops.DateTimeOps.TRUNC_SECOND, "{0}"); // not truncated - } - - @Override - public String serialize(String literal, int jdbcType) { - if (jdbcType == Types.DATE) { - return "date '" + literal + "'"; - } else if (jdbcType == Types.TIMESTAMP) { - return "timestamp '" + literal + "'"; - } else if (jdbcType == Types.TIME) { - return "timestamp '1970-01-01 " + literal + "'"; - } else { - return super.serialize(literal, jdbcType); - } - } - - @Override - public void serialize(QueryMetadata metadata, boolean forCountRow, SQLSerializer context) { - if (!forCountRow && metadata.getModifiers().isRestricting() && !metadata.getJoins().isEmpty()) { - QueryModifiers mod = metadata.getModifiers(); - - if (mod.getOffset() == null) { - context.append(limitQueryStart); - context.serializeForQuery(metadata, forCountRow); - context.handle(limitQueryEnd, mod.getLimit()); - } else { - context.append(outerQueryStart); - context.serializeForQuery(metadata, forCountRow); - context.append(outerQueryEnd); - - if (mod.getLimit() == null) { - context.handle(offsetTemplate, mod.getOffset()); - } else { - context.handle(limitOffsetTemplate, mod.getOffset(), mod.getLimit()); - } - } - - } else { - context.serializeForQuery(metadata, forCountRow); - } - - if (!metadata.getFlags().isEmpty()) { - context.serialize(Position.END, metadata.getFlags()); - } - } - - @Override - public void serializeDelete(QueryMetadata metadata, RelationalPath entity, SQLSerializer context) { - context.serializeForDelete(metadata, entity); - - // limit - if (metadata.getModifiers().isRestricting()) { - serializeModifiersForDML(metadata, context); - } - - if (!metadata.getFlags().isEmpty()) { - context.serialize(Position.END, metadata.getFlags()); - } - } - - @Override - public void serializeUpdate(QueryMetadata metadata, RelationalPath entity, - List, Expression>> updates, SQLSerializer context) { - context.serializeForUpdate(metadata, entity, updates); - - // limit - if (metadata.getModifiers().isRestricting()) { - serializeModifiersForDML(metadata, context); - } - - if (!metadata.getFlags().isEmpty()) { - context.serialize(Position.END, metadata.getFlags()); - } - } - - private void serializeModifiersForDML(QueryMetadata metadata, SQLSerializer context) { - if (metadata.getWhere() != null) { - context.append(" and "); - } else { - context.append(getWhere()); - } - context.append("rownum <= "); - context.visitConstant(metadata.getModifiers().getLimit()); - } - - @Override - protected void serializeModifiers(QueryMetadata metadata, SQLSerializer context) { - // do nothing - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/PostgresTemplates.java b/querydsl-sql/src/main/java/com/mysema/query/sql/PostgresTemplates.java deleted file mode 100644 index 2c06685ae6..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/PostgresTemplates.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import com.mysema.query.types.Ops; - -/** - * PostgresTemplates is an SQL dialect for PostgreSQL - * - *

tested with PostgreSQL 8.4 and 9.1

- * - * @author tiwe - * - */ -public class PostgresTemplates extends SQLTemplates { - - public static Builder builder() { - return new Builder() { - @Override - protected SQLTemplates build(char escape, boolean quote) { - return new PostgresTemplates(escape, quote); - } - }; - } - - public PostgresTemplates() { - this('\\', false); - } - - public PostgresTemplates(boolean quote) { - this('\\', quote); - } - - public PostgresTemplates(char escape, boolean quote) { - super("\"", escape, quote); - setDummyTable(null); - setCountDistinctMultipleColumns(true); - setCountViaAnalytics(true); - setDefaultValues("\ndefault values"); - - addClass2TypeMappings("numeric(3,0)", Byte.class); - addClass2TypeMappings("double precision", Double.class); - - // String - add(Ops.MATCHES, "{0} ~ {1}"); - add(Ops.INDEX_OF, "strpos({0},{1})-1"); - add(Ops.INDEX_OF_2ARGS, "strpos({0},{1})-1"); //FIXME - add(Ops.StringOps.LOCATE, "strpos({1},{0})"); - add(Ops.StringOps.LOCATE2, "strpos(repeat('^',{2s}-1) || substr({1},{2s}),{0})"); - - // like without escape - if (escape == '\\') { - add(Ops.LIKE, "{0} like {1}"); - add(Ops.ENDS_WITH, "{0} like {%1}"); - add(Ops.ENDS_WITH_IC, "{0l} like {%%1}"); - add(Ops.STARTS_WITH, "{0} like {1%}"); - add(Ops.STARTS_WITH_IC, "{0l} like {1%%}"); - add(Ops.STRING_CONTAINS, "{0} like {%1%}"); - add(Ops.STRING_CONTAINS_IC, "{0l} like {%%1%%}"); - } - - // Number - add(Ops.MathOps.RANDOM, "random()"); - add(Ops.MathOps.LN, "ln({0})"); - add(Ops.MathOps.LOG, "log({1},{0})"); - add(Ops.MathOps.COSH, "(exp({0}) + exp({0} * -1)) / 2"); - add(Ops.MathOps.COTH, "(exp({0} * 2) + 1) / (exp({0} * 2) - 1)"); - add(Ops.MathOps.SINH, "(exp({0}) - exp({0} * -1)) / 2"); - add(Ops.MathOps.TANH, "(exp({0} * 2) - 1) / (exp({0} * 2) + 1)"); - - // Date / time - add(Ops.DateTimeOps.DAY_OF_WEEK, "extract(dow from {0}) + 1"); - add(Ops.DateTimeOps.DAY_OF_YEAR, "extract(doy from {0})"); - add(Ops.DateTimeOps.YEAR_WEEK, "(extract(isoyear from {0}) * 100 + extract(week from {0}))"); - - add(Ops.AggOps.BOOLEAN_ANY, "bool_or({0})", 0); - add(Ops.AggOps.BOOLEAN_ALL, "bool_and({0})", 0); - - add(Ops.DateTimeOps.ADD_YEARS, "{0} + interval '{1s} years'"); - add(Ops.DateTimeOps.ADD_MONTHS, "{0} + interval '{1s} months'"); - add(Ops.DateTimeOps.ADD_WEEKS, "{0} + interval '{1s} weeks'"); - add(Ops.DateTimeOps.ADD_DAYS, "{0} + interval '{1s} days'"); - add(Ops.DateTimeOps.ADD_HOURS, "{0} + interval '{1s} hours'"); - add(Ops.DateTimeOps.ADD_MINUTES, "{0} + interval '{1s} minutes'"); - add(Ops.DateTimeOps.ADD_SECONDS, "{0} + interval '{1s} seconds'"); - - String yearsDiff = "date_part('year', age({1}, {0}))"; - String monthsDiff = "(" + yearsDiff + " * 12 + date_part('month', age({1}, {0})))"; - String weeksDiff = "trunc((cast({1} as date) - cast({0} as date))/7)"; - String daysDiff = "(cast({1} as date) - cast({0} as date))"; - String hoursDiff = "("+ daysDiff + " * 24 + date_part('hour', age({1}, {0})))"; - String minutesDiff = "(" + hoursDiff + " * 60 + date_part('minute', age({1}, {0})))"; - String secondsDiff = "(" + minutesDiff + " * 60 + date_part('second', age({1}, {0})))"; - - add(Ops.DateTimeOps.DIFF_YEARS, yearsDiff); - add(Ops.DateTimeOps.DIFF_MONTHS, monthsDiff); - add(Ops.DateTimeOps.DIFF_WEEKS, weeksDiff); - add(Ops.DateTimeOps.DIFF_DAYS, daysDiff); - add(Ops.DateTimeOps.DIFF_HOURS, hoursDiff); - add(Ops.DateTimeOps.DIFF_MINUTES, minutesDiff); - add(Ops.DateTimeOps.DIFF_SECONDS, secondsDiff); - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/PrimaryKey.java b/querydsl-sql/src/main/java/com/mysema/query/sql/PrimaryKey.java deleted file mode 100644 index fe6e286e51..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/PrimaryKey.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import java.io.Serializable; -import java.util.List; - -import javax.annotation.Nullable; -import javax.annotation.concurrent.Immutable; - -import com.google.common.collect.ImmutableList; -import com.mysema.query.Tuple; -import com.mysema.query.types.CollectionExpression; -import com.mysema.query.types.Expression; -import com.mysema.query.types.ExpressionUtils; -import com.mysema.query.types.Ops; -import com.mysema.query.types.Path; -import com.mysema.query.types.ProjectionRole; -import com.mysema.query.types.expr.BooleanExpression; -import com.mysema.query.types.expr.BooleanOperation; - -/** - * PrimaryKey defines a primary key on table - * - * @author tiwe - */ -@Immutable -public final class PrimaryKey implements Serializable, ProjectionRole { - - private static final long serialVersionUID = -6913344535043394649L; - - private final RelationalPath entity; - - private final ImmutableList> localColumns; - - @Nullable - private volatile Expression mixin; - - public PrimaryKey(RelationalPath entity, Path... localColumns) { - this(entity, ImmutableList.copyOf(localColumns)); - } - - public PrimaryKey(RelationalPath entity, ImmutableList> localColumns) { - this.entity = entity; - this.localColumns = localColumns; - this.mixin = ExpressionUtils.list(Tuple.class, localColumns); - } - - public RelationalPath getEntity() { - return entity; - } - - public List> getLocalColumns() { - return localColumns; - } - - public BooleanExpression in(CollectionExpression coll) { - return BooleanOperation.create(Ops.IN, getProjection(), coll); - } - - @Override - public Expression getProjection() { - if (mixin == null) { - mixin = ExpressionUtils.list(Tuple.class, localColumns); - } - return mixin; - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/ProjectableSQLQuery.java b/querydsl-sql/src/main/java/com/mysema/query/sql/ProjectableSQLQuery.java deleted file mode 100644 index e3365475f7..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/ProjectableSQLQuery.java +++ /dev/null @@ -1,522 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import javax.annotation.Nullable; -import java.util.List; -import java.util.Map; - -import com.google.common.collect.ImmutableList; -import com.infradna.tool.bridge_method_injector.WithBridgeMethods; -import com.mysema.commons.lang.CloseableIterator; -import com.mysema.query.*; -import com.mysema.query.QueryFlag.Position; -import com.mysema.query.support.Expressions; -import com.mysema.query.support.ProjectableQuery; -import com.mysema.query.support.QueryMixin; -import com.mysema.query.types.*; -import com.mysema.query.types.expr.Wildcard; -import com.mysema.query.types.query.ListSubQuery; -import com.mysema.query.types.template.NumberTemplate; -import com.mysema.query.types.template.SimpleTemplate; - -/** - * ProjectableSQLQuery is the base type for SQL query implementations - * - * @param concrete subtype - */ -public abstract class ProjectableSQLQuery & Query> extends ProjectableQuery implements SQLCommonQuery { - - protected final Configuration configuration; - - @Nullable - protected Expression union; - - protected boolean unionAll; - - @SuppressWarnings("unchecked") - public ProjectableSQLQuery(QueryMixin queryMixin, Configuration configuration) { - super(queryMixin); - this.queryMixin.setSelf((Q) this); - this.configuration = configuration; - } - - /** - * Add the given String literal as a join flag to the last added join with the position - * BEFORE_TARGET - * - * @param flag - * @return - */ - @Override - @WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true) - public Q addJoinFlag(String flag) { - return addJoinFlag(flag, JoinFlag.Position.BEFORE_TARGET); - } - - /** - * Add the given String literal as a join flag to the last added join - * - * @param flag - * @param position - * @return - */ - @Override - @WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true) - @SuppressWarnings("unchecked") - public Q addJoinFlag(String flag, JoinFlag.Position position) { - queryMixin.addJoinFlag(new JoinFlag(flag, position)); - return (Q)this; - } - - /** - * Add the given prefix and expression as a general query flag - * - * @param position position of the flag - * @param prefix prefix for the flag - * @param expr expression of the flag - * @return - */ - @Override - @WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true) - public Q addFlag(Position position, String prefix, Expression expr) { - Expression flag = SimpleTemplate.create(expr.getType(), prefix + "{0}", expr); - return queryMixin.addFlag(new QueryFlag(position, flag)); - } - - /** - * Add the given query flag - * - * @param flag - * @return - */ - @WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true) - public Q addFlag(QueryFlag flag) { - return queryMixin.addFlag(flag); - } - - /** - * Add the given String literal as query flag - * - * @param position - * @param flag - * @return - */ - @Override - @WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true) - public Q addFlag(Position position, String flag) { - return queryMixin.addFlag(new QueryFlag(position, flag)); - } - - /** - * Add the given Expression as a query flag - * - * @param position - * @param flag - * @return - */ - @Override - @WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true) - public Q addFlag(Position position, Expression flag) { - return queryMixin.addFlag(new QueryFlag(position, flag)); - } - - @Override - public long count() { - Number number = uniqueResult(Wildcard.countAsInt); - return number.longValue(); - } - - @Override - public boolean exists() { - return limit(1).singleResult(NumberTemplate.ONE) != null; - } - - @WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true) - public Q from(Expression arg) { - return queryMixin.from(arg); - } - - @Override - @WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true) - public Q from(Expression... args) { - return queryMixin.from(args); - } - - @Override - @WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true) - @SuppressWarnings({ "unchecked", "rawtypes" }) - public Q from(SubQueryExpression subQuery, Path alias) { - return queryMixin.from(ExpressionUtils.as((Expression) subQuery, alias)); - } - - @Override - @WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true) - public Q fullJoin(EntityPath target) { - return queryMixin.fullJoin(target); - } - - @Override - @WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true) - public Q fullJoin(RelationalFunctionCall target, Path alias) { - return queryMixin.fullJoin(target, alias); - } - - @Override - @WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true) - public Q fullJoin(SubQueryExpression target, Path alias) { - return queryMixin.fullJoin(target, alias); - } - - @Override - @WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true) - public Q fullJoin(ForeignKey key, RelationalPath entity) { - return queryMixin.fullJoin(entity).on(key.on(entity)); - } - - @Override - @WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true) - public Q innerJoin(EntityPath target) { - return queryMixin.innerJoin(target); - } - - @Override - @WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true) - public Q innerJoin(RelationalFunctionCall target, Path alias) { - return queryMixin.innerJoin(target, alias); - } - - @Override - @WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true) - public Q innerJoin(SubQueryExpression target, Path alias) { - return queryMixin.innerJoin(target, alias); - } - - @Override - @WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true) - public Q innerJoin(ForeignKey key, RelationalPath entity) { - return queryMixin.innerJoin(entity).on(key.on(entity)); - } - - @Override - @WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true) - public Q join(EntityPath target) { - return queryMixin.join(target); - } - - @Override - @WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true) - public Q join(RelationalFunctionCall target, Path alias) { - return queryMixin.join(target, alias); - } - - @Override - @WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true) - public Q join(SubQueryExpression target, Path alias) { - return queryMixin.join(target, alias); - } - - @Override - @WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true) - public Q join(ForeignKey key, RelationalPath entity) { - return queryMixin.join(entity).on(key.on(entity)); - } - - @Override - @WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true) - public Q leftJoin(EntityPath target) { - return queryMixin.leftJoin(target); - } - - @Override - @WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true) - public Q leftJoin(RelationalFunctionCall target, Path alias) { - return queryMixin.leftJoin(target, alias); - } - - @Override - @WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true) - public Q leftJoin(SubQueryExpression target, Path alias) { - return queryMixin.leftJoin(target, alias); - } - - @Override - @WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true) - public Q leftJoin(ForeignKey key, RelationalPath entity) { - return queryMixin.leftJoin(entity).on(key.on(entity)); - } - - @Override - @WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true) - public Q rightJoin(EntityPath target) { - return queryMixin.rightJoin(target); - } - - @Override - @WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true) - public Q rightJoin(RelationalFunctionCall target, Path alias) { - return queryMixin.rightJoin(target, alias); - } - - @Override - @WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true) - public Q rightJoin(SubQueryExpression target, Path alias) { - return queryMixin.rightJoin(target, alias); - } - - @Override - @WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true) - public Q rightJoin(ForeignKey key, RelationalPath entity) { - return queryMixin.rightJoin(entity).on(key.on(entity)); - } - - public QueryMetadata getMetadata() { - return queryMixin.getMetadata(); - } - - @SuppressWarnings("unchecked") - private Union innerUnion(SubQueryExpression... sq) { - queryMixin.getMetadata().setValidate(false); - if (!queryMixin.getMetadata().getJoins().isEmpty()) { - throw new IllegalArgumentException("Don't mix union and from"); - } - this.union = UnionUtils.union(sq, unionAll); - return new UnionImpl((Q)this, sq[0].getMetadata().getProjection()); - } - - @Override - public CloseableIterator iterate(Expression... args) { - return iterate(queryMixin.createProjection(args)); - } - - @Override - public List list(Expression... args) { - return list(queryMixin.createProjection(args)); - } - - @Override - public SearchResults listResults(Expression... args) { - return listResults(queryMixin.createProjection(args)); - } - - @WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true) - public Q on(Predicate condition) { - return queryMixin.on(condition); - } - - @Override - @WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true) - public Q on(Predicate... conditions) { - return queryMixin.on(conditions); - } - - /** - * Creates an union expression for the given subqueries - * - * @param - * @param sq - * @return - */ - public Union union(ListSubQuery... sq) { - return innerUnion(sq); - } - - /** - * Creates an union expression for the given subqueries - * - * @param - * @param sq - * @return - */ - @WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true) - public Q union(Path alias, ListSubQuery... sq) { - return from(UnionUtils.union(sq, alias, false)); - } - - /** - * Creates an union expression for the given subqueries - * - * @param - * @param sq - * @return - */ - public Union union(SubQueryExpression... sq) { - return innerUnion(sq); - } - - /** - * Creates an union expression for the given subqueries - * - * @param - * @param sq - * @return - */ - @WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true) - public Q union(Path alias, SubQueryExpression... sq) { - return from(UnionUtils.union(sq, alias, false)); - } - - /** - * Creates an union expression for the given subqueries - * - * @param - * @param sq - * @return - */ - public Union unionAll(ListSubQuery... sq) { - unionAll = true; - return innerUnion(sq); - } - - /** - * Creates an union expression for the given subqueries - * - * @param - * @param sq - * @return - */ - @WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true) - public Q unionAll(Path alias, ListSubQuery... sq) { - return from(UnionUtils.union(sq, alias, true)); - } - - /** - * Creates an union expression for the given subqueries - * - * @param - * @param sq - * @return - */ - public Union unionAll(SubQueryExpression... sq) { - unionAll = true; - return innerUnion(sq); - } - - /** - * Creates an union expression for the given subqueries - * - * @param - * @param sq - * @return - */ - @WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true) - public Q unionAll(Path alias, SubQueryExpression... sq) { - return from(UnionUtils.union(sq, alias, true)); - } - - @Override - public Tuple uniqueResult(Expression... args) { - return uniqueResult(queryMixin.createProjection(args)); - } - - @Override - public RT uniqueResult(Expression expr) { - if (getMetadata().getModifiers().getLimit() == null - && !expr.toString().contains("count(")) { - limit(2); - } - CloseableIterator iterator = iterate(expr); - return uniqueResult(iterator); - } - - @Override - @WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true) - public Q withRecursive(Path alias, SubQueryExpression query) { - queryMixin.addFlag(new QueryFlag(QueryFlag.Position.WITH, SQLTemplates.RECURSIVE)); - return with(alias, query); - } - - @Override - @WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true) - public Q withRecursive(Path alias, Expression query) { - queryMixin.addFlag(new QueryFlag(QueryFlag.Position.WITH, SQLTemplates.RECURSIVE)); - return with(alias, query); - } - - @Override - public WithBuilder withRecursive(Path alias, Path... columns) { - queryMixin.addFlag(new QueryFlag(QueryFlag.Position.WITH, SQLTemplates.RECURSIVE)); - return with(alias, columns); - } - - @Override - @WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true) - public Q with(Path alias, SubQueryExpression query) { - Expression expr = OperationImpl.create(alias.getType(), SQLOps.WITH_ALIAS, alias, query); - return queryMixin.addFlag(new QueryFlag(QueryFlag.Position.WITH, expr)); - } - - @Override - @WithBridgeMethods(value=AbstractSQLQuery.class, castRequired=true) - public Q with(Path alias, Expression query) { - Expression expr = OperationImpl.create(alias.getType(), SQLOps.WITH_ALIAS, alias, query); - return queryMixin.addFlag(new QueryFlag(QueryFlag.Position.WITH, expr)); - } - - @Override - public WithBuilder with(Path alias, Path... columns) { - Expression columnsCombined = ExpressionUtils.list(Object.class, columns); - Expression aliasCombined = Expressions.operation(alias.getType(), SQLOps.WITH_COLUMNS, alias, columnsCombined); - return new WithBuilder(queryMixin, aliasCombined); - } - - protected void clone(Q query) { - this.union = query.union; - this.unionAll = query.unionAll; - } - - @Override - public abstract Q clone(); - - protected abstract SQLSerializer createSerializer(); - - protected SQLSerializer serialize(boolean forCountRow) { - SQLSerializer serializer = createSerializer(); - if (union != null) { - serializer.serializeUnion(union, queryMixin.getMetadata(), unionAll); - } else { - serializer.serialize(queryMixin.getMetadata(), forCountRow); - } - return serializer; - } - - /** - * Get the query as an SQL query string and bindings - * - * @param exprs - * @return - */ - public SQLBindings getSQL(Expression... exprs) { - queryMixin.addProjection(exprs); - SQLSerializer serializer = serialize(false); - ImmutableList.Builder args = ImmutableList.builder(); - Map, Object> params = getMetadata().getParams(); - for (Object o : serializer.getConstants()) { - if (o instanceof ParamExpression) { - if (!params.containsKey(o)) { - throw new ParamNotSetException((ParamExpression) o); - } - o = queryMixin.getMetadata().getParams().get(o); - } - args.add(o); - } - return new SQLBindings(serializer.toString(), args.build()); - } - - public String toString() { - SQLSerializer serializer = serialize(false); - return serializer.toString().trim(); - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/QBeans.java b/querydsl-sql/src/main/java/com/mysema/query/sql/QBeans.java deleted file mode 100644 index 2086df450e..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/QBeans.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.mysema.query.types.Expression; -import com.mysema.query.types.ExpressionBase; -import com.mysema.query.types.FactoryExpression; -import com.mysema.query.types.Path; -import com.mysema.query.types.QBean; -import com.mysema.query.types.Visitor; -import com.mysema.util.ArrayUtils; - -/** - * Expression used to project a list of beans - * - * @author luis - */ -public class QBeans extends ExpressionBase implements FactoryExpression { - - private static final long serialVersionUID = -4411839816134215923L; - - private final ImmutableMap, QBean> qBeans; - - private final ImmutableList> expressions; - - @SuppressWarnings("unchecked") - public QBeans(RelationalPath... beanPaths) { - super(Beans.class); - try { - final ImmutableList.Builder> listBuilder = ImmutableList.builder(); - final ImmutableMap.Builder, QBean> mapBuilder = ImmutableMap.builder(); - for (RelationalPath path : beanPaths) { - Map> bindings = new LinkedHashMap>(); - for (Path column : path.getColumns()) { - bindings.put(column.getMetadata().getName(), column); - listBuilder.add(column); - } - mapBuilder.put(path, new QBean((Class)path.getType(), bindings)); - } - expressions = listBuilder.build(); - qBeans = mapBuilder.build(); - } catch (Exception e) { - throw new IllegalStateException(e); - } - } - - @Override - public R accept(Visitor v, C context) { - return v.visit(this, context); - } - - @Override - public List> getArgs() { - return expressions; - } - - @Override - public Beans newInstance(Object... args) { - int offset = 0; - Map, Object> beans = new HashMap, Object>(); - for (Map.Entry, QBean> entry : qBeans.entrySet()) { - RelationalPath path = entry.getKey(); - QBean qBean = entry.getValue(); - int argsSize = qBean.getArgs().size(); - Object[] subArgs = ArrayUtils.subarray(args, offset, offset + argsSize); - beans.put(path, qBean.newInstance(subArgs)); - offset += argsSize; - } - return new Beans(beans); - } - -} \ No newline at end of file diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/RelationalFunctionCall.java b/querydsl-sql/src/main/java/com/mysema/query/sql/RelationalFunctionCall.java deleted file mode 100644 index 85c232a9c3..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/RelationalFunctionCall.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import java.util.List; - -import com.mysema.query.types.Template; -import com.mysema.query.types.TemplateExpression; -import com.mysema.query.types.TemplateExpressionImpl; -import com.mysema.query.types.TemplateFactory; -import com.mysema.query.types.Visitor; -import com.mysema.query.types.expr.SimpleExpression; - -/** - * Represents a table valued function call - * - * @author tiwe - * - * @param - */ -public class RelationalFunctionCall extends SimpleExpression implements TemplateExpression { - - private static final long serialVersionUID = 256739044928186923L; - - private static Template createTemplate(String function, int argCount) { - StringBuilder builder = new StringBuilder(); - builder.append(function); - builder.append("("); - for (int i = 0; i < argCount; i++) { - if (i > 0) { - builder.append(", "); - } - builder.append("{"+ i + "}"); - } - builder.append(")"); - return TemplateFactory.DEFAULT.create(builder.toString()); - } - - private final TemplateExpression templateMixin; - - /** - * Create a new RelationalFunctionCall for the given function and arguments - * - * @param type - * @param function - * @param args - * @return - */ - public static RelationalFunctionCall create(Class type, String function, Object... args) { - return new RelationalFunctionCall(type, function, args); - } - - public RelationalFunctionCall(Class type, String function, Object... args) { - super(TemplateExpressionImpl.create((Class)type, createTemplate(function, args.length), args)); - templateMixin = (TemplateExpression)mixin; - } - - @Override - public final R accept(Visitor v, C context) { - return v.visit(this, context); - } - - @Override - public Object getArg(int index) { - return templateMixin.getArg(index); - } - - @Override - public List getArgs() { - return templateMixin.getArgs(); - } - - @Override - public Template getTemplate() { - return templateMixin.getTemplate(); - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/RelationalPathBase.java b/querydsl-sql/src/main/java/com/mysema/query/sql/RelationalPathBase.java deleted file mode 100644 index f9dfc8e2fb..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/RelationalPathBase.java +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import javax.annotation.Nullable; -import java.util.Collection; -import java.util.List; -import java.util.Map; - -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.mysema.query.types.*; -import com.mysema.query.types.expr.NumberExpression; -import com.mysema.query.types.expr.NumberOperation; -import com.mysema.query.types.path.BeanPath; -import static com.google.common.collect.ImmutableList.copyOf; - -/** - * RelationalPathBase is a base class for {@link RelationalPath} implementations - * - * @author tiwe - * - * @param - * entity type - */ -public class RelationalPathBase extends BeanPath implements RelationalPath { - - private static final long serialVersionUID = -7031357250283629202L; - - @Nullable - private PrimaryKey primaryKey; - - private final Map, ColumnMetadata> columnMetadata = Maps.newLinkedHashMap(); - - private final List> foreignKeys = Lists.newArrayList(); - - private final List> inverseForeignKeys = Lists.newArrayList(); - - private final String schema, table; - - private final SchemaAndTable schemaAndTable; - - private transient FactoryExpression projection; - - private transient NumberExpression count, countDistinct; - - public RelationalPathBase(Class type, String variable, String schema, String table) { - this(type, PathMetadataFactory.forVariable(variable), schema, table); - } - - public RelationalPathBase(Class type, PathMetadata metadata, String schema, - String table) { - super(type, metadata); - this.schema = schema; - this.table = table; - this.schemaAndTable = new SchemaAndTable(schema, table); - } - - protected PrimaryKey createPrimaryKey(Path... columns) { - primaryKey = new PrimaryKey(this, columns); - return primaryKey; - } - - protected ForeignKey createForeignKey(Path local, String foreign) { - ForeignKey foreignKey = new ForeignKey(this, local, foreign); - foreignKeys.add(foreignKey); - return foreignKey; - } - - protected ForeignKey createForeignKey(List> local, List foreign) { - ForeignKey foreignKey = new ForeignKey(this, copyOf(local), copyOf(foreign)); - foreignKeys.add(foreignKey); - return foreignKey; - } - - protected ForeignKey createInvForeignKey(Path local, String foreign) { - ForeignKey foreignKey = new ForeignKey(this, local, foreign); - inverseForeignKeys.add(foreignKey); - return foreignKey; - } - - protected ForeignKey createInvForeignKey(List> local, - List foreign) { - ForeignKey foreignKey = new ForeignKey(this, copyOf(local), copyOf(foreign)); - inverseForeignKeys.add(foreignKey); - return foreignKey; - } - - protected

> P addMetadata(P path, ColumnMetadata metadata) { - columnMetadata.put(path, metadata); - return path; - } - - @Override - public NumberExpression count() { - if (count == null) { - if (primaryKey != null) { - count = NumberOperation.create(Long.class, Ops.AggOps.COUNT_AGG, - primaryKey.getLocalColumns().get(0)); - } else { - throw new IllegalStateException("No count expression can be created"); - } - } - return count; - } - - @Override - public NumberExpression countDistinct() { - if (countDistinct == null) { - if (primaryKey != null) { - // TODO handle multiple column primary keys properly - countDistinct = NumberOperation.create(Long.class, Ops.AggOps.COUNT_DISTINCT_AGG, - primaryKey.getLocalColumns().get(0)); - } else { - throw new IllegalStateException("No count distinct expression can be created"); - } - } - return countDistinct; - } - - @Override - public FactoryExpression getProjection() { - if (projection == null) { - projection = RelationalPathUtils.createProjection(this); - } - return projection; - } - - public Path[] all() { - Path[] all = new Path[columnMetadata.size()]; - columnMetadata.keySet().toArray(all); - return all; - } - - @Override - protected

> P add(P path) { - return path; - } - - @Override - public List> getColumns() { - return Lists.newArrayList(this.columnMetadata.keySet()); - } - - @Override - public Collection> getForeignKeys() { - return foreignKeys; - } - - @Override - public Collection> getInverseForeignKeys() { - return inverseForeignKeys; - } - - @Override - public PrimaryKey getPrimaryKey() { - return primaryKey; - } - - @Override - public SchemaAndTable getSchemaAndTable() { - return schemaAndTable; - } - - @Override - public String getSchemaName() { - return schema; - } - - @Override - public String getTableName() { - return table; - } - - @Override - public ColumnMetadata getMetadata(Path column) { - return columnMetadata.get(column); - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/RelationalPathUtils.java b/querydsl-sql/src/main/java/com/mysema/query/sql/RelationalPathUtils.java deleted file mode 100644 index 7a81a09f13..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/RelationalPathUtils.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import java.util.HashMap; -import java.util.Map; - -import com.mysema.query.types.Expression; -import com.mysema.query.types.FactoryExpression; -import com.mysema.query.types.Path; -import com.mysema.query.types.Projections; -import com.mysema.query.types.QBean; - -/** - * RelationalPathUtils provides static utility methods for {@link RelationalPath} instances - * - * @author tiwe - * - */ -@SuppressWarnings("unchecked") -public final class RelationalPathUtils { - - public static FactoryExpression createProjection(RelationalPath path) { - if (path.getType().equals(path.getClass())) { - throw new IllegalArgumentException("RelationalPath based projection can only be used with generated Bean types"); - } - try { - // ensure that empty constructor is available - path.getType().getConstructor(); - return createBeanProjection(path); - } catch (NoSuchMethodException e) { - // fallback to constructor projection - return createConstructorProjection(path); - } - } - - private static FactoryExpression createConstructorProjection(RelationalPath path) { - Expression[] exprs = path.getColumns().toArray(new Expression[path.getColumns().size()]); - return Projections.constructor((Class)path.getType(), exprs); - } - - private static FactoryExpression createBeanProjection(RelationalPath path) { - Map> bindings = new HashMap>(); - for (Path column : path.getColumns()) { - bindings.put(column.getMetadata().getName(), column); - } - if (bindings.isEmpty()) { - throw new IllegalArgumentException("No bindings could be derived from " + path); - } - return new QBean((Class)path.getType(), true, bindings); - } - - private RelationalPathUtils() {} - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/SQLBindings.java b/querydsl-sql/src/main/java/com/mysema/query/sql/SQLBindings.java deleted file mode 100644 index 3d03177d23..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/SQLBindings.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2013, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import com.google.common.collect.ImmutableList; - -/** - * SQLBindings provides the SQL query string and bindings - * - * @author tiwe - * - */ -public class SQLBindings { - - private final String sql; - - private final ImmutableList bindings; - - public SQLBindings(String sql, ImmutableList bindings) { - this.sql = sql; - this.bindings = bindings; - } - - @Deprecated - public String getSql() { - return sql; - } - - public String getSQL() { - return sql; - } - - public ImmutableList getBindings() { - return bindings; - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/SQLCommonQuery.java b/querydsl-sql/src/main/java/com/mysema/query/sql/SQLCommonQuery.java deleted file mode 100644 index bf8af58894..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/SQLCommonQuery.java +++ /dev/null @@ -1,314 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import com.mysema.query.JoinFlag; -import com.mysema.query.Query; -import com.mysema.query.QueryFlag.Position; -import com.mysema.query.types.EntityPath; -import com.mysema.query.types.Expression; -import com.mysema.query.types.Path; -import com.mysema.query.types.Predicate; -import com.mysema.query.types.SubQueryExpression; - -/** - * SQLCommonQuery is a common interface for SQLQuery and SQLSubQuery - * - * @author tiwe - * - * @param concrete type - */ -public interface SQLCommonQuery> extends Query { - - /** - * Add the given Expression as a query flag - * - * @param position - * @param flag - * @return - */ - Q addFlag(Position position, Expression flag); - - /** - * Add the given String literal as query flag - * - * @param position - * @param flag - * @return - */ - Q addFlag(Position position, String flag); - - /** - * Add the given prefix and expression as a general query flag - * - * @param position position of the flag - * @param prefix prefix for the flag - * @param expr expression of the flag - * @return - */ - Q addFlag(Position position, String prefix, Expression expr); - - /** - * Add the given String literal as a join flag to the last added join with the - * position BEFORE_TARGET - * - * @param flag - * @return - */ - Q addJoinFlag(String flag); - - /** - * Add the given String literal as a join flag to the last added join - * - * @param flag - * @param position - * @return - */ - Q addJoinFlag(String flag, JoinFlag.Position position); - - /** - * Defines the sources of the query - * - * @param o - * @return - */ - Q from(Expression... o); - - /** - * Adds a sub query source - * - * @param subQuery - * @param alias - * @return - */ - Q from(SubQueryExpression subQuery, Path alias); - - /** - * Adds a full join to the given target - * - * @param o - * @return - */ - Q fullJoin(EntityPath o); - - /** - * Adds a full join to the given target - * - * @param o - * @return - */ - Q fullJoin(RelationalFunctionCall o, Path alias); - - /** - * Adds a full join to the given target - * - * @param o - * @return - */ - Q fullJoin(ForeignKey key, RelationalPath entity); - - /** - * Adds a full join to the given target - * - * @param o - * @return - */ - Q fullJoin(SubQueryExpression o, Path alias); - - /** - * Adds an inner join to the given target - * - * @param o - * @return - */ - Q innerJoin(EntityPath o); - - /** - * Adds a full join to the given target - * - * @param o - * @return - */ - Q innerJoin(RelationalFunctionCall o, Path alias); - - /** - * Adds an inner join to the given target - * - * @param o - * @return - */ - Q innerJoin(ForeignKey foreign, RelationalPath entity); - - /** - * Adds an inner join to the given target - * - * @param o - * @return - */ - Q innerJoin(SubQueryExpression o, Path alias); - - /** - * Adds a join to the given target - * - * @param o - * @return - */ - Q join(EntityPath o); - - /** - * Adds a full join to the given target - * - * @param o - * @return - */ - Q join(RelationalFunctionCall o, Path alias); - - /** - * Adds a join to the given target - * - * @param o - * @return - */ - Q join(ForeignKey foreign, RelationalPath entity); - - /** - * Adds a join to the given target - * - * @param o - * @return - */ - Q join(SubQueryExpression o, Path alias); - - /** - * Adds a left join to the given target - * - * @param o - * @return - */ - Q leftJoin(EntityPath o); - - /** - * Adds a full join to the given target - * - * @param o - * @return - */ - Q leftJoin(RelationalFunctionCall o, Path alias); - - /** - * Adds a left join to the given target - * - * @param o - * @return - */ - Q leftJoin(ForeignKey foreign, RelationalPath entity); - - /** - * Adds a left join to the given target - * - * @param o - * @return - */ - Q leftJoin(SubQueryExpression o, Path alias); - - /** - * Defines a filter to the last added join - * - * @param conditions - * @return - */ - Q on(Predicate... conditions); - - /** - * Adds a right join to the given target - * - * @param o - * @return - */ - Q rightJoin(EntityPath o); - - /** - * Adds a full join to the given target - * - * @param o - * @return - */ - Q rightJoin(RelationalFunctionCall o, Path alias); - - /** - * Adds a right join to the given target - * - * @param o - * @return - */ - Q rightJoin(ForeignKey foreign, RelationalPath entity); - - /** - * Adds a right join to the given target - * - * @param o - * @return - */ - Q rightJoin(SubQueryExpression o, Path alias); - - /** - * Adds a common table expression - * - * @return - */ - Q with(Path alias, SubQueryExpression o); - - /** - * Adds a common table expression - * - * @param alias - * @param query - * @return - */ - Q with(Path alias, Expression query); - - /** - * Adds a common table expression - * - * @param alias - * @param columns - * @return - */ - WithBuilder with(Path alias, Path... columns); - - /** - * Adds a common table expression - * - * @return - */ - Q withRecursive(Path alias, SubQueryExpression o); - - /** - * Adds a common table expression - * - * @param alias - * @param query - * @return - */ - Q withRecursive(Path alias, Expression query); - - /** - * Adds a common table expression - * - * @param alias - * @param columns - * @return - */ - WithBuilder withRecursive(Path alias, Path... columns); -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/SQLCommonQueryFactory.java b/querydsl-sql/src/main/java/com/mysema/query/sql/SQLCommonQueryFactory.java deleted file mode 100644 index ba3f0b285c..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/SQLCommonQueryFactory.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import com.mysema.query.QueryFactory; -import com.mysema.query.sql.dml.SQLDeleteClause; -import com.mysema.query.sql.dml.SQLInsertClause; -import com.mysema.query.sql.dml.SQLMergeClause; -import com.mysema.query.sql.dml.SQLUpdateClause; -import com.mysema.query.types.Expression; -import com.mysema.query.types.Path; -import com.mysema.query.types.SubQueryExpression; - -/** - * Factory interface for query and clause creation. - * - *

The default implementation is {@link SQLQueryFactory} and should be used for general - * query creation. Type specific variants are available if database specific queries need to be created.

- * - * @author tiwe - * - * @param query type - * @param subquery type - * @param delete clause type - * @param update clause type - * @param insert clause type - * @param merge clause type - */ -public interface SQLCommonQueryFactory, // extends AbstractSQLQuery - SQ extends AbstractSQLSubQuery, - D extends SQLDeleteClause, - U extends SQLUpdateClause, - I extends SQLInsertClause, - M extends SQLMergeClause> extends QueryFactory { - - /** - * Create a new DELETE clause - * - * @param path - * @return - */ - D delete(RelationalPath path); - - /** - * Create a new SELECT query - * - * @param from - * @return - */ - Q from(Expression from); - - /** - * Create a new SELECT query - * - * @param from - * @return - */ - Q from(Expression... from); - - /** - * Create a new SELECT query - * - * @param from - * @return - */ - Q from(SubQueryExpression subQuery, Path alias); - - /** - * Create a new INSERT INTO clause - * - * @param path - * @return - */ - I insert(RelationalPath path); - - /** - * Create a new MERGE clause - * - * @param path - * @return - */ - M merge(RelationalPath path); - - /** - * Create a new UPDATE clause - * - * @param path - * @return - */ - U update(RelationalPath path); - - /* (non-Javadoc) - * @see com.mysema.query.QueryFactory#query() - */ - @Override - Q query(); - - /* (non-Javadoc) - * @see com.mysema.query.QueryFactory#subQuery() - */ - @Override - SQ subQuery(); - - /** - * @param from - * @return - */ - SQ subQuery(Expression from); - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/SQLExceptionTranslator.java b/querydsl-sql/src/main/java/com/mysema/query/sql/SQLExceptionTranslator.java deleted file mode 100644 index 8b80542fe6..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/SQLExceptionTranslator.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2014, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import java.sql.SQLException; -import java.util.List; - -/** - * SQLExceptionTranslator translate SQLExceptions to runtime exceptions - * - * @author tiwe - * - */ -public interface SQLExceptionTranslator { - - /** - * @param sql - * @param e - * @return - */ - RuntimeException translate(String sql, List bindings, SQLException e); - - /** - * @param e - * @return - */ - RuntimeException translate(SQLException e); -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/SQLExpressions.java b/querydsl-sql/src/main/java/com/mysema/query/sql/SQLExpressions.java deleted file mode 100644 index f76bd00404..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/SQLExpressions.java +++ /dev/null @@ -1,937 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import java.util.EnumMap; -import java.util.Map; - -import com.mysema.query.types.ConstantImpl; -import com.mysema.query.types.Expression; -import com.mysema.query.types.Operator; -import com.mysema.query.types.Ops; -import com.mysema.query.types.expr.BooleanExpression; -import com.mysema.query.types.expr.BooleanOperation; -import com.mysema.query.types.expr.DateExpression; -import com.mysema.query.types.expr.DateOperation; -import com.mysema.query.types.expr.DateTimeExpression; -import com.mysema.query.types.expr.DateTimeOperation; -import com.mysema.query.types.expr.NumberExpression; -import com.mysema.query.types.expr.NumberOperation; -import com.mysema.query.types.expr.SimpleExpression; -import com.mysema.query.types.expr.SimpleOperation; -import com.mysema.query.types.expr.StringExpression; -import com.mysema.query.types.expr.StringOperation; -import com.mysema.query.types.expr.Wildcard; - -/** - * Common SQL expressions - * - * @author tiwe - * - */ -@SuppressWarnings("rawtypes") -public final class SQLExpressions { - - private static final Map DATE_ADD_OPS - = new EnumMap(DatePart.class); - - private static final Map DATE_DIFF_OPS - = new EnumMap(DatePart.class); - - private static final Map DATE_TRUNC_OPS - = new EnumMap(DatePart.class); - - static { - DATE_ADD_OPS.put(DatePart.year, Ops.DateTimeOps.ADD_YEARS); - DATE_ADD_OPS.put(DatePart.month, Ops.DateTimeOps.ADD_MONTHS); - DATE_ADD_OPS.put(DatePart.week, Ops.DateTimeOps.ADD_WEEKS); - DATE_ADD_OPS.put(DatePart.day, Ops.DateTimeOps.ADD_DAYS); - DATE_ADD_OPS.put(DatePart.hour, Ops.DateTimeOps.ADD_HOURS); - DATE_ADD_OPS.put(DatePart.minute, Ops.DateTimeOps.ADD_MINUTES); - DATE_ADD_OPS.put(DatePart.second, Ops.DateTimeOps.ADD_SECONDS); - DATE_ADD_OPS.put(DatePart.millisecond, null); // TODO - - DATE_DIFF_OPS.put(DatePart.year, Ops.DateTimeOps.DIFF_YEARS); - DATE_DIFF_OPS.put(DatePart.month, Ops.DateTimeOps.DIFF_MONTHS); - DATE_DIFF_OPS.put(DatePart.week, Ops.DateTimeOps.DIFF_WEEKS); - DATE_DIFF_OPS.put(DatePart.day, Ops.DateTimeOps.DIFF_DAYS); - DATE_DIFF_OPS.put(DatePart.hour, Ops.DateTimeOps.DIFF_HOURS); - DATE_DIFF_OPS.put(DatePart.minute, Ops.DateTimeOps.DIFF_MINUTES); - DATE_DIFF_OPS.put(DatePart.second, Ops.DateTimeOps.DIFF_SECONDS); - DATE_DIFF_OPS.put(DatePart.millisecond, null); // TODO - - DATE_TRUNC_OPS.put(DatePart.year, Ops.DateTimeOps.TRUNC_YEAR); - DATE_TRUNC_OPS.put(DatePart.month, Ops.DateTimeOps.TRUNC_MONTH); - DATE_TRUNC_OPS.put(DatePart.week, Ops.DateTimeOps.TRUNC_WEEK); - DATE_TRUNC_OPS.put(DatePart.day, Ops.DateTimeOps.TRUNC_DAY); - DATE_TRUNC_OPS.put(DatePart.hour, Ops.DateTimeOps.TRUNC_HOUR); - DATE_TRUNC_OPS.put(DatePart.minute, Ops.DateTimeOps.TRUNC_MINUTE); - DATE_TRUNC_OPS.put(DatePart.second, Ops.DateTimeOps.TRUNC_SECOND); - - } - - private static final WindowOver cumeDist = new WindowOver(Double.class, SQLOps.CUMEDIST); - - private static final WindowOver rank = new WindowOver(Long.class, SQLOps.RANK); - - private static final WindowOver denseRank = new WindowOver(Long.class, SQLOps.DENSERANK); - - private static final WindowOver percentRank = new WindowOver(Double.class, SQLOps.PERCENTRANK); - - private static final WindowOver rowNumber = new WindowOver(Long.class, SQLOps.ROWNUMBER); - - private static Expression[] convertToExpressions(Object... args) { - Expression[] exprs = new Expression[args.length]; - for (int i = 0; i < args.length; i++) { - if (args[i] instanceof Expression) { - exprs[i] = (Expression)args[i]; - } else { - exprs[i] = new ConstantImpl(args[i]); - } - } - return exprs; - } - - /** - * Wildcard expression - */ - public static final Expression all = Wildcard.all; - - /** - * Wilcard count expression - */ - public static final Expression countAll = Wildcard.count; - - /** - * Get an aggregate any expression for the given boolean expression - */ - public static BooleanExpression any(BooleanExpression expr) { - return BooleanOperation.create(Ops.AggOps.BOOLEAN_ANY, expr); - } - - /** - * Get an aggregate all expression for the given boolean expression - */ - public static BooleanExpression all(BooleanExpression expr) { - return BooleanOperation.create(Ops.AggOps.BOOLEAN_ALL, expr); - } - - /** - * Get a nextval(sequence) expression - * - * @param sequence - * @return - */ - public static SimpleExpression nextval(String sequence) { - return nextval(Long.class, sequence); - } - - /** - * Get a nextval(sequence) expression of the given type - * - * @param type - * @param sequence - * @return - */ - public static SimpleExpression nextval(Class type, String sequence) { - return SimpleOperation.create(type, SQLOps.NEXTVAL, ConstantImpl.create(sequence)); - } - - /** - * Convert timestamp to date - * - * @param dateTime - * @return - */ - public static DateExpression date(DateTimeExpression dateTime) { - return DateOperation.create((Class)dateTime.getType(), Ops.DateTimeOps.DATE, dateTime); - } - - /** - * Convert timestamp to date - * - * @param type - * @param dateTime - * @return - */ - public static DateExpression date(Class type, DateTimeExpression dateTime) { - return DateOperation.create(type, Ops.DateTimeOps.DATE, dateTime); - } - - /** - * Get a dateadd(unit, date, amount) expression - * - * @param unit - * @param date - * @param amount - * @return - */ - public static DateTimeExpression dateadd(DatePart unit, DateTimeExpression date, int amount) { - return DateTimeOperation.create((Class)date.getType(), DATE_ADD_OPS.get(unit), date, ConstantImpl.create(amount)); - } - - /** - * Get a dateadd(unit, date, amount) expression - * - * @param unit - * @param date - * @param amount - * @return - */ - public static DateExpression dateadd(DatePart unit, DateExpression date, int amount) { - return DateOperation.create((Class)date.getType(), DATE_ADD_OPS.get(unit), date, ConstantImpl.create(amount)); - } - - /** - * Get a datediff(unit, start, end) expression - * - * @param unit - * @param start - * @param end - * @return - */ - public static NumberExpression datediff(DatePart unit, - DateExpression start, DateExpression end) { - return NumberOperation.create(Integer.class, DATE_DIFF_OPS.get(unit), start, end); - } - - /** - * Get a datediff(unit, start, end) expression - * - * @param unit - * @param start - * @param end - * @return - */ - public static NumberExpression datediff(DatePart unit, - D start, DateExpression end) { - return NumberOperation.create(Integer.class, DATE_DIFF_OPS.get(unit), ConstantImpl.create(start), end); - } - - /** - * Get a datediff(unit, start, end) expression - * - * @param unit - * @param start - * @param end - * @return - */ - public static NumberExpression datediff(DatePart unit, - DateExpression start, D end) { - return NumberOperation.create(Integer.class, DATE_DIFF_OPS.get(unit), start, ConstantImpl.create(end)); - } - - /** - * Get a datediff(unit, start, end) expression - * - * @param unit - * @param start - * @param end - * @return - */ - public static NumberExpression datediff(DatePart unit, - DateTimeExpression start, DateTimeExpression end) { - return NumberOperation.create(Integer.class, DATE_DIFF_OPS.get(unit), start, end); - } - - /** - * Get a datediff(unit, start, end) expression - * - * @param unit - * @param start - * @param end - * @return - */ - public static NumberExpression datediff(DatePart unit, - D start, DateTimeExpression end) { - return NumberOperation.create(Integer.class, DATE_DIFF_OPS.get(unit), ConstantImpl.create(start), end); - } - - /** - * Get a datediff(unit, start, end) expression - * - * @param unit - * @param start - * @param end - * @return - */ - public static NumberExpression datediff(DatePart unit, - DateTimeExpression start, D end) { - return NumberOperation.create(Integer.class, DATE_DIFF_OPS.get(unit), start, ConstantImpl.create(end)); - } - - /** - * Truncate the given date expression - * - * @param unit - * @param expr - */ - public static DateExpression datetrunc(DatePart unit, DateExpression expr) { - return DateOperation.create(expr.getType(), DATE_TRUNC_OPS.get(unit), expr); - } - - /** - * Truncate the given datetime expression - * - * @param unit - * @param expr - */ - public static DateTimeExpression datetrunc(DatePart unit, DateTimeExpression expr) { - return DateTimeOperation.create(expr.getType(), DATE_TRUNC_OPS.get(unit), expr); - } - - /** - * Add the given amount of years to the date - * - * @param date - * @param years - * @return - */ - public static DateTimeExpression addYears(DateTimeExpression date, int years) { - return DateTimeOperation.create((Class)date.getType(), Ops.DateTimeOps.ADD_YEARS, date, ConstantImpl.create(years)); - } - - /** - * Add the given amount of months to the date - * - * @param date - * @param months - * @return - */ - public static DateTimeExpression addMonths(DateTimeExpression date, int months) { - return DateTimeOperation.create((Class)date.getType(), Ops.DateTimeOps.ADD_MONTHS, date, ConstantImpl.create(months)); - } - - /** - * Add the given amount of weeks to the date - * - * @param date - * @param weeks - * @return - */ - public static DateTimeExpression addWeeks(DateTimeExpression date, int weeks) { - return DateTimeOperation.create((Class)date.getType(), Ops.DateTimeOps.ADD_WEEKS, date, ConstantImpl.create(weeks)); - } - - /** - * Add the given amount of days to the date - * - * @param date - * @param days - * @return - */ - public static DateTimeExpression addDays(DateTimeExpression date, int days) { - return DateTimeOperation.create((Class)date.getType(), Ops.DateTimeOps.ADD_DAYS, date, ConstantImpl.create(days)); - } - - /** - * Add the given amount of hours to the date - * - * @param date - * @param hours - * @return - */ - public static DateTimeExpression addHours(DateTimeExpression date, int hours) { - return DateTimeOperation.create((Class)date.getType(), Ops.DateTimeOps.ADD_HOURS, date, ConstantImpl.create(hours)); - } - - /** - * Add the given amount of minutes to the date - * - * @param date - * @param minutes - * @return - */ - public static DateTimeExpression addMinutes(DateTimeExpression date, int minutes) { - return DateTimeOperation.create((Class)date.getType(), Ops.DateTimeOps.ADD_MINUTES, date, ConstantImpl.create(minutes)); - } - - /** - * Add the given amount of seconds to the date - * - * @param date - * @param seconds - * @return - */ - public static DateTimeExpression addSeconds(DateTimeExpression date, int seconds) { - return DateTimeOperation.create((Class)date.getType(), Ops.DateTimeOps.ADD_SECONDS, date, ConstantImpl.create(seconds)); - } - - /** - * Add the given amount of years to the date - * - * @param date - * @param years - * @return - */ - public static DateExpression addYears(DateExpression date, int years) { - return DateOperation.create((Class)date.getType(), Ops.DateTimeOps.ADD_YEARS, date, ConstantImpl.create(years)); - } - - /** - * Add the given amount of months to the date - * - * @param date - * @param months - * @return - */ - public static DateExpression addMonths(DateExpression date, int months) { - return DateOperation.create((Class)date.getType(), Ops.DateTimeOps.ADD_MONTHS, date, ConstantImpl.create(months)); - } - - /** - * Add the given amount of weeks to the date - * - * @param date - * @param weeks - * @return - */ - public static DateExpression addWeeks(DateExpression date, int weeks) { - return DateOperation.create((Class)date.getType(), Ops.DateTimeOps.ADD_WEEKS, date, ConstantImpl.create(weeks)); - } - - /** - * Add the given amount of days to the date - * - * @param date - * @param days - * @return - */ - public static DateExpression addDays(DateExpression date, int days) { - return DateOperation.create((Class)date.getType(), Ops.DateTimeOps.ADD_DAYS, date, ConstantImpl.create(days)); - } - - /** - * Start a window function expression - * - * @param expr - * @return - */ - public static WindowOver sum(Expression expr) { - return new WindowOver((Class)expr.getType(), Ops.AggOps.SUM_AGG, expr); - } - - /** - * Start a window function expression - * - * @return - */ - public static WindowOver count() { - return new WindowOver(Long.class, Ops.AggOps.COUNT_ALL_AGG); - } - - /** - * Start a window function expression - * - * @param expr - * @return - */ - public static WindowOver count(Expression expr) { - return new WindowOver(Long.class, Ops.AggOps.COUNT_AGG, expr); - } - - /** - * Start a window function expression - * - * @param expr - * @return - */ - public static WindowOver countDistinct(Expression expr) { - return new WindowOver(Long.class, Ops.AggOps.COUNT_DISTINCT_AGG, expr); - } - - /** - * Start a window function expression - * - * @param expr - * @return - */ - public static WindowOver avg(Expression expr) { - return new WindowOver((Class)expr.getType(), Ops.AggOps.AVG_AGG, expr); - } - - /** - * Start a window function expression - * - * @param expr - * @return - */ - public static WindowOver min(Expression expr) { - return new WindowOver((Class)expr.getType(), Ops.AggOps.MIN_AGG, expr); - } - - /** - * Start a window function expression - * - * @param expr - * @return - */ - public static WindowOver max(Expression expr) { - return new WindowOver((Class)expr.getType(), Ops.AggOps.MAX_AGG, expr); - } - - /** - * expr evaluated at the row that is one row after the current row within the partition; - * - * @param expr - * @return - */ - public static WindowOver lead(Expression expr) { - return new WindowOver((Class)expr.getType(), SQLOps.LEAD, expr); - } - - /** - * expr evaluated at the row that is one row before the current row within the partition - * - * @param expr - * @return - */ - public static WindowOver lag(Expression expr) { - return new WindowOver((Class)expr.getType(), SQLOps.LAG, expr); - } - - /** - * @param expr - * @param delimiter - * @return - */ - public static WithinGroup listagg(Expression expr, String delimiter) { - return new WithinGroup(Object.class, SQLOps.LISTAGG, expr, ConstantImpl.create(delimiter)); - } - - /** - * @param measureExpr - * @param n - * @return - */ - public static WindowOver nthValue(Expression measureExpr, Number n) { - return nthValue(measureExpr, new ConstantImpl(n)); - } - - /** - * @param measureExpr - * @param n - * @return - */ - public static WindowOver nthValue(Expression measureExpr, Expression n) { - return new WindowOver((Class)measureExpr.getType(), SQLOps.NTHVALUE, measureExpr, n); - } - - /** - * divides an ordered data set into a number of buckets indicated by expr and assigns the - * appropriate bucket number to each row - * - * @param num - * @return - */ - public static WindowOver ntile(T num) { - return new WindowOver((Class)num.getClass(), SQLOps.NTILE, new ConstantImpl(num)); - } - - /** - * rank of the current row with gaps; same as row_number of its first peer - * - * @return - */ - public static WindowOver rank() { - return rank; - } - - /** - * @param args - * @return - */ - public static WithinGroup rank(Object... args) { - return rank(convertToExpressions(args)); - } - - /** - * @param args - * @return - */ - public static WithinGroup rank(Expression... args) { - return new WithinGroup(Long.class, SQLOps.RANK2, args); - } - - /** - * rank of the current row without gaps; this function counts peer groups - * - * @return - */ - public static WindowOver denseRank() { - return denseRank; - } - - /** - * @param args - * @return - */ - public static WithinGroup denseRank(Object... args) { - return denseRank(convertToExpressions(args)); - } - - /** - * @param args - * @return - */ - public static WithinGroup denseRank(Expression... args) { - return new WithinGroup(Long.class, SQLOps.DENSERANK2, args); - } - - /** - * @return - */ - public static WindowOver percentRank() { - return percentRank; - } - - /** - * @param args - * @return - */ - public static WithinGroup percentRank(Object... args) { - return percentRank(convertToExpressions(args)); - } - - /** - * @param args - * @return - */ - public static WithinGroup percentRank(Expression... args) { - return new WithinGroup(Double.class, SQLOps.PERCENTRANK2, args); - } - - /** - * @param arg - * @return - */ - public static WithinGroup percentileCont(T arg) { - if (arg.doubleValue() < 0.0 || arg.doubleValue() > 1.0) { - throw new IllegalArgumentException("The percentile value should be a number between 0 and 1"); - } - return percentileCont(new ConstantImpl(arg)); - } - - /** - * @param arg - * @return - */ - public static WithinGroup percentileCont(Expression arg) { - return new WithinGroup((Class)arg.getType(), SQLOps.PERCENTILECONT, arg); - } - - /** - * @param arg - * @return - */ - public static WithinGroup percentileDisc(T arg) { - if (arg.doubleValue() < 0.0 || arg.doubleValue() > 1.0) { - throw new IllegalArgumentException("The percentile value should be a number between 0 and 1"); - } - return percentileDisc(new ConstantImpl(arg)); - } - - /** - * @param arg - * @return - */ - public static WithinGroup percentileDisc(Expression arg) { - return new WithinGroup((Class)arg.getType(), SQLOps.PERCENTILEDISC, arg); - } - - /** - * @param arg1 - * @param arg2 - * @return - */ - public static WindowOver regrSlope(Expression arg1, Expression arg2) { - return new WindowOver(Double.class, SQLOps.REGR_SLOPE, arg1, arg2); - } - - /** - * @param arg1 - * @param arg2 - * @return - */ - public static WindowOver regrIntercept(Expression arg1, Expression arg2) { - return new WindowOver(Double.class, SQLOps.REGR_INTERCEPT, arg1, arg2); - } - - /** - * @param arg1 - * @param arg2 - * @return - */ - public static WindowOver regrCount(Expression arg1, Expression arg2) { - return new WindowOver(Double.class, SQLOps.REGR_COUNT, arg1, arg2); - } - - /** - * @param arg1 - * @param arg2 - * @return - */ - public static WindowOver regrR2(Expression arg1, Expression arg2) { - return new WindowOver(Double.class, SQLOps.REGR_R2, arg1, arg2); - } - - /** - * @param arg1 - * @param arg2 - * @return - */ - public static WindowOver regrAvgx(Expression arg1, Expression arg2) { - return new WindowOver(Double.class, SQLOps.REGR_AVGX, arg1, arg2); - } - - /** - * @param arg1 - * @param arg2 - * @return - */ - public static WindowOver regrAvgy(Expression arg1, Expression arg2) { - return new WindowOver(Double.class, SQLOps.REGR_AVGY, arg1, arg2); - } - - /** - * @param arg1 - * @param arg2 - * @return - */ - public static WindowOver regrSxx(Expression arg1, Expression arg2) { - return new WindowOver(Double.class, SQLOps.REGR_SXX, arg1, arg2); - } - - /** - * @param arg1 - * @param arg2 - * @return - */ - public static WindowOver regrSyy(Expression arg1, Expression arg2) { - return new WindowOver(Double.class, SQLOps.REGR_SYY, arg1, arg2); - } - - /** - * @param arg1 - * @param arg2 - * @return - */ - public static WindowOver regrSxy(Expression arg1, Expression arg2) { - return new WindowOver(Double.class, SQLOps.REGR_SXY, arg1, arg2); - } - - /** - * @return - */ - public static WindowOver cumeDist() { - return cumeDist; - } - - /** - * @param args - * @return - */ - public static WithinGroup cumeDist(Object... args) { - return cumeDist(convertToExpressions(args)); - } - - /** - * @param args - * @return - */ - public static WithinGroup cumeDist(Expression... args) { - return new WithinGroup(Double.class, SQLOps.CUMEDIST2, args); - } - - /** - * @param expr1 - * @param expr2 - * @return - */ - public static WindowOver corr(Expression expr1, Expression expr2) { - return new WindowOver(Double.class, SQLOps.CORR, expr1, expr2); - } - - /** - * @param expr1 - * @param expr2 - * @return - */ - public static WindowOver covarPop(Expression expr1, Expression expr2) { - return new WindowOver(Double.class, SQLOps.COVARPOP, expr1, expr2); - } - - /** - * @param expr1 - * @param expr2 - * @return - */ - public static WindowOver covarSamp(Expression expr1, Expression expr2) { - return new WindowOver(Double.class, SQLOps.COVARSAMP, expr1, expr2); - } - - /** - * computes the ratio of a value to the sum of a set of values. If expr evaluates to null, - * then the ratio-to-report value also evaluates to null. - * - * @return - */ - public static WindowOver ratioToReport(Expression expr) { - return new WindowOver((Class)expr.getType(), SQLOps.RATIOTOREPORT, expr); - } - - /** - * number of the current row within its partition, counting from 1 - * - * @return - */ - public static WindowOver rowNumber() { - return rowNumber; - } - - /** - * returns the sample standard deviation of expr, a set of numbers. - * - * @param expr - * @return - */ - public static WindowOver stddev(Expression expr) { - return new WindowOver((Class)expr.getType(), SQLOps.STDDEV, expr); - } - - /** - * @param expr - * @return - */ - public static WindowOver stddevDistinct(Expression expr) { - return new WindowOver((Class)expr.getType(), SQLOps.STDDEV_DISTINCT, expr); - } - - /** - * returns the population standard deviation and returns the square root of the population variance. - * - * @param expr - * @return - */ - public static WindowOver stddevPop(Expression expr) { - return new WindowOver((Class)expr.getType(), SQLOps.STDDEVPOP, expr); - } - - /** - * returns the cumulative sample standard deviation and returns the square root of the sample variance. - * - * @param expr - * @return - */ - public static WindowOver stddevSamp(Expression expr) { - return new WindowOver((Class)expr.getType(), SQLOps.STDDEVSAMP, expr); - } - - /** - * returns the variance of expr - * - * @param expr - * @return - */ - public static WindowOver variance(Expression expr) { - return new WindowOver((Class)expr.getType(), SQLOps.VARIANCE, expr); - } - - /** - * returns the population variance of a set of numbers after discarding the nulls in this set. - * - * @param expr - * @return - */ - public static WindowOver varPop(Expression expr) { - return new WindowOver((Class)expr.getType(), SQLOps.VARPOP, expr); - } - - /** - * returns the sample variance of a set of numbers after discarding the nulls in this set. - * - * @param expr - * @return - */ - public static WindowOver varSamp(Expression expr) { - return new WindowOver((Class)expr.getType(), SQLOps.VARSAMP, expr); - } - - /** - * returns value evaluated at the row that is the first row of the window frame - * - * @param expr - * @return - */ - public static WindowOver firstValue(Expression expr) { - return new WindowOver((Class)expr.getType(), SQLOps.FIRSTVALUE, expr); - } - - /** - * returns value evaluated at the row that is the last row of the window frame - * - * @param expr - * @return - */ - public static WindowOver lastValue(Expression expr) { - return new WindowOver((Class)expr.getType(), SQLOps.LASTVALUE, expr); - } - - /** - * Get the rhs leftmost characters of lhs - * - * @param lhs - * @param rhs - * @return - */ - public static StringExpression left(Expression lhs, int rhs) { - return left(lhs, ConstantImpl.create(rhs)); - } - - /** - * Get the rhs rightmost characters of lhs - * - * @param lhs - * @param rhs - * @return - */ - public static StringExpression right(Expression lhs, int rhs) { - return right(lhs, ConstantImpl.create(rhs)); - } - - /** - * Get the rhs leftmost characters of lhs - * - * @param lhs - * @param rhs - * @return - */ - public static StringExpression left(Expression lhs, Expression rhs) { - return StringOperation.create(Ops.StringOps.LEFT, lhs, rhs); - } - - /** - * Get the rhs leftmost characters of lhs - * - * @param lhs - * @param rhs - * @return - */ - public static StringExpression right(Expression lhs, Expression rhs) { - return StringOperation.create(Ops.StringOps.RIGHT, lhs, rhs); - } - - private SQLExpressions() {} - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/SQLListeners.java b/querydsl-sql/src/main/java/com/mysema/query/sql/SQLListeners.java deleted file mode 100644 index 8df7e2bf4a..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/SQLListeners.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import java.util.List; - -import javax.annotation.Nullable; - -import com.google.common.collect.Lists; -import com.mysema.commons.lang.Pair; -import com.mysema.query.QueryMetadata; -import com.mysema.query.sql.dml.SQLInsertBatch; -import com.mysema.query.sql.dml.SQLMergeBatch; -import com.mysema.query.sql.dml.SQLUpdateBatch; -import com.mysema.query.types.Expression; -import com.mysema.query.types.Path; -import com.mysema.query.types.SubQueryExpression; - -/** - * SQLListeners is an SQLListener implementation which dispatches the - * notifications to a list of SQLListener instances - * - * @author tiwe - * - */ -public class SQLListeners implements SQLListener { - - @Nullable - private final SQLListener parent; - - private final List listeners = Lists.newArrayList(); - - public SQLListeners(SQLListener parent) { - this.parent = parent; - } - - public SQLListeners() { - this.parent = null; - } - - public void add(SQLListener listener) { - listeners.add(listener); - } - - @Override - public void notifyQuery(QueryMetadata md) { - if (parent != null) { - parent.notifyQuery(md); - } - for (SQLListener listener : listeners) { - listener.notifyQuery(md); - } - } - - @Override - public void notifyDelete(RelationalPath entity, QueryMetadata md) { - if (parent != null) { - parent.notifyDelete(entity, md); - } - for (SQLListener listener : listeners) { - listener.notifyDelete(entity, md); - } - } - - @Override - public void notifyDeletes(RelationalPath entity, List batches) { - if (parent != null) { - parent.notifyDeletes(entity, batches); - } - for (SQLListener listener : listeners) { - listener.notifyDeletes(entity, batches); - } - } - - @Override - public void notifyMerge(RelationalPath entity, QueryMetadata md, List> keys, - List> columns, List> values, SubQueryExpression subQuery) { - if (parent != null) { - parent.notifyMerge(entity, md, keys, columns, values, subQuery); - } - for (SQLListener listener : listeners) { - listener.notifyMerge(entity, md, keys, columns, values, subQuery); - } - } - - @Override - public void notifyMerges(RelationalPath entity, QueryMetadata md, List batches) { - if (parent != null) { - parent.notifyMerges(entity, md, batches); - } - for (SQLListener listener : listeners) { - listener.notifyMerges(entity, md, batches); - } - } - - @Override - public void notifyInsert(RelationalPath entity, QueryMetadata md, List> columns, - List> values, SubQueryExpression subQuery) { - if (parent != null) { - parent.notifyInsert(entity, md, columns, values, subQuery); - } - for (SQLListener listener : listeners) { - listener.notifyInsert(entity, md, columns, values, subQuery); - } - } - - @Override - public void notifyInserts(RelationalPath entity, QueryMetadata md, - List batches) { - if (parent != null) { - parent.notifyInserts(entity, md, batches); - } - for (SQLListener listener : listeners) { - listener.notifyInserts(entity, md, batches); - } - } - - @Override - public void notifyUpdate(RelationalPath entity, QueryMetadata md, - List, Expression>> updates) { - if (parent != null) { - parent.notifyUpdate(entity, md, updates); - } - for (SQLListener listener : listeners) { - listener.notifyUpdate(entity, md, updates); - } - } - - @Override - public void notifyUpdates(RelationalPath entity, List batches) { - if (parent != null) { - parent.notifyUpdates(entity, batches); - } - for (SQLListener listener : listeners) { - listener.notifyUpdates(entity, batches); - } - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/SQLOps.java b/querydsl-sql/src/main/java/com/mysema/query/sql/SQLOps.java deleted file mode 100644 index 0a599896c4..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/SQLOps.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright 2013, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import com.google.common.collect.ImmutableList; -import com.mysema.query.QueryFlag; -import com.mysema.query.QueryFlag.Position; -import com.mysema.query.types.Expression; -import com.mysema.query.types.OperationImpl; -import com.mysema.query.types.Operator; -import com.mysema.query.types.OperatorImpl; - -/** - * SQLOps provides SQL specific operators - * - * @author tiwe - * - */ -public final class SQLOps { - - private static final String NS = SQLOps.class.getName(); - - public static final Operator ALL = new OperatorImpl(NS, "ALL"); - - public static final Operator CAST = new OperatorImpl(NS, "CAST"); - - public static final Operator CORR = new OperatorImpl(NS, "CORR"); - - public static final Operator COVARPOP = new OperatorImpl(NS, "COVARPOP"); - - public static final Operator COVARSAMP = new OperatorImpl(NS, "COVARSAMP"); - - public static final Operator CUMEDIST = new OperatorImpl(NS, "CUMEDIST"); - - public static final Operator CUMEDIST2 = new OperatorImpl(NS, "CUMEDIST2"); - - public static final Operator DENSERANK = new OperatorImpl(NS, "DENSERANK"); - - public static final Operator DENSERANK2 = new OperatorImpl(NS, "DENSERANK2"); - - public static final Operator FIRSTVALUE = new OperatorImpl(NS, "FIRSTVALUE"); - - public static final Operator FOR_SHARE = new OperatorImpl(NS, "FOR_SHARE"); - - public static final Operator FOR_UPDATE = new OperatorImpl(NS, "FOR_UPDATE"); - - public static final Operator LAG = new OperatorImpl(NS, "LAG"); - - public static final Operator LASTVALUE = new OperatorImpl(NS, "LASTVALUE"); - - public static final Operator LEAD = new OperatorImpl(NS, "LEAD"); - - public static final Operator LISTAGG = new OperatorImpl(NS, "LISTAGG"); - - public static final Operator NEXTVAL = new OperatorImpl(NS, "NEXTVAL"); - - public static final Operator NO_WAIT = new OperatorImpl(NS, "NO_WAIT"); - - public static final Operator NTHVALUE = new OperatorImpl(NS, "NTHVALUE"); - - public static final Operator NTILE = new OperatorImpl(NS, "NTILE"); - - public static final Operator PERCENTRANK = new OperatorImpl(NS, "PERCENTRANK"); - - public static final Operator PERCENTRANK2 = new OperatorImpl(NS, "PERCENTRANK2"); - - public static final Operator PERCENTILECONT = new OperatorImpl(NS, "PERCENTILECONT"); - - public static final Operator PERCENTILEDISC = new OperatorImpl(NS, "PERCENTILEDISC"); - - public static final Operator QUALIFY = new OperatorImpl(NS, "QUALIFY"); - - public static final Operator RANK = new OperatorImpl(NS, "RANK"); - - public static final Operator RANK2 = new OperatorImpl(NS, "RANK2"); - - public static final Operator REGR_SLOPE = new OperatorImpl(NS, "REGR_SLOPE"); - - public static final Operator REGR_INTERCEPT = new OperatorImpl(NS, "REGR_INTERCEPT"); - - public static final Operator REGR_COUNT = new OperatorImpl(NS, "REGR_COUNT"); - - public static final Operator REGR_R2 = new OperatorImpl(NS, "REGR_R2"); - - public static final Operator REGR_AVGX = new OperatorImpl(NS, "REGR_AVGX"); - - public static final Operator REGR_AVGY = new OperatorImpl(NS, "REGR_AVGY"); - - public static final Operator REGR_SXX = new OperatorImpl(NS, "REGR_SXX"); - - public static final Operator REGR_SYY = new OperatorImpl(NS, "REGR_SYY"); - - public static final Operator REGR_SXY = new OperatorImpl(NS, "REGR_SXY"); - - public static final Operator RATIOTOREPORT = new OperatorImpl(NS, "RATIOTOREPORT"); - - public static final Operator ROWNUMBER = new OperatorImpl(NS, "ROWNUMBER"); - - public static final Operator STDDEV = new OperatorImpl(NS, "STDDEV"); - - public static final Operator STDDEVPOP = new OperatorImpl(NS, "STDDEVPOP"); - - public static final Operator STDDEVSAMP = new OperatorImpl(NS, "STDDEVSAMP"); - - public static final Operator STDDEV_DISTINCT = new OperatorImpl(NS, "STDDEV_DISTINCT"); - - public static final Operator UNION = new OperatorImpl(NS, "UNION"); - - public static final Operator UNION_ALL = new OperatorImpl(NS, "UNION_ALL"); - - public static final Operator VARIANCE = new OperatorImpl(NS, "VARIANCE"); - - public static final Operator VARPOP = new OperatorImpl(NS, "VARPOP"); - - public static final Operator VARSAMP = new OperatorImpl(NS, "VARSAMP"); - - public static final Operator WITH_ALIAS = new OperatorImpl(NS, "WITH_ALIAS"); - - public static final Operator WITH_COLUMNS = new OperatorImpl(NS, "WITH_COLUMNS"); - - public static final QueryFlag FOR_SHARE_FLAG = new QueryFlag(Position.END, new OperationImpl( - Object.class, FOR_SHARE, ImmutableList.>of())); - - public static final QueryFlag FOR_UPDATE_FLAG = new QueryFlag(Position.END, new OperationImpl( - Object.class, FOR_UPDATE, ImmutableList.>of())); - - public static final QueryFlag NO_WAIT_FLAG = new QueryFlag(Position.END, new OperationImpl( - Object.class, NO_WAIT, ImmutableList.>of())); - - private SQLOps() {} - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/SQLQuery.java b/querydsl-sql/src/main/java/com/mysema/query/sql/SQLQuery.java deleted file mode 100644 index 0de5e70b63..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/SQLQuery.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import java.sql.Connection; - -import com.mysema.query.DefaultQueryMetadata; -import com.mysema.query.QueryMetadata; - -/** - * SQLQuery is a JDBC based implementation of the {@link SQLCommonQuery} interface - * - * @author tiwe - */ -public final class SQLQuery extends AbstractSQLQuery { - - /** - * Create a detached SQLQuery instance - * The query can be attached via the clone method - * - * @param connection Connection to use - * @param templates SQLTemplates to use - */ - public SQLQuery(SQLTemplates templates) { - super(null, new Configuration(templates), new DefaultQueryMetadata()); - } - - /** - * Create a new SQLQuery instance - * - * @param conn Connection to use - * @param templates SQLTemplates to use - */ - public SQLQuery(Connection conn, SQLTemplates templates) { - super(conn, new Configuration(templates), new DefaultQueryMetadata()); - } - - /** - * Create a new SQLQuery instance - * - * @param conn Connection to use - * @param templates SQLTemplates to use - * @param metadata - */ - public SQLQuery(Connection conn, SQLTemplates templates, QueryMetadata metadata) { - super(conn, new Configuration(templates), metadata); - } - - /** - * Create a new SQLQuery instance - * - * @param configuration - */ - public SQLQuery( Configuration configuration) { - this(null, configuration); - } - - /** - * Create a new SQLQuery instance - * - * @param conn Connection to use - * @param configuration - */ - public SQLQuery(Connection conn, Configuration configuration) { - super(conn, configuration, new DefaultQueryMetadata()); - } - - /** - * Create a new SQLQuery instance - * - * @param conn - * @param templates - * @param metadata - */ - public SQLQuery(Connection conn, Configuration configuration, QueryMetadata metadata) { - super(conn, configuration, metadata); - } - - @Override - public SQLQuery clone(Connection conn) { - SQLQuery q = new SQLQuery(conn, getConfiguration(), getMetadata().clone()); - q.clone(this); - return q; - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/SQLQueryFactory.java b/querydsl-sql/src/main/java/com/mysema/query/sql/SQLQueryFactory.java deleted file mode 100644 index ee9364d57b..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/SQLQueryFactory.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import java.sql.Connection; -import java.sql.SQLException; - -import javax.inject.Provider; -import javax.sql.DataSource; - -/** - * Factory class for query and DML clause creation - * - * @author tiwe - * - */ -public class SQLQueryFactory extends AbstractSQLQueryFactory { - - static class DataSourceProvider implements Provider { - - private final DataSource ds; - - public DataSourceProvider(DataSource ds) { - this.ds = ds; - } - - @Override - public Connection get() { - try { - return ds.getConnection(); - } catch (SQLException e) { - throw new RuntimeException(e.getMessage(), e); - } - } - - } - - public SQLQueryFactory(SQLTemplates templates, Provider connection) { - this(new Configuration(templates), connection); - } - - public SQLQueryFactory(Configuration configuration, Provider connection) { - super(configuration, connection); - } - - public SQLQueryFactory(Configuration configuration, DataSource dataSource) { - super(configuration, new DataSourceProvider(dataSource)); - } - - @Override - public SQLQuery query() { - return new SQLQuery(connection.get(), configuration); - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/SQLQueryFactoryImpl.java b/querydsl-sql/src/main/java/com/mysema/query/sql/SQLQueryFactoryImpl.java deleted file mode 100644 index f07182396b..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/SQLQueryFactoryImpl.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import java.sql.Connection; -import java.sql.SQLException; - -import javax.inject.Provider; -import javax.sql.DataSource; - -/** - * Use SQLQueryFactory instead - * - * @author tiwe - * - */ -@Deprecated -public class SQLQueryFactoryImpl extends AbstractSQLQueryFactory { - - static class DataSourceProvider implements Provider { - - private final DataSource ds; - - public DataSourceProvider(DataSource ds) { - this.ds = ds; - } - - @Override - public Connection get() { - try { - return ds.getConnection(); - } catch (SQLException e) { - throw new RuntimeException(e.getMessage(), e); - } - } - - } - - public SQLQueryFactoryImpl(SQLTemplates templates, Provider connection) { - this(new Configuration(templates), connection); - } - - public SQLQueryFactoryImpl(Configuration configuration, Provider connection) { - super(configuration, connection); - } - - public SQLQueryFactoryImpl(Configuration configuration, DataSource dataSource) { - super(configuration, new DataSourceProvider(dataSource)); - } - - @Override - public SQLQuery query() { - return new SQLQuery(connection.get(), configuration); - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/SQLSerializer.java b/querydsl-sql/src/main/java/com/mysema/query/sql/SQLSerializer.java deleted file mode 100644 index faea0566d8..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/SQLSerializer.java +++ /dev/null @@ -1,885 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import javax.annotation.Nullable; -import java.util.*; - -import com.google.common.base.Strings; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Lists; -import com.mysema.commons.lang.Pair; -import com.mysema.query.JoinExpression; -import com.mysema.query.JoinFlag; -import com.mysema.query.QueryFlag; -import com.mysema.query.QueryFlag.Position; -import com.mysema.query.QueryMetadata; -import com.mysema.query.support.SerializerBase; -import com.mysema.query.types.*; -import com.mysema.query.types.Template.Element; - -/** - * SqlSerializer serializes Querydsl queries into SQL - * - * @author tiwe - */ -public class SQLSerializer extends SerializerBase { - - protected enum Stage {SELECT, FROM, WHERE, GROUP_BY, HAVING, ORDER_BY, MODIFIERS} - - private static final String COMMA = ", "; - - private final List> constantPaths = new ArrayList>(); - - private final List constants = new ArrayList(); - - private final boolean dml; - - protected Stage stage = Stage.SELECT; - - private boolean skipParent; - - private boolean dmlWithSchema; - - private RelationalPath entity; - - private final Configuration configuration; - - private final SQLTemplates templates; - - private boolean inUnion = false; - - private boolean inJoin = false; - - private boolean useLiterals = false; - - public SQLSerializer(Configuration conf) { - this(conf, false); - } - - public SQLSerializer(Configuration conf, boolean dml) { - super(conf.getTemplates()); - this.configuration = conf; - this.templates = conf.getTemplates(); - this.dml = dml; - } - - private void appendAsColumnName(Path path) { - String column = ColumnMetadata.getName(path); - if (path.getMetadata().getParent() instanceof RelationalPath) { - RelationalPath parent = (RelationalPath)path.getMetadata().getParent(); - column = configuration.getColumnOverride(parent.getSchemaAndTable(), column); - } - append(templates.quoteIdentifier(column)); - } - - private SchemaAndTable getSchemaAndTable(RelationalPath path) { - return configuration.getOverride(path.getSchemaAndTable()); - } - - private void appendSchemaName(String schema) { - append(templates.quoteIdentifier(schema)); - } - - private void appendTableName(String table) { - append(templates.quoteIdentifier(table)); - } - - public List getConstants() { - return constants; - } - - public List> getConstantPaths() { - return constantPaths; - } - - /** - * Return a list of expressions that can be used to uniquely define the query sources - * - * @param joins - * @return - */ - @SuppressWarnings("unchecked") - private List> getIdentifierColumns(List joins, boolean alias) { - if (joins.size() == 1) { - JoinExpression join = joins.get(0); - if (join.getTarget() instanceof RelationalPath) { - return ((RelationalPath)join.getTarget()).getColumns(); - } else { - return Collections.emptyList(); - } - - } else { - List> rv = Lists.newArrayList(); - int counter = 0; - for (JoinExpression join : joins) { - if (join.getTarget() instanceof RelationalPath) { - RelationalPath path = (RelationalPath)join.getTarget(); - List> columns; - if (path.getPrimaryKey() != null) { - columns = path.getPrimaryKey().getLocalColumns(); - } else { - columns = path.getColumns(); - } - if (alias) { - for (Expression column : columns) { - rv.add(ExpressionUtils.as(column, "col" + (++counter))); - } - } else { - rv.addAll(columns); - } - - } else { - // not able to provide a distinct list of columns - return Collections.emptyList(); - } - } - return rv; - } - - } - - protected SQLTemplates getTemplates() { - return templates; - } - - public void handle(String template, Object... args) { - handleTemplate(TemplateFactory.DEFAULT.create(template), Arrays.asList(args)); - } - - private void handleJoinTarget(JoinExpression je) { - // type specifier - if (je.getTarget() instanceof RelationalPath && templates.isSupportsAlias()) { - final RelationalPath pe = (RelationalPath) je.getTarget(); - if (pe.getMetadata().getParent() == null) { - SchemaAndTable schemaAndTable = getSchemaAndTable(pe); - if (templates.isPrintSchema()) { - appendSchemaName(schemaAndTable.getSchema()); - append("."); - } - appendTableName(schemaAndTable.getTable()); - append(templates.getTableAlias()); - } - } - inJoin = true; - handle(je.getTarget()); - inJoin = false; - } - - public void serialize(QueryMetadata metadata, boolean forCountRow) { - templates.serialize(metadata, forCountRow, this); - } - - void serializeForQuery(QueryMetadata metadata, boolean forCountRow) { - boolean oldSkipParent = skipParent; - skipParent = false; - final List> select = metadata.getProjection(); - final List joins = metadata.getJoins(); - final Predicate where = metadata.getWhere(); - final List> groupBy = metadata.getGroupBy(); - final Predicate having = metadata.getHaving(); - final List> orderBy = metadata.getOrderBy(); - final Set flags = metadata.getFlags(); - final boolean hasFlags = !flags.isEmpty(); - String suffix = null; - - List> sqlSelect; - if (select.size() == 1) { - final Expression first = select.get(0); - if (first instanceof FactoryExpression) { - sqlSelect = ((FactoryExpression)first).getArgs(); - } else { - sqlSelect = (List)select; - } - } else { - sqlSelect = new ArrayList>(select.size()); - for (Expression selectExpr : select) { - if (selectExpr instanceof FactoryExpression) { - // transforms constructor arguments into individual select expressions - sqlSelect.addAll(((FactoryExpression) selectExpr).getArgs()); - } else { - sqlSelect.add(selectExpr); - } - } - } - - // with - if (hasFlags){ - boolean handled = false; - boolean recursive = false; - for (QueryFlag flag : flags) { - if (flag.getPosition() == Position.WITH) { - if (flag.getFlag() == SQLTemplates.RECURSIVE) { - recursive = true; - continue; - } - if (handled) { - append(", "); - } - handle(flag.getFlag()); - handled = true; - } - } - if (handled) { - if (recursive) { - prepend(templates.getWithRecursive()); - } else { - prepend(templates.getWith()); - } - append("\n"); - } - } - - // start - if (hasFlags) { - serialize(Position.START, flags); - } - - // select - Stage oldStage = stage; - stage = Stage.SELECT; - if (forCountRow) { - append(templates.getSelect()); - if (hasFlags) { - serialize(Position.AFTER_SELECT, flags); - } - - if (!metadata.isDistinct()) { - append(templates.getCountStar()); - } else { - List> columns; - if (sqlSelect.isEmpty()) { - columns = getIdentifierColumns(joins, !templates.isCountDistinctMultipleColumns()); - } else { - columns = sqlSelect; - } - if (columns.size() == 1) { - append(templates.getDistinctCountStart()); - handle(columns.get(0)); - append(templates.getDistinctCountEnd()); - } else if (templates.isCountDistinctMultipleColumns()) { - append(templates.getDistinctCountStart()); - append("(").handle(COMMA, columns).append(")"); - append(templates.getDistinctCountEnd()); - } else { - // select count(*) from (select distinct ...) - append(templates.getCountStar()); - append(templates.getFrom()); - append("("); - append(templates.getSelectDistinct()); - handle(COMMA, columns); - suffix = ") internal"; - } - } - - } else if (!sqlSelect.isEmpty()) { - if (!metadata.isDistinct()) { - append(templates.getSelect()); - } else { - append(templates.getSelectDistinct()); - } - if (hasFlags) { - serialize(Position.AFTER_SELECT, flags); - } - - handle(COMMA, sqlSelect); - } - if (hasFlags) { - serialize(Position.AFTER_PROJECTION, flags); - } - - // from - stage = Stage.FROM; - serializeSources(joins); - - // where - if (where != null) { - stage = Stage.WHERE; - if (hasFlags) { - serialize(Position.BEFORE_FILTERS, flags); - } - append(templates.getWhere()).handle(where); - if (hasFlags) { - serialize(Position.AFTER_FILTERS, flags); - } - } - - // group by - if (!groupBy.isEmpty()) { - stage = Stage.GROUP_BY; - if (hasFlags) { - serialize(Position.BEFORE_GROUP_BY, flags); - } - append(templates.getGroupBy()).handle(COMMA, groupBy); - if (hasFlags) { - serialize(Position.AFTER_GROUP_BY, flags); - } - } - - // having - if (having != null) { - stage = Stage.HAVING; - if (hasFlags) { - serialize(Position.BEFORE_HAVING, flags); - } - append(templates.getHaving()).handle(having); - if (hasFlags) { - serialize(Position.AFTER_HAVING, flags); - } - } - - // order by - if (hasFlags) { - serialize(Position.BEFORE_ORDER, flags); - } - if (!orderBy.isEmpty() && !forCountRow) { - stage = Stage.ORDER_BY; - append(templates.getOrderBy()); - handleOrderBy(orderBy); - if (hasFlags) { - serialize(Position.AFTER_ORDER, flags); - } - } - - // modifiers - if (!forCountRow && metadata.getModifiers().isRestricting() && !joins.isEmpty()) { - stage = Stage.MODIFIERS; - templates.serializeModifiers(metadata, this); - } - - if (suffix != null) { - append(suffix); - } - - // reset stage - stage = oldStage; - skipParent = oldSkipParent; - } - - protected void handleOrderBy(List> orderBy) { - boolean first = true; - for (final OrderSpecifier os : orderBy) { - if (!first) { - append(COMMA); - } - String order = os.getOrder() == Order.ASC ? templates.getAsc() : templates.getDesc(); - if (os.getNullHandling() == OrderSpecifier.NullHandling.NullsFirst) { - if (templates.getNullsFirst() != null) { - handle(os.getTarget()); - append(order); - append(templates.getNullsFirst()); - } else { - append("(case when "); - handle(os.getTarget()); - append(" is null then 0 else 1 end), "); - handle(os.getTarget()); - append(order); - } - } else if (os.getNullHandling() == OrderSpecifier.NullHandling.NullsLast) { - if (templates.getNullsLast() != null) { - handle(os.getTarget()); - append(order); - append(templates.getNullsLast()); - } else { - append("(case when "); - handle(os.getTarget()); - append(" is null then 1 else 0 end), "); - handle(os.getTarget()); - append(order); - } - - } else { - handle(os.getTarget()); - append(order); - } - first = false; - } - } - - public void serializeDelete(QueryMetadata metadata, RelationalPath entity) { - this.entity = entity; - templates.serializeDelete(metadata, entity, this); - } - - void serializeForDelete(QueryMetadata metadata, RelationalPath entity) { - serialize(Position.START, metadata.getFlags()); - - if (!serialize(Position.START_OVERRIDE, metadata.getFlags())) { - append(templates.getDelete()); - } - serialize(Position.AFTER_SELECT, metadata.getFlags()); - append("from "); - - dmlWithSchema = true; - handle(entity); - dmlWithSchema = false; - - if (metadata.getWhere() != null) { - append(templates.getWhere()).handle(metadata.getWhere()); - } - } - - public void serializeMerge(QueryMetadata metadata, RelationalPath entity, List> keys, - List> columns, List> values, @Nullable SubQueryExpression subQuery) { - this.entity = entity; - templates.serializeMerge(metadata, entity, keys, columns, values, subQuery, this); - } - - void serializeForMerge(QueryMetadata metadata, RelationalPath entity, List> keys, - List> columns, List> values, @Nullable SubQueryExpression subQuery) { - serialize(Position.START, metadata.getFlags()); - - if (!serialize(Position.START_OVERRIDE, metadata.getFlags())) { - append(templates.getMergeInto()); - } - serialize(Position.AFTER_SELECT, metadata.getFlags()); - - dmlWithSchema = true; - handle(entity); - dmlWithSchema = false; - append(" "); - // columns - if (!columns.isEmpty()) { - skipParent = true; - append("(").handle(COMMA, columns).append(") "); - skipParent = false; - } - // keys - if (!keys.isEmpty()) { - append(templates.getKey()); - skipParent = true; - append("(").handle(COMMA, keys).append(") "); - skipParent = false; - } - - if (subQuery != null) { - // subquery - append("\n"); - serialize(subQuery.getMetadata(), false); - } else { - if (!useLiterals) { - for (int i = 0; i < columns.size(); i++) { - if (values.get(i) instanceof Constant) { - constantPaths.add(columns.get(i)); - } - } - } - - // values - append(templates.getValues()); - append("(").handle(COMMA, values).append(") "); - } - } - - public void serializeInsert(QueryMetadata metadata, RelationalPath entity, List> columns, - List> values, @Nullable SubQueryExpression subQuery) { - this.entity = entity; - templates.serializeInsert(metadata, entity, columns, values, subQuery, this); - } - - void serializeForInsert(QueryMetadata metadata, RelationalPath entity, List> columns, - List> values, @Nullable SubQueryExpression subQuery) { - serialize(Position.START, metadata.getFlags()); - - if (!serialize(Position.START_OVERRIDE, metadata.getFlags())) { - append(templates.getInsertInto()); - } - serialize(Position.AFTER_SELECT, metadata.getFlags()); - - dmlWithSchema = true; - handle(entity); - dmlWithSchema = false; - // columns - if (!columns.isEmpty()) { - append(" ("); - skipParent = true; - handle(COMMA, columns); - skipParent = false; - append(")"); - } - - if (subQuery != null) { - append("\n"); - serialize(subQuery.getMetadata(), false); - - } else { - if (!useLiterals) { - for (int i = 0; i < columns.size(); i++) { - if (values.get(i) instanceof Constant) { - constantPaths.add(columns.get(i)); - } - } - } - - if (!values.isEmpty()) { - // values - append(templates.getValues()); - append("("); - handle(COMMA, values); - append(")"); - } else { - append(templates.getDefaultValues()); - } - } - - } - - public void serializeUpdate(QueryMetadata metadata, RelationalPath entity, - List, Expression>> updates) { - templates.serializeUpdate(metadata, entity, updates, this); - } - - void serializeForUpdate(QueryMetadata metadata, RelationalPath entity, - List, Expression>> updates) { - this.entity = entity; - - serialize(Position.START, metadata.getFlags()); - - if (!serialize(Position.START_OVERRIDE, metadata.getFlags())) { - append(templates.getUpdate()); - } - serialize(Position.AFTER_SELECT, metadata.getFlags()); - - dmlWithSchema = true; - handle(entity); - dmlWithSchema = false; - append("\n"); - append(templates.getSet()); - boolean first = true; - skipParent = true; - for (final Pair,Expression> update : updates) { - if (!first) { - append(COMMA); - } - handle(update.getFirst()); - append(" = "); - if (!useLiterals && update.getSecond() instanceof Constant) { - constantPaths.add(update.getFirst()); - } - handle(update.getSecond()); - first = false; - } - skipParent = false; - - if (metadata.getWhere() != null) { - append(templates.getWhere()).handle(metadata.getWhere()); - } - } - - private void serializeSources(List joins) { - if (joins.isEmpty()) { - String dummyTable = templates.getDummyTable(); - if (!Strings.isNullOrEmpty(dummyTable)) { - append(templates.getFrom()); - append(dummyTable); - } - } else { - append(templates.getFrom()); - for (int i = 0; i < joins.size(); i++) { - final JoinExpression je = joins.get(i); - if (je.getFlags().isEmpty()) { - if (i > 0) { - append(templates.getJoinSymbol(je.getType())); - } - handleJoinTarget(je); - if (je.getCondition() != null) { - append(templates.getOn()).handle(je.getCondition()); - } - } else { - serialize(JoinFlag.Position.START, je.getFlags()); - if (!serialize(JoinFlag.Position.OVERRIDE, je.getFlags()) && i > 0) { - append(templates.getJoinSymbol(je.getType())); - } - serialize(JoinFlag.Position.BEFORE_TARGET, je.getFlags()); - handleJoinTarget(je); - serialize(JoinFlag.Position.BEFORE_CONDITION, je.getFlags()); - if (je.getCondition() != null) { - append(templates.getOn()).handle(je.getCondition()); - } - serialize(JoinFlag.Position.END, je.getFlags()); - } - } - } - } - - public void serializeUnion(Expression union, QueryMetadata metadata, boolean unionAll) { - final List> groupBy = metadata.getGroupBy(); - final Predicate having = metadata.getHaving(); - final List> orderBy = metadata.getOrderBy(); - final Set flags = metadata.getFlags(); - final boolean hasFlags = !flags.isEmpty(); - - // with - if (hasFlags){ - boolean handled = false; - boolean recursive = false; - for (QueryFlag flag : flags) { - if (flag.getPosition() == Position.WITH) { - if (flag.getFlag() == SQLTemplates.RECURSIVE) { - recursive = true; - continue; - } - if (handled) { - append(", "); - } - handle(flag.getFlag()); - handled = true; - } - } - if (handled) { - if (recursive) { - prepend(templates.getWithRecursive()); - } else { - prepend(templates.getWith()); - } - append("\n"); - } - } - - // union - Stage oldStage = stage; - handle(union); - - // group by - if (!groupBy.isEmpty()) { - stage = Stage.GROUP_BY; - if (hasFlags) { - serialize(Position.BEFORE_GROUP_BY, flags); - } - append(templates.getGroupBy()).handle(COMMA, groupBy); - if (hasFlags) { - serialize(Position.AFTER_GROUP_BY, flags); - } - } - - // having - if (having != null) { - stage = Stage.HAVING; - if (hasFlags) { - serialize(Position.BEFORE_HAVING, flags); - } - append(templates.getHaving()).handle(having); - if (hasFlags) { - serialize(Position.AFTER_HAVING, flags); - } - } - - // order by - if (hasFlags) { - serialize(Position.BEFORE_ORDER, flags); - } - if (!orderBy.isEmpty()) { - stage = Stage.ORDER_BY; - append(templates.getOrderBy()); - boolean first = true; - skipParent = true; - for (OrderSpecifier os : orderBy) { - if (!first) { - append(COMMA); - } - handle(os.getTarget()); - append(os.getOrder() == Order.ASC ? templates.getAsc() : templates.getDesc()); - first = false; - } - skipParent = false; - if (hasFlags) { - serialize(Position.AFTER_ORDER, flags); - } - } - - // end - if (hasFlags) { - serialize(Position.END, flags); - } - - // reset stage - stage = oldStage; - } - - @Override - public void visitConstant(Object constant) { - if (useLiterals) { - if (constant instanceof Collection) { - append("("); - boolean first = true; - for (Object o : ((Collection)constant)) { - if (!first) { - append(COMMA); - } - append(configuration.asLiteral(o)); - first = false; - } - append(")"); - } else { - append(configuration.asLiteral(constant)); - } - } else if (constant instanceof Collection) { - append("("); - boolean first = true; - for (Object o : ((Collection)constant)) { - if (!first) { - append(COMMA); - } - append("?"); - constants.add(o); - if (first && (constantPaths.size() < constants.size())) { - constantPaths.add(null); - } - first = false; - } - append(")"); - - int size = ((Collection)constant).size() - 1; - Path lastPath = constantPaths.get(constantPaths.size()-1); - for (int i = 0; i < size; i++) { - constantPaths.add(lastPath); - } - } else { - append("?"); - constants.add(constant); - if (constantPaths.size() < constants.size()) { - constantPaths.add(null); - } - } - } - - @Override - public Void visit(ParamExpression param, Void context) { - append("?"); - constants.add(param); - if (constantPaths.size() < constants.size()) { - constantPaths.add(null); - } - return null; - } - - @Override - public Void visit(Path path, Void context) { - if (dml) { - if (path.equals(entity) && path instanceof RelationalPath) { - SchemaAndTable schemaAndTable = getSchemaAndTable((RelationalPath) path); - if (dmlWithSchema && templates.isPrintSchema()) { - appendSchemaName(schemaAndTable.getSchema()); - append("."); - } - appendTableName(schemaAndTable.getTable()); - return null; - } else if (entity.equals(path.getMetadata().getParent()) && skipParent) { - appendAsColumnName(path); - return null; - } - } - final PathMetadata metadata = path.getMetadata(); - if (metadata.getParent() != null && (!skipParent || dml)) { - visit(metadata.getParent(), context); - append("."); - } - appendAsColumnName(path); - return null; - } - - @Override - public Void visit(SubQueryExpression query, Void context) { - if (inUnion && !templates.isUnionsWrapped()) { - serialize(query.getMetadata(), false); - } else { - append("("); - serialize(query.getMetadata(), false); - append(")"); - } - return null; - } - - @Override - public Void visit(TemplateExpression expr, Void context) { - if (inJoin && templates.isFunctionJoinsWrapped()) { - append("table("); - super.visit(expr, context); - append(")"); - } else { - super.visit(expr, context); - } - return null; - } - - @Override - protected void visitOperation(Class type, Operator operator, List> args) { - if (args.size() == 2 - && !useLiterals - && args.get(0) instanceof Path - && args.get(1) instanceof Constant - && operator != Ops.NUMCAST) { - for (Element element : templates.getTemplate(operator).getElements()) { - if (element instanceof Template.ByIndex && ((Template.ByIndex)element).getIndex() == 1) { - constantPaths.add((Path)args.get(0)); - break; - } - } - } - - if (operator == SQLOps.UNION || operator == SQLOps.UNION_ALL) { - boolean oldUnion = inUnion; - inUnion = true; - super.visitOperation(type, operator, args); - inUnion = oldUnion; - - } else if (operator == Ops.LIKE && args.get(1) instanceof Constant) { - final String escape = String.valueOf(templates.getEscapeChar()); - final String escaped = args.get(1).toString().replace(escape, escape + escape); - super.visitOperation(String.class, Ops.LIKE, - ImmutableList.of(args.get(0), ConstantImpl.create(escaped))); - - } else if (operator == Ops.STRING_CAST) { - final String typeName = templates.getTypeForCast(String.class); - super.visitOperation(String.class, SQLOps.CAST, - ImmutableList.of(args.get(0), ConstantImpl.create(typeName))); - - } else if (operator == Ops.NUMCAST) { - final Class targetType = (Class) ((Constant) args.get(1)).getConstant(); - final String typeName = templates.getTypeForCast(targetType); - super.visitOperation(targetType, SQLOps.CAST, - ImmutableList.of(args.get(0), ConstantImpl.create(typeName))); - - } else if (operator == Ops.ALIAS) { - if (stage == Stage.SELECT || stage == Stage.FROM) { - super.visitOperation(type, operator, args); - } else { - // handle only target - handle(args.get(1)); - } - - } else if (operator == SQLOps.WITH_COLUMNS) { - boolean oldSkipParent = skipParent; - skipParent = true; - super.visitOperation(type, operator, args); - skipParent = oldSkipParent; - - } else { - super.visitOperation(type, operator, args); - } - } - - public void setUseLiterals(boolean useLiterals) { - this.useLiterals = useLiterals; - } - - protected void setSkipParent(boolean b) { - skipParent = b; - } - - protected void setDmlWithSchema(boolean b) { - dmlWithSchema = b; - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/SQLServer2005Templates.java b/querydsl-sql/src/main/java/com/mysema/query/sql/SQLServer2005Templates.java deleted file mode 100644 index 768974a908..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/SQLServer2005Templates.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright 2013, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import java.util.List; - -import com.mysema.commons.lang.Pair; -import com.mysema.query.QueryFlag; -import com.mysema.query.QueryFlag.Position; -import com.mysema.query.QueryMetadata; -import com.mysema.query.QueryModifiers; -import com.mysema.query.support.Expressions; -import com.mysema.query.types.Expression; -import com.mysema.query.types.OrderSpecifier; -import com.mysema.query.types.Path; - - -/** - * SQLServer2005Templates is an SQL dialect for Microsoft SQL Server 2005 - * - * @author tiwe - */ -public class SQLServer2005Templates extends SQLServerTemplates { - - public static Builder builder() { - return new Builder() { - @Override - protected SQLTemplates build(char escape, boolean quote) { - return new SQLServer2005Templates(escape, quote); - } - }; - } - - private String topTemplate = "top ({0}) "; - - private String outerQueryStart = "select * from (\n "; - - private String outerQueryEnd = ") a where "; - - private String limitOffsetTemplate = "rn > {0} and rn <= {1}"; - - private String offsetTemplate = "rn > {0}"; - - private String outerQuerySuffix = " order by rn"; - - public SQLServer2005Templates() { - this('\\',false); - } - - public SQLServer2005Templates(boolean quote) { - this('\\',quote); - } - - public SQLServer2005Templates(char escape, boolean quote) { - super(escape, quote); - } - - @Override - public void serialize(QueryMetadata metadata, boolean forCountRow, SQLSerializer context) { - if (!forCountRow && metadata.getModifiers().isRestricting() && !metadata.getJoins().isEmpty()) { - QueryModifiers mod = metadata.getModifiers(); - if (mod.getOffset() == null) { - // select top ... - metadata = metadata.clone(); - metadata.addFlag(new QueryFlag(QueryFlag.Position.AFTER_SELECT, - Expressions.template(Integer.class, topTemplate, mod.getLimit()))); - context.serializeForQuery(metadata, forCountRow); - } else { - context.append(outerQueryStart); - metadata = metadata.clone(); - WindowFunction rn = SQLExpressions.rowNumber().over(); - for (OrderSpecifier os : metadata.getOrderBy()) { - rn.orderBy(os); - } - metadata.addProjection(rn.as("rn")); - metadata.clearOrderBy(); - context.serializeForQuery(metadata, forCountRow); - context.append(outerQueryEnd); - if (mod.getLimit() == null) { - context.handle(offsetTemplate, mod.getOffset()); - } else { - context.handle(limitOffsetTemplate, mod.getOffset(), mod.getLimit() + mod.getOffset()); - } - context.append(outerQuerySuffix); - } - - } else { - context.serializeForQuery(metadata, forCountRow); - } - - if (!metadata.getFlags().isEmpty()) { - context.serialize(Position.END, metadata.getFlags()); - } - } - - @Override - public void serializeDelete(QueryMetadata metadata, RelationalPath entity, SQLSerializer context) { - // limit - QueryModifiers mod = metadata.getModifiers(); - if (mod.isRestricting()) { - metadata = metadata.clone(); - metadata.addFlag(new QueryFlag(QueryFlag.Position.AFTER_SELECT, - Expressions.template(Integer.class, topTemplate, mod.getLimit()))); - } - - context.serializeForDelete(metadata, entity); - - if (!metadata.getFlags().isEmpty()) { - context.serialize(Position.END, metadata.getFlags()); - } - } - - @Override - public void serializeUpdate(QueryMetadata metadata, RelationalPath entity, - List, Expression>> updates, SQLSerializer context) { - // limit - QueryModifiers mod = metadata.getModifiers(); - if (mod.isRestricting()) { - metadata = metadata.clone(); - metadata.addFlag(new QueryFlag(QueryFlag.Position.AFTER_SELECT, - Expressions.template(Integer.class, topTemplate, mod.getLimit()))); - } - - context.serializeForUpdate(metadata, entity, updates); - - if (!metadata.getFlags().isEmpty()) { - context.serialize(Position.END, metadata.getFlags()); - } - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/SQLServer2008Templates.java b/querydsl-sql/src/main/java/com/mysema/query/sql/SQLServer2008Templates.java deleted file mode 100644 index e361821f2a..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/SQLServer2008Templates.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2013, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - - -/** - * SQLServer2008Templates is an SQL dialect for Microsoft SQL Server 2008 - * - * @author tiwe - * - */ -public class SQLServer2008Templates extends SQLServer2005Templates { - - public static Builder builder() { - return new Builder() { - @Override - protected SQLTemplates build(char escape, boolean quote) { - return new SQLServer2008Templates(escape, quote); - } - }; - } - - public SQLServer2008Templates() { - this('\\',false); - } - - public SQLServer2008Templates(boolean quote) { - this('\\',quote); - } - - public SQLServer2008Templates(char escape, boolean quote) { - super(escape, quote); - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/SQLServer2012Templates.java b/querydsl-sql/src/main/java/com/mysema/query/sql/SQLServer2012Templates.java deleted file mode 100644 index bf371e96d2..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/SQLServer2012Templates.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2013, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import com.mysema.query.QueryFlag.Position; -import com.mysema.query.QueryMetadata; -import com.mysema.query.QueryModifiers; - -/** - * SQLServer2012Templates is an SQL dialect for Microsoft SQL Server 2012 and later - * - * @author tiwe - * - */ -public class SQLServer2012Templates extends SQLServerTemplates { - - private String limitOffsetTemplate = "\noffset {1} rows fetch next {0} rows only"; - - private String offsetTemplate = "\noffset {0} rows"; - - public static Builder builder() { - return new Builder() { - @Override - protected SQLTemplates build(char escape, boolean quote) { - return new SQLServer2012Templates(escape, quote); - } - }; - } - - public SQLServer2012Templates() { - this('\\',false); - } - - public SQLServer2012Templates(boolean quote) { - this('\\',quote); - } - - public SQLServer2012Templates(char escape, boolean quote) { - super(escape, quote); - } - - @Override - public void serialize(QueryMetadata metadata, boolean forCountRow, SQLSerializer context) { - context.serializeForQuery(metadata, forCountRow); - - if (!metadata.getFlags().isEmpty()) { - context.serialize(Position.END, metadata.getFlags()); - } - } - - @Override - protected void serializeModifiers(QueryMetadata metadata, SQLSerializer context) { - QueryModifiers mod = metadata.getModifiers(); - if (mod.getLimit() == null) { - context.handle(offsetTemplate, mod.getOffset()); - } else if (mod.getOffset() == null) { - context.handle(limitOffsetTemplate, mod.getLimit(), 0); - } else { - context.handle(limitOffsetTemplate, mod.getLimit(), mod.getOffset()); - } - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/SQLServerTemplates.java b/querydsl-sql/src/main/java/com/mysema/query/sql/SQLServerTemplates.java deleted file mode 100644 index c18577a671..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/SQLServerTemplates.java +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import java.sql.Types; - -import com.mysema.query.QueryFlag; -import com.mysema.query.QueryFlag.Position; -import com.mysema.query.QueryMetadata; -import com.mysema.query.QueryModifiers; -import com.mysema.query.support.Expressions; -import com.mysema.query.types.Ops; - -/** - * SQLServerTemplates is an SQL dialect for Microsoft SQL Server - * - * @author tiwe - * - */ -public class SQLServerTemplates extends SQLTemplates { - - public static Builder builder() { - return new Builder() { - @Override - protected SQLTemplates build(char escape, boolean quote) { - return new SQLServerTemplates(escape, quote); - } - }; - } - - private String topTemplate = "top {0s} "; - - public SQLServerTemplates() { - this('\\',false); - } - - public SQLServerTemplates(boolean quote) { - this('\\',quote); - } - - public SQLServerTemplates(char escape, boolean quote) { - super("\"", escape, quote); - addClass2TypeMappings("decimal", Double.class); - setDummyTable(""); - setNullsFirst(null); - setNullsLast(null); - setDefaultValues("\ndefault values"); - - // String - add(Ops.CONCAT, "{0} + {1}", 13); - add(Ops.CHAR_AT, "cast(substring({0},{1}+1,1) as char)"); - add(Ops.INDEX_OF, "charindex({1},{0})-1"); - add(Ops.INDEX_OF_2ARGS, "charindex({1},{0},{2})-1"); - // NOTE : needs to be replaced with real regular expression - add(Ops.MATCHES, "{0} like {1}"); - add(Ops.STRING_IS_EMPTY, "len({0}) = 0"); - add(Ops.STRING_LENGTH, "len({0})"); - add(Ops.SUBSTR_1ARG, "substring({0},{1}+1,255)"); - add(Ops.SUBSTR_2ARGS, "substring({0},{1}+1,{2s}-{1s})", 1); - add(Ops.TRIM, "ltrim(rtrim({0}))"); - - add(Ops.StringOps.LOCATE, "charindex({0},{1})"); - add(Ops.StringOps.LOCATE2, "charindex({0},{1},{2})"); - - add(SQLOps.NEXTVAL, "{0s}.nextval"); - - add(Ops.MOD, "{0} % {1}", 10); - add(Ops.MathOps.COSH, "(exp({0}) + exp({0} * -1)) / 2"); - add(Ops.MathOps.COTH, "(exp({0} * 2) + 1) / (exp({0} * 2) - 1)"); - add(Ops.MathOps.SINH, "(exp({0}) - exp({0} * -1)) / 2"); - add(Ops.MathOps.TANH, "(exp({0} * 2) - 1) / (exp({0} * 2) + 1)"); - - // Date / time - add(Ops.DateTimeOps.YEAR, "datepart(year, {0})"); - add(Ops.DateTimeOps.MONTH, "datepart(month, {0})"); - add(Ops.DateTimeOps.WEEK, "datepart(week, {0})"); - add(Ops.DateTimeOps.DAY_OF_MONTH, "datepart(day, {0})"); - add(Ops.DateTimeOps.DAY_OF_WEEK, "datepart(weekday, {0})"); - add(Ops.DateTimeOps.DAY_OF_YEAR, "datepart(dayofyear, {0})"); - add(Ops.DateTimeOps.HOUR, "datepart(hour, {0})"); - add(Ops.DateTimeOps.MINUTE, "datepart(minute, {0})"); - add(Ops.DateTimeOps.SECOND, "datepart(second, {0})"); - add(Ops.DateTimeOps.MILLISECOND, "datepart(millisecond, {0})"); - - add(Ops.DateTimeOps.YEAR_MONTH, "(datepart(year, {0}) * 100 + datepart(month, {0}))"); - add(Ops.DateTimeOps.YEAR_WEEK, "(datepart(year, {0}) * 100 + datepart(isowk, {0}))"); - - add(Ops.DateTimeOps.ADD_YEARS, "dateadd(year, {1s}, {0})"); - add(Ops.DateTimeOps.ADD_MONTHS, "dateadd(month, {1s}, {0})"); - add(Ops.DateTimeOps.ADD_WEEKS, "dateadd(week, {1s}, {0})"); - add(Ops.DateTimeOps.ADD_DAYS, "dateadd(day, {1s}, {0})"); - add(Ops.DateTimeOps.ADD_HOURS, "dateadd(hour, {1s}, {0})"); - add(Ops.DateTimeOps.ADD_MINUTES, "dateadd(minute, {1s}, {0})"); - add(Ops.DateTimeOps.ADD_SECONDS, "dateadd(second, {1s}, {0})"); - - add(Ops.DateTimeOps.DIFF_YEARS, "datediff(year,{0},{1})"); - add(Ops.DateTimeOps.DIFF_MONTHS, "datediff(month,{0},{1})"); - add(Ops.DateTimeOps.DIFF_WEEKS, "datediff(week,{0},{1})"); - add(Ops.DateTimeOps.DIFF_DAYS, "datediff(day,{0},{1})"); - add(Ops.DateTimeOps.DIFF_HOURS, "datediff(hour,{0},{1})"); - add(Ops.DateTimeOps.DIFF_MINUTES, "datediff(minute,{0},{1})"); - add(Ops.DateTimeOps.DIFF_SECONDS, "datediff(second,{0},{1})"); - - add(Ops.DateTimeOps.DATE, "cast({0} as date)"); - add(Ops.DateTimeOps.CURRENT_DATE, "cast(getdate() as date)"); - } - - @Override - public String serialize(String literal, int jdbcType) { - if (jdbcType == Types.TIMESTAMP) { - return "{ts '" + literal + "'}"; - } else if (jdbcType == Types.DATE) { - return "{d '" + literal + "'}"; - } else if (jdbcType == Types.TIME) { - return "{t '" + literal + "'}"; - } else { - return super.serialize(literal, jdbcType); - } - } - - @Override - protected String escapeForLike(String str) { - final StringBuilder rv = new StringBuilder(str.length() + 3); - for (char ch : str.toCharArray()) { - if (ch == getEscapeChar() || ch == '%' || ch == '_' || ch == '[') { - rv.append(getEscapeChar()); - } - rv.append(ch); - } - return rv.toString(); - } - - @Override - public void serialize(QueryMetadata metadata, boolean forCountRow, SQLSerializer context) { - if (!forCountRow && metadata.getModifiers().isRestricting() && !metadata.getJoins().isEmpty()) { - QueryModifiers mod = metadata.getModifiers(); - if (mod.getOffset() == null) { - // select top ... - metadata = metadata.clone(); - metadata.addFlag(new QueryFlag(QueryFlag.Position.AFTER_SELECT, - Expressions.template(Integer.class, topTemplate, mod.getLimit()))); - context.serializeForQuery(metadata, forCountRow); - } else { - throw new IllegalStateException("offset not supported"); - } - - } else { - context.serializeForQuery(metadata, forCountRow); - } - - if (!metadata.getFlags().isEmpty()) { - context.serialize(Position.END, metadata.getFlags()); - } - } - - @Override - protected void serializeModifiers(QueryMetadata metadata, SQLSerializer context) { - // do nothing - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/SQLSubQuery.java b/querydsl-sql/src/main/java/com/mysema/query/sql/SQLSubQuery.java deleted file mode 100644 index ec5e556808..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/SQLSubQuery.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import com.mysema.query.QueryMetadata; - -/** - * SQLSubQuery is a subquery implementation for SQL queries - * - * @author tiwe - * - */ -public class SQLSubQuery extends AbstractSQLSubQuery { - - public SQLSubQuery() { - super(); - } - - public SQLSubQuery(QueryMetadata metadata) { - super(metadata); - } - - public SQLSubQuery(Configuration configuration, QueryMetadata metadata) { - super(metadata); - } - - @Override - public SQLSubQuery clone() { - SQLSubQuery subQuery = new SQLSubQuery(configuration, getMetadata()); - return subQuery; - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/SQLTemplates.java b/querydsl-sql/src/main/java/com/mysema/query/sql/SQLTemplates.java deleted file mode 100644 index 91f631cb98..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/SQLTemplates.java +++ /dev/null @@ -1,1011 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import java.lang.reflect.Field; -import java.sql.Types; -import java.util.Arrays; -import java.util.List; -import java.util.Locale; -import java.util.Map; - -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.primitives.Primitives; -import com.mysema.commons.lang.Pair; -import com.mysema.query.JoinType; -import com.mysema.query.QueryException; -import com.mysema.query.QueryFlag.Position; -import com.mysema.query.QueryMetadata; -import com.mysema.query.QueryModifiers; -import com.mysema.query.sql.types.Type; -import com.mysema.query.types.*; - -/** - * SQLTemplates extends Templates to provides SQL specific extensions - * and acts as database specific Dialect for Querydsl SQL - * - * @author tiwe - */ -public class SQLTemplates extends Templates { - - public static final Expression RECURSIVE = TemplateExpressionImpl.create(Object.class, ""); - - public static final SQLTemplates DEFAULT = new SQLTemplates("\"",'\\',false); - - public abstract static class Builder { - - protected boolean printSchema, quote, newLineToSingleSpace; - - protected char escape = '\\'; - - public Builder printSchema() { - printSchema = true; - return this; - } - - public Builder quote() { - quote = true; - return this; - } - - public Builder newLineToSingleSpace() { - newLineToSingleSpace = true; - return this; - } - - public Builder escape(char ch) { - escape = ch; - return this; - } - - protected abstract SQLTemplates build(char escape, boolean quote); - - public SQLTemplates build() { - SQLTemplates templates = build(escape, quote); - if (newLineToSingleSpace) { - templates.newLineToSingleSpace(); - } - templates.setPrintSchema(printSchema); - return templates; - } - - } - - private final Map, String> class2type = Maps.newHashMap(); - - private final Map tableOverrides = Maps.newHashMap(); - - private final List> customTypes = Lists.newArrayList(); - - private final String quoteStr; - - private final boolean useQuotes; - - private boolean printSchema; - - private String createTable = "create table "; - - private String asc = " asc"; - - private String autoIncrement = " auto_increment"; - - private String columnAlias = " "; - - private String count = "count "; - - private String countStar = "count(*)"; - - private String delete = "delete "; - - private String desc = " desc"; - - private String distinctCountEnd = ")"; - - private String distinctCountStart = "count(distinct "; - - private String dummyTable = "dual"; - - private String from = "\nfrom "; - - private String fullJoin = "\nfull join "; - - private String groupBy = "\ngroup by "; - - private String having = "\nhaving "; - - private String innerJoin = "\ninner join "; - - private String insertInto = "insert into "; - - private String join = "\njoin "; - - private String key = "key"; - - private String leftJoin = "\nleft join "; - - private String rightJoin = "\nright join ";; - - private String limitTemplate = "\nlimit {0}"; - - private String mergeInto = "merge into "; - - private boolean nativeMerge; - - private String notNull = " not null"; - - private String offsetTemplate = "\noffset {0}"; - - private String on = "\non "; - - private String orderBy = "\norder by "; - - private String select = "select "; - - private String selectDistinct = "select distinct "; - - private String set = "set "; - - private String tableAlias = " "; - - private String update = "update "; - - private String values = "\nvalues "; - - private String defaultValues = "\nvalues ()"; - - private String where = "\nwhere "; - - private String with = "with "; - - private String withRecursive = "with recursive "; - - private String createIndex = "create index "; - - private String createUniqueIndex = "create unique index "; - - private String nullsFirst = " nulls first"; - - private String nullsLast = " nulls last"; - - private boolean parameterMetadataAvailable = true; - - private boolean batchCountViaGetUpdateCount = false; - - private boolean unionsWrapped = true; - - private boolean functionJoinsWrapped = false; - - private boolean limitRequired = false; - - private boolean countDistinctMultipleColumns = false; - - private boolean countViaAnalytics = false; - - protected SQLTemplates(String quoteStr, char escape, boolean useQuotes) { - super(escape); - this.quoteStr = quoteStr; - this.useQuotes = useQuotes; - - add(SQLOps.ALL, "{0}.*"); - - // flags - add(SQLOps.WITH_ALIAS, "{0} as {1}", 0); - add(SQLOps.WITH_COLUMNS, "{0} {1}", 0); - add(SQLOps.FOR_UPDATE, "\nfor update"); - add(SQLOps.FOR_SHARE, "\nfor share"); - add(SQLOps.NO_WAIT, " nowait"); - add(SQLOps.QUALIFY, "\nqualify {0}"); - - // boolean - add(Ops.AND, "{0} and {1}", 36); - add(Ops.NOT, "not {0}", 35); - add(Ops.OR, "{0} or {1}", 38); - add(Ops.XNOR, "{0} xnor {1}", 39); - add(Ops.XOR, "{0} xor {1}", 39); - - // math - add(Ops.MathOps.RANDOM, "rand()"); - add(Ops.MathOps.RANDOM2, "rand({0})"); - add(Ops.MathOps.CEIL, "ceiling({0})"); - add(Ops.MathOps.POWER, "power({0},{1})"); - add(Ops.MOD, "mod({0},{1})", -1); - - // date time - add(Ops.DateTimeOps.CURRENT_DATE, "current_date"); - add(Ops.DateTimeOps.CURRENT_TIME, "current_time"); - add(Ops.DateTimeOps.CURRENT_TIMESTAMP, "current_timestamp"); - - add(Ops.DateTimeOps.MILLISECOND, "0"); - add(Ops.DateTimeOps.SECOND, "extract(second from {0})"); - add(Ops.DateTimeOps.MINUTE, "extract(minute from {0})"); - add(Ops.DateTimeOps.HOUR, "extract(hour from {0})"); - add(Ops.DateTimeOps.WEEK, "extract(week from {0})"); - add(Ops.DateTimeOps.MONTH, "extract(month from {0})"); - add(Ops.DateTimeOps.YEAR, "extract(year from {0})"); - add(Ops.DateTimeOps.YEAR_MONTH, "(extract(year from {0}) * 100 + extract(month from {0}))"); - add(Ops.DateTimeOps.YEAR_WEEK, "(extract(year from {0}) * 100 + extract(week from {0}))"); - add(Ops.DateTimeOps.DAY_OF_WEEK, "extract(day_of_week from {0})"); - add(Ops.DateTimeOps.DAY_OF_MONTH, "extract(day from {0})"); - add(Ops.DateTimeOps.DAY_OF_YEAR, "extract(day_of_year from {0})"); - - add(Ops.DateTimeOps.ADD_YEARS, "dateadd('year',{1},{0})"); - add(Ops.DateTimeOps.ADD_MONTHS, "dateadd('month',{1},{0})"); - add(Ops.DateTimeOps.ADD_WEEKS, "dateadd('week',{1},{0})"); - add(Ops.DateTimeOps.ADD_DAYS, "dateadd('day',{1},{0})"); - add(Ops.DateTimeOps.ADD_HOURS, "dateadd('hour',{1},{0})"); - add(Ops.DateTimeOps.ADD_MINUTES, "dateadd('minute',{1},{0})"); - add(Ops.DateTimeOps.ADD_SECONDS, "dateadd('second',{1},{0})"); - - add(Ops.DateTimeOps.DIFF_YEARS, "datediff('year',{0},{1})"); - add(Ops.DateTimeOps.DIFF_MONTHS, "datediff('month',{0},{1})"); - add(Ops.DateTimeOps.DIFF_WEEKS, "datediff('week',{0},{1})"); - add(Ops.DateTimeOps.DIFF_DAYS, "datediff('day',{0},{1})"); - add(Ops.DateTimeOps.DIFF_HOURS, "datediff('hour',{0},{1})"); - add(Ops.DateTimeOps.DIFF_MINUTES, "datediff('minute',{0},{1})"); - add(Ops.DateTimeOps.DIFF_SECONDS, "datediff('second',{0},{1})"); - - add(Ops.DateTimeOps.TRUNC_YEAR, "date_trunc('year',{0})"); - add(Ops.DateTimeOps.TRUNC_MONTH, "date_trunc('month',{0})"); - add(Ops.DateTimeOps.TRUNC_WEEK, "date_trunc('week',{0})"); - add(Ops.DateTimeOps.TRUNC_DAY, "date_trunc('day',{0})"); - add(Ops.DateTimeOps.TRUNC_HOUR, "date_trunc('hour',{0})"); - add(Ops.DateTimeOps.TRUNC_MINUTE, "date_trunc('minute',{0})"); - add(Ops.DateTimeOps.TRUNC_SECOND, "date_trunc('second',{0})"); - - // string - add(Ops.CONCAT, "{0} || {1}", 38); - add(Ops.MATCHES, "{0} regexp {1}", 25); - add(Ops.CHAR_AT, "cast(substr({0},{1s}+1,1) as char)"); - add(Ops.EQ_IGNORE_CASE, "{0l} = {1l}"); - add(Ops.INDEX_OF, "locate({1},{0})-1"); - add(Ops.INDEX_OF_2ARGS, "locate({1},{0},{2s}+1)-1"); - add(Ops.STRING_IS_EMPTY, "length({0}) = 0"); - add(Ops.SUBSTR_1ARG, "substr({0},{1s}+1)", 1); - add(Ops.SUBSTR_2ARGS, "substr({0},{1s}+1,{2s}-{1s})", 1); - add(Ops.StringOps.LOCATE, "locate({0},{1})"); - add(Ops.StringOps.LOCATE2, "locate({0},{1},{2})"); - - // like with escape - add(Ops.LIKE, "{0} like {1} escape '"+escape+"'"); - add(Ops.ENDS_WITH, "{0} like {%1} escape '"+escape+"'"); - add(Ops.ENDS_WITH_IC, "{0l} like {%%1} escape '"+escape+"'"); - add(Ops.STARTS_WITH, "{0} like {1%} escape '"+escape+"'"); - add(Ops.STARTS_WITH_IC, "{0l} like {1%%} escape '"+escape+"'"); - add(Ops.STRING_CONTAINS, "{0} like {%1%} escape '"+escape+"'"); - add(Ops.STRING_CONTAINS_IC, "{0l} like {%%1%%} escape '"+escape+"'"); - - add(SQLOps.CAST, "cast({0} as {1s})"); - add(SQLOps.UNION, "{0}\nunion\n{1}", 50); - add(SQLOps.UNION_ALL, "{0}\nunion all\n{1}", 50); - add(SQLOps.NEXTVAL, "nextval('{0s}')"); - - // analytic functions - add(SQLOps.CORR, "corr({0},{1})"); - add(SQLOps.COVARPOP, "covar_pop({0},{1})"); - add(SQLOps.COVARSAMP, "covar_samp({0},{1})"); - add(SQLOps.CUMEDIST, "cume_dist()"); - add(SQLOps.CUMEDIST2, "cume_dist({0})"); - add(SQLOps.DENSERANK, "dense_rank()"); - add(SQLOps.DENSERANK2, "dense_rank({0})"); - add(SQLOps.FIRSTVALUE, "first_value({0})"); - add(SQLOps.LAG, "lag({0})"); - add(SQLOps.LASTVALUE, "last_value({0})"); - add(SQLOps.LEAD, "lead({0})"); - add(SQLOps.LISTAGG, "listagg({0},'{1s}')"); - add(SQLOps.NTHVALUE, "nth_value({0}, {1})"); - add(SQLOps.NTILE, "ntile({0})"); - add(SQLOps.PERCENTILECONT, "percentile_cont({0})"); - add(SQLOps.PERCENTILEDISC, "percentile_disc({0})"); - add(SQLOps.PERCENTRANK, "percent_rank()"); - add(SQLOps.PERCENTRANK2, "percent_rank({0})"); - add(SQLOps.RANK, "rank()"); - add(SQLOps.RANK2, "rank({0})"); - add(SQLOps.RATIOTOREPORT, "ratio_to_report({0})"); - add(SQLOps.REGR_SLOPE, "regr_slope({0}, {1})"); - add(SQLOps.REGR_INTERCEPT, "regr_intercept({0}, {1})"); - add(SQLOps.REGR_COUNT, "regr_count({0}, {1})"); - add(SQLOps.REGR_R2, "regr_r2({0}, {1})"); - add(SQLOps.REGR_AVGX, "regr_avgx({0}, {1})"); - add(SQLOps.REGR_AVGY, "regr_avgy({0}, {1})"); - add(SQLOps.REGR_SXX, "regr_sxx({0}, {1})"); - add(SQLOps.REGR_SYY, "regr_syy({0}, {1})"); - add(SQLOps.REGR_SXY, "regr_sxy({0}, {1})"); - add(SQLOps.ROWNUMBER, "row_number()"); - add(SQLOps.STDDEV, "stddev({0})"); - add(SQLOps.STDDEVPOP, "stddev_pop({0})"); - add(SQLOps.STDDEVSAMP, "stddev_samp({0})"); - add(SQLOps.STDDEV_DISTINCT, "stddev(distinct {0})"); - add(SQLOps.VARIANCE, "variance({0})"); - add(SQLOps.VARPOP, "var_pop({0})"); - add(SQLOps.VARSAMP, "var_samp({0})"); - - add(Ops.AggOps.BOOLEAN_ANY, "some({0})"); - add(Ops.AggOps.BOOLEAN_ALL, "every({0})"); - - for (Class cl : new Class[] { Boolean.class, Byte.class, - Double.class, Float.class, Integer.class, Long.class, - Short.class, String.class }) { - class2type.put(cl, cl.getSimpleName().toLowerCase(Locale.ENGLISH)); - } - - class2type.put(Boolean.class, "bit"); - class2type.put(Byte.class, "tinyint"); - class2type.put(Long.class, "bigint"); - class2type.put(Short.class, "smallint"); - class2type.put(String.class, "varchar"); - class2type.put(java.sql.Date.class, "date"); - class2type.put(java.sql.Time.class, "time"); - class2type.put(java.sql.Timestamp.class, "timestamp"); - } - - public String serialize(String literal, int jdbcType) { - switch (jdbcType) { - case Types.TIMESTAMP: - return "(timestamp '" + literal + "')"; - case Types.DATE: - return "(date '" + literal + "')"; - case Types.TIME: - return "(time '" + literal + "')"; - case Types.CHAR: - case Types.CLOB: - case Types.LONGNVARCHAR: - case Types.LONGVARCHAR: - case Types.NCHAR: - case Types.NCLOB: - case Types.NVARCHAR: - case Types.VARCHAR: - return "'" + escapeLiteral(literal) + "'"; - default: - return literal; - } - } - - public String escapeLiteral(String str) { - StringBuilder builder = new StringBuilder(); - for (char ch : str.toCharArray()) { - if (ch == '\n') { - builder.append("\\n"); - continue; - } else if (ch == '\r') { - builder.append("\\r"); - continue; - } else if (ch == '\'') { - builder.append("''"); - continue; - } - builder.append(ch); - } - return builder.toString(); - } - - protected void addClass2TypeMappings(String type, Class... classes) { - for (Class cl : classes) { - class2type.put(cl, type); - } - } - - protected void add(Map, String> ops) { - for (Map.Entry, String> entry : ops.entrySet()) { - add(entry.getKey(), entry.getValue()); - } - } - - protected void addTableOverride(SchemaAndTable from, SchemaAndTable to) { - tableOverrides.put(from, to); - } - - /** - * Use customTypes instead - */ - @Deprecated - public final boolean isBigDecimalSupported() { - return false; - } - - public final List> getCustomTypes() { - return customTypes; - } - - public final String getAsc() { - return asc; - } - - public final String getAutoIncrement() { - return autoIncrement; - } - - public final String getColumnAlias() { - return columnAlias; - } - - public final String getCount() { - return count; - } - - public final String getCountStar() { - return countStar; - } - - public final String getDelete() { - return delete; - } - - public final String getDesc() { - return desc; - } - - public final String getDistinctCountEnd() { - return distinctCountEnd; - } - - public final String getDistinctCountStart() { - return distinctCountStart; - } - - public final String getDummyTable() { - return dummyTable; - } - - public final String getFrom() { - return from; - } - - public final String getFullJoin() { - return fullJoin; - } - - public final String getGroupBy() { - return groupBy; - } - - public final String getHaving() { - return having; - } - - public final String getInnerJoin() { - return innerJoin; - } - - public final String getInsertInto() { - return insertInto; - } - - public final String getJoin() { - return join; - } - - public final String getJoinSymbol(JoinType joinType) { - switch (joinType) { - case JOIN: return join; - case INNERJOIN: return innerJoin; - case FULLJOIN: return fullJoin; - case LEFTJOIN: return leftJoin; - case RIGHTJOIN: return rightJoin; - default: return ", "; - } - } - - public final String getKey() { - return key; - } - - public final String getLeftJoin() { - return leftJoin; - } - - public final String getRightJoin() { - return rightJoin; - } - - public final String getLimitTemplate() { - return limitTemplate; - } - - public final String getMergeInto() { - return mergeInto; - } - - public final String getNotNull() { - return notNull; - } - - public final String getOffsetTemplate() { - return offsetTemplate; - } - - public final String getOn() { - return on; - } - - public final String getOrderBy() { - return orderBy; - } - - public final String getSelect() { - return select; - } - - public final String getSelectDistinct() { - return selectDistinct; - } - - public final String getSet() { - return set; - } - - public final String getTableAlias() { - return tableAlias; - } - - public final Map getTableOverrides() { - return tableOverrides; - } - - public String getTypeForCast(Class cl) { - return getTypeForClass(cl); - } - - public String getTypeForClass(Class cl) { - Class clazz = Primitives.wrap(cl); - if (class2type.containsKey(clazz)) { - return class2type.get(clazz); - } else { - throw new IllegalArgumentException("Got not type for " + clazz.getName()); - } - } - - public final String getUpdate() { - return update; - } - - public final String getValues() { - return values; - } - - public final String getDefaultValues() { - return defaultValues; - } - - public final String getWhere() { - return where; - } - - public final boolean isNativeMerge() { - return nativeMerge; - } - - public final boolean isSupportsAlias() { - return true; - } - - public final String getCreateIndex() { - return createIndex; - } - - public final String getCreateUniqueIndex() { - return createUniqueIndex; - } - - public final String getCreateTable() { - return createTable; - } - - public final String getWith() { - return with; - } - - public final String getWithRecursive() { - return withRecursive; - } - - public final boolean isCountDistinctMultipleColumns() { - return countDistinctMultipleColumns; - } - - public final boolean isPrintSchema() { - return printSchema; - } - - public final boolean isParameterMetadataAvailable() { - return parameterMetadataAvailable; - } - - public final boolean isBatchCountViaGetUpdateCount() { - return batchCountViaGetUpdateCount; - } - - public final boolean isUseQuotes() { - return useQuotes; - } - - public final boolean isUnionsWrapped() { - return unionsWrapped; - } - - public final boolean isFunctionJoinsWrapped() { - return functionJoinsWrapped; - } - - public final boolean isLimitRequired() { - return limitRequired; - } - - public final String getNullsFirst() { - return nullsFirst; - } - - public final String getNullsLast() { - return nullsLast; - } - - public boolean isCountViaAnalytics() { - return countViaAnalytics; - } - - protected void newLineToSingleSpace() { - for (Class cl : Arrays.>asList(getClass(), SQLTemplates.class)) { - for (Field field : cl.getDeclaredFields()) { - try { - if (field.getType().equals(String.class)) { - field.setAccessible(true); - Object val = field.get(this); - if (val != null) { - field.set(this, val.toString().replace('\n',' ')); - } - - } - } catch (IllegalAccessException e) { - throw new QueryException(e.getMessage(), e); - } - } - } - } - - public final String quoteIdentifier(String identifier) { - if (useQuotes || requiresQuotes(identifier)) { - return quoteStr + identifier + quoteStr; - } else { - return identifier; - } - } - - protected boolean requiresQuotes(final String identifier) { - for (int i = 0; i < identifier.length(); i++) { - final char ch = identifier.charAt(i); - //0-9,a-z,A-Z_ - if (ch < '0' || (ch > '9' && ch < 'A') || (ch > 'Z' && ch < '_') || ch > 'z') { - return true; - } - } - return false; - } - - /** - * template method for SELECT serialization - * - * @param metadata - * @param forCountRow - * @param context - */ - public void serialize(QueryMetadata metadata, boolean forCountRow, SQLSerializer context) { - context.serializeForQuery(metadata, forCountRow); - - if (!metadata.getFlags().isEmpty()) { - context.serialize(Position.END, metadata.getFlags()); - } - } - - /** - * template method for DELETE serialization - * - * @param metadata - * @param entity - * @param context - */ - public void serializeDelete(QueryMetadata metadata, RelationalPath entity, SQLSerializer context) { - context.serializeForDelete(metadata, entity); - - // limit - if (metadata.getModifiers().isRestricting()) { - serializeModifiers(metadata, context); - } - - if (!metadata.getFlags().isEmpty()) { - context.serialize(Position.END, metadata.getFlags()); - } - } - - /** - * template method for INSERT serialization - * - * @param metadata - * @param entity - * @param columns - * @param values - * @param subQuery - * @param context - */ - public void serializeInsert(QueryMetadata metadata, RelationalPath entity, - List> columns, List> values, SubQueryExpression subQuery, - SQLSerializer context) { - context.serializeForInsert(metadata, entity, columns, values, subQuery); - - if (!metadata.getFlags().isEmpty()) { - context.serialize(Position.END, metadata.getFlags()); - } - } - - /** - * template method for MERGE serialization - * - * @param metadata - * @param entity - * @param keys - * @param columns - * @param values - * @param subQuery - * @param context - */ - public void serializeMerge(QueryMetadata metadata, RelationalPath entity, - List> keys, List> columns, List> values, - SubQueryExpression subQuery, SQLSerializer context) { - context.serializeForMerge(metadata, entity, keys, columns, values, subQuery); - - if (!metadata.getFlags().isEmpty()) { - context.serialize(Position.END, metadata.getFlags()); - } - } - - /** - * template method for UPDATE serialization - * - * @param metadata - * @param entity - * @param updates - * @param context - */ - public void serializeUpdate(QueryMetadata metadata, RelationalPath entity, - List, Expression>> updates, SQLSerializer context) { - context.serializeForUpdate(metadata, entity, updates); - - // limit - if (metadata.getModifiers().isRestricting()) { - serializeModifiers(metadata, context); - } - - if (!metadata.getFlags().isEmpty()) { - context.serialize(Position.END, metadata.getFlags()); - } - } - - /** - * template method for LIMIT and OFFSET serialization - * - * @param metadata - * @param context - */ - protected void serializeModifiers(QueryMetadata metadata, SQLSerializer context) { - QueryModifiers mod = metadata.getModifiers(); - if (mod.getLimit() != null) { - context.handle(limitTemplate, mod.getLimit()); - } else if (limitRequired) { - context.handle(limitTemplate, Integer.MAX_VALUE); - } - if (mod.getOffset() != null) { - context.handle(offsetTemplate, mod.getOffset()); - } - } - - protected void addCustomType(Type type) { - customTypes.add(type); - } - - protected void setAsc(String asc) { - this.asc = asc; - } - - protected void setAutoIncrement(String autoIncrement) { - this.autoIncrement = autoIncrement; - } - - protected void setColumnAlias(String columnAlias) { - this.columnAlias = columnAlias; - } - - protected void setCount(String count) { - this.count = count; - } - - protected void setCountStar(String countStar) { - this.countStar = countStar; - } - - protected void setDelete(String delete) { - this.delete = delete; - } - - protected void setDesc(String desc) { - this.desc = desc; - } - - protected void setDistinctCountEnd(String distinctCountEnd) { - this.distinctCountEnd = distinctCountEnd; - } - - protected void setDistinctCountStart(String distinctCountStart) { - this.distinctCountStart = distinctCountStart; - } - - protected void setDummyTable(String dummyTable) { - this.dummyTable = dummyTable; - } - - protected void setFrom(String from) { - this.from = from; - } - - protected void setFullJoin(String fullJoin) { - this.fullJoin = fullJoin; - } - - protected void setGroupBy(String groupBy) { - this.groupBy = groupBy; - } - - protected void setHaving(String having) { - this.having = having; - } - - protected void setInnerJoin(String innerJoin) { - this.innerJoin = innerJoin; - } - - protected void setInsertInto(String insertInto) { - this.insertInto = insertInto; - } - - protected void setJoin(String join) { - this.join = join; - } - - protected void setKey(String key) { - this.key = key; - } - - protected void setLeftJoin(String leftJoin) { - this.leftJoin = leftJoin; - } - - protected void setRightJoin(String rightJoin) { - this.rightJoin = rightJoin; - } - - protected void setMergeInto(String mergeInto) { - this.mergeInto = mergeInto; - } - - protected void setNativeMerge(boolean nativeMerge) { - this.nativeMerge = nativeMerge; - } - - protected void setNotNull(String notNull) { - this.notNull = notNull; - } - - protected void setOffsetTemplate(String offsetTemplate) { - this.offsetTemplate = offsetTemplate; - } - - protected void setOn(String on) { - this.on = on; - } - - protected void setOrderBy(String orderBy) { - this.orderBy = orderBy; - } - - protected void setSelect(String select) { - this.select = select; - } - - protected void setSelectDistinct(String selectDistinct) { - this.selectDistinct = selectDistinct; - } - - protected void setSet(String set) { - this.set = set; - } - - protected void setTableAlias(String tableAlias) { - this.tableAlias = tableAlias; - } - - protected void setUpdate(String update) { - this.update = update; - } - - protected void setValues(String values) { - this.values = values; - } - - protected void setDefaultValues(String defaultValues) { - this.defaultValues = defaultValues; - } - - protected void setWhere(String where) { - this.where = where; - } - - protected void setWith(String with) { - this.with = with; - } - - protected void setWithRecursive(String withRecursive) { - this.withRecursive = withRecursive; - } - - protected void setCreateIndex(String createIndex) { - this.createIndex = createIndex; - } - - protected void setCreateUniqueIndex(String createUniqueIndex) { - this.createUniqueIndex = createUniqueIndex; - } - - protected void setCreateTable(String createTable) { - this.createTable = createTable; - } - - protected void setPrintSchema(boolean printSchema) { - this.printSchema = printSchema; - } - - protected void setParameterMetadataAvailable(boolean parameterMetadataAvailable) { - this.parameterMetadataAvailable = parameterMetadataAvailable; - } - - protected void setBatchCountViaGetUpdateCount(boolean batchCountViaGetUpdateCount) { - this.batchCountViaGetUpdateCount = batchCountViaGetUpdateCount; - } - - protected void setUnionsWrapped(boolean unionsWrapped) { - this.unionsWrapped = unionsWrapped; - } - - protected void setFunctionJoinsWrapped(boolean functionJoinsWrapped) { - this.functionJoinsWrapped = functionJoinsWrapped; - } - - protected void setNullsFirst(String nullsFirst) { - this.nullsFirst = nullsFirst; - } - - protected void setNullsLast(String nullsLast) { - this.nullsLast = nullsLast; - } - - protected void setLimitRequired(boolean limitRequired) { - this.limitRequired = limitRequired; - } - - protected void setCountDistinctMultipleColumns(boolean countDistinctMultipleColumns) { - this.countDistinctMultipleColumns = countDistinctMultipleColumns; - } - - protected void setCountViaAnalytics(boolean countViaAnalytics) { - this.countViaAnalytics = countViaAnalytics; - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/SQLiteTemplates.java b/querydsl-sql/src/main/java/com/mysema/query/sql/SQLiteTemplates.java deleted file mode 100644 index 9c612a0ae4..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/SQLiteTemplates.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import com.mysema.query.sql.types.BigDecimalAsDoubleType; -import com.mysema.query.types.Ops; -import org.joda.time.format.DateTimeFormat; -import org.joda.time.format.DateTimeFormatter; - -import java.sql.Types; - -/** - * SQLiteTemplates is a SQL dialect for SQLite - * - * @author tiwe - * - */ -public class SQLiteTemplates extends SQLTemplates { - - private static final DateTimeFormatter dateFormatter = DateTimeFormat.forPattern("yyyy-MM-dd"); - - private static final DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss"); - - private static final DateTimeFormatter timeFormatter = DateTimeFormat.forPattern("HH:mm:ss"); - - public static Builder builder() { - return new Builder() { - @Override - protected SQLTemplates build(char escape, boolean quote) { - return new SQLiteTemplates(escape, quote); - } - }; - } - - public SQLiteTemplates() { - this('\\', false); - } - - public SQLiteTemplates(boolean quote) { - this('\\', quote); - } - - public SQLiteTemplates(char escape, boolean quote) { - super("\"", escape, quote); - setDummyTable(null); - addCustomType(BigDecimalAsDoubleType.DEFAULT); - setUnionsWrapped(false); - setLimitRequired(true); - setNullsFirst(null); - setNullsLast(null); - setDefaultValues("\ndefault values"); - add(Ops.MOD, "{0} % {1}"); - - add(Ops.INDEX_OF, "charindex({1},{0},1)-1"); - add(Ops.INDEX_OF_2ARGS, "charindex({1},{0},{2s}+1)-1"); - - add(Ops.StringOps.LOCATE, "charindex({0},{1})"); - add(Ops.StringOps.LOCATE2, "charindex({0},{1},{2s})"); - - // TODO : optimize - add(Ops.DateTimeOps.YEAR, "cast(strftime('%Y',{0} / 1000, 'unixepoch', 'localtime') as integer)"); - add(Ops.DateTimeOps.MONTH, "cast(strftime('%m',{0} / 1000, 'unixepoch', 'localtime') as integer)"); - add(Ops.DateTimeOps.WEEK, "cast(strftime('%W',{0} / 1000, 'unixepoch', 'localtime') as integer) + 1"); - add(Ops.DateTimeOps.DAY_OF_MONTH, "cast(strftime('%d',{0} / 1000, 'unixepoch', 'localtime') as integer)"); - add(Ops.DateTimeOps.DAY_OF_WEEK, "cast(strftime('%w',{0} / 1000, 'unixepoch', 'localtime') as integer) + 1"); - add(Ops.DateTimeOps.DAY_OF_YEAR, "cast(strftime('%j',{0} / 1000, 'unixepoch', 'localtime') as integer)"); - add(Ops.DateTimeOps.HOUR, "cast(strftime('%H',{0} / 1000, 'unixepoch', 'localtime') as integer)"); - add(Ops.DateTimeOps.MINUTE, "cast(strftime('%M',{0} / 1000, 'unixepoch', 'localtime') as integer)"); - add(Ops.DateTimeOps.SECOND, "cast(strftime('%S',{0} / 1000, 'unixepoch', 'localtime') as integer)"); - - add(Ops.DateTimeOps.YEAR_MONTH, "cast(strftime('%Y',{0} / 1000, 'unixepoch', 'localtime') * 100 + strftime('%m',{0} / 1000, 'unixepoch', 'localtime') as integer)"); - add(Ops.DateTimeOps.YEAR_WEEK, "cast(strftime('%Y%W',{0} / 1000, 'unixepoch', 'localtime') as integer)"); - - add(Ops.DateTimeOps.ADD_YEARS, "date({0}, '+{1s} year')"); - add(Ops.DateTimeOps.ADD_MONTHS, "date({0}, '+{1s} month')"); - add(Ops.DateTimeOps.ADD_WEEKS, "date({0}, '+{1s} week')"); - add(Ops.DateTimeOps.ADD_DAYS, "date({0}, '+{1s} day')"); - add(Ops.DateTimeOps.ADD_HOURS, "date({0}, '+{1s} hour')"); - add(Ops.DateTimeOps.ADD_MINUTES, "date({0}, '+{1s} minute')"); - add(Ops.DateTimeOps.ADD_SECONDS, "date({0}, '+{1s} second')"); - - add(Ops.MathOps.RANDOM, "random()"); - add(Ops.MathOps.RANDOM2, "random({0})"); - add(Ops.MathOps.LN, "log({0})"); - add(Ops.MathOps.LOG, "(log({0}) / log({1}))"); - } - - @Override - public String serialize(String literal, int jdbcType) { - // XXX doesn't work with LocalDate, LocalDateTime and LocalTime - if (jdbcType == Types.TIMESTAMP) { - return String.valueOf(dateTimeFormatter.parseDateTime(literal).getMillis()); - } else if (jdbcType == Types.DATE) { - return String.valueOf(dateFormatter.parseDateTime(literal).getMillis()); - } else if (jdbcType == Types.TIME) { - return String.valueOf(timeFormatter.parseDateTime(literal).getMillis()); - } else { - return super.serialize(literal, jdbcType); - } - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/SchemaAndTable.java b/querydsl-sql/src/main/java/com/mysema/query/sql/SchemaAndTable.java deleted file mode 100644 index 733c2b51e4..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/SchemaAndTable.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2014, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import java.io.Serializable; - -/** - * - */ -public class SchemaAndTable implements Serializable { - - private final String schema, table; - - public SchemaAndTable(String schema, String table) { - this.schema = schema; - this.table = table; - } - - public String getSchema() { - return schema; - } - - public String getTable() { - return table; - } - - @Override - public boolean equals(Object o) { - if (o == this) { - return true; - } else if (o instanceof SchemaAndTable) { - SchemaAndTable st = (SchemaAndTable)o; - return st.schema.equals(schema) && st.table.equals(table); - } else { - return false; - } - } - - @Override - public int hashCode() { - return 31 * schema.hashCode() + table.hashCode(); - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/Union.java b/querydsl-sql/src/main/java/com/mysema/query/sql/Union.java deleted file mode 100644 index 4936445673..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/Union.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import java.util.List; - -import com.mysema.commons.lang.CloseableIterator; -import com.mysema.query.types.Expression; -import com.mysema.query.types.OrderSpecifier; -import com.mysema.query.types.Predicate; - -/** - * Union defines an interface for Union queries - * - * @author tiwe - * - * @param return type of projection - */ -public interface Union { - - /** - * Get the projection as a typed List - * - * @return - */ - List list(); - - - /** - * Get the projection as a typed Iterator - * - * @return - */ - CloseableIterator iterate(); - - /** - * Defines the grouping/aggregation expressions - * - * @param o - * @return - */ - Union groupBy(Expression... o); - - /** - * Defines the filters for aggregation - * - * @param o - * @return - */ - Union having(Predicate... o); - - - /** - * Define the ordering of the query results - * - * @param o - * @return - */ - Union orderBy(OrderSpecifier... o); - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/UnionImpl.java b/querydsl-sql/src/main/java/com/mysema/query/sql/UnionImpl.java deleted file mode 100644 index 4885c9fef3..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/UnionImpl.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import java.util.List; - -import com.mysema.commons.lang.CloseableIterator; -import com.mysema.query.Projectable; -import com.mysema.query.Query; -import com.mysema.query.types.Expression; -import com.mysema.query.types.OrderSpecifier; -import com.mysema.query.types.Predicate; - -/** - * Default implementation of the Union interface - * - * @author tiwe - * - * @param - * @param - */ -public class UnionImpl implements Union { - - private final Q query; - - private final Expression[] projection; - - public UnionImpl(Q query, List> projection) { - this.query = query; - this.projection = projection.toArray(new Expression[projection.size()]); - } - - @SuppressWarnings("unchecked") - @Override - public List list() { - if (projection.length == 1) { - return (List) query.list(projection[0]); - } else { - return (List) query.list(projection); - } - } - - @SuppressWarnings("unchecked") - @Override - public CloseableIterator iterate() { - if (projection.length == 1) { - return (CloseableIterator) query.iterate(projection[0]); - } else { - return (CloseableIterator) query.iterate(projection); - } - } - - @Override - public Union groupBy(Expression... o) { - query.groupBy(o); - return this; - } - - @Override - public Union having(Predicate... o) { - query.having(o); - return this; - } - - - @SuppressWarnings("unchecked") - @Override - public Union orderBy(OrderSpecifier... o) { - query.orderBy(o); - return this; - } - - @Override - public String toString() { - return query.toString(); - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/UnionUtils.java b/querydsl-sql/src/main/java/com/mysema/query/sql/UnionUtils.java deleted file mode 100644 index af30c610cb..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/UnionUtils.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2012, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import com.mysema.query.types.Expression; -import com.mysema.query.types.ExpressionUtils; -import com.mysema.query.types.OperationImpl; -import com.mysema.query.types.Operator; -import com.mysema.query.types.Path; -import com.mysema.query.types.SubQueryExpression; - -/** - * UnionUtils provides static utility methods for Union handling - * - * @author tiwe - * - */ -public final class UnionUtils { - - public static Expression union(SubQueryExpression[] union, boolean unionAll) { - final Operator operator = unionAll ? SQLOps.UNION_ALL : SQLOps.UNION; - Expression rv = union[0]; - for (int i = 1; i < union.length; i++) { - rv = OperationImpl.create(rv.getType(), operator, rv, union[i]); - } - return rv; - } - - public static Expression union(SubQueryExpression[] union, Path alias, - boolean unionAll) { - final Expression rv = union(union, unionAll); - return ExpressionUtils.as((Expression)rv, alias); - } - - private UnionUtils() {} - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/WindowFirstLast.java b/querydsl-sql/src/main/java/com/mysema/query/sql/WindowFirstLast.java deleted file mode 100644 index 3ecfa49299..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/WindowFirstLast.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import com.google.common.collect.ImmutableList; -import com.mysema.query.types.Expression; -import com.mysema.query.types.MutableExpressionBase; -import com.mysema.query.types.OrderSpecifier; -import com.mysema.query.types.TemplateFactory; -import com.mysema.query.types.Visitor; -import com.mysema.query.types.expr.ComparableExpressionBase; -import com.mysema.query.types.expr.SimpleExpression; -import com.mysema.query.types.template.SimpleTemplate; - -/** - * @author tiwe - * - * @param - */ -public class WindowFirstLast extends MutableExpressionBase { - - private static final long serialVersionUID = 4107262569593794721L; - - private static final String ORDER_BY = "order by "; - - private final List> orderBy = new ArrayList>(); - - private volatile SimpleExpression value; - - private final Expression target; - - private final boolean first; - - public WindowFirstLast(WindowOver target, boolean first) { - super(target.getType()); - this.target = target; - this.first = first; - } - - @Override - public R accept(Visitor v, C context) { - return getValue().accept(v, context); - } - - public WindowFirstLast orderBy(ComparableExpressionBase orderBy) { - value = null; - this.orderBy.add(orderBy.asc()); - return this; - } - - public WindowFirstLast orderBy(ComparableExpressionBase... orderBy) { - value = null; - for (ComparableExpressionBase e : orderBy) { - this.orderBy.add(e.asc()); - } - return this; - } - - public WindowFirstLast orderBy(OrderSpecifier orderBy) { - value = null; - this.orderBy.add(orderBy); - return this; - } - - public WindowFirstLast orderBy(OrderSpecifier... orderBy) { - value = null; - this.orderBy.addAll(Arrays.asList(orderBy)); - return this; - } - - SimpleExpression getValue() { - if (value == null) { - if (orderBy.isEmpty()) { - // TODO this check should be static - throw new IllegalStateException("No order by arguments given"); - } - ImmutableList.Builder> args = ImmutableList.builder(); - StringBuilder builder = new StringBuilder(); - builder.append("{0} keep (dense_rank "); - args.add(target); - builder.append(first ? "first " : "last "); - builder.append(ORDER_BY); - boolean first = true; - int size = 1; - for (OrderSpecifier expr : orderBy) { - if (!first) { - builder.append(", "); - } - builder.append("{" + size + "}"); - if (!expr.isAscending()) { - builder.append(" desc"); - } - args.add(expr.getTarget()); - size++; - first = false; - } - builder.append(")"); - value = new SimpleTemplate( - target.getType(), - TemplateFactory.DEFAULT.create(builder.toString()), - args.build()); - } - return value; - } - - public WindowFunction over() { - return new WindowFunction(getValue()); - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/WindowFunction.java b/querydsl-sql/src/main/java/com/mysema/query/sql/WindowFunction.java deleted file mode 100644 index f8894d5208..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/WindowFunction.java +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import com.google.common.collect.ImmutableList; -import com.mysema.query.types.Expression; -import com.mysema.query.types.MutableExpressionBase; -import com.mysema.query.types.Ops; -import com.mysema.query.types.OrderSpecifier; -import com.mysema.query.types.PathImpl; -import com.mysema.query.types.TemplateFactory; -import com.mysema.query.types.Visitor; -import com.mysema.query.types.expr.BooleanExpression; -import com.mysema.query.types.expr.ComparableExpressionBase; -import com.mysema.query.types.expr.SimpleExpression; -import com.mysema.query.types.expr.SimpleOperation; -import com.mysema.query.types.template.SimpleTemplate; - -/** - * @author tiwe - */ -public class WindowFunction extends MutableExpressionBase { - - private static final String ORDER_BY = "order by "; - - private static final String PARTITION_BY = "partition by "; - - private static final long serialVersionUID = -4130672293308756779L; - - private final List> orderBy = new ArrayList>(); - - private final List> partitionBy = new ArrayList>(); - - private final Expression target; - - private volatile SimpleExpression value; - - private String rowsOrRange; - - private List> rowsOrRangeArgs; - - public WindowFunction(Expression expr) { - super(expr.getType()); - this.target = expr; - } - - public SimpleExpression getValue() { - if (value == null) { - int size = 0; - ImmutableList.Builder> args = ImmutableList.builder(); - StringBuilder builder = new StringBuilder(); - builder.append("{0} over ("); - args.add(target); - size++; - if (!partitionBy.isEmpty()) { - builder.append(PARTITION_BY); - boolean first = true; - for (Expression expr : partitionBy) { - if (!first) { - builder.append(", "); - } - builder.append("{" + size + "}"); - args.add(expr); - size++; - first = false; - } - - } - if (!orderBy.isEmpty()) { - if (!partitionBy.isEmpty()) { - builder.append(" "); - } - builder.append(ORDER_BY); - boolean first = true; - for (OrderSpecifier expr : orderBy) { - if (!first) { - builder.append(", "); - } - builder.append("{" + size + "}"); - if (!expr.isAscending()) { - builder.append(" desc"); - } - args.add(expr.getTarget()); - size++; - first = false; - } - } - if (rowsOrRange != null) { - builder.append(rowsOrRange); - args.addAll(rowsOrRangeArgs); - size += rowsOrRangeArgs.size(); - } - builder.append(")"); - value = new SimpleTemplate( - target.getType(), - TemplateFactory.DEFAULT.create(builder.toString()), - args.build()); - } - return value; - } - - @SuppressWarnings("unchecked") - public SimpleExpression as(Expression alias) { - return SimpleOperation.create((Class)getType(),Ops.ALIAS, this, alias); - } - - public SimpleExpression as(String alias) { - return SimpleOperation.create((Class)getType(),Ops.ALIAS, this, new PathImpl(getType(), alias)); - } - - @Override - public R accept(Visitor v, C context) { - return getValue().accept(v, context); - } - - @Override - public boolean equals(Object o) { - if (o == this) { - return true; - } else if (o instanceof WindowFunction) { - WindowFunction so = (WindowFunction)o; - return so.target.equals(target) - && so.partitionBy.equals(partitionBy) - && so.orderBy.equals(orderBy); - } else { - return false; - } - } - - public BooleanExpression eq(Expression expr) { - return getValue().eq(expr); - } - - public BooleanExpression eq(A arg) { - return getValue().eq(arg); - } - - public BooleanExpression ne(Expression expr) { - return getValue().ne(expr); - } - - public BooleanExpression ne(A arg) { - return getValue().ne(arg); - } - - public WindowFunction orderBy(ComparableExpressionBase orderBy) { - value = null; - this.orderBy.add(orderBy.asc()); - return this; - } - - public WindowFunction orderBy(ComparableExpressionBase... orderBy) { - value = null; - for (ComparableExpressionBase e : orderBy) { - this.orderBy.add(e.asc()); - } - return this; - } - - public WindowFunction orderBy(OrderSpecifier orderBy) { - value = null; - this.orderBy.add(orderBy); - return this; - } - - public WindowFunction orderBy(OrderSpecifier... orderBy) { - value = null; - this.orderBy.addAll(Arrays.asList(orderBy)); - return this; - } - - public WindowFunction partitionBy(Expression partitionBy) { - value = null; - this.partitionBy.add(partitionBy); - return this; - } - - public WindowFunction partitionBy(Expression... partitionBy) { - value = null; - this.partitionBy.addAll(Arrays.asList(partitionBy)); - return this; - } - - WindowFunction withRowsOrRange(String s, List> args) { - rowsOrRange = s; - rowsOrRangeArgs = args; - return this; - } - - public WindowRows rows() { - value = null; - int offset = orderBy.size() + partitionBy.size() + 1; - return new WindowRows(this, " rows", offset); - } - - public WindowRows range() { - value = null; - int offset = orderBy.size() + partitionBy.size() + 1; - return new WindowRows(this, " range", offset); - } -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/WindowOver.java b/querydsl-sql/src/main/java/com/mysema/query/sql/WindowOver.java deleted file mode 100644 index a2da9f8edd..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/WindowOver.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import com.google.common.collect.ImmutableList; -import com.mysema.query.types.Expression; -import com.mysema.query.types.Operator; -import com.mysema.query.types.expr.SimpleOperation; - -/** - * WindowOver is the first part of a WindowFunction construction - * - * @author tiwe - * - * @param - */ -public class WindowOver extends SimpleOperation { - - private static final long serialVersionUID = 464583892898579544L; - - public WindowOver(Class type, Operator op) { - super(type, op, ImmutableList.>of()); - } - - public WindowOver(Class type, Operator op, Expression arg) { - super(type, op, ImmutableList.>of(arg)); - } - - public WindowOver(Class type, Operator op, Expression arg1, Expression arg2) { - super(type, op, ImmutableList.>of(arg1, arg2)); - } - - /** - * @return - */ - public WindowFirstLast keepFirst() { - return new WindowFirstLast(this, true); - } - - /** - * @return - */ - public WindowFirstLast keepLast() { - return new WindowFirstLast(this, false); - } - - /** - * @return - */ - public WindowFunction over() { - return new WindowFunction(this); - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/WithBuilder.java b/querydsl-sql/src/main/java/com/mysema/query/sql/WithBuilder.java deleted file mode 100644 index c54667c207..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/WithBuilder.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2013, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import com.mysema.query.QueryFlag; -import com.mysema.query.support.QueryMixin; -import com.mysema.query.types.Expression; -import com.mysema.query.types.OperationImpl; - -/** - * @author tiwe - * - * @param - */ -public class WithBuilder { - - private final QueryMixin queryMixin; - - private final Expression alias; - - public WithBuilder(QueryMixin queryMixin, Expression alias) { - this.queryMixin = queryMixin; - this.alias = alias; - } - - public R as(Expression expr) { - Expression flag = OperationImpl.create(alias.getType(), SQLOps.WITH_ALIAS, alias, expr); - return queryMixin.addFlag(new QueryFlag(QueryFlag.Position.WITH, flag)); - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/WithinGroup.java b/querydsl-sql/src/main/java/com/mysema/query/sql/WithinGroup.java deleted file mode 100644 index 6894c02fff..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/WithinGroup.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright 2013, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import java.util.ArrayList; -import java.util.List; - -import com.google.common.collect.ImmutableList; -import com.mysema.query.types.Expression; -import com.mysema.query.types.ExpressionUtils; -import com.mysema.query.types.MutableExpressionBase; -import com.mysema.query.types.Operator; -import com.mysema.query.types.OrderSpecifier; -import com.mysema.query.types.TemplateFactory; -import com.mysema.query.types.Visitor; -import com.mysema.query.types.expr.ComparableExpressionBase; -import com.mysema.query.types.expr.SimpleExpression; -import com.mysema.query.types.expr.SimpleOperation; -import com.mysema.query.types.template.SimpleTemplate; - -/** - * @author tiwe - * - * @param - */ -public class WithinGroup extends SimpleOperation { - - private static final long serialVersionUID = 464583892898579544L; - - private static Expression merge(Expression... args) { - if (args.length == 1) { - return args[0]; - } else { - return ExpressionUtils.list(Object.class, args); - } - } - - public class OrderBy extends MutableExpressionBase { - - private static final long serialVersionUID = -4936481493030913621L; - - private static final String ORDER_BY = "order by "; - - private volatile SimpleExpression value; - - private final List> orderBy = new ArrayList>(); - - public OrderBy() { - super(WithinGroup.this.getType()); - } - - public SimpleExpression getValue() { - if (value == null) { - int size = 0; - ImmutableList.Builder> args = ImmutableList.builder(); - StringBuilder builder = new StringBuilder(); - builder.append("{0} within group ("); - args.add(WithinGroup.this); - size++; - if (!orderBy.isEmpty()) { - builder.append(ORDER_BY); - boolean first = true; - for (OrderSpecifier expr : orderBy) { - if (!first) { - builder.append(", "); - } - builder.append("{" + size + "}"); - if (!expr.isAscending()) { - builder.append(" desc"); - } - args.add(expr.getTarget()); - size++; - first = false; - } - } - builder.append(")"); - value = new SimpleTemplate( - WithinGroup.this.getType(), - TemplateFactory.DEFAULT.create(builder.toString()), - args.build()); - } - return value; - } - - @Override - public R accept(Visitor v, C context) { - return getValue().accept(v, context); - } - - public OrderBy orderBy(ComparableExpressionBase orderBy) { - value = null; - this.orderBy.add(orderBy.asc()); - return this; - } - - public OrderBy orderBy(ComparableExpressionBase... orderBy) { - value = null; - for (ComparableExpressionBase e : orderBy) { - this.orderBy.add(e.asc()); - } - return this; - } - } - - public WithinGroup(Class type, Operator op) { - super(type, op, ImmutableList.>of()); - } - - public WithinGroup(Class type, Operator op, Expression arg) { - super(type, op, ImmutableList.>of(arg)); - } - - public WithinGroup(Class type, Operator op, Expression arg1, Expression arg2) { - super(type, op, ImmutableList.>of(arg1, arg2)); - } - - public WithinGroup(Class type, Operator op, Expression... args) { - super(type, op, merge(args)); - } - - /** - * @return - */ - public OrderBy withinGroup() { - return new OrderBy(); - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/dml/AbstractSQLClause.java b/querydsl-sql/src/main/java/com/mysema/query/sql/dml/AbstractSQLClause.java deleted file mode 100644 index 771042b6e3..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/dml/AbstractSQLClause.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql.dml; - -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.List; -import java.util.Map; - -import com.google.common.collect.ImmutableList; -import com.mysema.query.QueryMetadata; -import com.mysema.query.dml.DMLClause; -import com.mysema.query.sql.Configuration; -import com.mysema.query.sql.SQLBindings; -import com.mysema.query.sql.SQLListener; -import com.mysema.query.sql.SQLListeners; -import com.mysema.query.sql.SQLSerializer; -import com.mysema.query.types.ParamExpression; -import com.mysema.query.types.ParamNotSetException; -import com.mysema.query.types.Path; - -/** - * AbstractSQLClause is a superclass for SQL based DMLClause implementations - * - * @author tiwe - * - */ -public abstract class AbstractSQLClause> implements DMLClause { - - protected final Configuration configuration; - - protected final SQLListeners listeners; - - protected boolean useLiterals; - - /** - * @param configuration - */ - public AbstractSQLClause(Configuration configuration) { - this.configuration = configuration; - this.listeners = new SQLListeners(configuration.getListeners()); - this.useLiterals = configuration.getUseLiterals(); - } - - /** - * @param listener - */ - public void addListener(SQLListener listener) { - listeners.add(listener); - } - - protected SQLBindings createBindings(QueryMetadata metadata, SQLSerializer serializer) { - String queryString = serializer.toString(); - ImmutableList.Builder args = ImmutableList.builder(); - Map, Object> params = metadata.getParams(); - for (Object o : serializer.getConstants()) { - if (o instanceof ParamExpression) { - if (!params.containsKey(o)) { - throw new ParamNotSetException((ParamExpression) o); - } - o = metadata.getParams().get(o); - } - args.add(o); - } - return new SQLBindings(queryString, args.build()); - } - - protected SQLSerializer createSerializer() { - SQLSerializer serializer = new SQLSerializer(configuration, true); - serializer.setUseLiterals(useLiterals); - return serializer; - } - - /** - * Get the SQL string and bindings - * - * @return - */ - public abstract List getSQL(); - - /** - * Set the parameters to the given PreparedStatement - * - * @param stmt preparedStatement to be populated - * @param objects list of constants - * @param constantPaths list of paths related to the constants - * @param params map of param to value for param resolving - */ - protected void setParameters(PreparedStatement stmt, List objects, - List> constantPaths, Map, ?> params) { - if (objects.size() != constantPaths.size()) { - throw new IllegalArgumentException("Expected " + objects.size() + " paths, " + - "but got " + constantPaths.size()); - } - for (int i = 0; i < objects.size(); i++) { - Object o = objects.get(i); - try { - if (o instanceof ParamExpression) { - if (!params.containsKey(o)) { - throw new ParamNotSetException((ParamExpression) o); - } - o = params.get(o); - } - configuration.set(stmt, constantPaths.get(i), i+1, o); - } catch (SQLException e) { - throw configuration.translate(e); - } - } - } - - protected long executeBatch(PreparedStatement stmt) throws SQLException { - if (configuration.getTemplates().isBatchCountViaGetUpdateCount()) { - stmt.executeBatch(); - return stmt.getUpdateCount(); - } else { - long rv = 0; - for (int i : stmt.executeBatch()) { - rv += i; - } - return rv; - } - } - - protected void close(Statement stmt) { - try { - stmt.close(); - } catch (SQLException e) { - throw configuration.translate(e); - } - } - - protected void close(ResultSet rs) { - try { - rs.close(); - } catch (SQLException e) { - throw configuration.translate(e); - } - } - - public void setUseLiterals(boolean useLiterals) { - this.useLiterals = useLiterals; - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/dml/BeanMapper.java b/querydsl-sql/src/main/java/com/mysema/query/sql/dml/BeanMapper.java deleted file mode 100644 index c39c2e01cf..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/dml/BeanMapper.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql.dml; - -import java.util.HashMap; -import java.util.Map; - -import com.mysema.query.sql.RelationalPath; -import com.mysema.query.sql.types.Null; -import com.mysema.query.types.Path; -import com.mysema.util.BeanMap; - -/** - * Creates the mapping by inspecting object via bean inspection. - * Given bean doesn't need to have @Column metadata, but the fields need to have the same - * name as in the given relational path. - * - * @author tiwe - * - */ -public class BeanMapper extends AbstractMapper { - - public static final BeanMapper DEFAULT = new BeanMapper(false); - - public static final BeanMapper WITH_NULL_BINDINGS = new BeanMapper(true); - - private final boolean withNullBindings; - - public BeanMapper() { - this(false); - } - - public BeanMapper(boolean withNullBindings) { - this.withNullBindings = withNullBindings; - } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - @Override - public Map, Object> createMap(RelationalPath entity, Object bean) { - Map, Object> values = new HashMap, Object>(); - Map map = new BeanMap(bean); - Map> columns = getColumns(entity); - for (Map.Entry entry : map.entrySet()) { - String property = entry.getKey().toString(); - if (!property.equals("class") && columns.containsKey(property)) { - Path path = columns.get(property); - if (entry.getValue() != null) { - values.put(path, entry.getValue()); - } else if (withNullBindings && !isPrimaryKeyColumn(entity, path)) { - values.put(path, Null.DEFAULT); - } - } - } - return values; - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/dml/DefaultMapper.java b/querydsl-sql/src/main/java/com/mysema/query/sql/dml/DefaultMapper.java deleted file mode 100644 index 71871f66d5..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/dml/DefaultMapper.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql.dml; - -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.util.HashMap; -import java.util.Map; - -import com.mysema.query.QueryException; -import com.mysema.query.sql.RelationalPath; -import com.mysema.query.sql.types.Null; -import com.mysema.query.types.Path; -import com.mysema.util.ReflectionUtils; - -/** - * Creates the mapping by inspecting the RelationalPath and Object via reflection. - * Given bean doesn't need to have @Column metadata, but the fields need to have the same - * name as in the given relational path. - * - * @author tiwe - * - */ -public class DefaultMapper extends AbstractMapper { - - public static final DefaultMapper DEFAULT = new DefaultMapper(false); - - public static final DefaultMapper WITH_NULL_BINDINGS = new DefaultMapper(true); - - private final boolean withNullBindings; - - public DefaultMapper() { - this(false); - } - - public DefaultMapper(boolean withNullBindings) { - this.withNullBindings = withNullBindings; - } - - @Override - public Map, Object> createMap(RelationalPath entity, Object bean) { - try { - Map, Object> values = new HashMap, Object>(); - Class beanClass = bean.getClass(); - Map> columns = getColumns(entity); - for (Field beanField : ReflectionUtils.getFields(beanClass)) { - if (!Modifier.isStatic(beanField.getModifiers()) && columns.containsKey(beanField.getName())) { - @SuppressWarnings("rawtypes") - Path path = columns.get(beanField.getName()); - beanField.setAccessible(true); - Object propertyValue = beanField.get(bean); - if (propertyValue != null) { - values.put(path, propertyValue); - } else if (withNullBindings && !isPrimaryKeyColumn(entity, path)) { - values.put(path, Null.DEFAULT); - } - } - } - return values; - } catch (IllegalAccessException e) { - throw new QueryException(e); - } - } - - - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/dml/Mapper.java b/querydsl-sql/src/main/java/com/mysema/query/sql/dml/Mapper.java deleted file mode 100644 index a0e6a6b858..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/dml/Mapper.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql.dml; - -import java.util.Map; - -import com.mysema.query.sql.RelationalPath; -import com.mysema.query.types.Path; - -/** - * Create a Map of updates for a given domain object - * - * @author tiwe - * - */ -public interface Mapper { - - /** - * @param path - * @param object - * @return - */ - Map, Object> createMap(RelationalPath path, T object); - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/dml/SQLDeleteClause.java b/querydsl-sql/src/main/java/com/mysema/query/sql/dml/SQLDeleteClause.java deleted file mode 100644 index 9376735957..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/dml/SQLDeleteClause.java +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql.dml; - -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.List; - -import javax.annotation.Nonnegative; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.common.collect.ImmutableList; -import com.mysema.query.DefaultQueryMetadata; -import com.mysema.query.JoinType; -import com.mysema.query.QueryFlag; -import com.mysema.query.QueryFlag.Position; -import com.mysema.query.QueryMetadata; -import com.mysema.query.QueryModifiers; -import com.mysema.query.dml.DeleteClause; -import com.mysema.query.sql.Configuration; -import com.mysema.query.sql.RelationalPath; -import com.mysema.query.sql.SQLBindings; -import com.mysema.query.sql.SQLSerializer; -import com.mysema.query.sql.SQLTemplates; -import com.mysema.query.types.Expression; -import com.mysema.query.types.Predicate; -import com.mysema.query.types.ValidatingVisitor; - -/** - * SQLDeleteClause defines a DELETE clause - * - * @author tiwe - * - */ -public class SQLDeleteClause extends AbstractSQLClause implements DeleteClause { - - private static final Logger logger = LoggerFactory.getLogger(SQLDeleteClause.class); - - private static final ValidatingVisitor validatingVisitor = new ValidatingVisitor("Undeclared path '%s'. " + - "A delete operation can only reference a single table. " + - "Consider this alternative: DELETE ... WHERE EXISTS (subquery)"); - - private final Connection connection; - - private final RelationalPath entity; - - private final List batches = new ArrayList(); - - private DefaultQueryMetadata metadata = new DefaultQueryMetadata(); - - private transient String queryString; - - private transient List constants; - - public SQLDeleteClause(Connection connection, SQLTemplates templates, RelationalPath entity) { - this(connection, new Configuration(templates), entity); - } - - public SQLDeleteClause(Connection connection, Configuration configuration, RelationalPath entity) { - super(configuration); - this.connection = connection; - this.entity = entity; - metadata.addJoin(JoinType.DEFAULT, entity); - metadata.setValidatingVisitor(validatingVisitor); - } - - /** - * Add the given String literal at the given position as a query flag - * - * @param position - * @param flag - * @return - */ - public SQLDeleteClause addFlag(Position position, String flag) { - metadata.addFlag(new QueryFlag(position, flag)); - return this; - } - - /** - * Add the given Expression at the given position as a query flag - * - * @param position - * @param flag - * @return - */ - public SQLDeleteClause addFlag(Position position, Expression flag) { - metadata.addFlag(new QueryFlag(position, flag)); - return this; - } - - /** - * Add current state of bindings as a batch item - * - * @return - */ - public SQLDeleteClause addBatch() { - batches.add(metadata); - metadata = new DefaultQueryMetadata(); - metadata.addJoin(JoinType.DEFAULT, entity); - metadata.setValidatingVisitor(validatingVisitor); - return this; - } - - private PreparedStatement createStatement() throws SQLException{ - PreparedStatement stmt; - if (batches.isEmpty()) { - SQLSerializer serializer = createSerializer(); - serializer.serializeDelete(metadata, entity); - queryString = serializer.toString(); - constants = serializer.getConstants(); - logger.debug(queryString); - stmt = connection.prepareStatement(queryString); - setParameters(stmt, serializer.getConstants(), serializer.getConstantPaths(), metadata.getParams()); - } else { - SQLSerializer serializer = createSerializer(); - serializer.serializeDelete(batches.get(0), entity); - queryString = serializer.toString(); - constants = serializer.getConstants(); - logger.debug(queryString); - - // add first batch - stmt = connection.prepareStatement(queryString); - setParameters(stmt, serializer.getConstants(), serializer.getConstantPaths(), metadata.getParams()); - stmt.addBatch(); - - // add other batches - for (int i = 1; i < batches.size(); i++) { - serializer = createSerializer(); - serializer.serializeDelete(batches.get(i), entity); - setParameters(stmt, serializer.getConstants(), serializer.getConstantPaths(), metadata.getParams()); - stmt.addBatch(); - } - } - return stmt; - } - - @Override - public long execute() { - PreparedStatement stmt = null; - try { - stmt = createStatement(); - if (batches.isEmpty()) { - listeners.notifyDelete(entity, metadata); - return stmt.executeUpdate(); - } else { - listeners.notifyDeletes(entity, batches); - return executeBatch(stmt); - } - } catch (SQLException e) { - throw configuration.translate(queryString, constants, e); - } finally { - if (stmt != null) { - close(stmt); - } - } - } - - @Override - public List getSQL() { - if (batches.isEmpty()) { - SQLSerializer serializer = createSerializer(); - serializer.serializeDelete(metadata, entity); - return ImmutableList.of(createBindings(metadata, serializer)); - } else { - ImmutableList.Builder builder = ImmutableList.builder(); - for (QueryMetadata metadata : batches) { - SQLSerializer serializer = createSerializer(); - serializer.serializeDelete(metadata, entity); - builder.add(createBindings(metadata, serializer)); - } - return builder.build(); - } - } - - public SQLDeleteClause where(Predicate p) { - metadata.addWhere(p); - return this; - } - - @Override - public SQLDeleteClause where(Predicate... o) { - for (Predicate p : o) { - metadata.addWhere(p); - } - return this; - } - - public SQLDeleteClause limit(@Nonnegative long limit) { - metadata.setModifiers(QueryModifiers.limit(limit)); - return this; - } - - @Override - public String toString() { - SQLSerializer serializer = createSerializer(); - serializer.serializeDelete(metadata, entity); - return serializer.toString(); - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/dml/SQLInsertClause.java b/querydsl-sql/src/main/java/com/mysema/query/sql/dml/SQLInsertClause.java deleted file mode 100644 index ece68342b7..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/dml/SQLInsertClause.java +++ /dev/null @@ -1,451 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql.dml; - -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Map; - -import javax.annotation.Nullable; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.common.collect.ImmutableList; -import com.mysema.query.DefaultQueryMetadata; -import com.mysema.query.JoinType; -import com.mysema.query.QueryFlag; -import com.mysema.query.QueryFlag.Position; -import com.mysema.query.QueryMetadata; -import com.mysema.query.dml.InsertClause; -import com.mysema.query.sql.AbstractSQLSubQuery; -import com.mysema.query.sql.ColumnMetadata; -import com.mysema.query.sql.Configuration; -import com.mysema.query.sql.RelationalPath; -import com.mysema.query.sql.SQLBindings; -import com.mysema.query.sql.SQLSerializer; -import com.mysema.query.sql.SQLTemplates; -import com.mysema.query.sql.types.Null; -import com.mysema.query.types.ConstantImpl; -import com.mysema.query.types.Expression; -import com.mysema.query.types.ParamExpression; -import com.mysema.query.types.Path; -import com.mysema.query.types.SubQueryExpression; -import com.mysema.util.ResultSetAdapter; - -/** - * SQLInsertClause defines an INSERT INTO clause - * - * @author tiwe - * - */ -public class SQLInsertClause extends AbstractSQLClause implements - InsertClause { - - private static final Logger logger = LoggerFactory.getLogger(SQLInsertClause.class); - - private final Connection connection; - - private final RelationalPath entity; - - private final QueryMetadata metadata = new DefaultQueryMetadata(); - - @Nullable - private SubQueryExpression subQuery; - - @Nullable - private AbstractSQLSubQuery subQueryBuilder; - - private final List batches = new ArrayList(); - - private final List> columns = new ArrayList>(); - - private final List> values = new ArrayList>(); - - private transient String queryString; - - private transient List constants; - - public SQLInsertClause(Connection connection, SQLTemplates templates, RelationalPath entity) { - this(connection, new Configuration(templates), entity); - } - - public SQLInsertClause(Connection connection, SQLTemplates templates, RelationalPath entity, - AbstractSQLSubQuery subQuery) { - this(connection, new Configuration(templates), entity); - this.subQueryBuilder = subQuery; - } - - public SQLInsertClause(Connection connection, Configuration configuration, - RelationalPath entity, AbstractSQLSubQuery subQuery) { - this(connection, configuration, entity); - this.subQueryBuilder = subQuery; - } - - public SQLInsertClause(Connection connection, Configuration configuration, - RelationalPath entity) { - super(configuration); - this.connection = connection; - this.entity = entity; - metadata.addJoin(JoinType.DEFAULT, entity); - } - - /** - * Add the given String literal at the given position as a query flag - * - * @param position - * @param flag - * @return - */ - public SQLInsertClause addFlag(Position position, String flag) { - metadata.addFlag(new QueryFlag(position, flag)); - return this; - } - - /** - * Add the given Expression at the given position as a query flag - * - * @param position - * @param flag - * @return - */ - public SQLInsertClause addFlag(Position position, Expression flag) { - metadata.addFlag(new QueryFlag(position, flag)); - return this; - } - - /** - * Add the current state of bindings as a batch item - * - * @return - */ - public SQLInsertClause addBatch() { - if (subQueryBuilder != null) { - subQuery = subQueryBuilder.list(values.toArray(new Expression[values.size()])); - values.clear(); - } - batches.add(new SQLInsertBatch(columns, values, subQuery)); - columns.clear(); - values.clear(); - subQuery = null; - return this; - } - - @Override - public SQLInsertClause columns(Path... columns) { - this.columns.addAll(Arrays.asList(columns)); - return this; - } - - /** - * Execute the clause and return the generated key with the type of the - * given path. If no rows were created, null is returned, otherwise the key - * of the first row is returned. - * - * @param - * @param path - * @return - */ - @SuppressWarnings("unchecked") - @Nullable - public T executeWithKey(Path path) { - return executeWithKey((Class) path.getType(), path); - } - - /** - * Execute the clause and return the generated key cast to the given type. - * If no rows were created, null is returned, otherwise the key of the first - * row is returned. - * - * @param - * @param type - * @return - */ - public T executeWithKey(Class type) { - return executeWithKey(type, null); - } - - private T executeWithKey(Class type, @Nullable Path path) { - ResultSet rs = executeWithKeys(); - try { - if (rs.next()) { - return configuration.get(rs, path, 1, type); - } else { - return null; - } - } catch (SQLException e) { - throw configuration.translate(e); - } finally { - close(rs); - } - } - - /** - * Execute the clause and return the generated key with the type of the - * given path. If no rows were created, or the referenced column is not a - * generated key, null is returned. Otherwise, the key of the first row is - * returned. - * - * @param - * @param path - * @return - */ - @SuppressWarnings("unchecked") - public List executeWithKeys(Path path) { - return executeWithKeys((Class) path.getType(), path); - } - - public List executeWithKeys(Class type) { - return executeWithKeys(type, null); - } - - private List executeWithKeys(Class type, @Nullable Path path) { - ResultSet rs = executeWithKeys(); - try { - List rv = new ArrayList(); - while (rs.next()) { - rv.add(configuration.get(rs, path, 1, type)); - } - return rv; - } catch (SQLException e) { - throw configuration.translate(e); - } finally { - close(rs); - } - } - - private PreparedStatement createStatement(boolean withKeys) throws SQLException { - SQLSerializer serializer = createSerializer(); - if (subQueryBuilder != null) { - subQuery = subQueryBuilder.list(values.toArray(new Expression[values.size()])); - values.clear(); - } - PreparedStatement stmt = null; - if (batches.isEmpty()) { - serializer.serializeInsert(metadata, entity, columns, values, subQuery); - stmt = prepareStatementAndSetParameters(serializer, withKeys); - } else { - serializer.serializeInsert(metadata, entity, batches.get(0).getColumns(), batches - .get(0).getValues(), batches.get(0).getSubQuery()); - stmt = prepareStatementAndSetParameters(serializer, withKeys); - - // add first batch - stmt.addBatch(); - - // add other batches - for (int i = 1; i < batches.size(); i++) { - SQLInsertBatch batch = batches.get(i); - serializer = createSerializer(); - serializer.serializeInsert(metadata, entity, batch.getColumns(), - batch.getValues(), batch.getSubQuery()); - setParameters(stmt, serializer.getConstants(), serializer.getConstantPaths(), - metadata.getParams()); - stmt.addBatch(); - } - } - return stmt; - } - - private PreparedStatement prepareStatementAndSetParameters(SQLSerializer serializer, - boolean withKeys) throws SQLException { - queryString = serializer.toString(); - constants = serializer.getConstants(); - logger.debug(queryString); - PreparedStatement stmt; - if (withKeys) { - if (entity.getPrimaryKey() != null) { - String[] target = new String[entity.getPrimaryKey().getLocalColumns().size()]; - for (int i = 0; i < target.length; i++) { - Path path = entity.getPrimaryKey().getLocalColumns().get(i); - String column = ColumnMetadata.getName(path); - target[i] = column; - } - stmt = connection.prepareStatement(queryString, target); - } else { - stmt = connection.prepareStatement(queryString, Statement.RETURN_GENERATED_KEYS); - } - } else { - stmt = connection.prepareStatement(queryString); - } - setParameters(stmt, serializer.getConstants(), serializer.getConstantPaths(), - metadata.getParams()); - return stmt; - } - - /** - * Execute the clause and return the generated keys as a ResultSet - * - * @return - */ - public ResultSet executeWithKeys() { - try { - final PreparedStatement stmt = createStatement(true); - if (batches.isEmpty()) { - listeners.notifyInsert(entity, metadata, columns, values, subQuery); - stmt.executeUpdate(); - } else { - listeners.notifyInserts(entity, metadata, batches); - stmt.executeBatch(); - } - ResultSet rs = stmt.getGeneratedKeys(); - return new ResultSetAdapter(rs) { - @Override - public void close() throws SQLException { - try { - super.close(); - } finally { - stmt.close(); - } - } - }; - } catch (SQLException e) { - throw configuration.translate(queryString, constants, e); - } - } - - @Override - public long execute() { - PreparedStatement stmt = null; - try { - stmt = createStatement(false); - if (batches.isEmpty()) { - listeners.notifyInsert(entity, metadata, columns, values, subQuery); - return stmt.executeUpdate(); - } else { - listeners.notifyInserts(entity, metadata, batches); - return executeBatch(stmt); - } - } catch (SQLException e) { - throw configuration.translate(queryString, constants, e); - } finally { - if (stmt != null) { - close(stmt); - } - } - } - - @Override - public List getSQL() { - if (batches.isEmpty()) { - SQLSerializer serializer = createSerializer(); - serializer.serializeInsert(metadata, entity, columns, values, subQuery); - return ImmutableList.of(createBindings(metadata, serializer)); - } else { - ImmutableList.Builder builder = ImmutableList.builder(); - for (SQLInsertBatch batch : batches) { - SQLSerializer serializer = createSerializer(); - serializer.serializeInsert(metadata, entity, batch.getColumns(), batch.getValues(), batch.getSubQuery()); - builder.add(createBindings(metadata, serializer)); - } - return builder.build(); - } - } - - @Override - public SQLInsertClause select(SubQueryExpression sq) { - subQuery = sq; - for (Map.Entry, Object> entry : sq.getMetadata().getParams().entrySet()) { - metadata.setParam((ParamExpression) entry.getKey(), entry.getValue()); - } - return this; - } - - @Override - public SQLInsertClause set(Path path, T value) { - columns.add(path); - if (value instanceof Expression) { - values.add((Expression) value); - } else if (value != null) { - values.add(ConstantImpl.create(value)); - } else { - values.add(Null.CONSTANT); - } - return this; - } - - @Override - public SQLInsertClause set(Path path, Expression expression) { - columns.add(path); - values.add(expression); - return this; - } - - @Override - public SQLInsertClause setNull(Path path) { - columns.add(path); - values.add(Null.CONSTANT); - return this; - } - - @Override - public SQLInsertClause values(Object... v) { - for (Object value : v) { - if (value instanceof Expression) { - values.add((Expression) value); - } else if (value != null) { - values.add(ConstantImpl.create(value)); - } else { - values.add(Null.CONSTANT); - } - } - return this; - } - - @Override - public String toString() { - SQLSerializer serializer = createSerializer(); - serializer.serializeInsert(metadata, entity, columns, values, subQuery); - return serializer.toString(); - } - - /** - * Populate the INSERT clause with the properties of the given bean. The - * properties need to match the fields of the clause's entity instance. - * - * @param bean - * @return - */ - public SQLInsertClause populate(Object bean) { - return populate(bean, DefaultMapper.DEFAULT); - } - - /** - * Populate the INSERT clause with the properties of the given bean using - * the given Mapper. - * - * @param obj - * @param mapper - * @return - */ - @SuppressWarnings("rawtypes") - public SQLInsertClause populate(T obj, Mapper mapper) { - Map, Object> values = mapper.createMap(entity, obj); - for (Map.Entry, Object> entry : values.entrySet()) { - set((Path) entry.getKey(), entry.getValue()); - } - return this; - } - - @Override - public boolean isEmpty() { - return values.isEmpty() && batches.isEmpty(); - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/dml/SQLMergeClause.java b/querydsl-sql/src/main/java/com/mysema/query/sql/dml/SQLMergeClause.java deleted file mode 100644 index a0bffe2481..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/dml/SQLMergeClause.java +++ /dev/null @@ -1,460 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql.dml; - -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import javax.annotation.Nullable; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.common.collect.ImmutableList; -import com.mysema.query.DefaultQueryMetadata; -import com.mysema.query.JoinType; -import com.mysema.query.QueryFlag; -import com.mysema.query.QueryFlag.Position; -import com.mysema.query.QueryMetadata; -import com.mysema.query.dml.StoreClause; -import com.mysema.query.sql.ColumnMetadata; -import com.mysema.query.sql.Configuration; -import com.mysema.query.sql.RelationalPath; -import com.mysema.query.sql.SQLBindings; -import com.mysema.query.sql.SQLQuery; -import com.mysema.query.sql.SQLSerializer; -import com.mysema.query.sql.SQLTemplates; -import com.mysema.query.sql.types.Null; -import com.mysema.query.types.ConstantImpl; -import com.mysema.query.types.Expression; -import com.mysema.query.types.ExpressionUtils; -import com.mysema.query.types.NullExpression; -import com.mysema.query.types.Path; -import com.mysema.query.types.SubQueryExpression; -import com.mysema.util.ResultSetAdapter; - -/** - * SQLMergeClause defines an MERGE INTO clause - * - * @author tiwe - * - */ -public class SQLMergeClause extends AbstractSQLClause implements StoreClause { - - private static final Logger logger = LoggerFactory.getLogger(SQLMergeClause.class); - - private final List> columns = new ArrayList>(); - - private final Connection connection; - - private final RelationalPath entity; - - private final QueryMetadata metadata = new DefaultQueryMetadata(); - - private final List> keys = new ArrayList>(); - - @Nullable - private SubQueryExpression subQuery; - - private final List batches = new ArrayList(); - - private final List> values = new ArrayList>(); - - private transient String queryString; - - private transient List constants; - - public SQLMergeClause(Connection connection, SQLTemplates templates, RelationalPath entity) { - this(connection, new Configuration(templates), entity); - } - - public SQLMergeClause(Connection connection, Configuration configuration, RelationalPath entity) { - super(configuration); - this.connection = connection; - this.entity = entity; - metadata.addJoin(JoinType.DEFAULT, entity); - } - - /** - * Add the given String literal at the given position as a query flag - * - * @param position - * @param flag - * @return - */ - public SQLMergeClause addFlag(Position position, String flag) { - metadata.addFlag(new QueryFlag(position, flag)); - return this; - } - - /** - * Add the given Expression at the given position as a query flag - * - * @param position - * @param flag - * @return - */ - public SQLMergeClause addFlag(Position position, Expression flag) { - metadata.addFlag(new QueryFlag(position, flag)); - return this; - } - - /** - * Add the current state of bindings as a batch item - * - * @return - */ - public SQLMergeClause addBatch() { - if (!configuration.getTemplates().isNativeMerge()) { - throw new IllegalStateException("batch only supported for databases that support native merge"); - } - - batches.add(new SQLMergeBatch(keys, columns, values, subQuery)); - columns.clear(); - values.clear(); - keys.clear(); - subQuery = null; - return this; - } - - public SQLMergeClause columns(Path... columns) { - this.columns.addAll(Arrays.asList(columns)); - return this; - } - - /** - * Execute the clause and return the generated key with the type of the given path. - * If no rows were created, null is returned, otherwise the key of the first row is returned. - * - * @param - * @param path - * @return - */ - @SuppressWarnings("unchecked") - @Nullable - public T executeWithKey(Path path) { - return executeWithKey((Class)path.getType(), path); - } - - /** - * Execute the clause and return the generated key cast to the given type. - * If no rows were created, null is returned, otherwise the key of the first row is returned. - * - * @param - * @param type - * @return - */ - public T executeWithKey(Class type) { - return executeWithKey(type, null); - } - - private T executeWithKey(Class type, @Nullable Path path) { - ResultSet rs = executeWithKeys(); - try{ - if (rs.next()) { - return configuration.get(rs, path, 1, type); - } else { - return null; - } - } catch (SQLException e) { - throw configuration.translate(e); - }finally{ - close(rs); - } - } - - /** - * Execute the clause and return the generated key with the type of the given path. - * If no rows were created, or the referenced column is not a generated key, null is returned. - * Otherwise, the key of the first row is returned. - * - * @param - * @param path - * @return - */ - @SuppressWarnings("unchecked") - public List executeWithKeys(Path path) { - return executeWithKeys((Class)path.getType(), path); - } - - public List executeWithKeys(Class type) { - return executeWithKeys(type, null); - } - - private List executeWithKeys(Class type, @Nullable Path path) { - ResultSet rs = executeWithKeys(); - try{ - List rv = new ArrayList(); - while (rs.next()) { - rv.add(configuration.get(rs, path, 1, type)); - } - return rv; - } catch (SQLException e) { - throw configuration.translate(e); - }finally{ - close(rs); - } - } - - /** - * Execute the clause and return the generated keys as a ResultSet - * - * @return - */ - public ResultSet executeWithKeys() { - try { - if (configuration.getTemplates().isNativeMerge()) { - final PreparedStatement stmt = createStatement(true); - if (batches.isEmpty()) { - listeners.notifyMerge(entity, metadata, keys, columns, values, subQuery); - stmt.executeUpdate(); - } else { - listeners.notifyMerges(entity, metadata, batches); - stmt.executeBatch(); - } - ResultSet rs = stmt.getGeneratedKeys(); - return new ResultSetAdapter(rs) { - @Override - public void close() throws SQLException { - try { - super.close(); - } finally { - stmt.close(); - } - } - }; - } else { - List ids = getIds(); - if (!ids.isEmpty()) { - // update - SQLUpdateClause update = new SQLUpdateClause(connection, configuration.getTemplates(), entity); - populate(update); - update.where(ExpressionUtils.in((Expression)keys.get(0),ids)); - return EmptyResultSet.DEFAULT; - } else { - // insert - SQLInsertClause insert = new SQLInsertClause(connection, configuration.getTemplates(), entity); - populate(insert); - return insert.executeWithKeys(); - } - } - } catch (SQLException e) { - throw configuration.translate(queryString, constants, e); - } - } - - @Override - public long execute() { - if (configuration.getTemplates().isNativeMerge()) { - return executeNativeMerge(); - } else { - return executeCompositeMerge(); - } - } - - @Override - public List getSQL() { - if (batches.isEmpty()) { - SQLSerializer serializer = createSerializer(); - serializer.serializeMerge(metadata, entity, keys, columns, values, subQuery); - return ImmutableList.of(createBindings(metadata, serializer)); - } else { - ImmutableList.Builder builder = ImmutableList.builder(); - for (SQLMergeBatch batch : batches) { - SQLSerializer serializer = createSerializer(); - serializer.serializeMerge(metadata, entity, batch.getKeys(), batch.getColumns(), batch.getValues(), batch.getSubQuery()); - builder.add(createBindings(metadata, serializer)); - } - return builder.build(); - } - } - - private List getIds() { - // select - SQLQuery query = new SQLQuery(connection, configuration.getTemplates()).from(entity); - for (int i=0; i < columns.size(); i++) { - if (values.get(i) instanceof NullExpression) { - query.where(ExpressionUtils.isNull(columns.get(i))); - } else { - query.where(ExpressionUtils.eq(columns.get(i),(Expression)values.get(i))); - } - } - return query.list(keys.get(0)); - } - - @SuppressWarnings("unchecked") - private long executeCompositeMerge() { - List ids = getIds(); - if (!ids.isEmpty()) { - // update - SQLUpdateClause update = new SQLUpdateClause(connection, configuration.getTemplates(), entity); - populate(update); - update.where(ExpressionUtils.in((Expression)keys.get(0),ids)); - return update.execute(); - } else { - // insert - SQLInsertClause insert = new SQLInsertClause(connection, configuration.getTemplates(), entity); - populate(insert); - return insert.execute(); - - } - } - - @SuppressWarnings("unchecked") - private void populate(StoreClause clause) { - for (int i = 0; i < columns.size(); i++) { - clause.set((Path)columns.get(i), (Object)values.get(i)); - } - } - - private PreparedStatement createStatement(boolean withKeys) throws SQLException{ - SQLSerializer serializer = createSerializer(); - PreparedStatement stmt = null; - if (batches.isEmpty()) { - serializer.serializeMerge(metadata, entity, keys, columns, values, subQuery); - stmt = prepareStatementAndSetParameters(serializer, withKeys); - } else { - serializer.serializeMerge(metadata, entity, - batches.get(0).getKeys(), batches.get(0).getColumns(), - batches.get(0).getValues(), batches.get(0).getSubQuery()); - stmt = prepareStatementAndSetParameters(serializer, withKeys); - - // add first batch - stmt.addBatch(); - - // add other batches - for (int i = 1; i < batches.size(); i++) { - SQLMergeBatch batch = batches.get(i); - serializer = createSerializer(); - serializer.serializeMerge(metadata, entity, batch.getKeys(), batch.getColumns(), batch.getValues(), batch.getSubQuery()); - setParameters(stmt, serializer.getConstants(), serializer.getConstantPaths(), metadata.getParams()); - stmt.addBatch(); - } - } - return stmt; - } - - private PreparedStatement prepareStatementAndSetParameters(SQLSerializer serializer, - boolean withKeys) throws SQLException { - queryString = serializer.toString(); - constants = serializer.getConstants(); - logger.debug(queryString); - PreparedStatement stmt; - if (withKeys) { - String[] target = new String[keys.size()]; - for (int i = 0; i < target.length; i++) { - target[i] = ColumnMetadata.getName(keys.get(i)); - } - stmt = connection.prepareStatement(queryString, target); - } else { - stmt = connection.prepareStatement(queryString); - } - setParameters(stmt, serializer.getConstants(), serializer.getConstantPaths(), metadata.getParams()); - return stmt; - } - - private long executeNativeMerge() { - PreparedStatement stmt = null; - try { - stmt = createStatement(false); - if (batches.isEmpty()) { - listeners.notifyMerge(entity, metadata, keys, columns, values, subQuery); - return stmt.executeUpdate(); - } else { - listeners.notifyMerges(entity, metadata, batches); - return executeBatch(stmt); - } - } catch (SQLException e) { - throw configuration.translate(queryString, constants, e); - } finally { - if (stmt != null) { - close(stmt); - } - } - } - - /** - * Set the keys to be used in the MERGE clause - * - * @param paths - * @return - */ - public SQLMergeClause keys(Path... paths) { - for (Path path : paths) { - keys.add(path); - } - return this; - } - - public SQLMergeClause select(SubQueryExpression subQuery) { - this.subQuery = subQuery; - return this; - } - - @Override - public SQLMergeClause set(Path path, @Nullable T value) { - columns.add(path); - if (value != null) { - values.add(ConstantImpl.create(value)); - } else { - values.add(Null.CONSTANT); - } - return this; - } - - @Override - public SQLMergeClause set(Path path, Expression expression) { - columns.add(path); - values.add(expression); - return this; - } - - @Override - public SQLMergeClause setNull(Path path) { - columns.add(path); - values.add(Null.CONSTANT); - return this; - } - - @Override - public String toString() { - SQLSerializer serializer = createSerializer(); - serializer.serializeMerge(metadata, entity, keys, columns, values, subQuery); - return serializer.toString(); - } - - public SQLMergeClause values(Object... v) { - for (Object value : v) { - if (value instanceof Expression) { - values.add((Expression) value); - } else if (value != null) { - values.add(ConstantImpl.create(value)); - } else { - values.add(Null.CONSTANT); - } - } - return this; - } - - @Override - public boolean isEmpty() { - return values.isEmpty(); - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/dml/SQLUpdateBatch.java b/querydsl-sql/src/main/java/com/mysema/query/sql/dml/SQLUpdateBatch.java deleted file mode 100644 index 2995692a24..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/dml/SQLUpdateBatch.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql.dml; - -import java.util.List; - -import com.mysema.commons.lang.Pair; -import com.mysema.query.QueryMetadata; -import com.mysema.query.types.Expression; -import com.mysema.query.types.Path; - -/** - * SQLUpdateBatch defines the state of an SQL UPDATE batch item - * - * @author tiwe - * - */ -public class SQLUpdateBatch { - - private final QueryMetadata metadata; - - private final List,Expression>> updates; - - public SQLUpdateBatch(QueryMetadata metadata, List,Expression>> updates) { - this.metadata = metadata; - this.updates = updates; - } - - public QueryMetadata getMetadata() { - return metadata; - } - - public List, Expression>> getUpdates() { - return updates; - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/dml/SQLUpdateClause.java b/querydsl-sql/src/main/java/com/mysema/query/sql/dml/SQLUpdateClause.java deleted file mode 100644 index a3b89b2d52..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/dml/SQLUpdateClause.java +++ /dev/null @@ -1,298 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql.dml; - -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -import javax.annotation.Nonnegative; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.common.collect.ImmutableList; -import com.mysema.commons.lang.Pair; -import com.mysema.query.DefaultQueryMetadata; -import com.mysema.query.JoinType; -import com.mysema.query.QueryFlag; -import com.mysema.query.QueryFlag.Position; -import com.mysema.query.QueryMetadata; -import com.mysema.query.QueryModifiers; -import com.mysema.query.dml.UpdateClause; -import com.mysema.query.sql.Configuration; -import com.mysema.query.sql.RelationalPath; -import com.mysema.query.sql.SQLBindings; -import com.mysema.query.sql.SQLSerializer; -import com.mysema.query.sql.SQLTemplates; -import com.mysema.query.sql.types.Null; -import com.mysema.query.types.ConstantImpl; -import com.mysema.query.types.Expression; -import com.mysema.query.types.Path; -import com.mysema.query.types.Predicate; - -/** - * SQLUpdateClause defines a UPDATE clause - * - * @author tiwe - * - */ -public class SQLUpdateClause extends AbstractSQLClause implements UpdateClause { - - private static final Logger logger = LoggerFactory.getLogger(SQLInsertClause.class); - - private final Connection connection; - - private final RelationalPath entity; - - private final List batches = new ArrayList(); - - private List,Expression>> updates = new ArrayList,Expression>>(); - - private QueryMetadata metadata = new DefaultQueryMetadata(); - - private transient String queryString; - - private transient List constants; - - public SQLUpdateClause(Connection connection, SQLTemplates templates, RelationalPath entity) { - this(connection, new Configuration(templates), entity); - } - - public SQLUpdateClause(Connection connection, Configuration configuration, RelationalPath entity) { - super(configuration); - this.connection = connection; - this.entity = entity; - metadata.addJoin(JoinType.DEFAULT, entity); - } - - /** - * Add the given String literal at the given position as a query flag - * - * @param position - * @param flag - * @return - */ - public SQLUpdateClause addFlag(Position position, String flag) { - metadata.addFlag(new QueryFlag(position, flag)); - return this; - } - - /** - * Add the given Expression at the given position as a query flag - * - * @param position - * @param flag - * @return - */ - public SQLUpdateClause addFlag(Position position, Expression flag) { - metadata.addFlag(new QueryFlag(position, flag)); - return this; - } - - /** - * Add the current state of bindings as a batch item - * - * @return - */ - public SQLUpdateClause addBatch() { - batches.add(new SQLUpdateBatch(metadata, updates)); - updates = new ArrayList,Expression>>(); - metadata = new DefaultQueryMetadata(); - metadata.addJoin(JoinType.DEFAULT, entity); - return this; - } - - private PreparedStatement createStatement() throws SQLException{ - PreparedStatement stmt; - if (batches.isEmpty()) { - SQLSerializer serializer = createSerializer(); - serializer.serializeUpdate(metadata, entity, updates); - queryString = serializer.toString(); - constants = serializer.getConstants(); - logger.debug(queryString); - stmt = connection.prepareStatement(queryString); - setParameters(stmt, serializer.getConstants(), serializer.getConstantPaths(), metadata.getParams()); - } else { - SQLSerializer serializer = createSerializer(); - serializer.serializeUpdate(batches.get(0).getMetadata(), entity, batches.get(0).getUpdates()); - queryString = serializer.toString(); - constants = serializer.getConstants(); - logger.debug(queryString); - - // add first batch - stmt = connection.prepareStatement(queryString); - setParameters(stmt, serializer.getConstants(), serializer.getConstantPaths(), metadata.getParams()); - stmt.addBatch(); - - // add other batches - for (int i = 1; i < batches.size(); i++) { - serializer = createSerializer(); - serializer.serializeUpdate(batches.get(i).getMetadata(), entity, batches.get(i).getUpdates()); - setParameters(stmt, serializer.getConstants(), serializer.getConstantPaths(), metadata.getParams()); - stmt.addBatch(); - } - } - return stmt; - } - - @Override - public long execute() { - PreparedStatement stmt = null; - try { - stmt = createStatement(); - if (batches.isEmpty()) { - listeners.notifyUpdate(entity, metadata, updates); - return stmt.executeUpdate(); - } else { - listeners.notifyUpdates(entity, batches); - return executeBatch(stmt); - } - } catch (SQLException e) { - throw configuration.translate(queryString, constants, e); - } finally { - if (stmt != null) { - close(stmt); - } - } - } - - @Override - public List getSQL() { - if (batches.isEmpty()) { - SQLSerializer serializer = createSerializer(); - serializer.serializeUpdate(metadata, entity, updates); - return ImmutableList.of(createBindings(metadata, serializer)); - } else { - ImmutableList.Builder builder = ImmutableList.builder(); - for (SQLUpdateBatch batch : batches) { - SQLSerializer serializer = createSerializer(); - serializer.serializeUpdate(batch.getMetadata(), entity, batch.getUpdates()); - builder.add(createBindings(metadata, serializer)); - } - return builder.build(); - } - } - - @Override - public SQLUpdateClause set(Path path, T value) { - if (value instanceof Expression) { - updates.add(Pair.,Expression>of(path, (Expression)value)); - } else if (value != null) { - updates.add(Pair.,Expression>of(path, ConstantImpl.create(value))); - } else { - setNull(path); - } - return this; - } - - @Override - public SQLUpdateClause set(Path path, Expression expression) { - if (expression != null) { - updates.add(Pair.,Expression>of(path, expression)); - } else { - setNull(path); - } - return this; - } - - @Override - public SQLUpdateClause setNull(Path path) { - updates.add(Pair.,Expression>of(path, Null.CONSTANT)); - return this; - } - - @Override - public SQLUpdateClause set(List> paths, List values) { - for (int i = 0; i < paths.size(); i++) { - if (values.get(i) instanceof Expression) { - updates.add(Pair.,Expression>of(paths.get(i), (Expression)values.get(i))); - } else if (values.get(i) != null) { - updates.add(Pair.,Expression>of(paths.get(i), ConstantImpl.create(values.get(i)))); - } else { - updates.add(Pair.,Expression>of(paths.get(i), Null.CONSTANT)); - } - } - return this; - } - - public SQLUpdateClause where(Predicate p) { - metadata.addWhere(p); - return this; - } - - @Override - public SQLUpdateClause where(Predicate... o) { - for (Predicate p : o) { - metadata.addWhere(p); - } - return this; - } - - public SQLUpdateClause limit(@Nonnegative long limit) { - metadata.setModifiers(QueryModifiers.limit(limit)); - return this; - } - - @Override - public String toString() { - SQLSerializer serializer = createSerializer(); - serializer.serializeUpdate(metadata, entity, updates); - return serializer.toString(); - } - - /** - * Populate the UPDATE clause with the properties of the given bean. - * The properties need to match the fields of the clause's entity instance. - * Primary key columns are skipped in the population. - * - * @param bean - * @return - */ - @SuppressWarnings("unchecked") - public SQLUpdateClause populate(Object bean) { - return populate(bean, DefaultMapper.DEFAULT); - } - - /** - * Populate the UPDATE clause with the properties of the given bean using the given Mapper. - * - * @param obj - * @param mapper - * @return - */ - @SuppressWarnings({ "rawtypes", "unchecked" }) - public SQLUpdateClause populate(T obj, Mapper mapper) { - Collection> primaryKeyColumns = entity.getPrimaryKey() != null - ? entity.getPrimaryKey().getLocalColumns() - : Collections.>emptyList(); - Map, Object> values = mapper.createMap(entity, obj); - for (Map.Entry, Object> entry : values.entrySet()) { - if (!primaryKeyColumns.contains(entry.getKey())) { - set((Path)entry.getKey(), entry.getValue()); - } - } - return this; - } - - @Override - public boolean isEmpty() { - return updates.isEmpty() && batches.isEmpty(); - } -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/dml/package-info.java b/querydsl-sql/src/main/java/com/mysema/query/sql/dml/package-info.java deleted file mode 100644 index 8a9cd3e4b6..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/dml/package-info.java +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ - - -/** - * DML operations support - */ -package com.mysema.query.sql.dml; diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/mssql/SQLServerGrammar.java b/querydsl-sql/src/main/java/com/mysema/query/sql/mssql/SQLServerGrammar.java deleted file mode 100644 index 3fe69a9a2b..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/mssql/SQLServerGrammar.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql.mssql; - - -import com.mysema.query.types.expr.NumberExpression; -import com.mysema.query.types.template.NumberTemplate; - -/** - * Convenience functions and constants for SQL Server usage - * - * @author tiwe - * - */ -public final class SQLServerGrammar { - - private SQLServerGrammar() {} - - @Deprecated - public static final NumberExpression rowNumber = NumberTemplate.create(Long.class, "row_number"); - - @Deprecated - public static final NumberExpression rn = NumberTemplate.create(Long.class, "rn"); - - static String tableHints(SQLServerTableHints... tableHints) { - StringBuilder hints = new StringBuilder(" with ").append("("); - for (int i = 0; i < tableHints.length; i++) { - if (i > 0) { - hints.append(", "); - } - hints.append(tableHints[i].name()); - } - hints.append(")"); - return hints.toString(); - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/mssql/SQLServerQuery.java b/querydsl-sql/src/main/java/com/mysema/query/sql/mssql/SQLServerQuery.java deleted file mode 100644 index a067e6d0a7..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/mssql/SQLServerQuery.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql.mssql; - -import java.sql.Connection; - -import com.mysema.query.DefaultQueryMetadata; -import com.mysema.query.JoinFlag; -import com.mysema.query.QueryMetadata; -import com.mysema.query.sql.AbstractSQLQuery; -import com.mysema.query.sql.Configuration; -import com.mysema.query.sql.SQLServerTemplates; -import com.mysema.query.sql.SQLTemplates; - -/** - * SQLServerQuery provides SQL Server related extensions to SQLQuery - * - * @author tiwe - * - */ -public class SQLServerQuery extends AbstractSQLQuery { - - public SQLServerQuery(Connection conn) { - this(conn, new SQLServerTemplates(), new DefaultQueryMetadata()); - } - - public SQLServerQuery(Connection conn, SQLTemplates templates) { - this(conn, templates, new DefaultQueryMetadata()); - } - - protected SQLServerQuery(Connection conn, SQLTemplates templates, QueryMetadata metadata) { - super(conn, new Configuration(templates), metadata); - } - - public SQLServerQuery(Connection conn, Configuration configuration, QueryMetadata metadata) { - super(conn, configuration, metadata); - } - - public SQLServerQuery(Connection conn, Configuration configuration) { - super(conn, configuration); - } - - /** - * @param tableHints - * @return - */ - public SQLServerQuery tableHints(SQLServerTableHints... tableHints) { - if (tableHints.length > 0) { - String hints = SQLServerGrammar.tableHints(tableHints); - addJoinFlag(hints, JoinFlag.Position.END); - } - return this; - } - - @Override - public SQLServerQuery clone(Connection conn) { - SQLServerQuery q = new SQLServerQuery(conn, getConfiguration(), getMetadata().clone()); - q.clone(this); - return q; - } - -} \ No newline at end of file diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/mssql/SQLServerQueryFactory.java b/querydsl-sql/src/main/java/com/mysema/query/sql/mssql/SQLServerQueryFactory.java deleted file mode 100644 index 6956dbb574..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/mssql/SQLServerQueryFactory.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql.mssql; - -import java.sql.Connection; - -import javax.inject.Provider; - -import com.mysema.query.sql.AbstractSQLQueryFactory; -import com.mysema.query.sql.Configuration; -import com.mysema.query.sql.SQLServerTemplates; -import com.mysema.query.sql.SQLTemplates; - -/** - * SQL Server specific implementation of SQLQueryFactory - * - * @author tiwe - * - */ -public class SQLServerQueryFactory extends AbstractSQLQueryFactory { - - public SQLServerQueryFactory(Configuration configuration, Provider connection) { - super(configuration, connection); - } - - public SQLServerQueryFactory(Provider connection) { - this(new Configuration(new SQLServerTemplates()), connection); - } - - public SQLServerQueryFactory(SQLTemplates templates, Provider connection) { - this(new Configuration(templates), connection); - } - - public SQLServerQuery query() { - return new SQLServerQuery(connection.get(), configuration); - } - - @Override - public SQLServerSubQuery subQuery() { - return new SQLServerSubQuery(); - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/mssql/SQLServerSubQuery.java b/querydsl-sql/src/main/java/com/mysema/query/sql/mssql/SQLServerSubQuery.java deleted file mode 100644 index d41dee8577..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/mssql/SQLServerSubQuery.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2012, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql.mssql; - -import com.mysema.query.JoinFlag; -import com.mysema.query.QueryMetadata; -import com.mysema.query.sql.AbstractSQLSubQuery; -import com.mysema.query.sql.Configuration; - -/** - * @author tiwe - * - */ -public class SQLServerSubQuery extends AbstractSQLSubQuery { - - public SQLServerSubQuery() { - super(); - } - - public SQLServerSubQuery(QueryMetadata metadata) { - super(metadata); - } - - public SQLServerSubQuery(Configuration configuration, QueryMetadata metadata){ - super(configuration, metadata); - } - - /** - * @param tableHints - * @return - */ - public SQLServerSubQuery tableHints(SQLServerTableHints... tableHints) { - if (tableHints.length > 0) { - String hints = SQLServerGrammar.tableHints(tableHints); - addJoinFlag(hints, JoinFlag.Position.END); - } - return this; - } - - @Override - public SQLServerSubQuery clone() { - SQLServerSubQuery subQuery = new SQLServerSubQuery(this.configuration, this.getMetadata().clone()); - return subQuery; - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/mssql/SQLServerTableHints.java b/querydsl-sql/src/main/java/com/mysema/query/sql/mssql/SQLServerTableHints.java deleted file mode 100644 index d92a3bdc9b..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/mssql/SQLServerTableHints.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql.mssql; - -/** - * @author tiwe - * - */ -public enum SQLServerTableHints { - NOEXPAND, - FASTFIRSTROW, - FORCESEEK, - HOLDLOCK, - NOLOCK, - NOWAIT, - PAGLOCK, - READCOMMITTED, - READCOMMITTEDLOCK, - READPAST, - READUNCOMMITTED, - REPEATABLEREAD, - ROWLOCK, - SERIALIZABLE, - TABLOCK, - TABLOCKX, - UPDLOCK, - XLOCK -} \ No newline at end of file diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/mssql/package-info.java b/querydsl-sql/src/main/java/com/mysema/query/sql/mssql/package-info.java deleted file mode 100644 index 330a462eef..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/mssql/package-info.java +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ - - -/** - * SQL Server support - */ -package com.mysema.query.sql.mssql; diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/mysql/MySQLQuery.java b/querydsl-sql/src/main/java/com/mysema/query/sql/mysql/MySQLQuery.java deleted file mode 100644 index 95ba52bf10..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/mysql/MySQLQuery.java +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql.mysql; - -import java.io.File; -import java.sql.Connection; - -import com.google.common.base.Joiner; -import com.mysema.query.DefaultQueryMetadata; -import com.mysema.query.JoinFlag; -import com.mysema.query.QueryFlag.Position; -import com.mysema.query.QueryMetadata; -import com.mysema.query.sql.AbstractSQLQuery; -import com.mysema.query.sql.Configuration; -import com.mysema.query.sql.MySQLTemplates; -import com.mysema.query.sql.SQLQuery; -import com.mysema.query.sql.SQLTemplates; - -/** - * MySQLQuery provides MySQL related extensions to SQLQuery - * - * @author tiwe - * @see SQLQuery - * - */ -public class MySQLQuery extends AbstractSQLQuery { - - private static final String WITH_ROLLUP = "\nwith rollup "; - - private static final String STRAIGHT_JOIN = "straight_join "; - - private static final String SQL_SMALL_RESULT = "sql_small_result "; - - private static final String SQL_NO_CACHE = "sql_no_cache "; - - private static final String LOCK_IN_SHARE_MODE = "\nlock in share mode "; - - private static final String HIGH_PRIORITY = "high_priority "; - - private static final String SQL_CALC_FOUND_ROWS = "sql_calc_found_rows "; - - private static final String SQL_CACHE = "sql_cache "; - - private static final String SQL_BUFFER_RESULT = "sql_buffer_result "; - - private static final String SQL_BIG_RESULT = "sql_big_result "; - - private static final Joiner JOINER = Joiner.on(", "); - - public MySQLQuery(Connection conn) { - this(conn, new Configuration(new MySQLTemplates()), new DefaultQueryMetadata()); - } - - public MySQLQuery(Connection conn, SQLTemplates templates) { - this(conn, new Configuration(templates), new DefaultQueryMetadata()); - } - - public MySQLQuery(Connection conn, Configuration configuration) { - this(conn, configuration, new DefaultQueryMetadata()); - } - - public MySQLQuery(Connection conn, Configuration configuration, QueryMetadata metadata) { - super(conn, configuration, metadata); - } - - /** - * @return - */ - public MySQLQuery bigResult() { - return addFlag(Position.AFTER_SELECT, SQL_BIG_RESULT); - } - - /** - * @return - */ - public MySQLQuery bufferResult() { - return addFlag(Position.AFTER_SELECT, SQL_BUFFER_RESULT); - } - - /** - * @return - */ - public MySQLQuery cache() { - return addFlag(Position.AFTER_SELECT, SQL_CACHE); - } - - /** - * @return - */ - public MySQLQuery calcFoundRows() { - return addFlag(Position.AFTER_SELECT, SQL_CALC_FOUND_ROWS); - } - - /** - * @return - */ - public MySQLQuery highPriority() { - return addFlag(Position.AFTER_SELECT, HIGH_PRIORITY); - } - - /** - * @param var - * @return - */ - public MySQLQuery into(String var) { - return addFlag(Position.END, "\ninto " + var); - } - - /** - * @param file - * @return - */ - public MySQLQuery intoDumpfile(File file) { - return addFlag(Position.END, "\ninto dumpfile '" + file.getPath() + "'" ); - } - - /** - * @param file - * @return - */ - public MySQLQuery intoOutfile(File file) { - return addFlag(Position.END, "\ninto outfile '" + file.getPath() + "'" ); - } - - /** - * @return - */ - public MySQLQuery lockInShareMode() { - return addFlag(Position.END, LOCK_IN_SHARE_MODE); - } - - /** - * @return - */ - public MySQLQuery noCache() { - return addFlag(Position.AFTER_SELECT, SQL_NO_CACHE); - } - - /** - * @return - */ - public MySQLQuery smallResult() { - return addFlag(Position.AFTER_SELECT, SQL_SMALL_RESULT); - } - - /** - * @return - */ - public MySQLQuery straightJoin() { - return addFlag(Position.AFTER_SELECT, STRAIGHT_JOIN); - } - - /** - * @param indexes - * @return - */ - public MySQLQuery forceIndex(String... indexes) { - return addJoinFlag(" force index (" + JOINER.join(indexes) + ")", JoinFlag.Position.END); - } - - /** - * @param indexes - * @return - */ - public MySQLQuery ignoreIndex(String... indexes) { - return addJoinFlag(" ignore index (" + JOINER.join(indexes) + ")", JoinFlag.Position.END); - } - - - /** - * @param indexes - * @return - */ - public MySQLQuery useIndex(String... indexes) { - return addJoinFlag(" use index (" + JOINER.join(indexes) + ")", JoinFlag.Position.END); - } - - - /** - * @return - */ - public MySQLQuery withRollup() { - return addFlag(Position.AFTER_GROUP_BY, WITH_ROLLUP); - } - - @Override - public MySQLQuery clone(Connection conn) { - MySQLQuery q = new MySQLQuery(conn, getConfiguration(), getMetadata().clone()); - q.clone(this); - return q; - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/mysql/MySQLQueryFactory.java b/querydsl-sql/src/main/java/com/mysema/query/sql/mysql/MySQLQueryFactory.java deleted file mode 100644 index ebba5bbbcb..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/mysql/MySQLQueryFactory.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql.mysql; - -import java.sql.Connection; - -import javax.inject.Provider; - -import com.mysema.query.QueryFlag.Position; -import com.mysema.query.sql.AbstractSQLQueryFactory; -import com.mysema.query.sql.Configuration; -import com.mysema.query.sql.MySQLTemplates; -import com.mysema.query.sql.RelationalPath; -import com.mysema.query.sql.SQLSubQuery; -import com.mysema.query.sql.SQLTemplates; -import com.mysema.query.sql.dml.SQLInsertClause; -import com.mysema.query.types.Expression; -import com.mysema.query.types.TemplateExpressionImpl; - -/** - * MySQL specific implementation of SQLQueryFactory - * - * @author tiwe - * - */ -public class MySQLQueryFactory extends AbstractSQLQueryFactory { - - public MySQLQueryFactory(Configuration configuration, Provider connection) { - super(configuration, connection); - } - - public MySQLQueryFactory(Provider connection) { - this(new Configuration(new MySQLTemplates()), connection); - } - - public MySQLQueryFactory(SQLTemplates templates, Provider connection) { - this(new Configuration(templates), connection); - } - - public SQLInsertClause insertIgnore(RelationalPath entity) { - SQLInsertClause insert = insert(entity); - insert.addFlag(Position.START_OVERRIDE, "insert ignore into "); - return insert; - } - - public SQLInsertClause insertOnDuplicateKeyUpdate(RelationalPath entity, String clause) { - SQLInsertClause insert = insert(entity); - insert.addFlag(Position.END, " on duplicate key update " + clause); - return insert; - } - - public SQLInsertClause insertOnDuplicateKeyUpdate(RelationalPath entity, Expression clause) { - SQLInsertClause insert = insert(entity); - insert.addFlag(Position.END, TemplateExpressionImpl.create(String.class, " on duplicate key update {0}", clause)); - return insert; - } - - public MySQLQuery query() { - return new MySQLQuery(connection.get(), configuration); - } - - public MySQLReplaceClause replace(RelationalPath entity) { - return new MySQLReplaceClause(connection.get(), configuration, entity); - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/mysql/MySQLReplaceClause.java b/querydsl-sql/src/main/java/com/mysema/query/sql/mysql/MySQLReplaceClause.java deleted file mode 100644 index a6bd37ce31..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/mysql/MySQLReplaceClause.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql.mysql; - -import java.sql.Connection; - -import com.mysema.query.QueryFlag.Position; -import com.mysema.query.sql.Configuration; -import com.mysema.query.sql.RelationalPath; -import com.mysema.query.sql.SQLTemplates; -import com.mysema.query.sql.dml.SQLInsertClause; - -/** - * @author tiwe - * - */ -public class MySQLReplaceClause extends SQLInsertClause{ - - private static final String REPLACE_INTO = "replace into "; - - public MySQLReplaceClause(Connection connection, SQLTemplates templates, RelationalPath entity) { - super(connection, templates, entity); - addFlag(Position.START_OVERRIDE, REPLACE_INTO); - } - - public MySQLReplaceClause(Connection connection, Configuration configuration, RelationalPath entity) { - super(connection, configuration, entity); - addFlag(Position.START_OVERRIDE, REPLACE_INTO); - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/mysql/package-info.java b/querydsl-sql/src/main/java/com/mysema/query/sql/mysql/package-info.java deleted file mode 100644 index 83b9aec726..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/mysql/package-info.java +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ - - -/** - * MySQL support - */ -package com.mysema.query.sql.mysql; diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/oracle/OracleGrammar.java b/querydsl-sql/src/main/java/com/mysema/query/sql/oracle/OracleGrammar.java deleted file mode 100644 index 87ed8a6460..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/oracle/OracleGrammar.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql.oracle; - -import java.util.Date; - -import com.mysema.query.types.expr.DateExpression; -import com.mysema.query.types.expr.NumberExpression; -import com.mysema.query.types.template.DateTemplate; -import com.mysema.query.types.template.NumberTemplate; - -/** - * Convenience functions and constants for Oracle DB usage - * - * @author tiwe - */ -public final class OracleGrammar { - - private OracleGrammar() {} - - public static final NumberExpression level = NumberTemplate.create(Integer.class, "level"); - - public static final NumberExpression rownum = NumberTemplate.create(Integer.class, "rownum"); - - public static final NumberExpression rowid = NumberTemplate.create(Integer.class, "rowid"); - - public static final DateExpression sysdate = DateTemplate.create(Date.class, "sysdate"); - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/oracle/OracleQuery.java b/querydsl-sql/src/main/java/com/mysema/query/sql/oracle/OracleQuery.java deleted file mode 100644 index 5dbf3163a3..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/oracle/OracleQuery.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql.oracle; - -import java.sql.Connection; - -import com.mysema.query.DefaultQueryMetadata; -import com.mysema.query.QueryFlag.Position; -import com.mysema.query.QueryMetadata; -import com.mysema.query.sql.AbstractSQLQuery; -import com.mysema.query.sql.Configuration; -import com.mysema.query.sql.OracleTemplates; -import com.mysema.query.sql.SQLTemplates; -import com.mysema.query.types.Expression; -import com.mysema.query.types.Predicate; - -/** - * OracleQuery provides Oracle specific extensions to the base SQL query type - * - * @author tiwe - */ -public class OracleQuery extends AbstractSQLQuery { - - private static final String CONNECT_BY = "\nconnect by "; - - private static final String CONNECT_BY_NOCYCLE_PRIOR = "\nconnect by nocycle prior "; - - private static final String CONNECT_BY_PRIOR = "\nconnect by prior "; - - private static final String ORDER_SIBLINGS_BY = "\norder siblings by "; - - private static final String START_WITH = "\nstart with "; - - public OracleQuery(Connection conn) { - this(conn, new OracleTemplates(), new DefaultQueryMetadata()); - } - - public OracleQuery(Connection conn, SQLTemplates templates) { - this(conn, templates, new DefaultQueryMetadata()); - } - - public OracleQuery(Connection conn, Configuration configuration) { - super(conn, configuration, new DefaultQueryMetadata()); - } - - public OracleQuery(Connection conn, Configuration configuration, QueryMetadata metadata) { - super(conn, configuration, metadata); - } - - protected OracleQuery(Connection conn, SQLTemplates templates, QueryMetadata metadata) { - super(conn, new Configuration(templates), metadata); - } - - /** - * @param cond - * @return - */ - public OracleQuery connectByPrior(Predicate cond) { - return addFlag(Position.BEFORE_ORDER, CONNECT_BY_PRIOR, cond); - } - - /** - * @param cond - * @return - */ - public OracleQuery connectBy(Predicate cond) { - return addFlag(Position.BEFORE_ORDER, CONNECT_BY, cond); - } - - /** - * @param cond - * @return - */ - public OracleQuery connectByNocyclePrior(Predicate cond) { - return addFlag(Position.BEFORE_ORDER, CONNECT_BY_NOCYCLE_PRIOR, cond); - } - - /** - * @param cond - * @return - */ - public OracleQuery startWith(Predicate cond) { - return addFlag(Position.BEFORE_ORDER, START_WITH, cond); - } - - /** - * @param path - * @return - */ - public OracleQuery orderSiblingsBy(Expression path) { - return addFlag(Position.BEFORE_ORDER, ORDER_SIBLINGS_BY, path); - } - - @Override - public OracleQuery clone(Connection conn) { - OracleQuery q = new OracleQuery(conn, getConfiguration(), getMetadata().clone()); - q.clone(this); - return q; - } - - // TODO : connect by root - - // TODO : connect by iscycle - - // TODO : connect by isleaf (pseudocolumn) - - // TODO : sys connect path -} - - diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/oracle/OracleQueryFactory.java b/querydsl-sql/src/main/java/com/mysema/query/sql/oracle/OracleQueryFactory.java deleted file mode 100644 index 86dd507594..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/oracle/OracleQueryFactory.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql.oracle; - -import java.sql.Connection; - -import javax.inject.Provider; - -import com.mysema.query.sql.AbstractSQLQueryFactory; -import com.mysema.query.sql.Configuration; -import com.mysema.query.sql.OracleTemplates; -import com.mysema.query.sql.SQLSubQuery; -import com.mysema.query.sql.SQLTemplates; - -/** - * Oracle specific implementation of SQLQueryFactory - * - * @author tiwe - * - */ -public class OracleQueryFactory extends AbstractSQLQueryFactory { - - public OracleQueryFactory(Configuration configuration, Provider connection) { - super(configuration, connection); - } - - public OracleQueryFactory(Provider connection) { - this(new Configuration(new OracleTemplates()), connection); - } - - public OracleQueryFactory(SQLTemplates templates, Provider connection) { - this(new Configuration(templates), connection); - } - - public OracleQuery query() { - return new OracleQuery(connection.get(), configuration); - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/oracle/package-info.java b/querydsl-sql/src/main/java/com/mysema/query/sql/oracle/package-info.java deleted file mode 100644 index fd6548a42a..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/oracle/package-info.java +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ - - -/** - * Oracle support for Querydsl SQL - */ -package com.mysema.query.sql.oracle; diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/package-info.java b/querydsl-sql/src/main/java/com/mysema/query/sql/package-info.java deleted file mode 100644 index 421bd4e9e6..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/package-info.java +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ - - -/** - * SQL/JDBC support for Querydsl - */ -package com.mysema.query.sql; diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/postgres/PostgresQuery.java b/querydsl-sql/src/main/java/com/mysema/query/sql/postgres/PostgresQuery.java deleted file mode 100644 index 7988ddaaf0..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/postgres/PostgresQuery.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql.postgres; - -import java.sql.Connection; - -import com.mysema.query.DefaultQueryMetadata; -import com.mysema.query.QueryFlag.Position; -import com.mysema.query.QueryMetadata; -import com.mysema.query.sql.AbstractSQLQuery; -import com.mysema.query.sql.Configuration; -import com.mysema.query.sql.PostgresTemplates; -import com.mysema.query.sql.RelationalPath; -import com.mysema.query.sql.SQLOps; -import com.mysema.query.sql.SQLQuery; -import com.mysema.query.sql.SQLTemplates; - -/** - * PostgresQuery provides Postgres related extensions to SQLQuery - * - * @author tiwe - * @see SQLQuery - * - */ -public class PostgresQuery extends AbstractSQLQuery { - - public PostgresQuery(Connection conn) { - this(conn, new Configuration(new PostgresTemplates()), new DefaultQueryMetadata()); - } - - public PostgresQuery(Connection conn, SQLTemplates templates) { - this(conn, new Configuration(templates), new DefaultQueryMetadata()); - } - - public PostgresQuery(Connection conn, Configuration configuration) { - this(conn, configuration, new DefaultQueryMetadata()); - } - - public PostgresQuery(Connection conn, Configuration configuration, QueryMetadata metadata) { - super(conn, configuration, metadata); - } - - /** - * @return - */ - public PostgresQuery forShare() { - return addFlag(SQLOps.FOR_SHARE_FLAG); - } - - /** - * @return - */ - public PostgresQuery noWait() { - return addFlag(SQLOps.NO_WAIT_FLAG); - } - - /** - * @param paths - * @return - */ - public PostgresQuery of(RelationalPath... paths) { - StringBuilder builder = new StringBuilder(" of "); - for (RelationalPath path : paths) { - if (builder.length() > 4) { - builder.append(", "); - } - builder.append(getConfiguration().getTemplates().quoteIdentifier(path.getTableName())); - } - return addFlag(Position.END, builder.toString()); - } - - @Override - public PostgresQuery clone(Connection conn) { - PostgresQuery q = new PostgresQuery(conn, getConfiguration(), getMetadata().clone()); - q.clone(this); - return q; - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/postgres/PostgresQueryFactory.java b/querydsl-sql/src/main/java/com/mysema/query/sql/postgres/PostgresQueryFactory.java deleted file mode 100644 index ecd8b45575..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/postgres/PostgresQueryFactory.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql.postgres; - -import java.sql.Connection; - -import javax.inject.Provider; - -import com.mysema.query.sql.AbstractSQLQueryFactory; -import com.mysema.query.sql.Configuration; -import com.mysema.query.sql.PostgresTemplates; -import com.mysema.query.sql.SQLSubQuery; -import com.mysema.query.sql.SQLTemplates; - -/** - * PostgreSQL specific implementation of SQLQueryFactory - * - * @author tiwe - * - */ -public class PostgresQueryFactory extends AbstractSQLQueryFactory { - - public PostgresQueryFactory(Configuration configuration, Provider connection) { - super(configuration, connection); - } - - public PostgresQueryFactory(Provider connection) { - this(new Configuration(new PostgresTemplates()), connection); - } - - public PostgresQueryFactory(SQLTemplates templates, Provider connection) { - this(new Configuration(templates), connection); - } - - public PostgresQuery query() { - return new PostgresQuery(connection.get(), configuration); - } - - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/spatial/GeometryWktClobType.java b/querydsl-sql/src/main/java/com/mysema/query/sql/spatial/GeometryWktClobType.java deleted file mode 100644 index 8309de5173..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/spatial/GeometryWktClobType.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2014, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql.spatial; - -import javax.annotation.Nullable; -import java.sql.*; - -import com.mysema.query.sql.types.AbstractType; -import org.geolatte.geom.Geometry; -import org.geolatte.geom.codec.Wkt; - -/** - * @author tiwe - * - */ -public class GeometryWktClobType extends AbstractType { - - public static final GeometryWktClobType DEFAULT = new GeometryWktClobType(); - - public GeometryWktClobType() { - super(Types.CLOB); - } - - @Override - public Class getReturnedClass() { - return Geometry.class; - } - - @Override - @Nullable - public Geometry getValue(ResultSet rs, int startIndex) throws SQLException { - Clob clob = rs.getClob(startIndex); - String str = clob != null ? clob.getSubString(1, (int) clob.length()) : null; - if (str != null) { - return Wkt.newWktDecoder(Wkt.Dialect.POSTGIS_EWKT_1).decode(str); - } else { - return null; - } - } - - @Override - public void setValue(PreparedStatement st, int startIndex, Geometry value) throws SQLException { - String str = Wkt.newWktEncoder(Wkt.Dialect.POSTGIS_EWKT_1).encode(value); - st.setString(startIndex, str); - } - - @Override - public String getLiteral(Geometry geometry) { - String str = Wkt.newWktEncoder(Wkt.Dialect.POSTGIS_EWKT_1).encode(geometry); - return "'" + str + "'"; - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/spatial/GeometryWktType.java b/querydsl-sql/src/main/java/com/mysema/query/sql/spatial/GeometryWktType.java deleted file mode 100644 index d3bd8e2977..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/spatial/GeometryWktType.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2014, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql.spatial; - -import javax.annotation.Nullable; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Types; - -import com.mysema.query.sql.types.AbstractType; -import org.geolatte.geom.Geometry; -import org.geolatte.geom.codec.Wkt; - -/** - * @author tiwe - * - */ -public class GeometryWktType extends AbstractType { - - public static final GeometryWktType DEFAULT = new GeometryWktType(); - - public GeometryWktType() { - super(Types.VARCHAR); - } - - @Override - public Class getReturnedClass() { - return Geometry.class; - } - - @Override - @Nullable - public Geometry getValue(ResultSet rs, int startIndex) throws SQLException { - String str = rs.getString(startIndex); - if (str != null) { - return Wkt.newWktDecoder(Wkt.Dialect.POSTGIS_EWKT_1).decode(str); - } else { - return null; - } - } - - @Override - public void setValue(PreparedStatement st, int startIndex, Geometry value) throws SQLException { - String str = Wkt.newWktEncoder(Wkt.Dialect.POSTGIS_EWKT_1).encode(value); - st.setString(startIndex, str); - } - - @Override - public String getLiteral(Geometry geometry) { - String str = Wkt.newWktEncoder(Wkt.Dialect.POSTGIS_EWKT_1).encode(geometry); - return "'" + str + "'"; - } -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/spatial/JGeometryConverter.java b/querydsl-sql/src/main/java/com/mysema/query/sql/spatial/JGeometryConverter.java deleted file mode 100644 index 20df004615..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/spatial/JGeometryConverter.java +++ /dev/null @@ -1,295 +0,0 @@ -/* - * Copyright 2014, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql.spatial; - -import static oracle.spatial.geometry.JGeometry.GTYPE_COLLECTION; -import static oracle.spatial.geometry.JGeometry.GTYPE_CURVE; -import static oracle.spatial.geometry.JGeometry.GTYPE_MULTICURVE; -import static oracle.spatial.geometry.JGeometry.GTYPE_MULTIPOINT; -import static oracle.spatial.geometry.JGeometry.GTYPE_MULTIPOLYGON; -import static oracle.spatial.geometry.JGeometry.GTYPE_POINT; -import static oracle.spatial.geometry.JGeometry.GTYPE_POLYGON; -import oracle.spatial.geometry.JGeometry; - -import org.geolatte.geom.DimensionalFlag; -import org.geolatte.geom.Geometry; -import org.geolatte.geom.GeometryCollection; -import org.geolatte.geom.LineString; -import org.geolatte.geom.LinearRing; -import org.geolatte.geom.MultiLineString; -import org.geolatte.geom.MultiPoint; -import org.geolatte.geom.MultiPolygon; -import org.geolatte.geom.Point; -import org.geolatte.geom.PointCollection; -import org.geolatte.geom.PointCollectionFactory; -import org.geolatte.geom.PointSequence; -import org.geolatte.geom.PolyHedralSurface; -import org.geolatte.geom.Polygon; -import org.geolatte.geom.crs.CrsId; - -/** - * @author tiwe - * - */ -public class JGeometryConverter { - - // to jgeometry - - public static JGeometry convert(Geometry geometry) { - switch (geometry.getGeometryType()) { - case POINT: return convert((Point)geometry); -// case CURVE: -// case SURFACE: - case GEOMETRY_COLLECTION: return convert((GeometryCollection)geometry); - case LINE_STRING: return convert((LineString)geometry); - case LINEAR_RING: return convert((LinearRing)geometry); - case POLYGON: return convert((Polygon)geometry); - case POLYHEDRAL_SURFACE: return convert((PolyHedralSurface)geometry); -// case MULTI_SURFACE: - case MULTI_POINT: return convert((MultiPoint)geometry); -// case TIN - case MULTI_POLYGON: return convert((MultiPolygon)geometry); - case MULTI_LINE_STRING: return convert((MultiLineString)geometry); - default: throw new IllegalArgumentException(geometry.toString()); - } - } - - private static double[] getPoints(PointCollection points) { - int dim = points.getCoordinateDimension(); - double[] values = new double[points.size() * dim]; - int offset = 0; - for (int i = 0; i < points.size(); i++) { - values[offset++] = points.getX(i); - values[offset++] = points.getY(i); - if (points.is3D()) { - values[offset++] = points.getZ(i); - } - if (points.isMeasured()) { - values[offset++] = points.getM(i); - } - } - return values; - } - - private static double[] getCoordinates(Point geometry) { - double[] value = new double[geometry.getCoordinateDimension()]; - int offset = 0; - value[offset++] = geometry.getX(); - value[offset++] = geometry.getY(); - if (geometry.is3D()) { - value[offset++] = geometry.getZ(); - } - if (geometry.isMeasured()) { - value[offset++] = geometry.getM(); - } - return value; - } - - private static JGeometry convert(Polygon geometry) { - int srid = geometry.getSRID(); - int dim = geometry.getCoordinateDimension(); - double[] points = getPoints(geometry.getPoints()); - int[] elemInfo = new int[3 + geometry.getNumInteriorRing() * 3]; - int offset = 0; - int pointOffset = 1; - elemInfo[offset++] = pointOffset; - elemInfo[offset++] = 1003; // exterior - elemInfo[offset++] = 1; - pointOffset += geometry.getExteriorRing().getNumPoints() * dim; - for (int i = 0; i < geometry.getNumInteriorRing(); i++) { - elemInfo[offset++] = pointOffset; - elemInfo[offset++] = 2003; - elemInfo[offset++] = 1; - pointOffset += geometry.getInteriorRingN(i).getNumPoints() * dim; - } - int gtype = dim * 1000 + (geometry.isMeasured() ? dim : 0) * 100 + GTYPE_POLYGON; - return new JGeometry(gtype, srid, elemInfo, points); - } - - private static JGeometry convert(PolyHedralSurface geometry) { - throw new UnsupportedOperationException(); - } - - private static JGeometry convert(LineString geometry) { - int srid = geometry.getSRID(); - int dim = geometry.getCoordinateDimension(); - double[] points = getPoints(geometry.getPoints()); - int[] elemInfo = new int[]{1, 2, 1}; - int gtype = dim * 1000 + (geometry.isMeasured() ? dim : 0) * 100 + GTYPE_CURVE; - return new JGeometry(gtype, srid, elemInfo, points); - } - - private static JGeometry convert(GeometryCollection geometry) { - // TODO - throw new UnsupportedOperationException(); - } - - private static JGeometry convert(MultiPoint geometry) { - int srid = geometry.getSRID(); - int dim = geometry.getCoordinateDimension(); - double[] points = getPoints(geometry.getPoints()); - int[] elemInfo = new int[]{1, 1, geometry.getNumPoints()}; - int gtype = dim * 1000 + (geometry.isMeasured() ? dim : 0) * 100 + GTYPE_MULTIPOINT; - return new JGeometry(gtype, srid, elemInfo, points); - } - - private static JGeometry convert(MultiPolygon geometry) { - // TODO - throw new UnsupportedOperationException(); - } - - private static JGeometry convert(MultiLineString geometry) { - int srid = geometry.getSRID(); - int dim = geometry.getCoordinateDimension(); - double[] points = getPoints(geometry.getPoints()); - int[] elemInfo = new int[geometry.getNumGeometries() * 3]; - int offset = 0; - int pointOffset = 1; - for (int i = 0; i < geometry.getNumGeometries(); i++) { - elemInfo[offset++] = pointOffset; - elemInfo[offset++] = 2; - elemInfo[offset++] = 1; - pointOffset += geometry.getGeometryN(i).getNumPoints() * dim; - } - int gtype = dim * 1000 + (geometry.isMeasured() ? dim : 0) * 100 + GTYPE_MULTICURVE; - return new JGeometry(gtype, srid, elemInfo, points); - } - - private static JGeometry convert(Point geometry) { - double[] value = getCoordinates(geometry); - int srid = geometry.getSRID(); - if (geometry.isMeasured()) { - return JGeometry.createLRSPoint(value, value.length - 1, srid); - } else { - return JGeometry.createPoint(value, value.length, srid); - } - } - - // to geolatte - - public static Geometry convert(JGeometry geometry) { - switch (geometry.getType()) { - case GTYPE_COLLECTION: return convertCollection(geometry); - case GTYPE_CURVE: return convertCurve(geometry); - case GTYPE_MULTICURVE: return convertMultiCurve(geometry); - case GTYPE_MULTIPOINT: return convertMultiPoint(geometry); - case GTYPE_MULTIPOLYGON: return convertMultiPolygon(geometry); - case GTYPE_POINT: return convertPoint(geometry); - case GTYPE_POLYGON: return convertPolygon(geometry); - default: throw new IllegalArgumentException(geometry.toString()); - } - } - - private static PointSequence getPoints(JGeometry geometry) { - int dimensions = geometry.getDimensions(); - boolean measured = geometry.isLRSGeometry(); - DimensionalFlag flag = DimensionalFlag.valueOf(dimensions > (measured ? 3 : 2), measured); - double[] ordinates = geometry.getOrdinatesArray(); - return PointCollectionFactory.create(ordinates, flag); - } - - private static Polygon convertPolygon(JGeometry geometry) { - CrsId crs = CrsId.valueOf(geometry.getSRID()); - int dimensions = geometry.getDimensions(); - boolean measured = geometry.isLRSGeometry(); - DimensionalFlag flag = DimensionalFlag.valueOf(dimensions > (measured ? 3 : 2), measured); - Object[] elements = geometry.getOrdinatesOfElements(); - LinearRing[] rings = new LinearRing[elements.length]; - for (int i = 0; i < elements.length; i++) { - PointSequence points = PointCollectionFactory.create((double[]) elements[i], flag); - rings[i] = new LinearRing(points, crs); - } - return new Polygon(rings); - } - - private static Point convertPoint(JGeometry geometry) { - CrsId crs = CrsId.valueOf(geometry.getSRID()); - double[] point = geometry.getPoint(); - int dimensions = geometry.getDimensions(); - boolean measured = geometry.isLRSGeometry(); - DimensionalFlag flag = DimensionalFlag.valueOf(dimensions > (measured ? 3 : 2), measured); - return new Point(PointCollectionFactory.create(point, flag), crs); - } - - private static LineString convertCurve(JGeometry geometry) { - CrsId crs = CrsId.valueOf(geometry.getSRID()); - PointSequence points = getPoints(geometry); - return new LineString(points, crs); - } - - private static MultiPoint convertMultiPoint(JGeometry geometry) { - CrsId crs = CrsId.valueOf(geometry.getSRID()); - JGeometry[] elements = geometry.getElements(); - if (elements == null || elements.length == 0) { - return MultiPoint.createEmpty(); - } - Point[] points = new Point[elements.length]; - int dimensions = geometry.getDimensions(); - double[] ordinates = geometry.getOrdinatesArray(); - boolean measured = geometry.isLRSGeometry(); - DimensionalFlag flag = DimensionalFlag.valueOf(dimensions > (measured ? 3 : 2), measured); - int offset = 0; - for (int i = 0; i < points.length; i++) { - double[] coords = new double[dimensions]; - System.arraycopy(ordinates, offset, coords, 0, coords.length); - points[i] = new Point(PointCollectionFactory.create(coords, flag), crs); - offset += dimensions; - } - return new MultiPoint(points); - } - - // FIXME - private static MultiPolygon convertMultiPolygon(JGeometry geometry) { - JGeometry[] elements = geometry.getElements(); - if (elements == null || elements.length == 0) { - return MultiPolygon.createEmpty(); - } - Polygon[] polygons = new Polygon[elements.length]; - for (int i = 0; i < elements.length; i++) { - polygons[i] = convertPolygon(elements[i]); - } - return new MultiPolygon(polygons); - } - - // FIXME - private static MultiLineString convertMultiCurve(JGeometry geometry) { - JGeometry[] elements = geometry.getElements(); - if (elements == null || elements.length == 0) { - return MultiLineString.createEmpty(); - } - CrsId crs = CrsId.valueOf(geometry.getSRID()); - LineString[] lineStrings = new LineString[elements.length]; - for (int i = 0; i < elements.length; i++) { - PointSequence points = getPoints(elements[i]); - lineStrings[i] = new LineString(points, crs); - } - return new MultiLineString(lineStrings); - } - - // FIXME - private static GeometryCollection convertCollection(JGeometry geometry) { - JGeometry[] elements = geometry.getElements(); - if (elements == null || elements.length == 0) { - return GeometryCollection.createEmpty(); - } - Geometry[] geometries = new Geometry[elements.length]; - for (int i = 0; i < elements.length; i++) { - geometries[i] = convert(elements[i]); - } - return new GeometryCollection(geometries); - } - - private JGeometryConverter() {} - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/spatial/JGeometryType.java b/querydsl-sql/src/main/java/com/mysema/query/sql/spatial/JGeometryType.java deleted file mode 100644 index 2718810991..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/spatial/JGeometryType.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2014, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql.spatial; - -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Types; - -import javax.annotation.Nullable; - -import oracle.spatial.geometry.JGeometry; -import oracle.sql.STRUCT; - -import org.geolatte.geom.Geometry; - -import com.mysema.query.sql.types.AbstractType; - -/** - * @author tiwe - * - */ -public class JGeometryType extends AbstractType { - - public static final JGeometryType DEFAULT = new JGeometryType(); - - public JGeometryType() { - super(Types.OTHER); - } - - @Override - public Class getReturnedClass() { - return Geometry.class; - } - - @Override - @Nullable - public Geometry getValue(ResultSet rs, int startIndex) throws SQLException { - byte[] bytes = rs.getBytes(startIndex); - if (bytes != null) { - try { - JGeometry geometry = JGeometry.load(bytes); - return JGeometryConverter.convert(geometry); - } catch (Exception e) { - throw new SQLException(e); - } - } else { - return null; - } - } - - @Override - public void setValue(PreparedStatement st, int startIndex, Geometry value) throws SQLException { - try { - JGeometry geo = JGeometryConverter.convert(value); - STRUCT struct = JGeometry.store(st.getConnection(), geo); - st.setObject(startIndex, struct); - } catch (Exception e) { - throw new SQLException(e); - } - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/spatial/MySQLSpatialTemplates.java b/querydsl-sql/src/main/java/com/mysema/query/sql/spatial/MySQLSpatialTemplates.java deleted file mode 100644 index eaf2431a46..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/spatial/MySQLSpatialTemplates.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2014, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql.spatial; - -import com.mysema.query.spatial.SpatialOps; -import com.mysema.query.sql.MySQLTemplates; -import com.mysema.query.sql.SQLTemplates; - -/** - * MySQLSpatialTemplates is a spatial enabled SQL dialect for MySQL - * - * @author tiwe - * - */ -public class MySQLSpatialTemplates extends MySQLTemplates { - - public static Builder builder() { - return new Builder() { - @Override - protected SQLTemplates build(char escape, boolean quote) { - return new MySQLSpatialTemplates(escape, quote); - } - }; - } - - public MySQLSpatialTemplates() { - this('\\', false); - } - - public MySQLSpatialTemplates(boolean quote) { - this('\\', quote); - } - - public MySQLSpatialTemplates(char escape, boolean quote) { - super(escape, quote); - addCustomType(MySQLWkbType.DEFAULT); - add(SpatialTemplatesSupport.getSpatialOps("", true)); - add(SpatialOps.NUM_INTERIOR_RING, "NumInteriorRings({0})"); - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/spatial/OracleSpatialTemplates.java b/querydsl-sql/src/main/java/com/mysema/query/sql/spatial/OracleSpatialTemplates.java deleted file mode 100644 index 6f7faef1e5..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/spatial/OracleSpatialTemplates.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2014, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql.spatial; - -import com.mysema.query.sql.OracleTemplates; -import com.mysema.query.sql.SQLTemplates; - -/** - * @author tiwe - * - */ -public class OracleSpatialTemplates extends OracleTemplates { - - public static Builder builder() { - return new Builder() { - @Override - protected SQLTemplates build(char escape, boolean quote) { - return new OracleSpatialTemplates(escape, quote); - } - }; - } - - public OracleSpatialTemplates() { - this('\\', false); - } - - public OracleSpatialTemplates(boolean quote) { - this('\\', quote); - } - - public OracleSpatialTemplates(char escape, boolean quote) { - super(escape, quote); - addCustomType(JGeometryType.DEFAULT); - // TODO - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/spatial/PGgeometryConverter.java b/querydsl-sql/src/main/java/com/mysema/query/sql/spatial/PGgeometryConverter.java deleted file mode 100644 index 489d9e4159..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/spatial/PGgeometryConverter.java +++ /dev/null @@ -1,268 +0,0 @@ -/* - * Copyright 2014, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql.spatial; - -import org.geolatte.geom.DimensionalFlag; -import org.geolatte.geom.Geometry; -import org.geolatte.geom.GeometryCollection; -import org.geolatte.geom.LineString; -import org.geolatte.geom.LinearRing; -import org.geolatte.geom.MultiLineString; -import org.geolatte.geom.MultiPoint; -import org.geolatte.geom.MultiPolygon; -import org.geolatte.geom.Point; -import org.geolatte.geom.PointCollectionFactory; -import org.geolatte.geom.PointSequence; -import org.geolatte.geom.PointSequenceBuilder; -import org.geolatte.geom.PointSequenceBuilders; -import org.geolatte.geom.PolyHedralSurface; -import org.geolatte.geom.Polygon; -import org.geolatte.geom.crs.CrsId; - - -/** - * @author tiwe - * - */ -public class PGgeometryConverter { - - // to postgis - - public static org.postgis.Geometry convert(Geometry geometry) { - if (geometry instanceof Point) { - return convert((Point)geometry); - } else if (geometry instanceof LinearRing) { - return convert((LinearRing)geometry); - } else if (geometry instanceof LineString) { - return convert((LineString)geometry); - } else if (geometry instanceof MultiLineString) { - return convert((MultiLineString)geometry); - } else if (geometry instanceof Polygon) { - return convert((Polygon)geometry); - } else if (geometry instanceof PolyHedralSurface) { - return convert((PolyHedralSurface)geometry); - } else if (geometry instanceof MultiPoint) { - return convert((MultiPoint)geometry); - } else if (geometry instanceof MultiPolygon) { - return convert((MultiPolygon)geometry); - } else if (geometry instanceof GeometryCollection) { - return convert((GeometryCollection)geometry); - } else { - throw new IllegalArgumentException(geometry.getClass().getName()); - } - } - - private static org.postgis.Point convert(Point point) { - org.postgis.Point pgPoint = new org.postgis.Point(); - pgPoint.srid = point.getSRID(); - pgPoint.dimension = point.is3D() ? 3 : 2; - pgPoint.haveMeasure = false; - pgPoint.x = point.getX(); - pgPoint.y = point.getY(); - if (point.is3D()) { - pgPoint.z = point.getZ(); - } - if (point.isMeasured()) { - pgPoint.m = point.getM(); - pgPoint.haveMeasure = true; - } - return pgPoint; - } - - private static org.postgis.Point[] convertPoints(Geometry geometry) { - org.postgis.Point[] pgPoints = new org.postgis.Point[geometry.getNumPoints()]; - for (int i = 0; i < pgPoints.length; i++) { - pgPoints[i] = convert(geometry.getPointN(i)); - } - return pgPoints; - } - - private static org.postgis.LineString convert(LineString lineString) { - org.postgis.Point[] pgPoints = convertPoints(lineString); - org.postgis.LineString pgLineString = new org.postgis.LineString(pgPoints); - pgLineString.haveMeasure = lineString.isMeasured(); - pgLineString.setSrid(lineString.getSRID()); - return pgLineString; - } - - private static org.postgis.LinearRing convert(LinearRing linearRing) { - org.postgis.Point[] pgPoints = convertPoints(linearRing); - org.postgis.LinearRing pgLinearRing = new org.postgis.LinearRing(pgPoints); - pgLinearRing.haveMeasure = linearRing.isMeasured(); - pgLinearRing.setSrid(linearRing.getSRID()); - return pgLinearRing; - } - - private static org.postgis.MultiLineString convert(MultiLineString multiLineString) { - org.postgis.LineString[] pgLineStrings = new org.postgis.LineString[multiLineString.getNumGeometries()]; - for (int i = 0; i < pgLineStrings.length; i++) { - pgLineStrings[i] = convert(multiLineString.getGeometryN(i)); - } - org.postgis.MultiLineString pgMultiLineString = new org.postgis.MultiLineString(pgLineStrings); - pgMultiLineString.haveMeasure = multiLineString.isMeasured(); - pgMultiLineString.setSrid(multiLineString.getSRID()); - return pgMultiLineString; - } - - private static org.postgis.Polygon convert(Polygon polygon) { - int numRings = polygon.getNumInteriorRing(); - org.postgis.LinearRing[] rings = new org.postgis.LinearRing[numRings + 1]; - rings[0] = convert(polygon.getExteriorRing()); - for (int i = 0; i < numRings; i++) { - rings[i+1] = convert(polygon.getInteriorRingN(i)); - } - org.postgis.Polygon pgPolygon = new org.postgis.Polygon(rings); - pgPolygon.setSrid(polygon.getSRID()); - return pgPolygon; - } - - private static org.postgis.Polygon convert(PolyHedralSurface polyHedralSurface) { - throw new UnsupportedOperationException(); - } - - private static org.postgis.MultiPoint convert(MultiPoint multiPoint) { - org.postgis.Point[] pgPoints = convertPoints(multiPoint); - org.postgis.MultiPoint pgMultiPoint = new org.postgis.MultiPoint(pgPoints); - pgMultiPoint.setSrid(multiPoint.getSRID()); - return pgMultiPoint; - } - - private static org.postgis.MultiPolygon convert(MultiPolygon multiPolygon) { - org.postgis.Polygon[] pgPolygons = new org.postgis.Polygon[multiPolygon.getNumGeometries()]; - for (int i = 0; i < pgPolygons.length; i++) { - pgPolygons[i] = convert(multiPolygon.getGeometryN(i)); - } - org.postgis.MultiPolygon pgMultiPolygon = new org.postgis.MultiPolygon(pgPolygons); - pgMultiPolygon.setSrid(multiPolygon.getSRID()); - return pgMultiPolygon; - } - - private static org.postgis.GeometryCollection convert(GeometryCollection geometryCollection) { - org.postgis.Geometry[] pgGeometries = new org.postgis.Geometry[geometryCollection.getNumGeometries()]; - for (int i = 0; i < pgGeometries.length; i++) { - pgGeometries[i] = convert(geometryCollection.getGeometryN(i)); - } - org.postgis.GeometryCollection pgGeometryCollection = new org.postgis.GeometryCollection(pgGeometries); - pgGeometryCollection.setSrid(geometryCollection.getSRID()); - return pgGeometryCollection; - } - - // to geolatte - - public static Geometry convert(org.postgis.Geometry geometry) { - switch (geometry.getType()) { - case org.postgis.Geometry.POINT: - return convert((org.postgis.Point)geometry); - case org.postgis.Geometry.LINESTRING: - return convert((org.postgis.LineString)geometry); - case org.postgis.Geometry.LINEARRING: - return convert((org.postgis.LinearRing)geometry); - case org.postgis.Geometry.POLYGON: - return convert((org.postgis.Polygon)geometry); - case org.postgis.Geometry.MULTILINESTRING: - return convert((org.postgis.MultiLineString)geometry); - case org.postgis.Geometry.MULTIPOINT: - return convert((org.postgis.MultiPoint)geometry); - case org.postgis.Geometry.MULTIPOLYGON: - return convert((org.postgis.MultiPolygon)geometry); - case org.postgis.Geometry.GEOMETRYCOLLECTION: - return convert((org.postgis.GeometryCollection)geometry); - } - throw new IllegalArgumentException(geometry.toString()); - } - - private static Point convert(org.postgis.Point geometry) { - int d = geometry.dimension; - CrsId crs = CrsId.valueOf(geometry.srid); - double[] point = new double[d + (geometry.haveMeasure ? 1 : 0)]; - int offset = 0; - point[offset++] = geometry.x; - point[offset++] = geometry.y; - if (d == 3) { - point[offset++] = geometry.z; - } - if (geometry.haveMeasure) { - point[offset++] = geometry.m; - } - DimensionalFlag flag = DimensionalFlag.valueOf(d == 3, geometry.haveMeasure); - return new Point(PointCollectionFactory.create(point, flag), crs); - } - - private static PointSequence convertPoints(org.postgis.Point[] points) { - if (points.length == 0) { - return PointCollectionFactory.createEmpty(); - } - org.postgis.Point first = points[0]; - DimensionalFlag flag = DimensionalFlag.valueOf(first.dimension == 3, first.haveMeasure); - PointSequenceBuilder pointSequence = PointSequenceBuilders.variableSized(flag); - for (int i = 0; i < points.length; i++) { - pointSequence.add(convert(points[i])); - } - return pointSequence.toPointSequence(); - } - - private static GeometryCollection convert(org.postgis.GeometryCollection geometry) { - Geometry[] geometries = new Geometry[geometry.numGeoms()]; - for (int i = 0; i < geometries.length; i++) { - geometries[i] = convert(geometry.getSubGeometry(i)); - } - return new GeometryCollection(geometries); - } - - private static MultiPolygon convert(org.postgis.MultiPolygon geometry) { - Polygon[] polygons = new Polygon[geometry.numPolygons()]; - for (int i = 0; i < polygons.length; i++) { - polygons[i] = convert(geometry.getPolygon(i)); - } - return new MultiPolygon(polygons); - } - - private static MultiPoint convert(org.postgis.MultiPoint geometry) { - Point[] points = new Point[geometry.numPoints()]; - for (int i = 0; i < points.length; i++) { - points[i] = convert(geometry.getPoint(i)); - } - return new MultiPoint(points); - } - - private static MultiLineString convert(org.postgis.MultiLineString geometry) { - LineString[] lineStrings = new LineString[geometry.numLines()]; - for (int i = 0; i < lineStrings.length; i++) { - lineStrings[i] = convert(geometry.getLine(i)); - } - return new MultiLineString(lineStrings); - } - - private static Polygon convert(org.postgis.Polygon geometry) { - LinearRing[] rings = new LinearRing[geometry.numRings()]; - for (int i = 0; i < rings.length; i++) { - rings[i] = convert(geometry.getRing(i)); - } - return new Polygon(rings); - } - - private static LinearRing convert(org.postgis.LinearRing geometry) { - PointSequence points = convertPoints(geometry.getPoints()); - return new LinearRing(points, CrsId.valueOf(geometry.getSrid())); - } - - - private static LineString convert(org.postgis.LineString geometry) { - PointSequence points = convertPoints(geometry.getPoints()); - return new LineString(points, CrsId.valueOf(geometry.getSrid())); - } - - private PGgeometryConverter() {} - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/spatial/PGgeometryType.java b/querydsl-sql/src/main/java/com/mysema/query/sql/spatial/PGgeometryType.java deleted file mode 100644 index ba658b4ffc..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/spatial/PGgeometryType.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2014, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql.spatial; - -import javax.annotation.Nullable; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Types; - -import com.mysema.query.sql.types.AbstractType; -import org.geolatte.geom.Geometry; -import org.geolatte.geom.codec.Wkt; -import org.postgis.PGgeometry; - -/** - * @author tiwe - * - */ -public class PGgeometryType extends AbstractType { - - public static final PGgeometryType DEFAULT = new PGgeometryType(); - - public PGgeometryType() { - super(Types.STRUCT); - } - - @Override - public Class getReturnedClass() { - return Geometry.class; - } - - @Override - @Nullable - public Geometry getValue(ResultSet rs, int startIndex) throws SQLException { - Object obj = rs.getObject(startIndex); - return obj != null ? PGgeometryConverter.convert(((PGgeometry) obj).getGeometry()) : null; - } - - @Override - public void setValue(PreparedStatement st, int startIndex, Geometry value) throws SQLException { - PGgeometry geometry = new PGgeometry(PGgeometryConverter.convert(value)); - st.setObject(startIndex, geometry); - } - - @Override - public String getLiteral(Geometry geometry) { - String str = Wkt.newWktEncoder(Wkt.Dialect.POSTGIS_EWKT_1).encode(geometry); - return "'" + str + "'"; - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/spatial/PostGISTemplates.java b/querydsl-sql/src/main/java/com/mysema/query/sql/spatial/PostGISTemplates.java deleted file mode 100644 index 1423183620..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/spatial/PostGISTemplates.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2014, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql.spatial; - -import com.mysema.query.spatial.SpatialOps; -import com.mysema.query.sql.PostgresTemplates; -import com.mysema.query.sql.SQLTemplates; - -/** - * PostGISTemplates is a spatial enabled SQL dialect for PostGIS - * - * @author tiwe - * - */ -public class PostGISTemplates extends PostgresTemplates { - - public static Builder builder() { - return new Builder() { - @Override - protected SQLTemplates build(char escape, boolean quote) { - return new PostGISTemplates(escape, quote); - } - }; - } - - public PostGISTemplates() { - this('\\', false); - } - - public PostGISTemplates(boolean quote) { - this('\\', quote); - } - - public PostGISTemplates(char escape, boolean quote) { - super(escape, quote); - addCustomType(PGgeometryType.DEFAULT); - add(SpatialTemplatesSupport.getSpatialOps(true)); - add(SpatialOps.DISTANCE_SPHERE, "ST_Distance_Sphere({0}, {1})"); - add(SpatialOps.DISTANCE_SPHEROID, "ST_Distance_Spheroid({0}, {1})"); - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/spatial/RelationalPathSpatial.java b/querydsl-sql/src/main/java/com/mysema/query/sql/spatial/RelationalPathSpatial.java deleted file mode 100644 index f6e3ebb56b..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/spatial/RelationalPathSpatial.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright 2014, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql.spatial; - -import org.geolatte.geom.Geometry; -import org.geolatte.geom.GeometryCollection; -import org.geolatte.geom.LineString; -import org.geolatte.geom.LinearRing; -import org.geolatte.geom.MultiLineString; -import org.geolatte.geom.MultiPoint; -import org.geolatte.geom.MultiPolygon; -import org.geolatte.geom.Point; -import org.geolatte.geom.PolyHedralSurface; -import org.geolatte.geom.Polygon; - -import com.mysema.query.spatial.path.GeometryCollectionPath; -import com.mysema.query.spatial.path.GeometryPath; -import com.mysema.query.spatial.path.GeometryPaths; -import com.mysema.query.spatial.path.LineStringPath; -import com.mysema.query.spatial.path.LinearRingPath; -import com.mysema.query.spatial.path.MultiLineStringPath; -import com.mysema.query.spatial.path.MultiPointPath; -import com.mysema.query.spatial.path.MultiPolygonPath; -import com.mysema.query.spatial.path.PointPath; -import com.mysema.query.spatial.path.PolygonPath; -import com.mysema.query.spatial.path.PolyhedralSurfacePath; -import com.mysema.query.sql.RelationalPathBase; -import com.mysema.query.types.PathMetadata; -import com.mysema.query.types.PathMetadataFactory; - -/** - * @author tiwe - * - * @param - */ -public class RelationalPathSpatial extends RelationalPathBase implements GeometryPaths { - - private static final long serialVersionUID = -7176236689794620277L; - - public RelationalPathSpatial(Class type, String variable, String schema, String table) { - this(type, PathMetadataFactory.forVariable(variable), schema, table); - } - - public RelationalPathSpatial(Class type, PathMetadata metadata, String schema, String table) { - super(type, metadata, schema, table); - } - - @Override - public GeometryCollectionPath createGeometryCollection( - String property, Class type) { - return add(new GeometryCollectionPath(type, forProperty(property))); - } - - @Override - public GeometryPath createGeometry(String property, - Class type) { - return add(new GeometryPath(type, forProperty(property))); - } - - @Override - public LinearRingPath createLinearRing(String property, - Class type) { - return add(new LinearRingPath(type, forProperty(property))); - } - - @Override - public LineStringPath createLineString(String property, - Class type) { - return add(new LineStringPath(type, forProperty(property))); - } - - @Override - public MultiLineStringPath createMultiLineString( - String property, Class type) { - return add(new MultiLineStringPath(type, forProperty(property))); - } - - @Override - public MultiPointPath createMultiPoint(String property, - Class type) { - return add(new MultiPointPath(type, forProperty(property))); - } - - @Override - public MultiPolygonPath createMultiPolygon(String property, - Class type) { - return add(new MultiPolygonPath(type, forProperty(property))); - } - - @Override - public PointPath createPoint(String property, Class type) { - return add(new PointPath(type, forProperty(property))); - } - - @Override - public PolygonPath createPolygon(String property, Class type) { - return add(new PolygonPath(type, forProperty(property))); - } - - @Override - public PolyhedralSurfacePath createPolyhedralSurface( - String property, Class type) { - return add(new PolyhedralSurfacePath(type, forProperty(property))); - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/spatial/SQLServerGeometryReader.java b/querydsl-sql/src/main/java/com/mysema/query/sql/spatial/SQLServerGeometryReader.java deleted file mode 100644 index a5de8315f4..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/spatial/SQLServerGeometryReader.java +++ /dev/null @@ -1,302 +0,0 @@ -/* - * Copyright 2014, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql.spatial; - -import java.io.IOException; -import java.util.List; - -import org.geolatte.geom.DimensionalFlag; -import org.geolatte.geom.Geometry; -import org.geolatte.geom.GeometryCollection; -import org.geolatte.geom.GeometryType; -import org.geolatte.geom.LineString; -import org.geolatte.geom.LinearRing; -import org.geolatte.geom.MultiLineString; -import org.geolatte.geom.MultiPoint; -import org.geolatte.geom.MultiPolygon; -import org.geolatte.geom.Point; -import org.geolatte.geom.PointSequence; -import org.geolatte.geom.PointSequenceBuilder; -import org.geolatte.geom.PointSequenceBuilders; -import org.geolatte.geom.Points; -import org.geolatte.geom.Polygon; -import org.geolatte.geom.crs.CrsId; - -import com.google.common.collect.Lists; -import com.vividsolutions.jts.io.ByteArrayInStream; -import com.vividsolutions.jts.io.ByteOrderDataInStream; -import com.vividsolutions.jts.io.ByteOrderValues; -import com.vividsolutions.jts.io.InStream; - -/** - * @author tiwe - * - */ -public class SQLServerGeometryReader { - - private static class Figure { - int attributes; - int pointOffset; - } - - private static class Shape { - int parentOffset; - int figureOffset; - GeometryType type; - } - - private static GeometryType[] TYPES = new GeometryType[]{ - GeometryType.POINT, - GeometryType.LINE_STRING, - GeometryType.POLYGON, - GeometryType.MULTI_POINT, - GeometryType.MULTI_LINE_STRING, - GeometryType.MULTI_POLYGON, - GeometryType.GEOMETRY_COLLECTION, - // TODO CircularString - // TODO CompoundCurve - // TODO CurvePolygon - // TODO FullGlobe - }; - - private int srid, version, serializationProps, numberOfPoints; - - private boolean hasZ, hasM, singlePoint, singleLine; - - private DimensionalFlag dimensionalFlag; - - private double[][] points; - - private double[] zValues, mValues; - - private Figure[] figures; - - private Shape[] shapes; - - private CrsId crsId; - - public Geometry read(byte[] bytes) throws IOException { - return read(new ByteArrayInStream(bytes)); - } - - public Geometry read(InStream is) throws IOException { - ByteOrderDataInStream dis = new ByteOrderDataInStream(is); - dis.setOrder(ByteOrderValues.LITTLE_ENDIAN); - - srid = dis.readInt(); - version = dis.readByte(); - serializationProps = dis.readByte(); - hasZ = (serializationProps & 1) == 1; - hasM = (serializationProps & 2) == 2; - singlePoint = (serializationProps & 8) == 8; - singleLine = (serializationProps & 16) == 16; - numberOfPoints = 1; - if (singleLine) { - numberOfPoints = 2; - } else if (!singlePoint) { - numberOfPoints = dis.readInt(); - } - dimensionalFlag = DimensionalFlag.XY; - if (hasM) { - if (hasZ) { - dimensionalFlag = DimensionalFlag.XYZM; - } else { - dimensionalFlag = DimensionalFlag.XYM; - } - } else if (hasZ) { - dimensionalFlag = DimensionalFlag.XYZ; - } - - // points - points = readPoints(dis, numberOfPoints); - if (hasZ) { - zValues = readDoubles(dis, numberOfPoints); - } - if (hasM) { - mValues = readDoubles(dis, numberOfPoints); - } - - crsId = CrsId.valueOf(srid); - if (singlePoint) { - return createPoint(0); - - } else if (singleLine) { - PointSequence points = createPoints(0, 2); - return new LineString(points, crsId); - - } else { - // figures - int numberOfFigures = dis.readInt(); - figures = readFigures(dis, numberOfFigures); - // shapes - int numberOfShapes = dis.readInt(); - shapes = readShapes(dis, numberOfShapes); - return decode(0); - } - } - - private Geometry decode(int shapeIdx) { - switch (shapes[shapeIdx].type) { - case POINT: return decodePoint(shapeIdx); - case LINE_STRING: return decodeLineString(shapeIdx); - case POLYGON: return decodePolygon(shapeIdx); - case MULTI_POINT: return decodeMultiPoint(shapeIdx); - case MULTI_LINE_STRING: return decodeMultiLineString(shapeIdx); - case MULTI_POLYGON: return decodeMultiPolygon(shapeIdx); - case GEOMETRY_COLLECTION: return decodeGeometryCollection(shapeIdx); - default: throw new IllegalArgumentException(String.valueOf(shapeIdx)); - } - } - - private GeometryCollection decodeGeometryCollection(int shapeIdx) { - List geometries = Lists.newArrayList(); - for (int i = shapeIdx; i < shapes.length; i++) { - if (shapes[i].parentOffset == shapeIdx) { - geometries.add(decode(i)); - } - } - return new GeometryCollection(geometries.toArray(new Geometry[0])); - } - - private MultiLineString decodeMultiLineString(int shapeIdx) { - List lineStrings = Lists.newArrayList(); - for (int i = shapeIdx; i < shapes.length; i++) { - if (shapes[i].parentOffset == shapeIdx) { - lineStrings.add(decodeLineString(i)); - } - } - return new MultiLineString(lineStrings.toArray(new LineString[0])); - } - - private MultiPolygon decodeMultiPolygon(int shapeIdx) { - List polygons = Lists.newArrayList(); - for (int i = shapeIdx; i < shapes.length; i++) { - if (shapes[i].parentOffset == shapeIdx) { - polygons.add(decodePolygon(i)); - } - } - return new MultiPolygon(polygons.toArray(new Polygon[0])); - } - - private MultiPoint decodeMultiPoint(int shapeIdx) { - List points = Lists.newArrayList(); - for (int i = shapeIdx; i < shapes.length; i++) { - if (shapes[i].parentOffset == shapeIdx) { - points.add(decodePoint(i)); - } - } - return new MultiPoint(points.toArray(new Point[0])); - } - - private Polygon decodePolygon(int shapeIdx) { - Shape shape = shapes[shapeIdx]; - int figureOffset = shape.figureOffset; - if (figureOffset <= -1) { - return Polygon.createEmpty(); - } - int figureStopIdx = figures.length - 1; - if (shapeIdx < (shapes.length - 1)) { - figureStopIdx = shapes[shapeIdx + 1].figureOffset - 1; - } - List linearRings = Lists.newArrayList(); - for (int i = figureOffset; i <= figureStopIdx; i++) { - linearRings.add(new LinearRing(createPoints(i), crsId)); - } - return new Polygon(linearRings.toArray(new LinearRing[0])); - } - - private LineString decodeLineString(int shapeIdx) { - Shape shape = shapes[shapeIdx]; - return new LineString(createPoints(shape.figureOffset), crsId); - } - - private Point decodePoint(int shapeIdx) { - int pointIdx = figures[shapes[shapeIdx].figureOffset].pointOffset; - return createPoint(pointIdx); - } - - private Point createPoint(int idx) { - double x = points[idx][0]; - double y = points[idx][1]; - if (hasM) { - if (hasZ) { - return Points.create(x, y, zValues[idx], mValues[idx], crsId); - } else { - return Points.createMeasured(x, y, mValues[idx], crsId); - } - } else if (hasZ) { - return Points.create3D(x, y, zValues[idx], crsId); - } else { - return Points.create(x, y, crsId); - } - } - - private PointSequence createPoints(int idx1, int idx2) { - PointSequenceBuilder builder = PointSequenceBuilders.fixedSized(idx2 - idx1, dimensionalFlag); - for (int i = idx1; i < idx2; i++) { - builder.add(createPoint(i)); - } - return builder.toPointSequence(); - } - - private PointSequence createPoints(int figureIdx) { - int idx1 = figures[figureIdx].pointOffset; - int idx2 = points.length; - if (figureIdx < (figures.length - 1)) { - idx2 = figures[figureIdx + 1].pointOffset; - } - return createPoints(idx1, idx2); - } - - private double[] readDoubles(ByteOrderDataInStream is, int num) throws IOException { - double[] doubles = new double[num]; - for (int i = 0; i < num; i++) { - doubles[i] = is.readDouble(); - } - return doubles; - } - - private Figure[] readFigures(ByteOrderDataInStream is, int num) throws IOException { - Figure[] figures = new Figure[num]; - for (int i = 0; i < num; i++) { - Figure figure = new Figure(); - figure.attributes = is.readByte(); - figure.pointOffset = is.readInt(); - figures[i] = figure; - } - return figures; - } - - private double[][] readPoints(ByteOrderDataInStream is, int num) throws IOException { - double[][] points = new double[num][]; - for (int i = 0; i < num; i++) { - points[i] = new double[]{is.readDouble(), is.readDouble()}; - } - return points; - } - - private Shape[] readShapes(ByteOrderDataInStream is, int num) throws IOException { - Shape[] shapes = new Shape[num]; - for (int i = 0; i < num; i++) { - Shape shape = new Shape(); - shape.parentOffset = is.readInt(); - shape.figureOffset = is.readInt(); - shape.type = TYPES[is.readByte() - 1]; - shapes[i] = shape; - } - return shapes; - } - - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/spatial/SQLServerGeometryType.java b/querydsl-sql/src/main/java/com/mysema/query/sql/spatial/SQLServerGeometryType.java deleted file mode 100644 index d98268a9bf..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/spatial/SQLServerGeometryType.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2014, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql.spatial; - -import javax.annotation.Nullable; -import java.io.IOException; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Types; - -import com.mysema.query.sql.types.AbstractType; -import org.geolatte.geom.Geometry; -import org.geolatte.geom.codec.Wkt; - -/** - * @author tiwe - * - */ -public class SQLServerGeometryType extends AbstractType { - - public static final SQLServerGeometryType DEFAULT = new SQLServerGeometryType(); - - public SQLServerGeometryType() { - super(Types.BLOB); - } - - @Override - public Class getReturnedClass() { - return Geometry.class; - } - - @Override - @Nullable - public Geometry getValue(ResultSet rs, int startIndex) throws SQLException { - try { - byte[] bytes = rs.getBytes(startIndex); - if (bytes != null) { - return new SQLServerGeometryReader().read(bytes); - } else { - return null; - } - } catch (IOException e) { - throw new SQLException(e); - } - } - - @Override - public void setValue(PreparedStatement st, int startIndex, Geometry value) throws SQLException { - try { - byte[] bytes = new SQLServerGeometryWriter().write(value); - st.setBytes(startIndex, bytes); - } catch (IOException e) { - throw new SQLException(e); - } - } - - @Override - public String getLiteral(Geometry geometry) { - String str = Wkt.newWktEncoder(Wkt.Dialect.POSTGIS_EWKT_1).encode(geometry); - if (geometry.getSRID() > -1) { - return "geometry::STGeomFromText('" + str + "', " + geometry.getSRID() + ")"; - } else { - return "geometry::STGeomFromText('" + str + "')"; - } - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/spatial/SQLServerGeometryWriter.java b/querydsl-sql/src/main/java/com/mysema/query/sql/spatial/SQLServerGeometryWriter.java deleted file mode 100644 index c429b1aef1..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/spatial/SQLServerGeometryWriter.java +++ /dev/null @@ -1,280 +0,0 @@ -/* - * Copyright 2014, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql.spatial; - -import java.io.IOException; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.util.List; - -import org.geolatte.geom.Geometry; -import org.geolatte.geom.GeometryCollection; -import org.geolatte.geom.LineString; -import org.geolatte.geom.MultiLineString; -import org.geolatte.geom.MultiPoint; -import org.geolatte.geom.MultiPolygon; -import org.geolatte.geom.Point; -import org.geolatte.geom.PolyHedralSurface; -import org.geolatte.geom.Polygon; - -import com.google.common.collect.Lists; - -/** - * @author tiwe - * - */ -public class SQLServerGeometryWriter { - - private static final int POINT = 1; - - private static final int LINE_STRING = 2; - - private static final int POLYGON = 3; - - private static final int MULTI_POINT = 4; - - private static final int MULTI_LINESTRING = 5; - - private static final int MULTI_POLYGON = 6; - - private static final int GEOMETRY_COLLECTION = 7; - - private static class Figure { - int attributes; - int pointOffset; - } - - private static class Shape { - int parentOffset; - int figureOffset; - int type; - } - - private List points = Lists.newArrayList(); - - private List
figures = Lists.newArrayList(); - - private List shapes = Lists.newArrayList(); - - private int calculateCapacity(Geometry geometry) { - int numPoints = points.size(); - int prefixSize = 6; - - if (geometry instanceof Point) { - int capacity = prefixSize + 16 * numPoints; - if (geometry.is3D()) { - capacity += 8 * numPoints; - } - if (geometry.isMeasured()) { - capacity += 8 * numPoints; - } - return capacity; - } - - int pointSize = 16 + (geometry.is3D() ? 8 : 0) + (geometry.isMeasured() ? 8 : 0); - int size = prefixSize + 3 * 4; // prefix + 3 ints for points, shapes and - // figures - size += numPoints * pointSize; - size += figures.size() * 5; - size += shapes.size() * 9; - return size; - } - - public byte[] write(Geometry geometry) throws IOException { - visit(geometry, -1); - - int bytes = calculateCapacity(geometry); - boolean singlePoint = geometry instanceof Point; - ByteBuffer buffer = ByteBuffer.allocate(bytes); - buffer.order(ByteOrder.LITTLE_ENDIAN); - buffer.putInt(geometry.getSRID()); - buffer.put((byte)1); - buffer.put((byte)((geometry.is3D() ? 1 : 0) - + (geometry.isMeasured() ? 2 : 0) - + 4 // is valid - + (singlePoint ? 8 : 0) - + 0)); // TODO - - if (!singlePoint) { - buffer.putInt(points.size()); - } - for (Point point : points) { - buffer.putDouble(point.getX()); - buffer.putDouble(point.getY()); - } - if (geometry.is3D()) { - for (Point point : points) { - buffer.putDouble(point.getZ()); - } - } - if (geometry.isMeasured()) { - for (Point point : points) { - buffer.putDouble(point.getM()); - } - } - if (!singlePoint) { - buffer.putInt(figures.size()); - for (Figure figure : figures) { - buffer.put((byte)figure.attributes); - buffer.putInt(figure.pointOffset); - } - buffer.putInt(shapes.size()); - for (Shape shape : shapes) { - buffer.putInt(shape.parentOffset); - buffer.putInt(shape.figureOffset); - buffer.put((byte)shape.type); - } - } - return buffer.array(); - } - - private void visit(Geometry geometry, int parent) { - switch (geometry.getGeometryType()) { - case POINT: visit((Point)geometry, parent); break; - case POLYGON: visit((Polygon)geometry, parent); break; - case LINE_STRING: visit((LineString)geometry, parent); break; - case MULTI_POINT: visit((MultiPoint)geometry, parent); break; - case MULTI_LINE_STRING: visit((MultiLineString)geometry, parent); break; - case MULTI_POLYGON: visit((MultiPolygon)geometry, parent); break; - case GEOMETRY_COLLECTION: visit((GeometryCollection)geometry, parent); break; - default: throw new IllegalArgumentException(geometry.toString()); - } - } - - public void visit(Point point, int parent) { - Shape shape = new Shape(); - shape.type = POINT; - shape.figureOffset = figures.size(); - shape.parentOffset = parent; - shapes.add(shape); - - Figure figure = new Figure(); - figure.attributes = 1; - figure.pointOffset = points.size(); - figures.add(figure); - - points.add(point); - } - - public void visit(LineString lineString, int parent) { - Shape shape = new Shape(); - shape.type = LINE_STRING; - shape.figureOffset = figures.size(); - shape.parentOffset = parent; - shapes.add(shape); - - Figure figure = new Figure(); - figure.attributes = 1; - figure.pointOffset = points.size(); - figures.add(figure); - - for (Point point : lineString.getPoints()) { - points.add(point); - } - } - - public void visit(Polygon polygon, int parent) { - Shape shape = new Shape(); - shape.type = POLYGON; - shape.figureOffset = figures.size(); - shape.parentOffset = parent; - shapes.add(shape); - - // exterior - Figure figure = new Figure(); - figure.attributes = 2; - figure.pointOffset = points.size(); - figures.add(figure); - for (Point point : polygon.getExteriorRing().getPoints()) { - points.add(point); - } - - // interior - for (int i = 0; i < polygon.getNumInteriorRing(); i++) { - figure = new Figure(); - figure.attributes = 0; - figure.pointOffset = points.size(); - figures.add(figure); - for (Point point : polygon.getInteriorRingN(i).getPoints()) { - points.add(point); - } - } - } - - public void visit(MultiPoint collection, int parent) { - Shape shape = new Shape(); - shape.type = MULTI_POINT; - shape.figureOffset = figures.size(); - shape.parentOffset = parent; - shapes.add(shape); - - parent = shapes.size() - 1; - for (int i = 0; i < collection.getNumGeometries(); i++) { - visit(collection.getGeometryN(i), parent); - } - } - - public void visit(MultiLineString collection, int parent) { - Shape shape = new Shape(); - shape.type = MULTI_LINESTRING; - shape.figureOffset = figures.size(); - shape.parentOffset = parent; - shapes.add(shape); - - parent = shapes.size() - 1; - for (int i = 0; i < collection.getNumGeometries(); i++) { - visit(collection.getGeometryN(i), parent); - } - } - - public void visit(MultiPolygon collection, int parent) { - Shape shape = new Shape(); - shape.type = MULTI_POLYGON; - shape.figureOffset = figures.size(); - shape.parentOffset = parent; - shapes.add(shape); - - parent = shapes.size() - 1; - for (int i = 0; i < collection.getNumGeometries(); i++) { - visit(collection.getGeometryN(i), parent); - } - } - - public void visit(GeometryCollection collection, int parent) { - Shape shape = new Shape(); - shape.type = GEOMETRY_COLLECTION; - shape.figureOffset = figures.size(); - shape.parentOffset = parent; - shapes.add(shape); - - parent = shapes.size() - 1; - for (int i = 0; i < collection.getNumGeometries(); i++) { - visit(collection.getGeometryN(i), parent); - } - } - - public void visit(PolyHedralSurface surface, int parent) { - Shape shape = new Shape(); - shape.type = -1; // TODO - shape.figureOffset = figures.size(); - shape.parentOffset = parent; - shapes.add(shape); - - parent = shapes.size() - 1; - for (int i = 0; i < surface.getNumPatches(); i++) { - visit(surface.getPatchN(i), parent); - } - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/teradata/SetQueryBandClause.java b/querydsl-sql/src/main/java/com/mysema/query/sql/teradata/SetQueryBandClause.java deleted file mode 100644 index 8e7e11fbc3..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/teradata/SetQueryBandClause.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright 2013, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql.teradata; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Maps; -import com.mysema.query.sql.Configuration; -import com.mysema.query.sql.SQLBindings; -import com.mysema.query.sql.SQLTemplates; -import com.mysema.query.sql.dml.AbstractSQLClause; - -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.util.List; -import java.util.Map; - -/** - * SetQueryBandClause provides support for Teradata specific set query_band executions. - * - * @author tiwe - * - */ -public class SetQueryBandClause extends AbstractSQLClause { - - private final Connection connection; - - private boolean forSession = true; - - private final Map values = Maps.newHashMap(); - - private transient String queryString; - - private transient String parameter; - - public SetQueryBandClause(Connection connection, SQLTemplates templates) { - this(connection, new Configuration(templates)); - } - - public SetQueryBandClause(Connection connection, Configuration configuration) { - super(configuration); - this.connection = connection; - } - - public SetQueryBandClause forSession() { - queryString = null; - forSession = true; - return this; - } - - public SetQueryBandClause forTransaction(){ - queryString = null; - forSession = false; - return this; - } - - public SetQueryBandClause set(String key, String value) { - queryString = null; - values.put(key, value); - return this; - } - - public SetQueryBandClause set(Map values) { - queryString = null; - this.values.putAll(values); - return this; - } - - @Override - public long execute() { - PreparedStatement stmt = null; - try { - stmt = connection.prepareStatement(toString()); - if (parameter != null) { - stmt.setString(1, parameter); - } - return 1; - } catch (SQLException e) { - List bindings = parameter != null ? ImmutableList.of(parameter) : ImmutableList.of(); - throw configuration.translate(queryString, bindings, e); - } finally { - if (stmt != null) { - close(stmt); - } - } - } - - @Override - public List getSQL() { - SQLBindings bindings; - if (configuration.getUseLiterals() || forSession) { - bindings = new SQLBindings(toString(), ImmutableList.of()); - } else { - bindings = new SQLBindings(toString(), ImmutableList.of(parameter)); - } - return ImmutableList.of(bindings); - } - - @Override - public String toString() { - if (queryString == null) { - StringBuilder builder = new StringBuilder(); - for (Map.Entry entry : values.entrySet()) { - builder.append(entry.getKey()).append("=").append(entry.getValue()); - builder.append(";"); - } - if (configuration.getUseLiterals() || forSession) { - queryString = "set query_band='" - + configuration.getTemplates().escapeLiteral(builder.toString()) - + (forSession ? "' for session" : "' for transaction"); - parameter = null; - } else { - queryString = "set query_band=?" + (forSession ? " for session" : " for transaction"); - parameter = builder.toString(); - } - - } - return queryString; - } -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/teradata/TeradataQuery.java b/querydsl-sql/src/main/java/com/mysema/query/sql/teradata/TeradataQuery.java deleted file mode 100644 index 5d22f39a6f..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/teradata/TeradataQuery.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2013, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql.teradata; - -import java.sql.Connection; - -import com.mysema.query.DefaultQueryMetadata; -import com.mysema.query.QueryFlag; -import com.mysema.query.QueryMetadata; -import com.mysema.query.sql.AbstractSQLQuery; -import com.mysema.query.sql.Configuration; -import com.mysema.query.sql.SQLOps; -import com.mysema.query.sql.SQLTemplates; -import com.mysema.query.sql.TeradataTemplates; -import com.mysema.query.types.Predicate; -import com.mysema.query.types.PredicateOperation; - -/** - * TeradataQuery provides Teradata related extensions to SQLQuery - * - * @author tiwe - * - */ -public class TeradataQuery extends AbstractSQLQuery { - - public TeradataQuery(Connection conn) { - this(conn, new Configuration(new TeradataTemplates()), new DefaultQueryMetadata()); - } - - public TeradataQuery(Connection conn, SQLTemplates templates) { - this(conn, new Configuration(templates), new DefaultQueryMetadata()); - } - - public TeradataQuery(Connection conn, Configuration configuration) { - this(conn, configuration, new DefaultQueryMetadata()); - } - - public TeradataQuery(Connection conn, Configuration configuration, QueryMetadata metadata) { - super(conn, configuration, metadata); - } - - /** - * Adds a qualify expression - * - * @param predicate - * @return - */ - public TeradataQuery qualify(Predicate predicate) { - predicate = PredicateOperation.create(SQLOps.QUALIFY, predicate); - return queryMixin.addFlag(new QueryFlag(QueryFlag.Position.BEFORE_ORDER, predicate)); - } - - @Override - public TeradataQuery clone(Connection conn) { - TeradataQuery q = new TeradataQuery(conn, getConfiguration(), getMetadata().clone()); - q.clone(this); - return q; - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/teradata/TeradataQueryFactory.java b/querydsl-sql/src/main/java/com/mysema/query/sql/teradata/TeradataQueryFactory.java deleted file mode 100644 index e486347c44..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/teradata/TeradataQueryFactory.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql.teradata; - -import java.sql.Connection; - -import javax.inject.Provider; - -import com.mysema.query.sql.AbstractSQLQueryFactory; -import com.mysema.query.sql.Configuration; -import com.mysema.query.sql.SQLSubQuery; -import com.mysema.query.sql.SQLTemplates; -import com.mysema.query.sql.TeradataTemplates; - -/** - * Teradata specific implementation of SQLQueryFactory - * - * @author tiwe - * - */ -public class TeradataQueryFactory extends AbstractSQLQueryFactory { - - public TeradataQueryFactory(Configuration configuration, Provider connection) { - super(configuration, connection); - } - - public TeradataQueryFactory(Provider connection) { - this(new Configuration(new TeradataTemplates()), connection); - } - - public TeradataQueryFactory(SQLTemplates templates, Provider connection) { - this(new Configuration(templates), connection); - } - - @Override - public TeradataQuery query() { - return new TeradataQuery(connection.get(), configuration); - } - - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/types/AbstractDateTimeType.java b/querydsl-sql/src/main/java/com/mysema/query/sql/types/AbstractDateTimeType.java deleted file mode 100644 index 7e0ec7e3c6..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/types/AbstractDateTimeType.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2014, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql.types; - -import org.joda.time.format.DateTimeFormat; -import org.joda.time.format.DateTimeFormatter; - -import java.util.Calendar; -import java.util.TimeZone; - -/** - * Common abstract superclass for Type implementations - * - * @author tiwe - * - * @param - */ -public abstract class AbstractDateTimeType extends AbstractType { - - private static final Calendar UTC = Calendar.getInstance(TimeZone.getTimeZone("UTC")); - - static { - UTC.setTimeInMillis(0); - } - - protected static Calendar utc() { - return (Calendar) UTC.clone(); - } - - protected static final DateTimeFormatter dateFormatter = DateTimeFormat.forPattern("yyyy-MM-dd"); - - protected static final DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss"); - - protected static final DateTimeFormatter timeFormatter = DateTimeFormat.forPattern("HH:mm:ss"); - - public AbstractDateTimeType(int type) { - super(type); - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/types/AbstractNumberType.java b/querydsl-sql/src/main/java/com/mysema/query/sql/types/AbstractNumberType.java deleted file mode 100644 index 29f11597b1..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/types/AbstractNumberType.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql.types; - -import java.sql.ResultSet; -import java.sql.SQLException; - -import com.mysema.util.MathUtils; - -/** - * @author tiwe - * - * @param - */ -public abstract class AbstractNumberType> extends AbstractType { - - public AbstractNumberType(int type) { - super(type); - } - - @Override - public T getValue(ResultSet rs, int startIndex) throws SQLException { - Number num = (Number) rs.getObject(startIndex); - return num != null ? MathUtils.cast(num, getReturnedClass()) : null; - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/types/ByteType.java b/querydsl-sql/src/main/java/com/mysema/query/sql/types/ByteType.java deleted file mode 100644 index aa18c441cd..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/types/ByteType.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql.types; - -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.sql.Types; - -/** - * ByteType maps Byte to Byte on the JDBC level - * - * @author tiwe - * - */ -public class ByteType extends AbstractNumberType { - - public ByteType() { - super(Types.TINYINT); - } - - public ByteType(int type) { - super(type); - } - - @Override - public Class getReturnedClass() { - return Byte.class; - } - - @Override - public void setValue(PreparedStatement st, int startIndex, Byte value) throws SQLException { - st.setByte(startIndex, value); - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/types/DoubleType.java b/querydsl-sql/src/main/java/com/mysema/query/sql/types/DoubleType.java deleted file mode 100644 index a1c61bc292..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/types/DoubleType.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql.types; - -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.sql.Types; - -/** - * DoubleType maps Double to Double on the JDBC level - * - * @author tiwe - * - */ -public class DoubleType extends AbstractNumberType { - - public DoubleType() { - super(Types.DOUBLE); - } - - public DoubleType(int type) { - super(type); - } - - @Override - public Class getReturnedClass() { - return Double.class; - } - - @Override - public void setValue(PreparedStatement st, int startIndex, Double value) throws SQLException { - st.setDouble(startIndex, value); - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/types/FloatType.java b/querydsl-sql/src/main/java/com/mysema/query/sql/types/FloatType.java deleted file mode 100644 index 909ee6322d..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/types/FloatType.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql.types; - -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.sql.Types; - -/** - * FloatType maps Float to Float on the JDBC level - * - * @author tiwe - * - */ -public class FloatType extends AbstractNumberType { - - public FloatType() { - super(Types.FLOAT); - } - - public FloatType(int type) { - super(type); - } - - @Override - public Class getReturnedClass() { - return Float.class; - } - - @Override - public void setValue(PreparedStatement st, int startIndex, Float value) throws SQLException { - st.setFloat(startIndex, value); - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/types/IntegerType.java b/querydsl-sql/src/main/java/com/mysema/query/sql/types/IntegerType.java deleted file mode 100644 index 2cc213fea4..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/types/IntegerType.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql.types; - -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.sql.Types; - -/** - * IntegerType maps Integer to Integer on the JDBC level - * - * @author tiwe - * - */ -public class IntegerType extends AbstractNumberType { - - public IntegerType() { - super(Types.INTEGER); - } - - public IntegerType(int type) { - super(type); - } - - @Override - public Class getReturnedClass() { - return Integer.class; - } - - @Override - public void setValue(PreparedStatement st, int startIndex, Integer value) throws SQLException { - st.setInt(startIndex, value); - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/types/LongType.java b/querydsl-sql/src/main/java/com/mysema/query/sql/types/LongType.java deleted file mode 100644 index a9331b7a7b..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/types/LongType.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql.types; - -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.sql.Types; - -/** - * LongType maps Long to Long on the JDBC level - * - * @author tiwe - * - */ -public class LongType extends AbstractNumberType { - - public LongType() { - super(Types.BIGINT); - } - - public LongType(int type) { - super(type); - } - - @Override - public Class getReturnedClass() { - return Long.class; - } - - @Override - public void setValue(PreparedStatement st, int startIndex, Long value) throws SQLException { - st.setLong(startIndex, value); - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/types/Null.java b/querydsl-sql/src/main/java/com/mysema/query/sql/types/Null.java deleted file mode 100644 index 3cfdebbfa8..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/types/Null.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql.types; - -import com.mysema.query.types.Constant; -import com.mysema.query.types.ConstantImpl; - -/** - * @author tiwe - * - */ -public final class Null { - - public static final Null DEFAULT = new Null(); - - public static final Constant CONSTANT = ConstantImpl.create(DEFAULT); - - private Null() {} - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/types/NumericBooleanType.java b/querydsl-sql/src/main/java/com/mysema/query/sql/types/NumericBooleanType.java deleted file mode 100644 index 75ad920a0f..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/types/NumericBooleanType.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2013, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql.types; - -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Types; - -import javax.annotation.Nullable; - -/** - * NumericBooleanType maps Boolean to 1/0 (Integer) on the JDBC level - * - * @author tiwe - * - */ -public class NumericBooleanType extends AbstractType { - - public NumericBooleanType() { - super(Types.INTEGER); - } - - public NumericBooleanType(int type) { - super(type); - } - - @Override - public Class getReturnedClass() { - return Boolean.class; - } - - @Override - @Nullable - public Boolean getValue(ResultSet rs, int startIndex) throws SQLException { - Number num = (Number) rs.getObject(startIndex); - return num != null ? Boolean.valueOf(num.intValue() == 1) : null; - } - - @Override - public void setValue(PreparedStatement st, int startIndex, Boolean value) throws SQLException { - st.setInt(startIndex, value.booleanValue() ? 1 : 0); - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/types/ShortType.java b/querydsl-sql/src/main/java/com/mysema/query/sql/types/ShortType.java deleted file mode 100644 index 4ef3fe3330..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/types/ShortType.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql.types; - -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.sql.Types; - -/** - * ShortType maps Short to Short on the JDBC level - * - * @author tiwe - * - */ -public class ShortType extends AbstractNumberType { - - public ShortType() { - super(Types.SMALLINT); - } - - public ShortType(int type) { - super(type); - } - - @Override - public Class getReturnedClass() { - return Short.class; - } - - @Override - public void setValue(PreparedStatement st, int startIndex, Short value) throws SQLException { - st.setShort(startIndex, value); - } - -} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/types/Type.java b/querydsl-sql/src/main/java/com/mysema/query/sql/types/Type.java deleted file mode 100644 index 23c44402e1..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/types/Type.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql.types; - -import javax.annotation.Nullable; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; - -/** - * Defines the de/serialization of a typed Java object from a ResultSet or to a PreparedStatement - * - *

getValue(ResultSet, int) is used for extraction and setValue(PreparedStatement, int, T) is - * used for population

- * - * @author tiwe - * - * @param - */ -// TODO : rename this since it clashes with com.mysema.codegen.model.Type -public interface Type { - - /** - * Get the SQL supported SQL types - * - * @return - */ - int[] getSQLTypes(); - - /** - * Get the returned type - * - * @return - */ - Class getReturnedClass(); - - /** - * Get the literal representation - * - * @param value - * @return - */ - String getLiteral(T value); - - /** - * Get the object from the result set - * - * @param rs result set - * @param startIndex column index in result set - * @return - * @throws SQLException - */ - @Nullable - T getValue(ResultSet rs, int startIndex) throws SQLException; - - /** - * Set the object to the statement - * - * @param st statement - * @param startIndex column index in statement - * @param value value to be set - * @throws SQLException - */ - void setValue(PreparedStatement st, int startIndex, T value) throws SQLException; - -} \ No newline at end of file diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/types/UtilUUIDType.java b/querydsl-sql/src/main/java/com/mysema/query/sql/types/UtilUUIDType.java deleted file mode 100644 index 9ce744b1a5..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/types/UtilUUIDType.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2013, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql.types; - -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Types; -import java.util.UUID; - -/** - * UtilUUIDType maps UUID to String on the JDBC level - * - * @author tiwe - * - */ -public class UtilUUIDType extends AbstractType { - - public UtilUUIDType() { - super(Types.OTHER); - } - - public UtilUUIDType(int type) { - super(type); - } - - @Override - public UUID getValue(ResultSet rs, int startIndex) throws SQLException { - return UUID.fromString(rs.getString(startIndex)); - } - - @Override - public Class getReturnedClass() { - return UUID.class; - } - - @Override - public void setValue(PreparedStatement st, int startIndex, UUID value) throws SQLException { - st.setString(startIndex, value.toString()); - } -} \ No newline at end of file diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/types/package-info.java b/querydsl-sql/src/main/java/com/mysema/query/sql/types/package-info.java deleted file mode 100644 index 94bf5542cf..0000000000 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/types/package-info.java +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ - - -/** - * Types for de/serialization to ResultSet and PreparedStatement - */ -package com.mysema.query.sql.types; diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/AbstractSQLQuery.java b/querydsl-sql/src/main/java/com/querydsl/sql/AbstractSQLQuery.java new file mode 100644 index 0000000000..eae79e7efa --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/AbstractSQLQuery.java @@ -0,0 +1,681 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import java.lang.reflect.InvocationTargetException; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.function.Supplier; + +import org.jetbrains.annotations.Nullable; + +import com.mysema.commons.lang.CloseableIterator; +import com.querydsl.core.*; +import com.querydsl.core.support.QueryMixin; +import com.querydsl.core.types.*; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.SimpleExpression; +import com.querydsl.core.types.dsl.Wildcard; +import com.querydsl.core.util.ResultSetAdapter; + +/** + * {@code AbstractSQLQuery} is the base type for SQL query implementations + * + * @param result type + * @param concrete subtype + * + * @author tiwe + */ +public abstract class AbstractSQLQuery> extends ProjectableSQLQuery { + + protected static final String PARENT_CONTEXT = AbstractSQLQuery.class.getName() + "#PARENT_CONTEXT"; + + private static final Logger logger = Logger.getLogger(AbstractSQLQuery.class.getName()); + + private static final QueryFlag rowCountFlag = new QueryFlag(QueryFlag.Position.AFTER_PROJECTION, ", count(*) over() "); + + @Nullable + private Supplier connProvider; + + @Nullable + private Connection conn; + + protected SQLListeners listeners; + + protected boolean useLiterals; + + private boolean getLastCell; + + private Object lastCell; + + private SQLListenerContext parentContext; + + private StatementOptions statementOptions = StatementOptions.DEFAULT; + + public AbstractSQLQuery(@Nullable Connection conn, Configuration configuration) { + this(conn, configuration, new DefaultQueryMetadata()); + } + + public AbstractSQLQuery(@Nullable Connection conn, Configuration configuration, QueryMetadata metadata) { + super(new QueryMixin(metadata, false), configuration); + this.conn = conn; + this.listeners = new SQLListeners(configuration.getListeners()); + this.useLiterals = configuration.getUseLiterals(); + } + + public AbstractSQLQuery(Supplier connProvider, Configuration configuration) { + this(connProvider, configuration, new DefaultQueryMetadata()); + } + + public AbstractSQLQuery(Supplier connProvider, Configuration configuration, QueryMetadata metadata) { + super(new QueryMixin(metadata, false), configuration); + this.connProvider = connProvider; + this.listeners = new SQLListeners(configuration.getListeners()); + this.useLiterals = configuration.getUseLiterals(); + } + + /** + * Create an alias for the expression + * + * @param alias alias + * @return this as alias + */ + public SimpleExpression as(String alias) { + return Expressions.as(this, alias); + } + + /** + * Create an alias for the expression + * + * @param alias alias + * @return this as alias + */ + @SuppressWarnings("unchecked") + public SimpleExpression as(Path alias) { + return Expressions.as(this, (Path) alias); + } + + /** + * Add a listener + * + * @param listener listener to add + */ + public void addListener(SQLListener listener) { + listeners.add(listener); + } + + @Override + public long fetchCount() { + try { + return unsafeCount(); + } catch (SQLException e) { + String error = "Caught " + e.getClass().getName(); + logger.log(Level.SEVERE, error, e); + throw configuration.translate(e); + } + } + + /** + * If you use forUpdate() with a backend that uses page or row locks, rows examined by the + * query are write-locked until the end of the current transaction. + * + * Not supported for SQLite and CUBRID + * + * @return the current object + */ + public Q forUpdate() { + QueryFlag forUpdateFlag = configuration.getTemplates().getForUpdateFlag(); + return addFlag(forUpdateFlag); + } + + /** + * FOR SHARE causes the rows retrieved by the SELECT statement to be locked as though for update. + * + * Supported by MySQL, PostgreSQL, SQLServer. + * + * @return the current object + * + * @throws QueryException + * if the FOR SHARE is not supported. + */ + public Q forShare() { + return forShare(false); + } + + /** + * FOR SHARE causes the rows retrieved by the SELECT statement to be locked as though for update. + * + * Supported by MySQL, PostgreSQL, SQLServer. + * + * @param fallbackToForUpdate + * if the FOR SHARE is not supported and this parameter is true, the + * {@link #forUpdate()} functionality will be used. + * + * @return the current object + * + * @throws QueryException + * if the FOR SHARE is not supported and fallbackToForUpdate is set to + * false. + */ + public Q forShare(boolean fallbackToForUpdate) { + SQLTemplates sqlTemplates = configuration.getTemplates(); + + if (sqlTemplates.isForShareSupported()) { + QueryFlag forShareFlag = sqlTemplates.getForShareFlag(); + return addFlag(forShareFlag); + } + + if (fallbackToForUpdate) { + return forUpdate(); + } + + throw new QueryException("Using forShare() is not supported"); + } + + @Override + protected SQLSerializer createSerializer() { + SQLSerializer serializer = new SQLSerializer(configuration); + serializer.setUseLiterals(useLiterals); + return serializer; + } + + @Nullable + private U get(ResultSet rs, Expression expr, int i, Class type) throws SQLException { + return configuration.get(rs, expr instanceof Path ? (Path) expr : null, i, type); + } + + private void set(PreparedStatement stmt, Path path, int i, Object value) throws SQLException { + configuration.set(stmt, path, i, value); + } + + /** + * Called to create and start a new SQL Listener context + * + * @param connection the database connection + * @param metadata the meta data for that context + * @return the newly started context + */ + protected SQLListenerContextImpl startContext(Connection connection, QueryMetadata metadata) { + SQLListenerContextImpl context = new SQLListenerContextImpl(metadata, connection); + if (parentContext != null) { + context.setData(PARENT_CONTEXT, parentContext); + } + listeners.start(context); + return context; + } + + /** + * Called to make the call back to listeners when an exception happens + * + * @param context the current context in play + * @param e the exception + */ + protected void onException(SQLListenerContextImpl context, Exception e) { + context.setException(e); + listeners.exception(context); + } + + /** + * Called to end a SQL listener context + * + * @param context the listener context to end + */ + protected void endContext(SQLListenerContext context) { + listeners.end(context); + } + + /** + * Get the results as a JDBC ResultSet + * + * @param exprs the expression arguments to retrieve + * @return results as ResultSet + * @deprecated Use @{code select(..)} to define the projection and {@code getResults()} to obtain + * the result set + */ + @Deprecated + public ResultSet getResults(Expression... exprs) { + if (exprs.length > 0) { + queryMixin.setProjection(exprs); + } + return getResults(); + } + + /** + * Get the results as a JDBC ResultSet + * + * @return results as ResultSet + */ + public ResultSet getResults() { + final SQLListenerContextImpl context = startContext(connection(), queryMixin.getMetadata()); + String queryString = null; + List constants = Collections.emptyList(); + + try { + listeners.preRender(context); + SQLSerializer serializer = serialize(false); + queryString = serializer.toString(); + logQuery(queryString, serializer.getConstants()); + context.addSQL(getSQL(serializer)); + listeners.rendered(context); + + listeners.notifyQuery(queryMixin.getMetadata()); + + constants = serializer.getConstants(); + + listeners.prePrepare(context); + final PreparedStatement stmt = getPreparedStatement(queryString); + setParameters(stmt, constants, serializer.getConstantPaths(), getMetadata().getParams()); + context.addPreparedStatement(stmt); + listeners.prepared(context); + + listeners.preExecute(context); + final ResultSet rs = stmt.executeQuery(); + listeners.executed(context); + + return new ResultSetAdapter(rs) { + @Override + public void close() throws SQLException { + try { + super.close(); + } finally { + stmt.close(); + reset(); + endContext(context); + } + } + }; + } catch (SQLException e) { + onException(context, e); + reset(); + endContext(context); + throw configuration.translate(queryString, constants, e); + } + } + + private PreparedStatement getPreparedStatement(String queryString) throws SQLException { + PreparedStatement statement = connection().prepareStatement(queryString); + if (statementOptions.getFetchSize() != null) { + statement.setFetchSize(statementOptions.getFetchSize()); + } + if (statementOptions.getMaxFieldSize() != null) { + statement.setMaxFieldSize(statementOptions.getMaxFieldSize()); + } + if (statementOptions.getQueryTimeout() != null) { + statement.setQueryTimeout(statementOptions.getQueryTimeout()); + } + if (statementOptions.getMaxRows() != null) { + statement.setMaxRows(statementOptions.getMaxRows()); + } + return statement; + } + + protected Configuration getConfiguration() { + return configuration; + } + + @SuppressWarnings("unchecked") + @Override + public CloseableIterator iterate() { + Expression expr = (Expression) queryMixin.getMetadata().getProjection(); + return iterateSingle(queryMixin.getMetadata(), expr); + } + + @SuppressWarnings("unchecked") + private CloseableIterator iterateSingle(QueryMetadata metadata, @Nullable final Expression expr) { + SQLListenerContextImpl context = startContext(connection(), queryMixin.getMetadata()); + String queryString = null; + List constants = Collections.emptyList(); + + try { + listeners.preRender(context); + SQLSerializer serializer = serialize(false); + queryString = serializer.toString(); + logQuery(queryString, serializer.getConstants()); + context.addSQL(getSQL(serializer)); + listeners.rendered(context); + + + listeners.notifyQuery(queryMixin.getMetadata()); + constants = serializer.getConstants(); + + listeners.prePrepare(context); + final PreparedStatement stmt = getPreparedStatement(queryString); + setParameters(stmt, constants, serializer.getConstantPaths(), metadata.getParams()); + context.addPreparedStatement(stmt); + listeners.prepared(context); + + listeners.preExecute(context); + final ResultSet rs = stmt.executeQuery(); + listeners.executed(context); + + if (expr == null) { + return new SQLResultIterator(configuration, stmt, rs, listeners, context) { + @Override + public T produceNext(ResultSet rs) throws Exception { + return (T) rs.getObject(1); + } + }; + } else if (expr instanceof FactoryExpression) { + return new SQLResultIterator(configuration, stmt, rs, listeners, context) { + @Override + public T produceNext(ResultSet rs) throws Exception { + return newInstance((FactoryExpression) expr, rs, 0); + } + }; + } else if (expr.equals(Wildcard.all)) { + return new SQLResultIterator(configuration, stmt, rs, listeners, context) { + @Override + public T produceNext(ResultSet rs) throws Exception { + Object[] rv = new Object[rs.getMetaData().getColumnCount()]; + for (int i = 0; i < rv.length; i++) { + rv[i] = rs.getObject(i + 1); + } + return (T) rv; + } + }; + } else { + return new SQLResultIterator(configuration, stmt, rs, listeners, context) { + @Override + public T produceNext(ResultSet rs) throws Exception { + return get(rs, expr, 1, expr.getType()); + } + }; + } + + } catch (SQLException e) { + onException(context, e); + endContext(context); + throw configuration.translate(queryString, constants, e); + } catch (RuntimeException e) { + logger.log(Level.SEVERE, "Caught " + e.getClass().getName() + " for " + queryString); + onException(context, e); + endContext(context); + throw e; + } finally { + reset(); + } + } + + @SuppressWarnings("unchecked") + @Override + public List fetch() { + Expression expr = (Expression) queryMixin.getMetadata().getProjection(); + SQLListenerContextImpl context = startContext(connection(), queryMixin.getMetadata()); + String queryString = null; + List constants = Collections.emptyList(); + + try { + listeners.preRender(context); + SQLSerializer serializer = serialize(false); + queryString = serializer.toString(); + logQuery(queryString, serializer.getConstants()); + context.addSQL(getSQL(serializer)); + listeners.rendered(context); + + listeners.notifyQuery(queryMixin.getMetadata()); + constants = serializer.getConstants(); + + listeners.prePrepare(context); + try (PreparedStatement stmt = getPreparedStatement(queryString)) { + setParameters(stmt, constants, serializer.getConstantPaths(), queryMixin.getMetadata().getParams()); + context.addPreparedStatement(stmt); + listeners.prepared(context); + + listeners.preExecute(context); + try (ResultSet rs = stmt.executeQuery()) { + listeners.executed(context); + lastCell = null; + final List rv = new ArrayList(); + if (expr instanceof FactoryExpression) { + FactoryExpression fe = (FactoryExpression) expr; + while (rs.next()) { + if (getLastCell) { + lastCell = rs.getObject(fe.getArgs().size() + 1); + getLastCell = false; + } + rv.add(newInstance(fe, rs, 0)); + } + } else if (expr.equals(Wildcard.all)) { + while (rs.next()) { + Object[] row = new Object[rs.getMetaData().getColumnCount()]; + if (getLastCell) { + lastCell = rs.getObject(row.length); + getLastCell = false; + } + for (int i = 0; i < row.length; i++) { + row[i] = rs.getObject(i + 1); + } + rv.add((T) row); + } + } else { + while (rs.next()) { + if (getLastCell) { + lastCell = rs.getObject(2); + getLastCell = false; + } + rv.add(get(rs, expr, 1, expr.getType())); + } + } + return rv; + } catch (IllegalAccessException | InstantiationException | InvocationTargetException e) { + onException(context, e); + throw new QueryException(e); + } catch (SQLException e) { + onException(context, e); + throw configuration.translate(queryString, constants, e); + } + } + } catch (SQLException e) { + onException(context, e); + throw configuration.translate(queryString, constants, e); + } finally { + endContext(context); + reset(); + } + } + + @SuppressWarnings("unchecked") + @Override + public QueryResults fetchResults() { + parentContext = startContext(connection(), queryMixin.getMetadata()); + Expression expr = (Expression) queryMixin.getMetadata().getProjection(); + QueryModifiers originalModifiers = queryMixin.getMetadata().getModifiers(); + try { + if (configuration.getTemplates().isCountViaAnalytics() + && queryMixin.getMetadata().getGroupBy().isEmpty()) { + List results; + try { + queryMixin.addFlag(rowCountFlag); + getLastCell = true; + results = fetch(); + } finally { + queryMixin.removeFlag(rowCountFlag); + } + long total; + if (!results.isEmpty()) { + if (lastCell instanceof Number) { + total = ((Number) lastCell).longValue(); + } else { + throw new IllegalStateException("Unsupported lastCell instance " + lastCell); + } + } else { + total = fetchCount(); + } + return new QueryResults(results, originalModifiers, total); + + } else { + queryMixin.setProjection(expr); + long total = fetchCount(); + if (total > 0) { + return new QueryResults(fetch(), originalModifiers, total); + } else { + return QueryResults.emptyResults(); + } + } + + } finally { + endContext(parentContext); + reset(); + getLastCell = false; + parentContext = null; + } + } + + private RT newInstance(FactoryExpression c, ResultSet rs, int offset) + throws InstantiationException, IllegalAccessException, InvocationTargetException, SQLException { + Object[] args = new Object[c.getArgs().size()]; + for (int i = 0; i < args.length; i++) { + args[i] = get(rs, c.getArgs().get(i), offset + i + 1, c.getArgs().get(i).getType()); + } + return c.newInstance(args); + } + + private void reset() { + } + + protected void setParameters(PreparedStatement stmt, List objects, List> constantPaths, + Map, ?> params) { + if (objects.size() != constantPaths.size()) { + throw new IllegalArgumentException("Expected " + objects.size() + + " paths, but got " + constantPaths.size()); + } + for (int i = 0; i < objects.size(); i++) { + Object o = objects.get(i); + try { + if (o instanceof ParamExpression) { + if (!params.containsKey(o)) { + throw new ParamNotSetException((ParamExpression) o); + } + o = params.get(o); + } + set(stmt, constantPaths.get(i), i + 1, o); + } catch (SQLException e) { + throw configuration.translate(e); + } + } + } + + private long unsafeCount() throws SQLException { + SQLListenerContextImpl context = startContext(connection(), getMetadata()); + String queryString = null; + List constants = Collections.emptyList(); + PreparedStatement stmt = null; + ResultSet rs = null; + + try { + listeners.preRender(context); + SQLSerializer serializer = serialize(true); + queryString = serializer.toString(); + logQuery(queryString, serializer.getConstants()); + context.addSQL(getSQL(serializer)); + listeners.rendered(context); + + constants = serializer.getConstants(); + listeners.prePrepare(context); + + stmt = getPreparedStatement(queryString); + setParameters(stmt, constants, serializer.getConstantPaths(), getMetadata().getParams()); + + context.addPreparedStatement(stmt); + listeners.prepared(context); + + listeners.preExecute(context); + rs = stmt.executeQuery(); + boolean hasResult = rs.next(); + listeners.executed(context); + + if (hasResult) { + return rs.getLong(1); + } else { + return 0; + } + } catch (SQLException e) { + onException(context, e); + throw configuration.translate(queryString, constants, e); + } finally { + try { + if (rs != null) { + rs.close(); + } + } finally { + if (stmt != null) { + stmt.close(); + } + } + endContext(context); + } + } + + protected void logQuery(String queryString, Collection parameters) { + if (logger.isLoggable(Level.FINE)) { + String normalizedQuery = queryString.replace('\n', ' '); + logger.fine(normalizedQuery); + } + } + + private Connection connection() { + if (conn == null) { + if (connProvider != null) { + conn = connProvider.get(); + } else { + throw new IllegalStateException("No connection provided"); + } + } + return conn; + } + + /** + * Set whether literals are used in SQL strings instead of parameter bindings (default: false) + * + *

Warning: When literals are used, prepared statement won't have any parameter bindings + * and also batch statements will only be simulated, but not executed as actual batch statements.

+ * + * @param useLiterals true for literals and false for bindings + */ + public void setUseLiterals(boolean useLiterals) { + this.useLiterals = useLiterals; + } + + @Override + protected void clone(Q query) { + super.clone(query); + this.useLiterals = query.useLiterals; + this.listeners = new SQLListeners(query.listeners); + } + + @Override + public Q clone() { + return this.clone(this.conn); + } + + public abstract Q clone(Connection connection); + + /** + * Set the options to be applied to the JDBC statements of this query + * + * @param statementOptions options to be applied to statements + */ + public void setStatementOptions(StatementOptions statementOptions) { + this.statementOptions = statementOptions; + } +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/AbstractSQLQueryFactory.java b/querydsl-sql/src/main/java/com/querydsl/sql/AbstractSQLQueryFactory.java new file mode 100644 index 0000000000..fd845ca13d --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/AbstractSQLQueryFactory.java @@ -0,0 +1,150 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import java.sql.Connection; +import java.util.function.Supplier; + +import com.querydsl.core.Tuple; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.SubQueryExpression; +import com.querydsl.sql.dml.SQLDeleteClause; +import com.querydsl.sql.dml.SQLInsertClause; +import com.querydsl.sql.dml.SQLMergeClause; +import com.querydsl.sql.dml.SQLUpdateClause; + +/** + * {@code AbstractSQLQueryFactory} is the base class for {@link SQLCommonQueryFactory} implementations + * + * @param query type + * + * @author tiwe + */ +public abstract class AbstractSQLQueryFactory> implements SQLCommonQueryFactory { + + protected final Configuration configuration; + + protected final Supplier connection; + + public AbstractSQLQueryFactory(Configuration configuration, Supplier connProvider) { + this.configuration = configuration; + this.connection = connProvider; + } + + @Override + public final SQLDeleteClause delete(RelationalPath path) { + return new SQLDeleteClause(connection, configuration, path); + } + + @SuppressWarnings("unchecked") + @Override + public final Q from(Expression from) { + return (Q) query().from(from); + } + + @SuppressWarnings("unchecked") + @Override + public final Q from(Expression... args) { + return (Q) query().from(args); + } + + @SuppressWarnings("unchecked") + @Override + public final Q from(SubQueryExpression subQuery, Path alias) { + return (Q) query().from(subQuery, alias); + } + + @Override + public final SQLInsertClause insert(RelationalPath path) { + return new SQLInsertClause(connection, configuration, path); + } + + @Override + public final SQLMergeClause merge(RelationalPath path) { + return new SQLMergeClause(connection, configuration, path); + } + + @Override + public final SQLUpdateClause update(RelationalPath path) { + return new SQLUpdateClause(connection, configuration, path); + } + + public final Configuration getConfiguration() { + return configuration; + } + + public final Connection getConnection() { + return connection.get(); + } + + /** + * Create a new SQL query with the given projection + * + * @param expr projection + * @param type of the projection + * @return select(expr) + */ + public abstract AbstractSQLQuery select(Expression expr); + + /** + * Create a new SQL query with the given projection + * + * @param exprs projection + * @return select(exprs) + */ + public abstract AbstractSQLQuery select(Expression... exprs); + + /** + * Create a new SQL query with the given projection + * + * @param expr distinct projection + * @param type of the projection + * @return select(distinct expr) + */ + public abstract AbstractSQLQuery selectDistinct(Expression expr); + + /** + * Create a new SQL query with the given projection + * + * @param exprs distinct projection + * @return select(distinct exprs) + */ + public abstract AbstractSQLQuery selectDistinct(Expression... exprs); + + /** + * Create a new SQL query with zero as the projection + * + * @return select(0) + */ + public abstract AbstractSQLQuery selectZero(); + + /** + * Create a new SQL query with one as the projection + * + * @return select(1) + */ + public abstract AbstractSQLQuery selectOne(); + + /** + * Create a new SQL query with the given projection and source + * + * @param expr query source and projection + * @param type of the projection + * @return select(expr).from(expr) + */ + public abstract AbstractSQLQuery selectFrom(RelationalPath expr); + +} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/Beans.java b/querydsl-sql/src/main/java/com/querydsl/sql/Beans.java similarity index 83% rename from querydsl-sql/src/main/java/com/mysema/query/sql/Beans.java rename to querydsl-sql/src/main/java/com/querydsl/sql/Beans.java index da5badf2c3..8a7d10cf4e 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/Beans.java +++ b/querydsl-sql/src/main/java/com/querydsl/sql/Beans.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,13 +11,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql; +package com.querydsl.sql; import java.util.Map; /** - * Beans contains Objects mapped to {@link RelationalPath} instances - * + * {@code Beans} contains Objects mapped to {@link RelationalPath} instances + * * @author luis */ public class Beans { diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/CUBRIDTemplates.java b/querydsl-sql/src/main/java/com/querydsl/sql/CUBRIDTemplates.java new file mode 100644 index 0000000000..c432efb9a5 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/CUBRIDTemplates.java @@ -0,0 +1,147 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import java.sql.Types; + +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.QueryModifiers; +import com.querydsl.core.types.Ops; +import com.querydsl.sql.types.NumericBooleanType; + +/** + * {@code CUBRIDTemplates} is a SQL dialect for CUBRID + * + * @author tiwe + * + */ +public class CUBRIDTemplates extends SQLTemplates { + + @SuppressWarnings("FieldNameHidesFieldInSuperclass") //Intentional + public static final CUBRIDTemplates DEFAULT = new CUBRIDTemplates(); + + public static Builder builder() { + return new Builder() { + @Override + protected SQLTemplates build(char escape, boolean quote) { + return new CUBRIDTemplates(escape, quote); + } + }; + } + + private String limitTemplate = "\nlimit {0}"; + + private String offsetLimitTemplate = "\nlimit {0}, {1}"; + + public CUBRIDTemplates() { + this('\\', false); + } + + public CUBRIDTemplates(boolean quote) { + this('\\',quote); + } + + public CUBRIDTemplates(char escape, boolean quote) { + super(Keywords.CUBRID, "\"", escape, quote, false); + setDummyTable(null); + addCustomType(NumericBooleanType.DEFAULT); + setParameterMetadataAvailable(false); + setNullsFirst(null); + setNullsLast(null); + setDefaultValues("\ndefault values"); + setArraysSupported(false); + + add(Ops.DateTimeOps.DATE, "trunc({0})"); + + add(Ops.DateTimeOps.DAY_OF_YEAR, "dayofyear({0})"); + add(Ops.DateTimeOps.DAY_OF_WEEK, "dayofweek({0})"); + add(Ops.DateTimeOps.YEAR_WEEK, "(year({0}) * 100 + week({0}))"); + + add(Ops.DateTimeOps.ADD_YEARS, "date_add({0}, interval {1s} year)"); + add(Ops.DateTimeOps.ADD_MONTHS, "date_add({0}, interval {1s} month)"); + add(Ops.DateTimeOps.ADD_WEEKS, "date_add({0}, interval {1s} week)"); + add(Ops.DateTimeOps.ADD_DAYS, "date_add({0}, interval {1s} day)"); + add(Ops.DateTimeOps.ADD_HOURS, "date_add({0}, interval {1s} hour)"); + add(Ops.DateTimeOps.ADD_MINUTES, "date_add({0}, interval {1s} minute)"); + add(Ops.DateTimeOps.ADD_SECONDS, "date_add({0}, interval {1s} second)"); + + String diffSeconds = "(unix_timestamp({1}) - unix_timestamp({0}))"; + add(Ops.DateTimeOps.DIFF_YEARS, "(year({1}) - year({0}))"); + add(Ops.DateTimeOps.DIFF_MONTHS, "months_between({1}, {0})"); + add(Ops.DateTimeOps.DIFF_WEEKS, "ceil(({1}-{0}) / 7)"); + add(Ops.DateTimeOps.DIFF_DAYS, "({1}-{0})"); + add(Ops.DateTimeOps.DIFF_HOURS, "ceil(" + diffSeconds + " / 3600)"); + add(Ops.DateTimeOps.DIFF_MINUTES, "ceil(" + diffSeconds + " / 60)"); + add(Ops.DateTimeOps.DIFF_SECONDS, diffSeconds); + + add(Ops.DateTimeOps.TRUNC_YEAR, "trunc({0},'yyyy')"); + add(Ops.DateTimeOps.TRUNC_MONTH, "trunc({0},'mm')"); + add(Ops.DateTimeOps.TRUNC_WEEK, "trunc({0},'day')"); + add(Ops.DateTimeOps.TRUNC_DAY, "trunc({0},'dd')"); + // trunc works only with date arguments + // timestamp(datepart, timepart) reconstructs a datetime + add(Ops.DateTimeOps.TRUNC_HOUR, "timestamp(date({0}),concat(hour({0}),':00:00'))"); + add(Ops.DateTimeOps.TRUNC_MINUTE, "timestamp(date({0}),concat(hour({0}),':',minute({0}),':00'))"); + add(Ops.DateTimeOps.TRUNC_SECOND, "timestamp(date({0}),concat(hour({0}),':',minute({0}),':',second({0})))"); + + add(Ops.MathOps.LN, "ln({0})"); + add(Ops.MathOps.LOG, "(ln({0}) / ln({1}))"); + add(Ops.MathOps.COSH, "(exp({0}) + exp({0*'-1'})) / 2"); + add(Ops.MathOps.COTH, "(exp({0*'2'}) + 1) / (exp({0*'2'}) - 1)"); + add(Ops.MathOps.SINH, "(exp({0}) - exp({0*'-1'})) / 2"); + add(Ops.MathOps.TANH, "(exp({0*'2'}) - 1) / (exp({0*'2'}) + 1)"); + + add(SQLOps.GROUP_CONCAT2, "group_concat({0} separator '{1s}')"); + + addTypeNameToCode("numeric(1,0)", Types.BOOLEAN, true); + addTypeNameToCode("numeric(3,0)", Types.TINYINT, true); + addTypeNameToCode("numeric(38,0)", Types.BIGINT, true); + addTypeNameToCode("bit varying", Types.LONGVARBINARY); + addTypeNameToCode("bit varying", Types.VARBINARY); + addTypeNameToCode("bit", Types.BINARY, true); + addTypeNameToCode("varchar", Types.LONGVARCHAR, true); + addTypeNameToCode("double", Types.FLOAT, true); + addTypeNameToCode("float", Types.REAL, true); + } + + + @Override + public String serialize(String literal, int jdbcType) { + switch (jdbcType) { + case Types.TIMESTAMP: + return "timestamp'" + literal + "'"; + case Types.DATE: + return "date'" + literal + "'"; + case Types.TIME: + return "time'" + literal + "'"; + default: + return super.serialize(literal, jdbcType); + } + } + + @Override + protected void serializeModifiers(QueryMetadata metadata, SQLSerializer context) { + QueryModifiers mod = metadata.getModifiers(); + if (mod.getLimit() != null) { + if (mod.getOffset() != null) { + context.handle(offsetLimitTemplate, mod.getOffset(), mod.getLimit()); + } else { + context.handle(limitTemplate, mod.getLimit()); + } + } else if (mod.getOffset() != null) { + context.handle(offsetLimitTemplate, mod.getOffset(), Integer.MAX_VALUE); + } + } + +} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/Column.java b/querydsl-sql/src/main/java/com/querydsl/sql/Column.java similarity index 88% rename from querydsl-sql/src/main/java/com/mysema/query/sql/Column.java rename to querydsl-sql/src/main/java/com/querydsl/sql/Column.java index c6d3344504..bfbeac7378 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/Column.java +++ b/querydsl-sql/src/main/java/com/querydsl/sql/Column.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql; +package com.querydsl.sql; import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.METHOD; @@ -23,7 +23,7 @@ /** * Defines the related SQL table column for a property - * + * * @author tiwe * */ @@ -31,8 +31,10 @@ @Target({FIELD,METHOD}) @Retention(RUNTIME) public @interface Column { - + /** + * Get the column name + * * @return column name */ String value(); diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/ColumnImpl.java b/querydsl-sql/src/main/java/com/querydsl/sql/ColumnImpl.java similarity index 85% rename from querydsl-sql/src/main/java/com/mysema/query/sql/ColumnImpl.java rename to querydsl-sql/src/main/java/com/querydsl/sql/ColumnImpl.java index 624888c6ac..e2c1e671ad 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/ColumnImpl.java +++ b/querydsl-sql/src/main/java/com/querydsl/sql/ColumnImpl.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,14 +11,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql; +package com.querydsl.sql; import java.lang.annotation.Annotation; /** - * ColumnImpl is an implementation for the Column annotation - * + * ColumnImpl is an implementation of the {@link Column} annotation + * * @author tiwe * */ diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/ColumnMetadata.java b/querydsl-sql/src/main/java/com/querydsl/sql/ColumnMetadata.java similarity index 87% rename from querydsl-sql/src/main/java/com/mysema/query/sql/ColumnMetadata.java rename to querydsl-sql/src/main/java/com/querydsl/sql/ColumnMetadata.java index 490708f9da..111bbac0e8 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/ColumnMetadata.java +++ b/querydsl-sql/src/main/java/com/querydsl/sql/ColumnMetadata.java @@ -1,5 +1,5 @@ /* - * Copyright 2013, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,13 +11,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql; +package com.querydsl.sql; import java.io.Serializable; +import java.util.Objects; -import com.google.common.base.Objects; -import com.mysema.query.types.EntityPath; -import com.mysema.query.types.Path; +import com.querydsl.core.types.EntityPath; +import com.querydsl.core.types.Path; /** * Provides metadata like the column name, JDBC type and constraints @@ -35,18 +35,24 @@ public static ColumnMetadata getColumnMetadata(Path path) { if (parent instanceof EntityPath) { Object columnMetadata = ((EntityPath) parent).getMetadata(path); if (columnMetadata instanceof ColumnMetadata) { - return (ColumnMetadata)columnMetadata; + return (ColumnMetadata) columnMetadata; } } return ColumnMetadata.named(path.getMetadata().getName()); } + /** + * Extract the column name for the given path, returns the path name, if no ColumnMetadata is attached + * + * @param path patch + * @return column name or path name + */ public static String getName(Path path) { Path parent = path.getMetadata().getParent(); if (parent instanceof EntityPath) { Object columnMetadata = ((EntityPath) parent).getMetadata(path); if (columnMetadata instanceof ColumnMetadata) { - return ((ColumnMetadata)columnMetadata).getName(); + return ((ColumnMetadata) columnMetadata).getName(); } } return path.getMetadata().getName(); @@ -67,7 +73,7 @@ public static ColumnMetadata named(String name) { private static final int UNDEFINED = -1; private final String name; - + private final Integer index; private final Integer jdbcType; @@ -91,11 +97,11 @@ private ColumnMetadata(Integer index, String name, Integer jdbcType, boolean nul public String getName() { return name; } - + public int getIndex() { return index; } - + public ColumnMetadata withIndex(int index) { return new ColumnMetadata(index, name, jdbcType, nullable, size, decimalDigits); } @@ -123,7 +129,7 @@ public ColumnMetadata notNull() { /** * For char or date types this is the maximum number of characters, for numeric or decimal types this is precision. * - * @return + * @return size */ public int getSize() { return size; @@ -140,7 +146,7 @@ public ColumnMetadata withSize(int size) { /** * the number of fractional digits * - * @return + * @return digits */ public int getDigits() { return decimalDigits; @@ -159,9 +165,9 @@ public boolean equals(Object o) { if (o == this) { return true; } else if (o instanceof ColumnMetadata) { - ColumnMetadata md = (ColumnMetadata)o; + ColumnMetadata md = (ColumnMetadata) o; return name.equals(md.name) - && Objects.equal(jdbcType, md.jdbcType) + && Objects.equals(jdbcType, md.jdbcType) && nullable == md.nullable && size == md.size && decimalDigits == md.decimalDigits; diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/Configuration.java b/querydsl-sql/src/main/java/com/querydsl/sql/Configuration.java new file mode 100644 index 0000000000..13ab128785 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/Configuration.java @@ -0,0 +1,567 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import java.lang.reflect.Array; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Types; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.logging.Logger; + +import org.jetbrains.annotations.Nullable; + +import com.querydsl.core.util.PrimitiveUtils; + +import com.querydsl.core.types.Path; +import com.querydsl.sql.namemapping.ChainedNameMapping; +import com.querydsl.sql.namemapping.NameMapping; +import com.querydsl.sql.namemapping.PreConfiguredNameMapping; +import com.querydsl.sql.types.ArrayType; +import com.querydsl.sql.types.Null; +import com.querydsl.sql.types.Type; + +/** + * Configuration for SQLQuery instances + * + * @author tiwe + * + */ +public final class Configuration { + + private static final Logger logger = Logger.getLogger(Configuration.class.getName()); + + static final Configuration DEFAULT = new Configuration(SQLTemplates.DEFAULT); + + private final JDBCTypeMapping jdbcTypeMapping = new JDBCTypeMapping(); + + private final JavaTypeMapping javaTypeMapping = new JavaTypeMapping(); + + private final PreConfiguredNameMapping internalNameMapping = new PreConfiguredNameMapping(); + + private NameMapping nameMapping = internalNameMapping; + + private final Map schemaMapping = new HashMap<>(); + + private final Map> typeToName = new HashMap<>(); + + private SQLTemplates templates; + + private SQLExceptionTranslator exceptionTranslator = DefaultSQLExceptionTranslator.DEFAULT; + + private final SQLListeners listeners = new SQLListeners(); + + private boolean hasTableColumnTypes = false; + + private boolean useLiterals = false; + + /** + * Create a new Configuration instance + * + * @param templates templates for SQL serialization + */ + @SuppressWarnings("unchecked") + public Configuration(SQLTemplates templates) { + this.templates = templates; + for (Type customType : templates.getCustomTypes()) { + javaTypeMapping.register(customType); + } + for (Map.Entry entry : templates.getTableOverrides().entrySet()) { + registerTableOverride(entry.getKey(), entry.getValue()); + } + + if (templates.isArraysSupported()) { + // register array types + List> classes = Arrays.asList(String.class, Long.class, Integer.class, Short.class, + Byte.class, Boolean.class, java.sql.Date.class, java.sql.Timestamp.class, + java.sql.Time.class, Double.class, Float.class); + for (Class cl : classes) { + int code = jdbcTypeMapping.get(cl); + String name = templates.getTypeNameForCode(code); + Class arrType = Array.newInstance(cl, 0).getClass(); + javaTypeMapping.register(new ArrayType(arrType, name)); + if (PrimitiveUtils.isWrapperType(cl) && !cl.equals(Byte.class)) { + cl = PrimitiveUtils.unwrap(cl); + arrType = Array.newInstance(cl, 0).getClass(); + javaTypeMapping.register(new ArrayType(arrType, name)); + } + } + } + + } + + /** + * Get the literal representation of the given constant + * + * @param o object + * @return literal representation + */ + @SuppressWarnings("unchecked") + public String asLiteral(Object o) { + if (o == null || o instanceof Null) { + return "null"; + } else { + Type type = javaTypeMapping.getType(o.getClass()); + if (type != null) { + return templates.serialize(type.getLiteral(o), type.getSQLTypes()[0]); + } else { + throw new IllegalArgumentException("Unsupported literal type " + o.getClass().getName()); + } + } + } + + public SQLTemplates getTemplates() { + return templates; + } + + /** + * Get the java type for the given jdbc type, table name and column name + * + * @param sqlType JDBC type + * @param typeName JDBC type name + * @param size size + * @param digits digits + * @param tableName table name + * @param columnName column name + * @return Java type + */ + public Class getJavaType(int sqlType, String typeName, int size, int digits, String tableName, String columnName) { + // table.column mapped class + Type type = javaTypeMapping.getType(tableName, columnName); + if (type != null) { + return type.getReturnedClass(); + } else if (typeName != null && !typeName.isEmpty()) { + typeName = typeName.toLowerCase(); + // typename mapped class + Class clazz = typeToName.get(typeName); + if (clazz != null) { + return clazz; + } + if (sqlType == Types.ARRAY) { + if (typeName.startsWith("_")) { + typeName = typeName.substring(1); + } else if (typeName.endsWith(" array")) { + typeName = typeName.substring(0, typeName.length() - 6); + } + if (typeName.contains("[")) { + typeName = typeName.substring(0, typeName.indexOf("[")); + } + if (typeName.contains("(")) { + typeName = typeName.substring(0, typeName.indexOf("(")); + } + + Integer sqlComponentType = templates.getCodeForTypeName(typeName); + if (sqlComponentType == null) { + logger.warning("Found no JDBC type for " + typeName + " using OTHER instead"); + sqlComponentType = Types.OTHER; + } + Class componentType = jdbcTypeMapping.get(sqlComponentType, size, digits); + return Array.newInstance(componentType, 0).getClass(); + } + } + // sql type mapped class + return jdbcTypeMapping.get(sqlType, size, digits); + } + + /** + * Get the value at the given index from the result set + * + * @param type to return + * @param rs result set + * @param path path + * @param i one based index in result set row + * @param clazz type + * @return value + * @throws SQLException + */ + @Nullable + public T get(ResultSet rs, @Nullable Path path, int i, Class clazz) throws SQLException { + return getType(path, clazz).getValue(rs, i); + } + + /** + * Get the schema/table override + * + * @param key schema and table + * @return overridden schema and table + */ + @Nullable + public SchemaAndTable getOverride(SchemaAndTable key) { + SchemaAndTable result = nameMapping.getOverride(key).orElse(key); + if (schemaMapping.containsKey(key.getSchema())) { + result = new SchemaAndTable(schemaMapping.get(key.getSchema()), result.getTable()); + } + return result; + } + + /** + * Get the column override + * + * @param key schema and table + * @param column column + * @return overridden column + */ + public String getColumnOverride(SchemaAndTable key, String column) { + return nameMapping.getColumnOverride(key, column).orElse(column); + } + + /** + * Programmers can specify name mappings by implementing the + * {@link NameMapping} interface. The mapping rules that are specified by + * this property are checked if no mapping is specified by any of the + * register*Override functions. + * + * @param nameMapping + * The name mapping that is implemented by the user. + */ + public void setDynamicNameMapping(NameMapping nameMapping) { + if (nameMapping == null) { + this.nameMapping = this.internalNameMapping; + } else { + this.nameMapping = new ChainedNameMapping(this.internalNameMapping, nameMapping); + } + } + + /** + * Set the value at the given index in the statement + * + * @param + * @param stmt statement + * @param path path + * @param i one based index in statement + * @param value value to bind + * @throws SQLException + */ + @SuppressWarnings({ "unchecked", "rawtypes" }) + public void set(PreparedStatement stmt, Path path, int i, T value) throws SQLException { + if (value == null || value instanceof Null) { + Integer sqlType = null; + if (path != null) { + ColumnMetadata columnMetadata = ColumnMetadata.getColumnMetadata(path); + if (columnMetadata.hasJdbcType()) { + sqlType = columnMetadata.getJdbcType(); + } + } + if (sqlType != null) { + stmt.setNull(i, sqlType); + } else { + stmt.setNull(i, Types.NULL); + } + } else { + getType(path, (Class) value.getClass()).setValue(stmt, i, value); + } + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + private Type getType(@Nullable Path path, Class clazz) { + if (hasTableColumnTypes && path != null && !clazz.equals(Null.class) + && path.getMetadata().getParent() instanceof RelationalPath) { + String table = ((RelationalPath) path.getMetadata().getParent()).getTableName(); + String column = ColumnMetadata.getName(path); + Type type = (Type) javaTypeMapping.getType(table, column); + if (type != null) { + return type; + } + } + return javaTypeMapping.getType(clazz); + } + + /** + * Get the SQL type name for the given java type + * + * @param type java type + * @return SQL type name + */ + public String getTypeName(Class type) { + Integer jdbcType = jdbcTypeMapping.get(type); + if (jdbcType == null) { + jdbcType = javaTypeMapping.getType(type).getSQLTypes()[0]; + } + return templates.getTypeNameForCode(jdbcType); + } + + /** + * Get the SQL type name for a cast operation + * + * @param type java type + * @return SQL type name + */ + public String getTypeNameForCast(Class type) { + Integer jdbcType = jdbcTypeMapping.get(type); + if (jdbcType == null) { + jdbcType = javaTypeMapping.getType(type).getSQLTypes()[0]; + } + return templates.getCastTypeNameForCode(jdbcType); + } + + /** + * Register a schema override + * + * @param oldSchema schema to override + * @param newSchema override + * @return previous override value + * + * @deprecated Use {@link #setDynamicNameMapping(NameMapping)} instead. + */ + @Deprecated + public String registerSchemaOverride(String oldSchema, String newSchema) { + return schemaMapping.put(oldSchema, newSchema); + } + + /** + * Register a table override + * + * @param oldTable table to override + * @param newTable override + * @return previous override value + * + * @deprecated Use {@link #setDynamicNameMapping(NameMapping)} instead. + */ + @Deprecated + public String registerTableOverride(String oldTable, String newTable) { + return internalNameMapping.registerTableOverride(oldTable, newTable); + } + + /** + * Register a schema specific table override + * + * @param schema schema of table + * @param oldTable table to override + * @param newTable override + * @return previous override value + * + * @deprecated Use {@link #setDynamicNameMapping(NameMapping)} instead. + */ + @Deprecated + public String registerTableOverride(String schema, String oldTable, String newTable) { + SchemaAndTable st = registerTableOverride(schema, oldTable, schema, newTable); + return st != null ? st.getTable() : null; + } + + /** + * Register a schema specific table override + * + * @param schema schema of table + * @param oldTable table to override + * @param newSchema override schema + * @param newTable override table + * @return previous override value + * + * @deprecated Use {@link #setDynamicNameMapping(NameMapping)} instead. + */ + @Deprecated + public SchemaAndTable registerTableOverride(String schema, String oldTable, String newSchema, String newTable) { + return registerTableOverride(new SchemaAndTable(schema, oldTable), new SchemaAndTable(newSchema, newTable)); + } + + /** + * Register a schema specific table override + * + * @param from schema and table to override + * @param to override + * @return previous override + * + * @deprecated Use {@link #setDynamicNameMapping(NameMapping)} instead. + */ + @Deprecated + public SchemaAndTable registerTableOverride(SchemaAndTable from, SchemaAndTable to) { + return internalNameMapping.registerTableOverride(from, to); + } + + /** + * Register a column override + * + * @param schema schema + * @param table table + * @param oldColumn column + * @param newColumn override + * @return previous override + * + * @deprecated Use {@link #setDynamicNameMapping(NameMapping)} instead. + */ + @Deprecated + public String registerColumnOverride(String schema, String table, String oldColumn, String newColumn) { + return internalNameMapping.registerColumnOverride(schema, table, oldColumn, newColumn); + } + + /** + * Register a column override + * + * @param table table + * @param oldColumn column + * @param newColumn override + * @return previous override + * + * @deprecated Use {@link #setDynamicNameMapping(NameMapping)} instead. + */ + @Deprecated + public String registerColumnOverride(String table, String oldColumn, String newColumn) { + return internalNameMapping.registerColumnOverride(table, oldColumn, newColumn); + } + + /** + * Register the given {@link Type} converter + * + * @param type type + */ + public void register(Type type) { + jdbcTypeMapping.register(type.getSQLTypes()[0], type.getReturnedClass()); + javaTypeMapping.register(type); + } + + /** + * Register a typeName to Class mapping + * + * @param typeName SQL type name + * @param clazz java type + */ + public void registerType(String typeName, Class clazz) { + typeToName.put(typeName.toLowerCase(), clazz); + } + + /** + * Override the binding for the given NUMERIC type + * + * @param total total amount of digits + * @param decimal amount of fractional digits + * @param javaType java type + */ + public void registerNumeric(int total, int decimal, Class javaType) { + jdbcTypeMapping.registerNumeric(total, decimal, javaType); + } + + /** + * Override multiple numeric bindings, both begin and end are inclusive + * + * @param beginTotal inclusive start of range + * @param endTotal inclusive end of range + * @param beginDecimal inclusive start of range + * @param endDecimal inclusive end of range + * @param javaType java type + */ + public void registerNumeric(int beginTotal, int endTotal, int beginDecimal, int endDecimal, Class javaType) { + for (int total = beginTotal; total <= endTotal; total++) { + for (int decimal = beginDecimal; decimal <= endDecimal; decimal++) { + registerNumeric(total, decimal, javaType); + } + } + } + + /** + * Register the given javaType for the given table and column + * + * @param table table + * @param column column + * @param javaType java type + */ + public void register(String table, String column, Class javaType) { + register(table, column, javaTypeMapping.getType(javaType)); + } + + /** + * Register the given {@link Type} converter for the given table and column + * + * @param table table + * @param column column + * @param type type + */ + public void register(String table, String column, Type type) { + javaTypeMapping.setType(table, column, type); + hasTableColumnTypes = true; + } + + /** + * Translate the given SQLException + * + * @param ex SQLException to translate + * @return translated exception + */ + public RuntimeException translate(SQLException ex) { + return exceptionTranslator.translate(ex); + } + + /** + * Translate the given SQLException + * + * @param sql SQL string + * @param bindings bindings + * @param ex SQLException to translate + * @return translated exception + */ + public RuntimeException translate(String sql, List bindings, SQLException ex) { + return exceptionTranslator.translate(sql, bindings, ex); + } + + /** + * Add a listener + * + * @param listener listener + */ + public void addListener(SQLListener listener) { + listeners.add(listener); + } + + /** + * Get the registered listener + * + * @return listeners as single listener instance + */ + public SQLListeners getListeners() { + return listeners; + } + + /** + * Get whether literals are serialized or prepared statement bindings are used + * + * @return true for literals and false for bindings + */ + public boolean getUseLiterals() { + return useLiterals; + } + + /** + * Set whether literals are used in SQL strings instead of parameter bindings (default: false) + * + *

Warning: When literals are used, prepared statement won't have any parameter bindings + * and also batch statements will only be simulated, but not executed as actual batch statements.

+ * + * @param useLiterals true for literals and false for bindings + */ + public void setUseLiterals(boolean useLiterals) { + this.useLiterals = useLiterals; + } + + /** + * Set the exception translator + * + * @param exceptionTranslator exception translator + */ + public void setExceptionTranslator(SQLExceptionTranslator exceptionTranslator) { + this.exceptionTranslator = exceptionTranslator; + } + + /** + * Set the templates to use for serialization + * + * @param templates templates + */ + public void setTemplates(SQLTemplates templates) { + this.templates = templates; + } + +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/DB2Templates.java b/querydsl-sql/src/main/java/com/querydsl/sql/DB2Templates.java new file mode 100644 index 0000000000..19ad78058d --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/DB2Templates.java @@ -0,0 +1,183 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import java.sql.Types; + +import com.querydsl.core.QueryFlag; +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.QueryModifiers; +import com.querydsl.core.types.*; + +/** + * {@code DB2Templates} is an SQL dialect for DB2 10.1.2 + * + * @author tiwe + * + */ +public class DB2Templates extends SQLTemplates { + + @SuppressWarnings("FieldNameHidesFieldInSuperclass") //Intentional + public static final DB2Templates DEFAULT = new DB2Templates(); + + private String limitTemplate = "\nfetch first {0s} rows only"; + + private String outerQueryStart = "select * from (\n "; + + private String outerQueryEnd = ") a where "; + + private String limitOffsetTemplate = "rn > {0} and rn <= {1}"; + + private String offsetTemplate = "rn > {0}"; + + private String outerQuerySuffix = " order by rn"; + + public static Builder builder() { + return new Builder() { + @Override + protected SQLTemplates build(char escape, boolean quote) { + return new DB2Templates(escape, quote); + } + }; + } + + public DB2Templates() { + this('\\',false); + } + + public DB2Templates(boolean quote) { + this('\\',quote); + } + + public DB2Templates(char escape, boolean quote) { + super(Keywords.DB2, "\"", escape, quote, false); + setDummyTable("sysibm.sysdummy1"); + setAutoIncrement(" generated always as identity"); + setFunctionJoinsWrapped(true); + setDefaultValues("\nvalues (default)"); + setNullsFirst(null); + setNullsLast(null); + + setPrecedence(Precedence.ARITH_HIGH, Ops.CONCAT); + setPrecedence(Precedence.COMPARISON - 1, Ops.EQ, Ops.EQ_IGNORE_CASE, Ops.NE, Ops.LT, Ops.GT, Ops.LOE, Ops.GOE); + setPrecedence(Precedence.COMPARISON, Ops.IS_NULL, Ops.IS_NOT_NULL, Ops.LIKE, Ops.LIKE_ESCAPE, Ops.BETWEEN, + Ops.IN, Ops.NOT_IN, Ops.EXISTS); + + setPrecedence(Precedence.COMPARISON, OTHER_LIKE_CASES); + + add(SQLOps.NEXTVAL, "next value for {0s}"); + + add(Ops.MathOps.RANDOM, "rand()"); + add(Ops.MathOps.LN, "log({0})"); + add(Ops.MathOps.LOG, "(log({0}) / log({1}))"); + add(Ops.MathOps.COTH, "(exp({0*'2'}) + 1) / (exp({0*'2'}) - 1)"); + + // overrides of the SQL standard functions + add(Ops.DateTimeOps.SECOND, "second({0})"); + add(Ops.DateTimeOps.MINUTE, "minute({0})"); + add(Ops.DateTimeOps.HOUR, "hour({0})"); + add(Ops.DateTimeOps.WEEK, "week({0})"); + add(Ops.DateTimeOps.MONTH, "month({0})"); + add(Ops.DateTimeOps.YEAR, "year({0})"); + add(Ops.DateTimeOps.YEAR_MONTH, "(year({0}) * 100 + month({0}))"); + add(Ops.DateTimeOps.YEAR_WEEK, "(year({0}) * 100 + week({0}))"); + add(Ops.DateTimeOps.DAY_OF_WEEK, "dayofweek({0})"); + add(Ops.DateTimeOps.DAY_OF_MONTH, "day({0})"); + add(Ops.DateTimeOps.DAY_OF_YEAR, "dayofyear({0})"); + + add(Ops.DateTimeOps.ADD_YEARS, "{0} + {1} years"); + add(Ops.DateTimeOps.ADD_MONTHS, "{0} + {1} months"); + add(Ops.DateTimeOps.ADD_WEEKS, "{0} + {1} weeks"); + add(Ops.DateTimeOps.ADD_DAYS, "{0} + {1} days"); + add(Ops.DateTimeOps.ADD_HOURS, "{0} + {1} hours"); + add(Ops.DateTimeOps.ADD_MINUTES, "{0} + {1} minutes"); + add(Ops.DateTimeOps.ADD_SECONDS, "{0} + {1} seconds"); + + add(Ops.DateTimeOps.DIFF_YEARS, "timestampdiff(256, char(timestamp({1}) - timestamp({0})))"); + add(Ops.DateTimeOps.DIFF_MONTHS, "timestampdiff(64, char(timestamp({1}) - timestamp({0})))"); + add(Ops.DateTimeOps.DIFF_WEEKS, "timestampdiff(32, char(timestamp({1}) - timestamp({0})))"); + add(Ops.DateTimeOps.DIFF_DAYS, "timestampdiff(16, char(timestamp({1}) - timestamp({0})))"); + add(Ops.DateTimeOps.DIFF_HOURS, "timestampdiff(8, char(timestamp({1}) - timestamp({0})))"); + add(Ops.DateTimeOps.DIFF_MINUTES, "timestampdiff(4, char(timestamp({1}) - timestamp({0})))"); + add(Ops.DateTimeOps.DIFF_SECONDS, "timestampdiff(2, char(timestamp({1}) - timestamp({0})))"); + + add(Ops.DateTimeOps.TRUNC_YEAR, "trunc_timestamp({0}, 'year')"); + add(Ops.DateTimeOps.TRUNC_MONTH, "trunc_timestamp({0}, 'month')"); + add(Ops.DateTimeOps.TRUNC_WEEK, "trunc_timestamp({0}, 'ww')"); + add(Ops.DateTimeOps.TRUNC_DAY, "trunc_timestamp({0}, 'dd')"); + add(Ops.DateTimeOps.TRUNC_HOUR, "trunc_timestamp({0}, 'hh')"); + add(Ops.DateTimeOps.TRUNC_MINUTE, "trunc_timestamp({0}, 'mi')"); + add(Ops.DateTimeOps.TRUNC_SECOND, "trunc_timestamp({0}, 'ss')"); + + addTypeNameToCode("smallint", Types.BOOLEAN, true); + addTypeNameToCode("smallint", Types.TINYINT, true); + addTypeNameToCode("long varchar for bit data", Types.LONGVARBINARY); + addTypeNameToCode("varchar () for bit data", Types.VARBINARY); + addTypeNameToCode("char () for bit data", Types.BINARY); + addTypeNameToCode("long varchar", Types.LONGVARCHAR, true); + addTypeNameToCode("object", Types.JAVA_OBJECT, true); + addTypeNameToCode("xml", Types.SQLXML,true); + } + + @Override + public String getCastTypeNameForCode(int code) { + switch (code) { + case Types.VARCHAR: return "varchar(4000)"; + default: return super.getCastTypeNameForCode(code); + } + } + + @Override + public void serialize(QueryMetadata metadata, boolean forCountRow, SQLSerializer context) { + if (!forCountRow && metadata.getModifiers().isRestricting() && !metadata.getJoins().isEmpty()) { + QueryModifiers mod = metadata.getModifiers(); + if (mod.getOffset() == null) { + context.serializeForQuery(metadata, forCountRow); + context.handle(limitTemplate, mod.getLimit()); + } else { + context.append(outerQueryStart); + metadata = metadata.clone(); + WindowFunction rn = SQLExpressions.rowNumber().over(); + for (OrderSpecifier os : metadata.getOrderBy()) { + rn.orderBy(os); + } + FactoryExpression pr = Projections.appending(metadata.getProjection(), rn.as("rn")); + metadata.setProjection(FactoryExpressionUtils.wrap(pr)); + metadata.clearOrderBy(); + context.serializeForQuery(metadata, forCountRow); + context.append(outerQueryEnd); + if (mod.getLimit() == null) { + context.handle(offsetTemplate, mod.getOffset()); + } else { + context.handle(limitOffsetTemplate, mod.getOffset(), mod.getLimit() + mod.getOffset()); + } + context.append(outerQuerySuffix); + } + + } else { + context.serializeForQuery(metadata, forCountRow); + } + + if (!metadata.getFlags().isEmpty()) { + context.serialize(QueryFlag.Position.END, metadata.getFlags()); + } + } + + @Override + protected void serializeModifiers(QueryMetadata metadata, SQLSerializer context) { + // do nothing + } + + +} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/DatePart.java b/querydsl-sql/src/main/java/com/querydsl/sql/DatePart.java similarity index 77% rename from querydsl-sql/src/main/java/com/mysema/query/sql/DatePart.java rename to querydsl-sql/src/main/java/com/querydsl/sql/DatePart.java index 4e2c7354fc..afcd5fb980 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/DatePart.java +++ b/querydsl-sql/src/main/java/com/querydsl/sql/DatePart.java @@ -1,6 +1,6 @@ /* - * Copyright 2012, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,13 +11,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql; +package com.querydsl.sql; +/** + * {@code DatePart} defines date parts for various date/time operations + */ public enum DatePart { year, month, week, - day, + day, hour, minute, second, diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/DefaultSQLExceptionTranslator.java b/querydsl-sql/src/main/java/com/querydsl/sql/DefaultSQLExceptionTranslator.java new file mode 100644 index 0000000000..d8943382e9 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/DefaultSQLExceptionTranslator.java @@ -0,0 +1,59 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import java.sql.SQLException; +import java.util.List; + +import com.querydsl.core.QueryException; +import com.querydsl.sql.support.SQLExceptionWrapper; + +/** + * Default implementation of the {@link SQLExceptionTranslator} interface + * + * @author tiwe + * + */ +public final class DefaultSQLExceptionTranslator implements SQLExceptionTranslator { + + public static final SQLExceptionTranslator DEFAULT = new DefaultSQLExceptionTranslator(); + + private static final SQLExceptionWrapper WRAPPER = SQLExceptionWrapper.INSTANCE; + + @Override + public RuntimeException translate(SQLException e) { + if (containsAdditionalExceptions(e)) { + return WRAPPER.wrap(e); + } else { + return new QueryException(e); + } + } + + @Override + public RuntimeException translate(String sql, List bindings, SQLException e) { + String message = "Caught " + e.getClass().getSimpleName() + + " for " + sql; + if (containsAdditionalExceptions(e)) { + return WRAPPER.wrap(message, e); + } else { + return new QueryException(message, e); + } + } + + private static boolean containsAdditionalExceptions(SQLException e) { + return e.getNextException() != null; + } + + private DefaultSQLExceptionTranslator() { } +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/DerbyTemplates.java b/querydsl-sql/src/main/java/com/querydsl/sql/DerbyTemplates.java new file mode 100644 index 0000000000..831eb931eb --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/DerbyTemplates.java @@ -0,0 +1,161 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import java.sql.Types; + +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.QueryModifiers; +import com.querydsl.core.types.Ops; + +/** + * {@code DerbyTemplates} is an SQL dialect for Derby + * + * @author tiwe + * + */ +public class DerbyTemplates extends SQLTemplates { + + @SuppressWarnings("FieldNameHidesFieldInSuperclass") //Intentional + public static final DerbyTemplates DEFAULT = new DerbyTemplates(); + + private String limitOffsetTemplate = "\noffset {1s} rows fetch next {0s} rows only"; + + private String limitTemplate = "\nfetch first {0s} rows only"; + + private String offsetTemplate = "\noffset {0s} rows"; + + public static Builder builder() { + return new Builder() { + @Override + protected SQLTemplates build(char escape, boolean quote) { + return new DerbyTemplates(escape, quote); + } + }; + } + + public DerbyTemplates() { + this('\\',false); + } + + public DerbyTemplates(boolean quote) { + this('\\',quote); + } + + public DerbyTemplates(char escape, boolean quote) { + super(Keywords.DERBY, "\"", escape, quote, true); + setDummyTable("sysibm.sysdummy1"); + setAutoIncrement(" generated always as identity"); + setFunctionJoinsWrapped(true); + setDefaultValues("\nvalues (default)"); + + setPrecedence(Precedence.COMPARISON, Ops.EQ, Ops.EQ_IGNORE_CASE, Ops.NE, Ops.EXISTS); + + add(Ops.CONCAT, "varchar({0} || {1})", -1); + + add(SQLOps.NEXTVAL, "next value for {0s}"); + + // case for eq + add(Ops.CASE_EQ, "case {1} end"); + add(Ops.CASE_EQ_WHEN, "when {0} = {1} then {2} {3}"); + add(Ops.CASE_EQ_ELSE, "else {0}"); + + add(Ops.MathOps.RANDOM, "random()"); + add(Ops.MathOps.ROUND, "floor({0})"); // FIXME + add(Ops.MathOps.POWER, "exp({1} * log({0}))"); + add(Ops.MathOps.LN, "log({0})"); + add(Ops.MathOps.LOG, "(log({0}) / log({1}))"); + add(Ops.MathOps.COTH, "(exp({0*'2'}) + 1) / (exp({0*'2'}) - 1)"); + + // overrides of the SQL standard functions + add(Ops.DateTimeOps.SECOND, "second({0})"); + add(Ops.DateTimeOps.MINUTE, "minute({0})"); + add(Ops.DateTimeOps.HOUR, "hour({0})"); + add(Ops.DateTimeOps.WEEK, "week({0})"); + add(Ops.DateTimeOps.MONTH, "month({0})"); + add(Ops.DateTimeOps.YEAR, "year({0})"); + add(Ops.DateTimeOps.YEAR_MONTH, "(year({0}) * 100 + month({0}))"); + add(Ops.DateTimeOps.YEAR_WEEK, "(year({0}) * 100 + week({0}))"); + add(Ops.DateTimeOps.DAY_OF_WEEK, "dayofweek({0})"); + add(Ops.DateTimeOps.DAY_OF_MONTH, "day({0})"); + add(Ops.DateTimeOps.DAY_OF_YEAR, "dayofyear({0})"); + + add(Ops.DateTimeOps.ADD_YEARS, "{fn timestampadd(SQL_TSI_YEAR, {1}, {0})}"); + add(Ops.DateTimeOps.ADD_MONTHS, "{fn timestampadd(SQL_TSI_MONTH, {1}, {0})}"); + add(Ops.DateTimeOps.ADD_WEEKS, "{fn timestampadd(SQL_TSI_WEEK, {1}, {0})}"); + add(Ops.DateTimeOps.ADD_DAYS, "{fn timestampadd(SQL_TSI_DAY, {1}, {0})}"); + add(Ops.DateTimeOps.ADD_HOURS, "{fn timestampadd(SQL_TSI_HOUR, {1}, {0})}"); + add(Ops.DateTimeOps.ADD_MINUTES, "{fn timestampadd(SQL_TSI_MINUTE, {1}, {0})}"); + add(Ops.DateTimeOps.ADD_SECONDS, "{fn timestampadd(SQL_TSI_SECOND, {1}, {0})}"); + + add(Ops.DateTimeOps.DIFF_YEARS, "{fn timestampdiff(SQL_TSI_YEAR, {0}, {1})}"); + add(Ops.DateTimeOps.DIFF_MONTHS, "{fn timestampdiff(SQL_TSI_MONTH, {0}, {1})}"); + add(Ops.DateTimeOps.DIFF_WEEKS, "{fn timestampdiff(SQL_TSI_WEEK, {0}, {1})}"); + add(Ops.DateTimeOps.DIFF_DAYS, "{fn timestampdiff(SQL_TSI_DAY, {0}, {1})}"); + add(Ops.DateTimeOps.DIFF_HOURS, "{fn timestampdiff(SQL_TSI_HOUR, {0}, {1})}"); + add(Ops.DateTimeOps.DIFF_MINUTES, "{fn timestampdiff(SQL_TSI_MINUTE, {0}, {1})}"); + add(Ops.DateTimeOps.DIFF_SECONDS, "{fn timestampdiff(SQL_TSI_SECOND, {0}, {1})}"); + + // substrings 'yyyy-MM-dd hh:mm:ss' style date pattern and adds a static suffix + add(Ops.DateTimeOps.TRUNC_YEAR, "timestamp(substr(cast({0} as char(30)),1,4)||'-01-01 00:00:00')"); + add(Ops.DateTimeOps.TRUNC_MONTH, "timestamp(substr(cast({0} as char(30)),1,7)||'-01 00:00:00')"); + // TODO weeks + add(Ops.DateTimeOps.TRUNC_DAY, "timestamp(substr(cast({0} as char(30)),1,10)||' 00:00:00')"); + add(Ops.DateTimeOps.TRUNC_HOUR, "timestamp(substr(cast({0} as char(30)),1,13)||':00:00')"); + add(Ops.DateTimeOps.TRUNC_MINUTE, "timestamp(substr(cast({0} as char(30)),1,16)||':00')"); + add(Ops.DateTimeOps.TRUNC_SECOND, "timestamp(substr(cast({0} as char(30)),1,19))"); + + // left via substr + add(Ops.StringOps.LEFT, "substr({0},1,{1})"); + + addTypeNameToCode("smallint", Types.TINYINT, true); + addTypeNameToCode("long varchar for bit data", Types.LONGVARBINARY); + addTypeNameToCode("varchar () for bit data", Types.VARBINARY); + addTypeNameToCode("char () for bit data", Types.BINARY); + addTypeNameToCode("long varchar", Types.LONGVARCHAR, true); + addTypeNameToCode("object", Types.JAVA_OBJECT, true); + addTypeNameToCode("xml", Types.SQLXML,true); + } + + @Override + public String serialize(String literal, int jdbcType) { + switch (jdbcType) { + case Types.BOOLEAN: + return "1".equals(literal) ? "true" : "false"; + case Types.TIMESTAMP: + case TIMESTAMP_WITH_TIMEZONE: + return "{ts '" + literal + "'}"; + case Types.DATE: + return "{d '" + literal + "'}"; + case Types.TIME: + case TIME_WITH_TIMEZONE: + return "{t '" + literal + "'}"; + default: + return super.serialize(literal, jdbcType); + } + } + + @Override + protected void serializeModifiers(QueryMetadata metadata, SQLSerializer context) { + QueryModifiers mod = metadata.getModifiers(); + if (mod.getLimit() == null) { + context.handle(offsetTemplate, mod.getOffset()); + } else if (mod.getOffset() == null) { + context.handle(limitTemplate, mod.getLimit()); + } else { + context.handle(limitOffsetTemplate, mod.getLimit(), mod.getOffset()); + } + } + +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/FirebirdTemplates.java b/querydsl-sql/src/main/java/com/querydsl/sql/FirebirdTemplates.java new file mode 100644 index 0000000000..4276423f09 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/FirebirdTemplates.java @@ -0,0 +1,164 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import java.sql.Types; + +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.QueryModifiers; +import com.querydsl.core.types.Ops; + +/** + * {@code FirebirdTemplates} is an SQL dialect for Firebird + */ +public class FirebirdTemplates extends SQLTemplates { + + @SuppressWarnings("FieldNameHidesFieldInSuperclass") //Intentional + public static final FirebirdTemplates DEFAULT = new FirebirdTemplates(); + + private String limitOffsetTemplate = "\nrows {0} to {1}"; + + private String limitTemplate = "\nrows {0}"; + + private String offsetTemplate = "\nrows {0} to " + Integer.MAX_VALUE; + + public static Builder builder() { + return new Builder() { + @Override + protected SQLTemplates build(char escape, boolean quote) { + return new FirebirdTemplates(escape, quote); + } + }; + } + + public FirebirdTemplates() { + this('\\', false); + } + + public FirebirdTemplates(boolean quote) { + this('\\', quote); + } + + public FirebirdTemplates(char escape, boolean quote) { + super(Keywords.FIREBIRD, "\"", escape, quote, false); + setDummyTable("RDB$DATABASE"); + setUnionsWrapped(false); + setWrapSelectParameters(true); + setArraysSupported(false); + setBatchToBulkSupported(false); + + setPrecedence(Precedence.COMPARISON, Ops.EQ, Ops.EQ_IGNORE_CASE, Ops.NE); + + add(Ops.CONCAT, "{0} || {1}", Precedence.NEGATE - 1); + + // string + add(Ops.CHAR_AT, "cast(substring({0} from {1+'1's} for 1) as char)"); + add(Ops.SUBSTR_1ARG, "substring({0} from {1+'1's})"); + add(Ops.SUBSTR_2ARGS, "substring({0} from {1+'1's} for {2-1s})"); + add(Ops.INDEX_OF, "position({1},{0})-1", Precedence.ARITH_LOW); + add(Ops.INDEX_OF_2ARGS, "position({1},{0},{2+'1's})-1", Precedence.ARITH_LOW); + add(Ops.StringOps.LOCATE, "position({0},{1})"); + add(Ops.StringOps.LOCATE2, "position({0},{1},{2})"); + add(Ops.STRING_LENGTH, "char_length({0})"); + add(Ops.STRING_IS_EMPTY, "char_length({0}) = 0"); + add(Ops.StringOps.LTRIM, "trim (leading from {0})"); + add(Ops.StringOps.RTRIM, "trim (trailing from {0})"); + + add(Ops.AggOps.BOOLEAN_ANY, "any({0})"); + add(Ops.AggOps.BOOLEAN_ALL, "all({0})"); + + // math + add(Ops.MathOps.LOG, "log({1},{0})"); + add(Ops.MathOps.COSH, "(exp({0}) + exp({0*'-1'})) / 2"); + add(Ops.MathOps.COTH, "(exp({0*'2'}) + 1) / (exp({0*'2'}) - 1)"); + add(Ops.MathOps.SINH, "(exp({0}) - exp({0} * -1)) / 2"); + add(Ops.MathOps.TANH, "(exp({0*'2'}) - 1) / (exp({0*'2'}) + 1)"); + add(Ops.MathOps.DEG, "{0*'180.0'} / pi()", Precedence.ARITH_HIGH); + add(Ops.MathOps.RAD, "{0}*pi() / 180.0 ", Precedence.ARITH_HIGH); + + // + add(Ops.DateTimeOps.DATE, "cast({0} as date)"); + + add(Ops.DateTimeOps.MILLISECOND, "extract(millisecond from {0})"); + add(Ops.DateTimeOps.YEAR_MONTH, "extract(year from {0}) * 100 + extract(month from {0})", Precedence.ARITH_LOW); + add(Ops.DateTimeOps.YEAR_WEEK, "extract(year from {0}) * 100 + extract(week from {0})", Precedence.ARITH_LOW); + add(Ops.DateTimeOps.DAY_OF_WEEK, "extract(weekday from {0})"); + add(Ops.DateTimeOps.DAY_OF_MONTH, "extract(day from {0})"); + //add(Ops.DateTimeOps.DAY_OF_YEAR, "extract(day_of_year from {0})"); + + add(Ops.DateTimeOps.ADD_YEARS, "dateadd(year,{1},{0})"); + add(Ops.DateTimeOps.ADD_MONTHS, "dateadd(month,{1},{0})"); + add(Ops.DateTimeOps.ADD_WEEKS, "dateadd(week,{1},{0})"); + add(Ops.DateTimeOps.ADD_DAYS, "dateadd(day,{1},{0})"); + add(Ops.DateTimeOps.ADD_HOURS, "dateadd(hour,{1},{0})"); + add(Ops.DateTimeOps.ADD_MINUTES, "dateadd(minute,{1},{0})"); + add(Ops.DateTimeOps.ADD_SECONDS, "dateadd(second,{1},{0})"); + + add(Ops.DateTimeOps.DIFF_YEARS, "datediff(year,{0},{1})"); + add(Ops.DateTimeOps.DIFF_MONTHS, "datediff(month,{0},{1})"); + add(Ops.DateTimeOps.DIFF_WEEKS, "datediff(week,{0},{1})"); + add(Ops.DateTimeOps.DIFF_DAYS, "datediff(day,{0},{1})"); + add(Ops.DateTimeOps.DIFF_HOURS, "datediff(hour,{0},{1})"); + add(Ops.DateTimeOps.DIFF_MINUTES, "datediff(minute,{0},{1})"); + add(Ops.DateTimeOps.DIFF_SECONDS, "datediff(second,{0},{1})"); + + add(Ops.DateTimeOps.TRUNC_YEAR, "cast(extract(year from {0}) || '-1-1' as date)"); + add(Ops.DateTimeOps.TRUNC_MONTH, "cast(substring(cast({0} as char(100)) from 1 for 7) || '-1' as date)"); + // TODO weeks + add(Ops.DateTimeOps.TRUNC_DAY, "cast(substring(cast({0} as char(100)) from 1 for 10) as date)"); + add(Ops.DateTimeOps.TRUNC_HOUR, "cast(substring(cast({0} as char(100)) from 1 for 13) || ':00:00' as timestamp)"); + add(Ops.DateTimeOps.TRUNC_MINUTE, "cast(substring(cast({0} as char(100)) from 1 for 16) || ':00' as timestamp)"); + add(Ops.DateTimeOps.TRUNC_SECOND, "cast(substring(cast({0} as char(100)) from 1 for 19) as timestamp)"); + + add(SQLOps.GROUP_CONCAT, "list({0},',')"); + add(SQLOps.GROUP_CONCAT2, "list({0},{1})"); + + addTypeNameToCode("time with time zone", Types.TIME_WITH_TIMEZONE, true); + addTypeNameToCode("timestamp with time zone", Types.TIMESTAMP_WITH_TIMEZONE, true); + addTypeNameToCode("smallint", Types.BOOLEAN, true); + addTypeNameToCode("smallint", Types.BIT, true); + addTypeNameToCode("smallint", Types.TINYINT, true); + addTypeNameToCode("decimal", Types.DOUBLE, true); + addTypeNameToCode("blob sub_type 0", Types.LONGVARBINARY); + addTypeNameToCode("blob sub_type 1", Types.LONGVARCHAR); + addTypeNameToCode("double precision", Types.DOUBLE); + addTypeNameToCode("array", Types.OTHER); + addTypeNameToCode("blob sub_type 0 ", Types.BLOB); + } + + @Override + public String getCastTypeNameForCode(int code) { + if (code == Types.VARCHAR) { + return "varchar(256)"; + } else { + return super.getCastTypeNameForCode(code); + } + } + + @Override + protected void serializeModifiers(QueryMetadata metadata, SQLSerializer context) { + QueryModifiers mod = metadata.getModifiers(); + if (mod.isRestricting()) { + if (mod.getLimit() != null) { + if (mod.getOffset() != null) { + context.handle(limitOffsetTemplate, mod.getOffset() + 1, mod.getOffset() + mod.getLimit()); + } else { + context.handle(limitTemplate, mod.getLimit()); + } + } else { + context.handle(offsetTemplate, mod.getOffset() + 1); + } + } + } +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/ForeignKey.java b/querydsl-sql/src/main/java/com/querydsl/sql/ForeignKey.java new file mode 100644 index 0000000000..96369dd49c --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/ForeignKey.java @@ -0,0 +1,97 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import java.io.Serializable; +import java.util.Collections; +import java.util.List; + +import org.jetbrains.annotations.Nullable; +import com.querydsl.core.annotations.Immutable; + +import com.querydsl.core.BooleanBuilder; +import com.querydsl.core.Tuple; +import com.querydsl.core.types.*; +import com.querydsl.core.types.dsl.BooleanExpression; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.util.CollectionUtils; + +/** + * {@code ForeignKey} defines a foreign key on a table to another table + * + * @author tiwe + * + * @param + */ +@Immutable +public final class ForeignKey implements Serializable, ProjectionRole { + + private static final long serialVersionUID = 2260578033772289023L; + + private final RelationalPath entity; + + private final List> localColumns; + + private final List foreignColumns; + + @Nullable + private transient volatile Expression mixin; + + public ForeignKey(RelationalPath entity, Path localColumn, String foreignColumn) { + this(entity, Collections.singletonList(localColumn), Collections.singletonList(foreignColumn)); + } + + public ForeignKey(RelationalPath entity, List> localColumns, + List foreignColumns) { + this.entity = entity; + this.localColumns = CollectionUtils.unmodifiableList(localColumns); + this.foreignColumns = CollectionUtils.unmodifiableList(foreignColumns); + } + + public RelationalPath getEntity() { + return entity; + } + + public List> getLocalColumns() { + return localColumns; + } + + public List getForeignColumns() { + return foreignColumns; + } + + @SuppressWarnings("unchecked") + public Predicate on(RelationalPath entity) { + BooleanBuilder builder = new BooleanBuilder(); + for (int i = 0; i < localColumns.size(); i++) { + Expression local = (Expression) localColumns.get(i); + Expression foreign = ExpressionUtils.path(local.getType(), entity, foreignColumns.get(i)); + builder.and(ExpressionUtils.eq(local,foreign)); + } + return builder.getValue(); + } + + public BooleanExpression in(SubQueryExpression coll) { + return Expressions.booleanOperation(Ops.IN, getProjection(), coll); + } + + @Override + public Expression getProjection() { + if (mixin == null) { + mixin = ExpressionUtils.list(Tuple.class, localColumns); + } + return mixin; + } + +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/H2Templates.java b/querydsl-sql/src/main/java/com/querydsl/sql/H2Templates.java new file mode 100644 index 0000000000..5680129519 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/H2Templates.java @@ -0,0 +1,98 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import java.sql.Types; + +import com.querydsl.core.types.Ops; + +/** + * {@code H2Templates} is an SQL dialect for H2 + * + * @author tiwe + * + */ +public class H2Templates extends SQLTemplates { + + @SuppressWarnings("FieldNameHidesFieldInSuperclass") //Intentional + public static final H2Templates DEFAULT = new H2Templates(); + + public static Builder builder() { + return new Builder() { + @Override + protected SQLTemplates build(char escape, boolean quote) { + return new H2Templates(escape, quote); + } + }; + } + + public H2Templates() { + this('\\', false); + } + + public H2Templates(boolean quote) { + this('\\', quote); + } + + public H2Templates(char escape, boolean quote) { + super(Keywords.H2, "\"", escape, quote, false); + setNativeMerge(true); + setMaxLimit(2 ^ 31); + setLimitRequired(true); + setCountDistinctMultipleColumns(true); + + setPrecedence(Precedence.ARITH_LOW + 1, Ops.CONCAT); + setPrecedence(Precedence.COMPARISON, Ops.EQ, Ops.EQ_IGNORE_CASE, Ops.NE); + + add(Ops.MOD, "{0} % {1}", Precedence.ARITH_HIGH); + + add(Ops.MathOps.ROUND, "round({0},0)"); + add(Ops.TRIM, "trim(both from {0})"); + + add(Ops.DateTimeOps.DAY_OF_WEEK, "day_of_week({0})"); + + add(Ops.MathOps.LN, "log({0})"); + add(Ops.MathOps.LOG, "(log({0}) / log({1}))"); + add(Ops.MathOps.COTH, "(cosh({0}) / sinh({0}))"); + + add(Ops.DateTimeOps.DATE, "convert({0}, date)"); + + addTypeNameToCode("result_set", -10); + addTypeNameToCode("identity", Types.BIGINT); + addTypeNameToCode("uuid", Types.BINARY); + addTypeNameToCode("serial", Types.INTEGER); + addTypeNameToCode("varchar_ignorecase", Types.VARCHAR); + + add(Ops.DateTimeOps.TRUNC_YEAR, "parsedatetime(formatdatetime({0},'yyyy'),'yyyy')"); + add(Ops.DateTimeOps.TRUNC_MONTH, "parsedatetime(formatdatetime({0},'yyyy-MM'),'yyyy-MM')"); + add(Ops.DateTimeOps.TRUNC_WEEK, "parsedatetime(formatdatetime({0},'YYYY-ww'),'YYYY-ww')"); + add(Ops.DateTimeOps.TRUNC_DAY, "parsedatetime(formatdatetime({0},'yyyy-MM-dd'),'yyyy-MM-dd')"); + add(Ops.DateTimeOps.TRUNC_HOUR, "parsedatetime(formatdatetime({0},'yyyy-MM-dd HH'),'yyyy-MM-dd HH')"); + add(Ops.DateTimeOps.TRUNC_MINUTE, "parsedatetime(formatdatetime({0},'yyyy-MM-dd HH:mm'),'yyyy-MM-dd HH:mm')"); + add(Ops.DateTimeOps.TRUNC_SECOND, "parsedatetime(formatdatetime({0},'yyyy-MM-dd HH:mm:ss'),'yyyy-MM-dd HH:mm:ss')"); + } + + @Override + public String serialize(String literal, int jdbcType) { + switch (jdbcType) { + case TIMESTAMP_WITH_TIMEZONE: + return "(timestamp with time zone '" + literal + "')"; + case TIME_WITH_TIMEZONE: + return "(time with time zone '" + literal + "')"; + default: + return super.serialize(literal, jdbcType); + } + } + +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/HSQLDBTemplates.java b/querydsl-sql/src/main/java/com/querydsl/sql/HSQLDBTemplates.java new file mode 100644 index 0000000000..bacd6be6b8 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/HSQLDBTemplates.java @@ -0,0 +1,137 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import java.sql.Types; + +import com.querydsl.core.types.Ops; + +/** + * {@code HSQLDBTemplates} is an SQL dialect for HSQLDB + * + * @author tiwe + * + */ +public class HSQLDBTemplates extends SQLTemplates { + + @SuppressWarnings("FieldNameHidesFieldInSuperclass") //Intentional + public static final HSQLDBTemplates DEFAULT = new HSQLDBTemplates(); + + public static Builder builder() { + return new Builder() { + @Override + protected SQLTemplates build(char escape, boolean quote) { + return new HSQLDBTemplates(escape, quote); + } + }; + } + + public HSQLDBTemplates() { + this('\\', false); + } + + public HSQLDBTemplates(boolean quote) { + this('\\', quote); + } + + public HSQLDBTemplates(char escape, boolean quote) { + super(Keywords.HSQLDB, "\"", escape, quote, false); + setLimitRequired(true); + setAutoIncrement(" identity"); + setDefaultValues("\ndefault values"); + setFunctionJoinsWrapped(true); + setUnionsWrapped(false); + + setPrecedence(Precedence.ARITH_HIGH, Ops.CONCAT); + setPrecedence(Precedence.ARITH_LOW + 1, Ops.NOT); + setPrecedence(Precedence.COMPARISON, Ops.EQ, Ops.EQ_IGNORE_CASE, Ops.NE); + setPrecedence(Precedence.COMPARISON + 1, Ops.IS_NULL, Ops.IS_NOT_NULL, Ops.LIKE, Ops.LIKE_ESCAPE, Ops.BETWEEN, + Ops.IN, Ops.NOT_IN, Ops.EXISTS); + + setPrecedence(Precedence.COMPARISON + 1, OTHER_LIKE_CASES); + + add(Ops.TRIM, "trim(both from {0})"); + add(Ops.NEGATE, "{0} * -1", Precedence.ARITH_HIGH); + + add(SQLOps.NEXTVAL, "next value for {0s}"); + + add(Ops.MathOps.POWER, "power({0},{1s})"); + add(Ops.MathOps.ROUND, "round({0},0)"); + add(Ops.MathOps.LN, "log({0})"); + add(Ops.MathOps.LOG, "(log({0}) / log({1}))"); + add(Ops.MathOps.COSH, "(exp({0}) + exp({0*'-1'})) / 2"); + add(Ops.MathOps.COTH, "(exp({0*'2'}) + 1) / (exp({0*'2'}) - 1)"); + add(Ops.MathOps.SINH, "(exp({0}) - exp({0*'-1'})) / 2"); + add(Ops.MathOps.TANH, "(exp({0*'2'}) - 1) / (exp({0*'2'}) + 1)"); + + add(Ops.DateTimeOps.WEEK, "extract(week_of_year from {0})"); + add(Ops.DateTimeOps.YEAR_WEEK, "extract(year from {0}) * 100 + extract(week_of_year from {0})", Precedence.ARITH_LOW); + + add(Ops.DateTimeOps.ADD_YEARS, "dateadd('yy', {1s}, {0})"); + add(Ops.DateTimeOps.ADD_MONTHS, "dateadd('mm', {1s}, {0})"); + add(Ops.DateTimeOps.ADD_WEEKS, "dateadd('week', {1s}, {0})"); + add(Ops.DateTimeOps.ADD_DAYS, "dateadd('dd', {1s}, {0})"); + add(Ops.DateTimeOps.ADD_HOURS, "dateadd('hh', {1s}, {0})"); + add(Ops.DateTimeOps.ADD_MINUTES, "dateadd('mi', {1s}, {0})"); + add(Ops.DateTimeOps.ADD_SECONDS, "dateadd('ss', {1s}, {0})"); + + add(Ops.DateTimeOps.DIFF_YEARS, "datediff('yy', {0}, {1})"); + add(Ops.DateTimeOps.DIFF_MONTHS, "datediff('mm', {0}, {1})"); + add(Ops.DateTimeOps.DIFF_WEEKS, "trunc(datediff('dd', {0}, {1}) / 7)"); + add(Ops.DateTimeOps.DIFF_DAYS, "datediff('dd', {0}, {1})"); + add(Ops.DateTimeOps.DIFF_HOURS, "datediff('hh', {0}, {1})"); + add(Ops.DateTimeOps.DIFF_MINUTES, "datediff('mi', {0}, {1})"); + add(Ops.DateTimeOps.DIFF_SECONDS, "datediff('ss', {0}, {1})"); + + add(Ops.DateTimeOps.TRUNC_YEAR, "trunc({0},'YY')"); + add(Ops.DateTimeOps.TRUNC_MONTH, "trunc({0},'MM')"); + add(Ops.DateTimeOps.TRUNC_WEEK, "trunc({0},'WW')"); + add(Ops.DateTimeOps.TRUNC_DAY, "trunc({0},'DD')"); + add(Ops.DateTimeOps.TRUNC_HOUR, "trunc({0},'HH')"); + add(Ops.DateTimeOps.TRUNC_MINUTE, "trunc({0},'MI')"); + add(Ops.DateTimeOps.TRUNC_SECOND, "trunc({0},'SS')"); + + add(Ops.DateTimeOps.DATE, "convert({0}, date)"); + + add(SQLOps.GROUP_CONCAT2, "group_concat({0} separator '{1s}')"); + + addTypeNameToCode("character", Types.CHAR, true); + addTypeNameToCode("float", Types.DOUBLE, true); + addTypeNameToCode("real", Types.DOUBLE); + addTypeNameToCode("nvarchar", Types.VARCHAR); + } + + @Override + public String getCastTypeNameForCode(int code) { + if (code == Types.VARCHAR) { + return "varchar(10)"; + } else { + return super.getCastTypeNameForCode(code); + } + } + + @Override + public String serialize(String literal, int jdbcType) { + switch (jdbcType) { + case TIMESTAMP_WITH_TIMEZONE: + case TIME_WITH_TIMEZONE: + // HSQLDB does not tolerate space before the time zone, unlike other DBs + int tzSeparatorIndex = literal.lastIndexOf(' '); + literal = literal.substring(0, tzSeparatorIndex) + literal.substring(tzSeparatorIndex + 1); + break; + } + return super.serialize(literal, jdbcType); + } + +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/JDBCTypeMapping.java b/querydsl-sql/src/main/java/com/querydsl/sql/JDBCTypeMapping.java new file mode 100644 index 0000000000..1fe8d4f3b7 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/JDBCTypeMapping.java @@ -0,0 +1,177 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.sql.Blob; +import java.sql.Time; +import java.sql.Timestamp; +import java.sql.Types; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.jetbrains.annotations.Nullable; + +import com.mysema.commons.lang.Pair; +import com.querydsl.sql.types.Null; + +/** + * {@code JDBCTypeMapping} defines a mapping from JDBC types to Java classes. + * + * @author tiwe + * + */ +final class JDBCTypeMapping { + + private static final Set NUMERIC_TYPES; + + private static final Map> defaultTypes = new HashMap>(); + + private static final Map, Integer> defaultSqlTypes = new HashMap, Integer>(); + + static { + registerDefault(-101, Object.class); + registerDefault(-102, Timestamp.class); // Oracle: TIMESTAMP(6) WITH LOCAL TIME ZONE + registerDefault(2012, Object.class); // REF_CURSOR + registerDefault(2013, Time.class); // TIME_WITH_TIMEZONE + registerDefault(2014, Timestamp.class); // TIMESTAMP_WIH_TIMEZONE + + // BOOLEAN + registerDefault(Types.BIT, Boolean.class); + registerDefault(Types.BOOLEAN, Boolean.class); + + // NUMERIC + registerDefault(Types.BIGINT, Long.class); + registerDefault(Types.DECIMAL, BigDecimal.class); + registerDefault(Types.DOUBLE, Double.class); + registerDefault(Types.FLOAT, Float.class); + registerDefault(Types.INTEGER, Integer.class); + registerDefault(Types.NUMERIC, BigDecimal.class); + registerDefault(Types.REAL, Float.class); + registerDefault(Types.SMALLINT, Short.class); + registerDefault(Types.TINYINT, Byte.class); + + // DATE and TIME + registerDefault(Types.DATE, java.sql.Date.class); + registerDefault(Types.TIME, java.sql.Time.class); + registerDefault(Types.TIMESTAMP, java.sql.Timestamp.class); + + // TEXT + registerDefault(Types.NCHAR, String.class); + registerDefault(Types.CHAR, String.class); + registerDefault(Types.NCLOB, String.class); + registerDefault(Types.CLOB, String.class); + registerDefault(Types.LONGNVARCHAR, String.class); + registerDefault(Types.LONGVARCHAR, String.class); + registerDefault(Types.SQLXML, String.class); + registerDefault(Types.NVARCHAR, String.class); + registerDefault(Types.VARCHAR, String.class); + + // byte[] + registerDefault(Types.BINARY, byte[].class); + registerDefault(Types.LONGVARBINARY, byte[].class); + registerDefault(Types.VARBINARY, byte[].class); + + // BLOB + registerDefault(Types.BLOB, Blob.class); + + // OTHER + registerDefault(Types.ARRAY, Object[].class); + registerDefault(Types.DISTINCT, Object.class); + registerDefault(Types.DATALINK, Object.class); + registerDefault(Types.JAVA_OBJECT, Object.class); + registerDefault(Types.NULL, Null.class); + registerDefault(Types.OTHER, Object.class); + registerDefault(Types.REF, Object.class); + registerDefault(Types.ROWID, Object.class); + registerDefault(Types.STRUCT, Object.class); + + Set builder = new HashSet<>(); + for (Map.Entry> entry : defaultTypes.entrySet()) { + if (Number.class.isAssignableFrom(entry.getValue())) { + builder.add(entry.getKey()); + } + } + NUMERIC_TYPES = Collections.unmodifiableSet(builder); + } + + private static void registerDefault(int sqlType, Class javaType) { + defaultTypes.put(sqlType, javaType); + defaultSqlTypes.put(javaType, sqlType); + } + + private final Map> types = new HashMap>(); + + private final Map, Integer> sqlTypes = new HashMap, Integer>(); + + private final Map, Class> numericTypes = new HashMap, Class>(); + + public void register(int sqlType, Class javaType) { + types.put(sqlType, javaType); + sqlTypes.put(javaType, sqlType); + } + + public void registerNumeric(int total, int decimal, Class javaType) { + numericTypes.put(Pair.of(total, decimal), javaType); + } + + private static Class getNumericClass(int total, int decimal) { + if (decimal <= 0) { + if (total > 18 || total == 0) { + return BigInteger.class; + } else if (total > 9) { + return Long.class; + } else if (total > 4) { + return Integer.class; + } else if (total > 2) { + return Short.class; + } else { + return Byte.class; + } + } else { + return BigDecimal.class; + } + } + + @Nullable + public Class get(int sqlType, int total, int decimal) { + if (NUMERIC_TYPES.contains(sqlType)) { + Pair key = Pair.of(total, decimal); + if (numericTypes.containsKey(key)) { + return numericTypes.get(key); + } else if (sqlType == Types.NUMERIC || sqlType == Types.DECIMAL) { + return getNumericClass(total, decimal); + } + } + if (types.containsKey(sqlType)) { + return types.get(sqlType); + } else { + return defaultTypes.get(sqlType); + } + } + + @Nullable + public Integer get(Class clazz) { + if (sqlTypes.containsKey(clazz)) { + return sqlTypes.get(clazz); + } else { + return defaultSqlTypes.get(clazz); + } + } + +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/JavaTypeMapping.java b/querydsl-sql/src/main/java/com/querydsl/sql/JavaTypeMapping.java new file mode 100644 index 0000000000..b7d485813f --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/JavaTypeMapping.java @@ -0,0 +1,165 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import org.jetbrains.annotations.Nullable; + +import com.querydsl.core.util.PrimitiveUtils; +import com.querydsl.core.util.ReflectionUtils; +import com.querydsl.sql.types.*; + +/** + * {@code JavaTypeMapping} provides a mapping from Class to Type instances + * + * @author tiwe + * + */ +class JavaTypeMapping { + + private static final Type DEFAULT = new ObjectType(); + + private static final Map,Type> defaultTypes = new HashMap,Type>(); + + static { + registerDefault(new BigIntegerType()); + registerDefault(new BigDecimalType()); + registerDefault(new BlobType()); + registerDefault(new BooleanType()); + registerDefault(new BytesType()); + registerDefault(new ByteType()); + registerDefault(new CharacterType()); + registerDefault(new CalendarType()); + registerDefault(new ClobType()); + registerDefault(new CurrencyType()); + registerDefault(new DateType()); + registerDefault(new DoubleType()); + registerDefault(new FloatType()); + registerDefault(new IntegerType()); + registerDefault(new LocaleType()); + registerDefault(new LongType()); + registerDefault(new ObjectType()); + registerDefault(new ShortType()); + registerDefault(new StringType()); + registerDefault(new TimestampType()); + registerDefault(new TimeType()); + registerDefault(new URLType()); + registerDefault(new UtilDateType()); + registerDefault(new UtilUUIDType(false)); + registerDefault(new JSR310InstantType()); + registerDefault(new JSR310LocalDateTimeType()); + registerDefault(new JSR310LocalDateType()); + registerDefault(new JSR310LocalTimeType()); + registerDefault(new JSR310OffsetDateTimeType()); + registerDefault(new JSR310OffsetTimeType()); + registerDefault(new JSR310ZonedDateTimeType()); + + // initialize Joda-Time converters only if Joda-Time is available + try { + Class.forName("org.joda.time.Instant"); + registerDefault((Type) Class.forName("com.querydsl.sql.types.DateTimeType").newInstance()); + registerDefault((Type) Class.forName("com.querydsl.sql.types.LocalDateTimeType").newInstance()); + registerDefault((Type) Class.forName("com.querydsl.sql.types.LocalDateType").newInstance()); + registerDefault((Type) Class.forName("com.querydsl.sql.types.LocalTimeType").newInstance()); + } catch (ClassNotFoundException e) { + // converters for Joda-Time are not loaded + } catch (InstantiationException e) { + throw new RuntimeException(e); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + } + + private static void registerDefault(Type type) { + defaultTypes.put(type.getReturnedClass(), type); + Class primitive = PrimitiveUtils.unwrap(type.getReturnedClass()); + if (primitive != null) { + defaultTypes.put(primitive, type); + } + } + + private final Map,Type> typeByClass = new HashMap,Type>(); + + private final Map,Type> resolvedTypesByClass = new HashMap,Type>(); + + private final Map>> typeByColumn = new HashMap>>(); + + @Nullable + public Type getType(String table, String column) { + Map> columns = typeByColumn.get(table); + if (columns != null) { + return columns.get(column); + } else { + return null; + } + } + + @SuppressWarnings("unchecked") + public Type getType(Class clazz) { + Type resolvedType = resolvedTypesByClass.get(clazz); + if (resolvedType == null) { + resolvedType = findType(clazz); + if (resolvedType != null) { + resolvedTypesByClass.put(clazz, resolvedType); + } else { + return (Type) DEFAULT; + } + } + return (Type) resolvedType; + } + + @Nullable + private Type findType(Class clazz) { + //Look for a registered type in the class hierarchy + Class cl = clazz; + do { + if (typeByClass.containsKey(cl)) { + return typeByClass.get(cl); + } else if (defaultTypes.containsKey(cl)) { + return defaultTypes.get(cl); + } + cl = cl.getSuperclass(); + } while (!cl.equals(Object.class)); + + //Look for a registered type in any implemented interfaces + Set> interfaces = ReflectionUtils.getImplementedInterfaces(clazz); + for (Class itf : interfaces) { + if (typeByClass.containsKey(itf)) { + return typeByClass.get(itf); + } else if (defaultTypes.containsKey(itf)) { + return defaultTypes.get(itf); + } + } + return null; + } + + public void register(Type type) { + typeByClass.put(type.getReturnedClass(), type); + Class primitive = PrimitiveUtils.unwrap(type.getReturnedClass()); + if (primitive != null) { + typeByClass.put(primitive, type); + } + // Clear previous resolved types, so they won't impact future lookups + resolvedTypesByClass.clear(); + } + + public void setType(String table, String column, Type type) { + Map> columns = typeByColumn.computeIfAbsent(table, k -> new HashMap>()); + columns.put(column, type); + } + +} \ No newline at end of file diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/Keywords.java b/querydsl-sql/src/main/java/com/querydsl/sql/Keywords.java new file mode 100644 index 0000000000..ca01a42dab --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/Keywords.java @@ -0,0 +1,56 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.LinkedHashSet; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * Defines reserved keywords for the supported dialects + */ +final class Keywords { + + private Keywords() { } + + private static Set readLines(String path) { + try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(Keywords.class.getResourceAsStream("/keywords/" + path)));) { + return bufferedReader.lines() + .filter(line -> !line.isEmpty() && !line.startsWith("#")) + .collect(Collectors.toCollection(LinkedHashSet::new)); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + public static final Set DEFAULT = readLines("default"); + + public static final Set CUBRID = readLines("cubrid"); + public static final Set DB2 = readLines("db2"); + public static final Set DERBY = readLines("derby"); + public static final Set FIREBIRD = readLines("firebird"); + public static final Set H2 = readLines("h2"); + public static final Set HSQLDB = readLines("hsqldb"); + public static final Set MYSQL = readLines("mysql"); + public static final Set ORACLE = readLines("oracle"); + public static final Set POSTGRESQL = readLines("postgresql"); + public static final Set SQLITE = readLines("sqlite"); + public static final Set SQLSERVER2005 = readLines("sqlserver2005"); + public static final Set SQLSERVER2008 = readLines("sqlserver2008"); + public static final Set SQLSERVER2012 = readLines("sqlserver2012"); + +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/MySQLTemplates.java b/querydsl-sql/src/main/java/com/querydsl/sql/MySQLTemplates.java new file mode 100644 index 0000000000..5fdebf6602 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/MySQLTemplates.java @@ -0,0 +1,185 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import java.sql.Types; +import java.util.Collections; + +import com.querydsl.core.QueryFlag; +import com.querydsl.core.QueryFlag.Position; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.ExpressionUtils; +import com.querydsl.core.types.Ops; + +/** + * {@code MySQLTemplates} is an SQL dialect for MySQL + * + *

tested with MySQL CE 5.1 and 5.5

+ * + * @author tiwe + * + */ +public class MySQLTemplates extends SQLTemplates { + + protected static final Expression LOCK_IN_SHARE_MODE = ExpressionUtils.operation( + Object.class, SQLOps.LOCK_IN_SHARE_MODE, Collections.emptyList()); + + @SuppressWarnings("FieldNameHidesFieldInSuperclass") //Intentional + public static final MySQLTemplates DEFAULT = new MySQLTemplates(); + + public static Builder builder() { + return new Builder() { + @Override + protected SQLTemplates build(char escape, boolean quote) { + return new MySQLTemplates(escape, quote); + } + }; + } + + public MySQLTemplates() { + this('\\', false); + } + + public MySQLTemplates(boolean quote) { + this('\\', quote); + } + + public MySQLTemplates(char escape, boolean quote) { + super(Keywords.MYSQL, "`", escape, quote, false); + setArraysSupported(false); + setParameterMetadataAvailable(false); + setLimitRequired(true); + setSupportsUnquotedReservedWordsAsIdentifier(true); + setNullsFirst(null); + setNullsLast(null); + + setForShareSupported(true); + setForShareFlag(new QueryFlag(Position.END, LOCK_IN_SHARE_MODE)); + + setPrecedence(Precedence.COMPARISON, Ops.EQ, Ops.EQ_IGNORE_CASE, Ops.NE); + setPrecedence(Precedence.CASE, Ops.BETWEEN); + + add(SQLOps.LOCK_IN_SHARE_MODE, "\nlock in share mode"); + + add(Ops.MOD, "{0} % {1}", Precedence.ARITH_HIGH); + add(Ops.CONCAT, "concat({0}, {1})", -1); + + add(Ops.StringOps.LPAD, "lpad({0},{1},' ')"); + add(Ops.StringOps.RPAD, "rpad({0},{1},' ')"); + + // like without escape + if (escape == '\\') { + add(Ops.LIKE, "{0} like {1}"); + add(Ops.ENDS_WITH, "{0} like {%1}"); + add(Ops.ENDS_WITH_IC, "{0l} like {%%1}"); + add(Ops.STARTS_WITH, "{0} like {1%}"); + add(Ops.STARTS_WITH_IC, "{0l} like {1%%}"); + add(Ops.STRING_CONTAINS, "{0} like {%1%}"); + add(Ops.STRING_CONTAINS_IC, "{0l} like {%%1%%}"); + } + + add(Ops.MathOps.LOG, "log({1},{0})"); + add(Ops.MathOps.COSH, "(exp({0}) + exp({0*'-1'})) / 2"); + add(Ops.MathOps.COTH, "(exp({0*'2'}) + 1) / (exp({0*'2'}) - 1)"); + add(Ops.MathOps.SINH, "(exp({0}) - exp({0*'-1'})) / 2"); + add(Ops.MathOps.TANH, "(exp({0*'2'}) - 1) / (exp({0*'2'}) + 1)"); + + add(Ops.AggOps.BOOLEAN_ANY, "bit_or({0})", 0); + add(Ops.AggOps.BOOLEAN_ALL, "bit_and({0})", 0); + + add(Ops.DateTimeOps.DAY_OF_WEEK, "dayofweek({0})"); + add(Ops.DateTimeOps.DAY_OF_YEAR, "dayofyear({0})"); + add(Ops.DateTimeOps.YEAR_MONTH, "extract(year_month from {0})"); + add(Ops.DateTimeOps.YEAR_WEEK, "yearweek({0})"); + + add(Ops.DateTimeOps.ADD_YEARS, "date_add({0}, interval {1s} year)"); + add(Ops.DateTimeOps.ADD_MONTHS, "date_add({0}, interval {1s} month)"); + add(Ops.DateTimeOps.ADD_WEEKS, "date_add({0}, interval {1s} week)"); + add(Ops.DateTimeOps.ADD_DAYS, "date_add({0}, interval {1s} day)"); + add(Ops.DateTimeOps.ADD_HOURS, "date_add({0}, interval {1s} hour)"); + add(Ops.DateTimeOps.ADD_MINUTES, "date_add({0}, interval {1s} minute)"); + add(Ops.DateTimeOps.ADD_SECONDS, "date_add({0}, interval {1s} second)"); + + add(Ops.DateTimeOps.DIFF_YEARS, "timestampdiff(year,{0},{1})"); + add(Ops.DateTimeOps.DIFF_MONTHS, "timestampdiff(month,{0},{1})"); + add(Ops.DateTimeOps.DIFF_WEEKS, "timestampdiff(week,{0},{1})"); + add(Ops.DateTimeOps.DIFF_DAYS, "timestampdiff(day,{0},{1})"); + add(Ops.DateTimeOps.DIFF_HOURS, "timestampdiff(hour,{0},{1})"); + add(Ops.DateTimeOps.DIFF_MINUTES, "timestampdiff(minute,{0},{1})"); + add(Ops.DateTimeOps.DIFF_SECONDS, "timestampdiff(second,{0},{1})"); + + add(Ops.DateTimeOps.TRUNC_YEAR, "str_to_date(concat(date_format({0},'%Y'),'-1-1'),'%Y-%m-%d')"); + add(Ops.DateTimeOps.TRUNC_MONTH, "str_to_date(concat(date_format({0},'%Y-%m'),'-1'),'%Y-%m-%d')"); + add(Ops.DateTimeOps.TRUNC_WEEK, "str_to_date(concat(date_format({0},'%Y-%u'),'-1'),'%Y-%u-%w')"); + add(Ops.DateTimeOps.TRUNC_DAY, "str_to_date(date_format({0},'%Y-%m-%d'),'%Y-%m-%d')"); + add(Ops.DateTimeOps.TRUNC_HOUR, "str_to_date(date_format({0},'%Y-%m-%d %k'),'%Y-%m-%d %k')"); + add(Ops.DateTimeOps.TRUNC_MINUTE, "str_to_date(date_format({0},'%Y-%m-%d %k:%i'),'%Y-%m-%d %k:%i')"); + add(Ops.DateTimeOps.TRUNC_SECOND, "str_to_date(date_format({0},'%Y-%m-%d %k:%i:%s'),'%Y-%m-%d %k:%i:%s')"); + + addTypeNameToCode("bool", Types.BIT, true); + addTypeNameToCode("tinyint unsigned", Types.TINYINT); + addTypeNameToCode("bigint unsigned", Types.BIGINT); + addTypeNameToCode("long varbinary", Types.LONGVARBINARY, true); + addTypeNameToCode("mediumblob", Types.LONGVARBINARY); + addTypeNameToCode("longblob", Types.LONGVARBINARY); + addTypeNameToCode("blob", Types.LONGVARBINARY); + addTypeNameToCode("tinyblob", Types.LONGVARBINARY); + addTypeNameToCode("long varchar", Types.LONGVARCHAR, true); + addTypeNameToCode("mediumtext", Types.LONGVARCHAR); + addTypeNameToCode("longtext", Types.LONGVARCHAR); + addTypeNameToCode("text", Types.LONGVARCHAR); + addTypeNameToCode("tinytext", Types.LONGVARCHAR); + addTypeNameToCode("integer unsigned", Types.INTEGER); + addTypeNameToCode("int", Types.INTEGER); + addTypeNameToCode("int unsigned", Types.INTEGER); + addTypeNameToCode("mediumint", Types.INTEGER); + addTypeNameToCode("mediumint unsigned", Types.INTEGER); + addTypeNameToCode("smallint unsigned", Types.SMALLINT); + addTypeNameToCode("float", Types.REAL, true); + addTypeNameToCode("double precision", Types.DOUBLE, true); + addTypeNameToCode("real", Types.DOUBLE); + addTypeNameToCode("enum", Types.VARCHAR); + addTypeNameToCode("set", Types.VARCHAR); + addTypeNameToCode("datetime", Types.TIMESTAMP, true); + } + + @Override + public String escapeLiteral(String str) { + StringBuilder builder = new StringBuilder(); + for (char ch : super.escapeLiteral(str).toCharArray()) { + if (ch == '\\') { + builder.append("\\"); + } + builder.append(ch); + } + return builder.toString(); + } + + @Override + public String getCastTypeNameForCode(int code) { + switch (code) { + case Types.TINYINT: + case Types.SMALLINT: + case Types.INTEGER: + case Types.BIGINT: return "signed"; + case Types.FLOAT: + case Types.DOUBLE: + case Types.REAL: + case Types.DECIMAL: return "decimal"; + case Types.VARCHAR: return "char"; + default: return super.getCastTypeNameForCode(code); + } + } + +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/OracleTemplates.java b/querydsl-sql/src/main/java/com/querydsl/sql/OracleTemplates.java new file mode 100644 index 0000000000..77e909201d --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/OracleTemplates.java @@ -0,0 +1,271 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import java.sql.Types; +import java.util.List; +import java.util.Map; + +import com.querydsl.core.QueryFlag; +import com.querydsl.core.QueryFlag.Position; +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.QueryModifiers; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.Ops; +import com.querydsl.core.types.Path; +import com.querydsl.sql.dml.SQLInsertBatch; + +/** + * {@code OracleTemplates} is an SQL dialect for Oracle + * + *

tested with Oracle 10g XE

+ * + * @author tiwe + */ +public class OracleTemplates extends SQLTemplates { + + @SuppressWarnings("FieldNameHidesFieldInSuperclass") //Intentional + public static final OracleTemplates DEFAULT = new OracleTemplates(); + + public static Builder builder() { + return new Builder() { + @Override + protected SQLTemplates build(char escape, boolean quote) { + return new OracleTemplates(escape, quote); + } + }; + } + + private String outerQueryStart = "select * from (\n select a.*, rownum rn from (\n "; + + private String outerQueryEnd = "\n ) a) where "; + + private String limitQueryStart = "select * from (\n "; + + private String limitQueryEnd = "\n) where rownum <= {0}"; + + private String limitOffsetTemplate = "rn > {0s} and rownum <= {1s}"; + + private String offsetTemplate = "rn > {0}"; + + private String bulkInsertTemplate = "insert all"; + + private String bulkInsertSeparator = " into "; + + public OracleTemplates() { + this('\\', false); + } + + public OracleTemplates(boolean quote) { + this('\\',quote); + } + + public OracleTemplates(char escape, boolean quote) { + super(Keywords.ORACLE, "\"", escape, quote, false); + setParameterMetadataAvailable(false); + setBatchCountViaGetUpdateCount(true); + setWithRecursive("with "); + setCountViaAnalytics(true); + setListMaxSize(1000); + + setPrecedence(Precedence.COMPARISON, Ops.EQ, Ops.EQ_IGNORE_CASE, Ops.NE); + setPrecedence(Precedence.COMPARISON + 1, Ops.IS_NULL, Ops.IS_NOT_NULL, Ops.LIKE, Ops.LIKE_ESCAPE, Ops.BETWEEN, + Ops.IN, Ops.NOT_IN, Ops.EXISTS); + + setPrecedence(Precedence.COMPARISON + 1, OTHER_LIKE_CASES); + + add(Ops.ALIAS, "{0} {1}"); + add(SQLOps.NEXTVAL, "{0s}.nextval"); + + // String + add(Ops.INDEX_OF, "instrb({0},{1})-1", Precedence.ARITH_LOW); + add(Ops.INDEX_OF_2ARGS, "instrb({0},{1},{2+'1'})-1", Precedence.ARITH_LOW); + add(Ops.MATCHES, "regexp_like({0},{1})", -1); + add(Ops.StringOps.LOCATE, "instr({1},{0})"); + add(Ops.StringOps.LOCATE2, "instr({1},{0},{2s})"); + add(Ops.StringOps.LEFT, "substr({0},1,{1})"); + add(Ops.StringOps.RIGHT, "substr({0},-{1s},length({0}))"); + add(SQLOps.GROUP_CONCAT, "listagg({0},',')"); + add(SQLOps.GROUP_CONCAT2, "listagg({0},{1})"); + + // Number + add(Ops.MathOps.CEIL, "ceil({0})"); + add(Ops.MathOps.RANDOM, "dbms_random.value"); + add(Ops.MathOps.LN, "ln({0})"); + add(Ops.MathOps.LOG, "log({1},{0})"); + add(Ops.MathOps.COT, "(cos({0}) / sin({0}))"); + add(Ops.MathOps.COTH, "(exp({0*'2'}) + 1) / (exp({0*'2'}) - 1)"); + add(Ops.MathOps.DEG, "({0*'180.0'} / " + Math.PI + ")"); + add(Ops.MathOps.RAD, "({0*'" + Math.PI + "'} / 180.0)"); + + // Date / time + add(Ops.DateTimeOps.DATE, "trunc({0})"); + + add(Ops.DateTimeOps.WEEK, "to_number(to_char({0},'WW'))"); + add(Ops.DateTimeOps.DAY_OF_WEEK, "to_number(to_char({0},'D')) + 1"); + add(Ops.DateTimeOps.DAY_OF_YEAR, "to_number(to_char({0},'DDD'))"); + add(Ops.DateTimeOps.YEAR_WEEK, "to_number(to_char({0},'IYYY') || to_char({0},'IW'))"); + + add(Ops.DateTimeOps.ADD_YEARS, "{0} + interval '{1s}' year"); + add(Ops.DateTimeOps.ADD_MONTHS, "{0} + interval '{1s}' month"); + add(Ops.DateTimeOps.ADD_WEEKS, "{0} + interval '{1s}' week"); + add(Ops.DateTimeOps.ADD_DAYS, "{0} + interval '{1s}' day"); + add(Ops.DateTimeOps.ADD_HOURS, "{0} + interval '{1s}' hour"); + add(Ops.DateTimeOps.ADD_MINUTES, "{0} + interval '{1s}' minute"); + add(Ops.DateTimeOps.ADD_SECONDS, "{0} + interval '{1s}' second"); + + add(Ops.DateTimeOps.DIFF_YEARS, "trunc(months_between({1}, {0}) / 12)"); + add(Ops.DateTimeOps.DIFF_MONTHS, "trunc(months_between({1}, {0}))"); + add(Ops.DateTimeOps.DIFF_WEEKS, "round((cast({1} as date) - cast({0} as date)) / 7)"); + add(Ops.DateTimeOps.DIFF_DAYS, "round(cast({1} as date) - cast({0} as date))"); + add(Ops.DateTimeOps.DIFF_HOURS, "round((cast({1} as date) - cast({0} as date)) * 24)"); + add(Ops.DateTimeOps.DIFF_MINUTES, "round((cast({1} as date) - cast({0} as date)) * 1440)"); + add(Ops.DateTimeOps.DIFF_SECONDS, "round((cast({1} as date) - cast({0} as date)) * 86400)"); + + add(Ops.DateTimeOps.TRUNC_YEAR, "trunc({0}, 'year')"); + add(Ops.DateTimeOps.TRUNC_MONTH, "trunc({0}, 'month')"); + add(Ops.DateTimeOps.TRUNC_WEEK, "trunc({0}, 'iw')"); + add(Ops.DateTimeOps.TRUNC_DAY, "trunc({0}, 'dd')"); + add(Ops.DateTimeOps.TRUNC_HOUR, "trunc({0}, 'hh')"); + add(Ops.DateTimeOps.TRUNC_MINUTE, "trunc({0}, 'mi')"); + add(Ops.DateTimeOps.TRUNC_SECOND, "{0}"); // not truncated + + addTypeNameToCode("intervalds", -104); + addTypeNameToCode("intervalym", -103); + addTypeNameToCode("timestamp with local time zone", -102); + addTypeNameToCode("timestamp with time zone", -101); + addTypeNameToCode("long raw", Types.LONGVARBINARY); + addTypeNameToCode("raw", Types.VARBINARY); + addTypeNameToCode("long", Types.LONGVARCHAR); + addTypeNameToCode("varchar2", Types.VARCHAR); + + addTypeNameToCode("number(1,0)", Types.BOOLEAN, true); + addTypeNameToCode("number(3,0)", Types.TINYINT, true); + addTypeNameToCode("number(5,0)", Types.SMALLINT, true); + addTypeNameToCode("number(10,0)", Types.INTEGER, true); + addTypeNameToCode("number(19,0)", Types.BIGINT, true); + addTypeNameToCode("binary_float", Types.FLOAT, true); + addTypeNameToCode("binary_double", Types.DOUBLE, true); + } + + @Override + public String getCastTypeNameForCode(int code) { + switch (code) { + case Types.DOUBLE: return "double precision"; + case Types.VARCHAR: return "varchar(4000 char)"; + default: return super.getCastTypeNameForCode(code); + } + } + + @Override + public String serialize(String literal, int jdbcType) { + switch (jdbcType) { + case Types.TIMESTAMP: + case TIMESTAMP_WITH_TIMEZONE: + return "timestamp '" + literal + "'"; + case Types.DATE: + return "date '" + literal + "'"; + case Types.TIME: + case TIME_WITH_TIMEZONE: + return "timestamp '1970-01-01 " + literal + "'"; + default: + return super.serialize(literal, jdbcType); + } + } + + @Override + public void serialize(QueryMetadata metadata, boolean forCountRow, SQLSerializer context) { + if (!forCountRow && metadata.getModifiers().isRestricting() && !metadata.getJoins().isEmpty()) { + QueryModifiers mod = metadata.getModifiers(); + + if (mod.getOffset() == null) { + context.append(limitQueryStart); + context.serializeForQuery(metadata, forCountRow); + context.handle(limitQueryEnd, mod.getLimit()); + } else { + context.append(outerQueryStart); + context.serializeForQuery(metadata, forCountRow); + context.append(outerQueryEnd); + + if (mod.getLimit() == null) { + context.handle(offsetTemplate, mod.getOffset()); + } else { + context.handle(limitOffsetTemplate, mod.getOffset(), mod.getLimit()); + } + } + + } else { + context.serializeForQuery(metadata, forCountRow); + } + + if (!metadata.getFlags().isEmpty()) { + context.serialize(Position.END, metadata.getFlags()); + } + } + + @Override + public void serializeDelete(QueryMetadata metadata, RelationalPath entity, SQLSerializer context) { + context.serializeForDelete(metadata, entity); + + // limit + if (metadata.getModifiers().isRestricting()) { + serializeModifiersForDML(metadata, context); + } + + if (!metadata.getFlags().isEmpty()) { + context.serialize(Position.END, metadata.getFlags()); + } + } + + @Override + public void serializeInsert(QueryMetadata metadata, RelationalPath entity, List batches, SQLSerializer context) { + context.append(bulkInsertTemplate); + metadata.addFlag(new QueryFlag(Position.START_OVERRIDE, bulkInsertSeparator)); + for (SQLInsertBatch batch : batches) { + serializeInsert(metadata, entity, batch.getColumns(), batch.getValues(), batch.getSubQuery(), context); + } + context.append(" select * from dual"); + } + + @Override + public void serializeUpdate(QueryMetadata metadata, RelationalPath entity, + Map, Expression> updates, SQLSerializer context) { + context.serializeForUpdate(metadata, entity, updates); + + // limit + if (metadata.getModifiers().isRestricting()) { + serializeModifiersForDML(metadata, context); + } + + if (!metadata.getFlags().isEmpty()) { + context.serialize(Position.END, metadata.getFlags()); + } + } + + private void serializeModifiersForDML(QueryMetadata metadata, SQLSerializer context) { + if (metadata.getWhere() != null) { + context.append(" and "); + } else { + context.append(getWhere()); + } + context.append("rownum <= "); + context.visitConstant(metadata.getModifiers().getLimit()); + } + + @Override + protected void serializeModifiers(QueryMetadata metadata, SQLSerializer context) { + // do nothing + } + +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/PostgreSQLTemplates.java b/querydsl-sql/src/main/java/com/querydsl/sql/PostgreSQLTemplates.java new file mode 100644 index 0000000000..a1c76d6f96 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/PostgreSQLTemplates.java @@ -0,0 +1,176 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import java.sql.Types; + +import com.querydsl.core.types.Ops; + +/** + * {@code PostgreSQLTemplates} is an SQL dialect for PostgreSQL + * + *

tested with PostgreSQL 8.4 and 9.1

+ * + * @author tiwe + * + */ +public class PostgreSQLTemplates extends SQLTemplates { + + @SuppressWarnings("FieldNameHidesFieldInSuperclass") //Intentional + public static final PostgreSQLTemplates DEFAULT = new PostgreSQLTemplates(); + + public static Builder builder() { + return new Builder() { + @Override + protected SQLTemplates build(char escape, boolean quote) { + return new PostgreSQLTemplates(escape, quote); + } + }; + } + + public PostgreSQLTemplates() { + this('\\', false); + } + + public PostgreSQLTemplates(boolean quote) { + this('\\', quote); + } + + public PostgreSQLTemplates(char escape, boolean quote) { + super(Keywords.POSTGRESQL, "\"", escape, quote, false); + setDummyTable(null); + setCountDistinctMultipleColumns(true); + setCountViaAnalytics(true); + setDefaultValues("\ndefault values"); + setSupportsUnquotedReservedWordsAsIdentifier(true); + + setForShareSupported(true); + + setPrecedence(Precedence.COMPARISON - 3, Ops.IS_NULL, Ops.IS_NOT_NULL); + setPrecedence(Precedence.COMPARISON - 2, Ops.CONCAT, Ops.MATCHES); + setPrecedence(Precedence.COMPARISON - 1, Ops.IN); + setPrecedence(Precedence.COMPARISON, Ops.BETWEEN); + setPrecedence(Precedence.COMPARISON + 1, Ops.LIKE, Ops.LIKE_ESCAPE); + setPrecedence(Precedence.COMPARISON + 2, Ops.LT, Ops.GT, Ops.LOE, Ops.GOE); + setPrecedence(Precedence.COMPARISON + 3, Ops.EQ, Ops.EQ_IGNORE_CASE); + + setPrecedence(Precedence.COMPARISON + 1, OTHER_LIKE_CASES); + + add(Ops.MOD, "{0} % {1}", Precedence.ARITH_HIGH); + + // String + add(Ops.MATCHES, "{0} ~ {1}"); + add(Ops.INDEX_OF, "strpos({0},{1})-1", Precedence.ARITH_LOW); + add(Ops.INDEX_OF_2ARGS, "strpos({0},{1})-1", Precedence.ARITH_LOW); //FIXME + add(Ops.StringOps.LOCATE, "strpos({1},{0})"); + add(Ops.StringOps.LOCATE2, "strpos(repeat('^',{2-'1's}) || substr({1},{2s}),{0})"); + add(SQLOps.GROUP_CONCAT, "string_agg({0},',')"); + add(SQLOps.GROUP_CONCAT2, "string_agg({0},{1})"); + + add(Ops.LIKE_ESCAPE_IC, "{0} ilike {1} escape '{2s}'"); + // like without escape + if (escape == '\\') { + add(Ops.LIKE, "{0} like {1}"); + add(Ops.LIKE_IC, "{0} ilike {1}"); + add(Ops.ENDS_WITH, "{0} like {%1}"); + add(Ops.ENDS_WITH_IC, "{0} ilike {%1}"); + add(Ops.STARTS_WITH, "{0} like {1%}"); + add(Ops.STARTS_WITH_IC, "{0} ilike {1%}"); + add(Ops.STRING_CONTAINS, "{0} like {%1%}"); + add(Ops.STRING_CONTAINS_IC, "{0} ilike {%1%}"); + } else { + // remap case insensitive operations under 'ilike' + add(Ops.LIKE_IC, "{0} ilike {1} escape '" + escape + "'"); + add(Ops.ENDS_WITH_IC, "{0} ilike {%1} escape '" + escape + "'"); + add(Ops.STARTS_WITH_IC, "{0} ilike {1%} escape '" + escape + "'"); + add(Ops.STRING_CONTAINS_IC, "{0} ilike {%1%} escape '" + escape + "'"); + } + + // Number + add(Ops.MathOps.RANDOM, "random()"); + add(Ops.MathOps.LN, "ln({0})"); + add(Ops.MathOps.LOG, "log({1s},{0s})"); + add(Ops.MathOps.COSH, "(exp({0}) + exp({0*'-1'})) / 2"); + add(Ops.MathOps.COTH, "(exp({0*'2'}) + 1) / (exp({0*'2'}) - 1)"); + add(Ops.MathOps.SINH, "(exp({0}) - exp({0} * -1)) / 2"); + add(Ops.MathOps.TANH, "(exp({0*'2'}) - 1) / (exp({0*'2'}) + 1)"); + + // Date / time + add(Ops.DateTimeOps.DAY_OF_MONTH, "cast(extract(day from {0}) as integer)"); + add(Ops.DateTimeOps.DAY_OF_WEEK, "cast(extract(dow from {0}) + 1 as integer)"); + add(Ops.DateTimeOps.DAY_OF_YEAR, "cast(extract(doy from {0}) as integer)"); + add(Ops.DateTimeOps.HOUR, "cast(extract(hour from {0}) as integer)"); + add(Ops.DateTimeOps.MINUTE, "cast(extract(minute from {0}) as integer)"); + add(Ops.DateTimeOps.MONTH, "cast(extract(month from {0}) as integer)"); + add(Ops.DateTimeOps.SECOND, "cast(extract(second from {0}) as integer)"); + add(Ops.DateTimeOps.WEEK, "cast(extract(week from {0}) as integer)"); + add(Ops.DateTimeOps.YEAR, "cast(extract(year from {0}) as integer)"); + add(Ops.DateTimeOps.YEAR_MONTH, "cast(extract(year from {0}) * 100 + extract(month from {0}) as integer)"); + add(Ops.DateTimeOps.YEAR_WEEK, "cast(extract(isoyear from {0}) * 100 + extract(week from {0}) as integer)"); + + add(Ops.AggOps.BOOLEAN_ANY, "bool_or({0})", 0); + add(Ops.AggOps.BOOLEAN_ALL, "bool_and({0})", 0); + + add(Ops.DateTimeOps.ADD_YEARS, "{0} + interval '{1s} years'"); + add(Ops.DateTimeOps.ADD_MONTHS, "{0} + interval '{1s} months'"); + add(Ops.DateTimeOps.ADD_WEEKS, "{0} + interval '{1s} weeks'"); + add(Ops.DateTimeOps.ADD_DAYS, "{0} + interval '{1s} days'"); + add(Ops.DateTimeOps.ADD_HOURS, "{0} + interval '{1s} hours'"); + add(Ops.DateTimeOps.ADD_MINUTES, "{0} + interval '{1s} minutes'"); + add(Ops.DateTimeOps.ADD_SECONDS, "{0} + interval '{1s} seconds'"); + + String yearsDiff = "date_part('year', age({1}, {0}))"; + String monthsDiff = "(" + yearsDiff + " * 12 + date_part('month', age({1}, {0})))"; + String weeksDiff = "trunc((cast({1} as date) - cast({0} as date))/7)"; + String daysDiff = "(cast({1} as date) - cast({0} as date))"; + String hoursDiff = "(" + daysDiff + " * 24 + date_part('hour', age({1}, {0})))"; + String minutesDiff = "(" + hoursDiff + " * 60 + date_part('minute', age({1}, {0})))"; + String secondsDiff = "(" + minutesDiff + " * 60 + date_part('second', age({1}, {0})))"; + + add(Ops.DateTimeOps.DIFF_YEARS, yearsDiff); + add(Ops.DateTimeOps.DIFF_MONTHS, monthsDiff); + add(Ops.DateTimeOps.DIFF_WEEKS, weeksDiff); + add(Ops.DateTimeOps.DIFF_DAYS, daysDiff); + add(Ops.DateTimeOps.DIFF_HOURS, hoursDiff); + add(Ops.DateTimeOps.DIFF_MINUTES, minutesDiff); + add(Ops.DateTimeOps.DIFF_SECONDS, secondsDiff); + + addTypeNameToCode("bool", Types.BIT, true); + addTypeNameToCode("bytea", Types.BINARY); + addTypeNameToCode("name", Types.VARCHAR); + addTypeNameToCode("int8", Types.BIGINT, true); + addTypeNameToCode("bigserial", Types.BIGINT); + addTypeNameToCode("int2", Types.SMALLINT, true); + addTypeNameToCode("int2", Types.TINYINT, true); // secondary mapping + addTypeNameToCode("int4", Types.INTEGER, true); + addTypeNameToCode("serial", Types.INTEGER); + addTypeNameToCode("text", Types.VARCHAR); + addTypeNameToCode("oid", Types.BIGINT); + addTypeNameToCode("xml", Types.SQLXML, true); + addTypeNameToCode("float4", Types.REAL, true); + addTypeNameToCode("float8", Types.DOUBLE, true); + addTypeNameToCode("bpchar", Types.CHAR); + addTypeNameToCode("timestamptz", Types.TIMESTAMP); + } + + @Override + public String serialize(String literal, int jdbcType) { + if (jdbcType == Types.BOOLEAN) { + return "1".equals(literal) ? "true" : "false"; + } else { + return super.serialize(literal, jdbcType); + } + } + +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/PrimaryKey.java b/querydsl-sql/src/main/java/com/querydsl/sql/PrimaryKey.java new file mode 100644 index 0000000000..e4f1862804 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/PrimaryKey.java @@ -0,0 +1,78 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import java.io.Serializable; +import java.util.Arrays; +import java.util.List; + +import org.jetbrains.annotations.Nullable; +import com.querydsl.core.annotations.Immutable; + +import com.querydsl.core.Tuple; +import com.querydsl.core.types.*; +import com.querydsl.core.types.dsl.BooleanExpression; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.util.CollectionUtils; + +/** + * {@code PrimaryKey} defines a primary key on table + * + * @param expression type + * + * @author tiwe + */ +@Immutable +public final class PrimaryKey implements Serializable, ProjectionRole { + + private static final long serialVersionUID = -6913344535043394649L; + + private final RelationalPath entity; + + private final List> localColumns; + + @Nullable + private transient volatile Expression mixin; + + public PrimaryKey(RelationalPath entity, Path... localColumns) { + this(entity, Arrays.asList(localColumns)); + } + + public PrimaryKey(RelationalPath entity, List> localColumns) { + this.entity = entity; + this.localColumns = CollectionUtils.unmodifiableList(localColumns); + this.mixin = ExpressionUtils.list(Tuple.class, localColumns); + } + + public RelationalPath getEntity() { + return entity; + } + + public List> getLocalColumns() { + return localColumns; + } + + public BooleanExpression in(CollectionExpression coll) { + return Expressions.booleanOperation(Ops.IN, getProjection(), coll); + } + + @Override + public Expression getProjection() { + if (mixin == null) { + mixin = ExpressionUtils.list(Tuple.class, localColumns); + } + return mixin; + } + +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/ProjectableSQLQuery.java b/querydsl-sql/src/main/java/com/querydsl/sql/ProjectableSQLQuery.java new file mode 100644 index 0000000000..b3884a3434 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/ProjectableSQLQuery.java @@ -0,0 +1,528 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.jetbrains.annotations.Nullable; + +import com.mysema.commons.lang.CloseableIterator; +import com.querydsl.core.FetchableQuery; +import com.querydsl.core.JoinFlag; +import com.querydsl.core.NonUniqueResultException; +import com.querydsl.core.Query; +import com.querydsl.core.QueryFlag; +import com.querydsl.core.QueryFlag.Position; +import com.querydsl.core.support.FetchableSubQueryBase; +import com.querydsl.core.support.QueryMixin; +import com.querydsl.core.types.*; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.Wildcard; + +/** + * {@code ProjectableSQLQuery} is the base type for SQL query implementations + * + * @param result type + * @param concrete subtype + */ +public abstract class ProjectableSQLQuery & Query> extends FetchableSubQueryBase + implements SQLCommonQuery, FetchableQuery { + + private static final Path defaultQueryAlias = ExpressionUtils.path(Object.class, "query"); + + protected final Configuration configuration; + + @Nullable + protected Expression union; + + protected SubQueryExpression firstUnionSubQuery; + + protected boolean unionAll; + + @SuppressWarnings("unchecked") + public ProjectableSQLQuery(QueryMixin queryMixin, Configuration configuration) { + super(queryMixin); + this.queryMixin.setSelf((Q) this); + this.configuration = configuration; + } + + @Override + public R accept(Visitor v, @Nullable C context) { + if (union != null) { + return union.accept(v, context); + } else { + return super.accept(v, context); + } + } + + /** + * Add the given String literal as a join flag to the last added join with the position + * BEFORE_TARGET + * + * @param flag join flag + * @return the current object + */ + @Override + public Q addJoinFlag(String flag) { + return addJoinFlag(flag, JoinFlag.Position.BEFORE_TARGET); + } + + /** + * Add the given String literal as a join flag to the last added join + * + * @param flag join flag + * @param position position + * @return the current object + */ + @Override + @SuppressWarnings("unchecked") + public Q addJoinFlag(String flag, JoinFlag.Position position) { + queryMixin.addJoinFlag(new JoinFlag(flag, position)); + return (Q) this; + } + + /** + * Add the given prefix and expression as a general query flag + * + * @param position position of the flag + * @param prefix prefix for the flag + * @param expr expression of the flag + * @return the current object + */ + @Override + public Q addFlag(Position position, String prefix, Expression expr) { + Expression flag = Expressions.template(expr.getType(), prefix + "{0}", expr); + return queryMixin.addFlag(new QueryFlag(position, flag)); + } + + /** + * Add the given query flag + * + * @param flag query flag + * @return the current object + */ + public Q addFlag(QueryFlag flag) { + return queryMixin.addFlag(flag); + } + + /** + * Add the given String literal as query flag + * + * @param position position + * @param flag query flag + * @return the current object + */ + @Override + public Q addFlag(Position position, String flag) { + return queryMixin.addFlag(new QueryFlag(position, flag)); + } + + /** + * Add the given Expression as a query flag + * + * @param position position + * @param flag query flag + * @return the current object + */ + @Override + public Q addFlag(Position position, Expression flag) { + return queryMixin.addFlag(new QueryFlag(position, flag)); + } + + @Override + public long fetchCount() { + queryMixin.setProjection(Wildcard.countAsInt); + return ((Number) fetchOne()).longValue(); + } + + public Q from(Expression arg) { + return queryMixin.from(arg); + } + + @Override + public Q from(Expression... args) { + return queryMixin.from(args); + } + + @Override + @SuppressWarnings({ "unchecked", "rawtypes" }) + public Q from(SubQueryExpression subQuery, Path alias) { + return queryMixin.from((Expression) ExpressionUtils.as((Expression) subQuery, alias)); + } + + @Override + public Q fullJoin(EntityPath target) { + return queryMixin.fullJoin(target); + } + + @Override + public Q fullJoin(EntityPath target, Path alias) { + return queryMixin.fullJoin(target, alias); + } + + @Override + public Q fullJoin(RelationalFunctionCall target, Path alias) { + return queryMixin.fullJoin(target, alias); + } + + @Override + public Q fullJoin(SubQueryExpression target, Path alias) { + return queryMixin.fullJoin(target, alias); + } + + @Override + public Q fullJoin(ForeignKey key, RelationalPath entity) { + return queryMixin.fullJoin(entity).on(key.on(entity)); + } + + @Override + public Q innerJoin(EntityPath target) { + return queryMixin.innerJoin(target); + } + + @Override + public Q innerJoin(EntityPath target, Path alias) { + return queryMixin.innerJoin(target, alias); + } + + @Override + public Q innerJoin(RelationalFunctionCall target, Path alias) { + return queryMixin.innerJoin(target, alias); + } + + @Override + public Q innerJoin(SubQueryExpression target, Path alias) { + return queryMixin.innerJoin(target, alias); + } + + @Override + public Q innerJoin(ForeignKey key, RelationalPath entity) { + return queryMixin.innerJoin(entity).on(key.on(entity)); + } + + @Override + public Q join(EntityPath target) { + return queryMixin.join(target); + } + + @Override + public Q join(EntityPath target, Path alias) { + return queryMixin.join(target, alias); + } + + @Override + public Q join(RelationalFunctionCall target, Path alias) { + return queryMixin.join(target, alias); + } + + @Override + public Q join(SubQueryExpression target, Path alias) { + return queryMixin.join(target, alias); + } + + @Override + public Q join(ForeignKey key, RelationalPath entity) { + return queryMixin.join(entity).on(key.on(entity)); + } + + @Override + public Q leftJoin(EntityPath target) { + return queryMixin.leftJoin(target); + } + + @Override + public Q leftJoin(EntityPath target, Path alias) { + return queryMixin.leftJoin(target, alias); + } + + @Override + public Q leftJoin(RelationalFunctionCall target, Path alias) { + return queryMixin.leftJoin(target, alias); + } + + @Override + public Q leftJoin(SubQueryExpression target, Path alias) { + return queryMixin.leftJoin(target, alias); + } + + @Override + public Q leftJoin(ForeignKey key, RelationalPath entity) { + return queryMixin.leftJoin(entity).on(key.on(entity)); + } + + @Override + public Q rightJoin(EntityPath target) { + return queryMixin.rightJoin(target); + } + + @Override + public Q rightJoin(EntityPath target, Path alias) { + return queryMixin.rightJoin(target, alias); + } + + @Override + public Q rightJoin(RelationalFunctionCall target, Path alias) { + return queryMixin.rightJoin(target, alias); + } + + @Override + public Q rightJoin(SubQueryExpression target, Path alias) { + return queryMixin.rightJoin(target, alias); + } + + @Override + public Q rightJoin(ForeignKey key, RelationalPath entity) { + return queryMixin.rightJoin(entity).on(key.on(entity)); + } + + @SuppressWarnings("unchecked") + private Union innerUnion(SubQueryExpression... sq) { + return innerUnion((List) Arrays.asList(sq)); + } + + @SuppressWarnings("unchecked") + private Union innerUnion(List> sq) { + queryMixin.setProjection(sq.get(0).getMetadata().getProjection()); + if (!queryMixin.getMetadata().getJoins().isEmpty()) { + throw new IllegalArgumentException("Don't mix union and from"); + } + this.union = UnionUtils.union(sq, unionAll); + this.firstUnionSubQuery = sq.get(0); + return new UnionImpl(this); + } + + public Q on(Predicate condition) { + return queryMixin.on(condition); + } + + @Override + public Q on(Predicate... conditions) { + return queryMixin.on(conditions); + } + + /** + * Creates an union expression for the given subqueries + * + * @param + * @param sq subqueries + * @return union + */ + public Union union(SubQueryExpression... sq) { + return innerUnion(sq); + } + + /** + * Creates an union expression for the given subqueries + * + * @param + * @param sq subqueries + * @return union + */ + public Union union(List> sq) { + return innerUnion(sq); + } + + /** + * Creates an union expression for the given subqueries + * + * @param + * @param alias alias for union + * @param sq subqueries + * @return the current object + */ + @SuppressWarnings("unchecked") + public Q union(Path alias, SubQueryExpression... sq) { + return from((Expression) UnionUtils.union(Arrays.asList(sq), (Path) alias, false)); + } + + /** + * Creates an union expression for the given subqueries + * + * @param + * @param sq subqueries + * @return union + */ + public Union unionAll(SubQueryExpression... sq) { + unionAll = true; + return innerUnion(sq); + } + + /** + * Creates an union expression for the given subqueries + * + * @param + * @param sq subqueries + * @return union + */ + public Union unionAll(List> sq) { + unionAll = true; + return innerUnion(sq); + } + + + /** + * Creates an union expression for the given subqueries + * + * @param + * @param alias alias for union + * @param sq subqueries + * @return the current object + */ + @SuppressWarnings("unchecked") + public Q unionAll(Path alias, SubQueryExpression... sq) { + return from((Expression) UnionUtils.union(Arrays.asList(sq), (Path) alias, true)); + } + + @Override + public T fetchOne() throws NonUniqueResultException { + if (getMetadata().getModifiers().getLimit() == null + && !queryMixin.getMetadata().getProjection().toString().contains("count(")) { + limit(2); + } + CloseableIterator iterator = iterate(); + return uniqueResult(iterator); + } + + @Override + public Q withRecursive(Path alias, SubQueryExpression query) { + queryMixin.addFlag(new QueryFlag(QueryFlag.Position.WITH, SQLTemplates.RECURSIVE)); + return with(alias, query); + } + + @Override + public Q withRecursive(Path alias, Expression query) { + queryMixin.addFlag(new QueryFlag(QueryFlag.Position.WITH, SQLTemplates.RECURSIVE)); + return with(alias, query); + } + + @Override + public WithBuilder withRecursive(Path alias, Path... columns) { + queryMixin.addFlag(new QueryFlag(QueryFlag.Position.WITH, SQLTemplates.RECURSIVE)); + return with(alias, columns); + } + + @Override + public Q with(Path alias, SubQueryExpression query) { + Expression expr = ExpressionUtils.operation(alias.getType(), SQLOps.WITH_ALIAS, alias, query); + return queryMixin.addFlag(new QueryFlag(QueryFlag.Position.WITH, expr)); + } + + @Override + public Q with(Path alias, Expression query) { + Expression expr = ExpressionUtils.operation(alias.getType(), SQLOps.WITH_ALIAS, alias, query); + return queryMixin.addFlag(new QueryFlag(QueryFlag.Position.WITH, expr)); + } + + @Override + public WithBuilder with(Path alias, Path... columns) { + Expression columnsCombined = ExpressionUtils.list(Object.class, columns); + Expression aliasCombined = Expressions.operation(alias.getType(), SQLOps.WITH_COLUMNS, alias, columnsCombined); + return new WithBuilder(queryMixin, aliasCombined); + } + + protected void clone(Q query) { + this.union = query.union; + this.unionAll = query.unionAll; + this.firstUnionSubQuery = query.firstUnionSubQuery; + } + + @Override + public abstract Q clone(); + + protected abstract SQLSerializer createSerializer(); + + private Set> getRootPaths(Collection> exprs) { + Set> paths = new HashSet<>(); + for (Expression e : exprs) { + Path path = e.accept(PathExtractor.DEFAULT, null); + if (path != null && !path.getMetadata().isRoot()) { + paths.add(path.getMetadata().getRootPath()); + } + } + return paths; + } + + @SuppressWarnings("unchecked") + private Collection> expandProjection(Expression expr) { + if (expr instanceof FactoryExpression) { + return ((FactoryExpression) expr).getArgs(); + } else { + return Collections.singletonList(expr); + } + } + + @SuppressWarnings("unchecked") + protected SQLSerializer serialize(boolean forCountRow) { + SQLSerializer serializer = createSerializer(); + if (union != null) { + if (queryMixin.getMetadata().getProjection() == null || + expandProjection(queryMixin.getMetadata().getProjection()) + .equals(expandProjection(firstUnionSubQuery.getMetadata().getProjection()))) { + serializer.serializeUnion(union, queryMixin.getMetadata(), unionAll); + } else { + QueryMixin mixin2 = new QueryMixin(queryMixin.getMetadata().clone()); + Set> paths = getRootPaths(expandProjection(mixin2.getMetadata().getProjection())); + if (paths.isEmpty()) { + mixin2.from(ExpressionUtils.as((Expression) union, defaultQueryAlias)); + } else if (paths.size() == 1) { + mixin2.from(ExpressionUtils.as((Expression) union, paths.iterator().next())); + } else { + throw new IllegalStateException("Unable to create serialize union"); + } + serializer.serialize(mixin2.getMetadata(), forCountRow); + } + } else { + serializer.serialize(queryMixin.getMetadata(), forCountRow); + } + return serializer; + } + + /** + * Get the query as an SQL query string and bindings + * + * @return SQL string and bindings + */ + public SQLBindings getSQL() { + return getSQL(serialize(false)); + } + + protected SQLBindings getSQL(SQLSerializer serializer) { + List args = new ArrayList<>(); + Map, Object> params = getMetadata().getParams(); + for (Object o : serializer.getConstants()) { + if (o instanceof ParamExpression) { + if (!params.containsKey(o)) { + throw new ParamNotSetException((ParamExpression) o); + } + o = queryMixin.getMetadata().getParams().get(o); + } + args.add(o); + } + return new SQLBindings(serializer.toString(), args); + } + + @Override + public String toString() { + SQLSerializer serializer = serialize(false); + return serializer.toString().trim(); + } + +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/QBeans.java b/querydsl-sql/src/main/java/com/querydsl/sql/QBeans.java new file mode 100644 index 0000000000..be954c625a --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/QBeans.java @@ -0,0 +1,86 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import com.querydsl.core.types.*; +import com.querydsl.core.util.ArrayUtils; +import com.querydsl.core.util.CollectionUtils; + +/** + * Expression used to project a list of beans + * + * @author luis + */ +public class QBeans extends FactoryExpressionBase { + + private static final long serialVersionUID = -4411839816134215923L; + + private final Map, QBean> qBeans; + + private final List> expressions; + + @SuppressWarnings("unchecked") + public QBeans(RelationalPath... beanPaths) { + super(Beans.class); + try { + final List> listBuilder = new ArrayList<>(); + final Map, QBean> mapBuilder = new HashMap<>(); + for (RelationalPath path : beanPaths) { + Map> bindings = new LinkedHashMap>(); + for (Path column : path.getColumns()) { + bindings.put(column.getMetadata().getName(), column); + listBuilder.add(column); + } + mapBuilder.put(path, Projections.bean((Class) path.getType(), bindings)); + } + expressions = CollectionUtils.unmodifiableList(listBuilder); + qBeans = Collections.unmodifiableMap(mapBuilder); + } catch (Exception e) { + throw new IllegalStateException(e); + } + } + + @Override + public R accept(Visitor v, C context) { + return v.visit(this, context); + } + + @Override + public List> getArgs() { + return expressions; + } + + @Override + public Beans newInstance(Object... args) { + int offset = 0; + Map, Object> beans = new HashMap, Object>(); + for (Map.Entry, QBean> entry : qBeans.entrySet()) { + RelationalPath path = entry.getKey(); + QBean qBean = entry.getValue(); + int argsSize = qBean.getArgs().size(); + Object[] subArgs = ArrayUtils.subarray(args, offset, offset + argsSize); + beans.put(path, qBean.newInstance(subArgs)); + offset += argsSize; + } + return new Beans(beans); + } + +} \ No newline at end of file diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/RelationalFunctionCall.java b/querydsl-sql/src/main/java/com/querydsl/sql/RelationalFunctionCall.java new file mode 100644 index 0000000000..d39142bd18 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/RelationalFunctionCall.java @@ -0,0 +1,73 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import java.util.List; + +import com.querydsl.core.types.*; +import com.querydsl.core.types.dsl.SimpleExpression; + +/** + * Represents a table valued function call + * + * @author tiwe + * + * @param + */ +public class RelationalFunctionCall extends SimpleExpression implements TemplateExpression { + + private static final long serialVersionUID = 256739044928186923L; + + private static Template createTemplate(String function, int argCount) { + StringBuilder builder = new StringBuilder(); + builder.append(function); + builder.append("("); + for (int i = 0; i < argCount; i++) { + if (i > 0) { + builder.append(", "); + } + builder.append("{").append(i).append("}"); + } + builder.append(")"); + return TemplateFactory.DEFAULT.create(builder.toString()); + } + + private final TemplateExpression templateMixin; + + protected RelationalFunctionCall(Class type, String function, Object... args) { + super(ExpressionUtils.template(type, createTemplate(function, args.length), args)); + templateMixin = (TemplateExpression) mixin; + } + + @Override + public final R accept(Visitor v, C context) { + return v.visit(this, context); + } + + @Override + public Object getArg(int index) { + return templateMixin.getArg(index); + } + + @Override + public List getArgs() { + return templateMixin.getArgs(); + } + + @Override + public Template getTemplate() { + return templateMixin.getTemplate(); + } + +} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/RelationalPath.java b/querydsl-sql/src/main/java/com/querydsl/sql/RelationalPath.java similarity index 77% rename from querydsl-sql/src/main/java/com/mysema/query/sql/RelationalPath.java rename to querydsl-sql/src/main/java/com/querydsl/sql/RelationalPath.java index 84a677a754..904ee6fba9 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/RelationalPath.java +++ b/querydsl-sql/src/main/java/com/querydsl/sql/RelationalPath.java @@ -1,5 +1,5 @@ /* - * Copyright 2011, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,57 +11,59 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql; +package com.querydsl.sql; -import javax.annotation.Nullable; import java.util.Collection; import java.util.List; -import com.mysema.query.types.EntityPath; -import com.mysema.query.types.Path; -import com.mysema.query.types.ProjectionRole; +import org.jetbrains.annotations.Nullable; + +import com.querydsl.core.types.EntityPath; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.ProjectionRole; /** * RelationalPath extends {@link EntityPath} to provide access to relational * metadata * - * @author tiwe + * @param expression type * + * @author tiwe */ public interface RelationalPath extends EntityPath, ProjectionRole { /** * Get the schema and table name * - * @return + * @return schema and table */ SchemaAndTable getSchemaAndTable(); /** * Get the schema name * - * @return + * @return schema */ String getSchemaName(); /** * Get the table name * - * @return + * @return table */ String getTableName(); /** * Get all columns * - * @return + * @return columns */ List> getColumns(); /** * Get the primary key for this relation or null if none exists * - * @return + * @return primary key */ @Nullable PrimaryKey getPrimaryKey(); @@ -69,14 +71,14 @@ public interface RelationalPath extends EntityPath, ProjectionRole { /** * Get the foreign keys for this relation * - * @return + * @return foreign keys */ Collection> getForeignKeys(); /** * Get the inverse foreign keys for this relation * - * @return + * @return inverse foreign keys */ Collection> getInverseForeignKeys(); @@ -84,6 +86,8 @@ public interface RelationalPath extends EntityPath, ProjectionRole { * Returns the metadata for this path or null if none was assigned. See * {@link ColumnMetadata#getColumnMetadata(Path)} for a null safe * alternative + * + * @return column metadata for path */ @Override @Nullable diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/RelationalPathBase.java b/querydsl-sql/src/main/java/com/querydsl/sql/RelationalPathBase.java new file mode 100644 index 0000000000..40969d2bfb --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/RelationalPathBase.java @@ -0,0 +1,265 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import org.jetbrains.annotations.Nullable; + +import com.querydsl.core.types.*; +import com.querydsl.core.types.dsl.BeanPath; +import com.querydsl.core.types.dsl.BooleanExpression; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberExpression; + +/** + * {@code RelationalPathBase} is a base class for {@link RelationalPath} implementations + * + * @author tiwe + * + * @param + * entity type + */ +public class RelationalPathBase extends BeanPath implements RelationalPath { + + private static final long serialVersionUID = -7031357250283629202L; + + @Nullable + private PrimaryKey primaryKey; + + private final Map, ColumnMetadata> columnMetadata = new LinkedHashMap<>(); + + private final List> foreignKeys = new ArrayList<>(); + + private final List> inverseForeignKeys = new ArrayList<>(); + + private final String schema, table; + + private final SchemaAndTable schemaAndTable; + + private transient FactoryExpression projection; + + private transient NumberExpression count, countDistinct; + + public RelationalPathBase(Class type, String variable, String schema, String table) { + this(type, PathMetadataFactory.forVariable(variable), schema, table); + } + + public RelationalPathBase(Class type, PathMetadata metadata, String schema, + String table) { + super(type, metadata); + this.schema = schema; + this.table = table; + this.schemaAndTable = new SchemaAndTable(schema, table); + } + + protected PrimaryKey createPrimaryKey(Path... columns) { + primaryKey = new PrimaryKey(this, columns); + return primaryKey; + } + + protected ForeignKey createForeignKey(Path local, String foreign) { + ForeignKey foreignKey = new ForeignKey(this, local, foreign); + foreignKeys.add(foreignKey); + return foreignKey; + } + + protected ForeignKey createForeignKey(List> local, List foreign) { + ForeignKey foreignKey = new ForeignKey(this, new ArrayList<>(local), new ArrayList<>(foreign)); + foreignKeys.add(foreignKey); + return foreignKey; + } + + protected ForeignKey createInvForeignKey(Path local, String foreign) { + ForeignKey foreignKey = new ForeignKey(this, local, foreign); + inverseForeignKeys.add(foreignKey); + return foreignKey; + } + + protected ForeignKey createInvForeignKey(List> local, + List foreign) { + ForeignKey foreignKey = new ForeignKey(this, new ArrayList<>(local), new ArrayList<>(foreign)); + inverseForeignKeys.add(foreignKey); + return foreignKey; + } + + protected

> P addMetadata(P path, ColumnMetadata metadata) { + columnMetadata.put(path, metadata); + return path; + } + + @Override + public NumberExpression count() { + if (count == null) { + if (primaryKey != null) { + count = Expressions.numberOperation(Long.class, Ops.AggOps.COUNT_AGG, + primaryKey.getLocalColumns().get(0)); + } else { + throw new IllegalStateException("No count expression can be created"); + } + } + return count; + } + + @Override + public NumberExpression countDistinct() { + if (countDistinct == null) { + if (primaryKey != null) { + // TODO handle multiple column primary keys properly + countDistinct = Expressions.numberOperation(Long.class, Ops.AggOps.COUNT_DISTINCT_AGG, + primaryKey.getLocalColumns().get(0)); + } else { + throw new IllegalStateException("No count distinct expression can be created"); + } + } + return countDistinct; + } + + /** + * Compares the two relational paths using primary key columns + * + * @param right rhs of the comparison + * @return this == right + */ + @Override + public BooleanExpression eq(T right) { + if (right instanceof RelationalPath) { + return primaryKeyOperation(Ops.EQ, primaryKey, ((RelationalPath) right).getPrimaryKey()); + } else { + return super.eq(right); + } + } + + /** + * Compares the two relational paths using primary key columns + * + * @param right rhs of the comparison + * @return this == right + */ + @Override + public BooleanExpression eq(Expression right) { + if (right instanceof RelationalPath) { + return primaryKeyOperation(Ops.EQ, primaryKey, ((RelationalPath) right).getPrimaryKey()); + } else { + return super.eq(right); + } + } + + /** + * Compares the two relational paths using primary key columns + * + * @param right rhs of the comparison + * @return this != right + */ + @Override + public BooleanExpression ne(T right) { + if (right instanceof RelationalPath) { + return primaryKeyOperation(Ops.NE, primaryKey, ((RelationalPath) right).getPrimaryKey()); + } else { + return super.ne(right); + } + } + + /** + * Compares the two relational paths using primary key columns + * + * @param right rhs of the comparison + * @return this != right + */ + @Override + public BooleanExpression ne(Expression right) { + if (right instanceof RelationalPath) { + return primaryKeyOperation(Ops.NE, primaryKey, ((RelationalPath) right).getPrimaryKey()); + } else { + return super.ne(right); + } + } + + private BooleanExpression primaryKeyOperation(Operator op, PrimaryKey pk1, PrimaryKey pk2) { + if (pk1 == null || pk2 == null) { + throw new UnsupportedOperationException("No primary keys available"); + } + if (pk1.getLocalColumns().size() != pk2.getLocalColumns().size()) { + throw new UnsupportedOperationException("Size mismatch for primary key columns"); + } + BooleanExpression rv = null; + for (int i = 0; i < pk1.getLocalColumns().size(); i++) { + BooleanExpression pred = Expressions.booleanOperation(op, pk1.getLocalColumns().get(i), pk2.getLocalColumns().get(i)); + rv = rv != null ? rv.and(pred) : pred; + } + return rv; + } + + @Override + public FactoryExpression getProjection() { + if (projection == null) { + projection = RelationalPathUtils.createProjection(this); + } + return projection; + } + + public Path[] all() { + return columnMetadata.keySet().toArray(new Path[0]); + } + + @Override + protected

> P add(P path) { + return path; + } + + @Override + public List> getColumns() { + return new ArrayList<>(this.columnMetadata.keySet()); + } + + @Override + public Collection> getForeignKeys() { + return foreignKeys; + } + + @Override + public Collection> getInverseForeignKeys() { + return inverseForeignKeys; + } + + @Override + public PrimaryKey getPrimaryKey() { + return primaryKey; + } + + @Override + public SchemaAndTable getSchemaAndTable() { + return schemaAndTable; + } + + @Override + public String getSchemaName() { + return schema; + } + + @Override + public String getTableName() { + return table; + } + + @Override + public ColumnMetadata getMetadata(Path column) { + return columnMetadata.get(column); + } + +} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/RelationalPathExtractor.java b/querydsl-sql/src/main/java/com/querydsl/sql/RelationalPathExtractor.java similarity index 75% rename from querydsl-sql/src/main/java/com/mysema/query/sql/RelationalPathExtractor.java rename to querydsl-sql/src/main/java/com/querydsl/sql/RelationalPathExtractor.java index 8f5566bf85..6c8f2880c7 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/RelationalPathExtractor.java +++ b/querydsl-sql/src/main/java/com/querydsl/sql/RelationalPathExtractor.java @@ -1,5 +1,5 @@ /* - * Copyright 2013, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,28 +11,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql; +package com.querydsl.sql; -import static com.mysema.query.util.CollectionUtils.add; +import static com.querydsl.core.util.CollectionUtils.add; +import java.util.Collections; import java.util.Set; -import com.google.common.collect.ImmutableSet; -import com.mysema.query.JoinExpression; -import com.mysema.query.QueryMetadata; -import com.mysema.query.types.Constant; -import com.mysema.query.types.Expression; -import com.mysema.query.types.FactoryExpression; -import com.mysema.query.types.Operation; -import com.mysema.query.types.OrderSpecifier; -import com.mysema.query.types.ParamExpression; -import com.mysema.query.types.Path; -import com.mysema.query.types.SubQueryExpression; -import com.mysema.query.types.TemplateExpression; -import com.mysema.query.types.Visitor; +import com.querydsl.core.JoinExpression; +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.types.*; /** - * RelationalPathExtractor extracts RelationlPath instances from expressions and queries + * {@code RelationalPathExtractor} extracts {@link RelationalPath} instances from expressions and queries * * @author tiwe * @@ -42,10 +33,10 @@ public final class RelationalPathExtractor implements Visitor> extract(QueryMetadata md) { - Set> known = ImmutableSet.of(); + Set> known = Collections.emptySet(); known = DEFAULT.visitJoins(md.getJoins(), known); - for (Expression p : md.getProjection()) { - known = p.accept(DEFAULT, known); + if (md.getProjection() != null) { + known = md.getProjection().accept(DEFAULT, known); } for (OrderSpecifier o : md.getOrderBy()) { known = o.getTarget().accept(DEFAULT, known); @@ -63,7 +54,7 @@ public static Set> extract(QueryMetadata md) { } public static Set> extract(Expression expr) { - return expr.accept(DEFAULT, ImmutableSet.>of()); + return expr.accept(DEFAULT, Collections.emptySet()); } @Override @@ -96,7 +87,7 @@ public Set> visit(ParamExpression expr, Set> visit(Path expr, Set> known) { if (expr.getMetadata().isRoot()) { if (expr instanceof RelationalPath) { - known = add(known, (RelationalPath)expr); + known = add(known, (RelationalPath) expr); } } else { known = expr.getMetadata().getParent().accept(this, known); @@ -109,8 +100,8 @@ public Set> visit(SubQueryExpression expr, Set> old = known; final QueryMetadata md = expr.getMetadata(); known = visitJoins(md.getJoins(), known); - for (Expression p : md.getProjection()) { - known = p.accept(this, known); + if (md.getProjection() != null) { + known = md.getProjection().accept(this, known); } for (OrderSpecifier o : md.getOrderBy()) { known = o.getTarget().accept(this, known); @@ -132,7 +123,7 @@ public Set> visit(SubQueryExpression expr, Set> visit(TemplateExpression expr, Set> known) { for (Object arg : expr.getArgs()) { if (arg instanceof Expression) { - known = ((Expression)arg).accept(this, known); + known = ((Expression) arg).accept(this, known); } } return known; @@ -148,6 +139,6 @@ private Set> visitJoins(Iterable joins, Set FactoryExpression createProjection(RelationalPath path) { + if (path.getType().equals(path.getClass())) { + throw new IllegalArgumentException("RelationalPath based projection can only be used with generated Bean types"); + } + try { + // ensure that empty constructor is available + path.getType().getConstructor(); + return createBeanProjection(path); + } catch (NoSuchMethodException e) { + // fallback to constructor projection + return createConstructorProjection(path); + } + } + + private static FactoryExpression createConstructorProjection(RelationalPath path) { + Expression[] exprs = path.getColumns().toArray(new Expression[0]); + return Projections.constructor((Class) path.getType(), exprs); + } + + private static FactoryExpression createBeanProjection(RelationalPath path) { + Map> bindings = new LinkedHashMap>(); + for (Path column : path.getColumns()) { + bindings.put(column.getMetadata().getName(), column); + } + if (bindings.isEmpty()) { + throw new IllegalArgumentException("No bindings could be derived from " + path); + } + return Projections.fields((Class) path.getType(), bindings); + } + + private RelationalPathUtils() { } + +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/SQLBaseListener.java b/querydsl-sql/src/main/java/com/querydsl/sql/SQLBaseListener.java new file mode 100644 index 0000000000..5d250aca26 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/SQLBaseListener.java @@ -0,0 +1,122 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import java.util.List; +import java.util.Map; + +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.SubQueryExpression; +import com.querydsl.sql.dml.SQLInsertBatch; +import com.querydsl.sql.dml.SQLMergeBatch; +import com.querydsl.sql.dml.SQLUpdateBatch; + +/** + * {@code SQLBaseListener} is a base implementation of the {@link SQLDetailedListener} interface + * with empty method implementations + */ +public class SQLBaseListener implements SQLDetailedListener { + + @Override + public void start(SQLListenerContext context) { + + } + + @Override + public void preRender(SQLListenerContext context) { + + } + + @Override + public void rendered(SQLListenerContext context) { + + } + + @Override + public void prePrepare(SQLListenerContext context) { + + } + + @Override + public void prepared(SQLListenerContext context) { + + } + + @Override + public void preExecute(SQLListenerContext context) { + + } + + @Override + public void executed(SQLListenerContext context) { + + } + + @Override + public void exception(SQLListenerContext context) { + + } + + @Override + public void end(SQLListenerContext context) { + + } + + @Override + public void notifyQuery(QueryMetadata md) { + + } + + @Override + public void notifyDelete(RelationalPath entity, QueryMetadata md) { + + } + + @Override + public void notifyDeletes(RelationalPath entity, List batches) { + + } + + @Override + public void notifyMerge(RelationalPath entity, QueryMetadata md, List> keys, List> columns, List> values, SubQueryExpression subQuery) { + + } + + @Override + public void notifyMerges(RelationalPath entity, QueryMetadata md, List batches) { + + } + + @Override + public void notifyInsert(RelationalPath entity, QueryMetadata md, List> columns, List> values, SubQueryExpression subQuery) { + + } + + @Override + public void notifyInserts(RelationalPath entity, QueryMetadata md, List batches) { + + } + + @Override + public void notifyUpdate(RelationalPath entity, QueryMetadata md, Map, Expression> updates) { + + } + + @Override + public void notifyUpdates(RelationalPath entity, List batches) { + + } +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/SQLBindings.java b/querydsl-sql/src/main/java/com/querydsl/sql/SQLBindings.java new file mode 100644 index 0000000000..82bcfc1f02 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/SQLBindings.java @@ -0,0 +1,48 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import java.util.List; +import java.util.logging.Logger; + +import com.querydsl.core.util.CollectionUtils; + +/** + * {@code SQLBindings} provides the SQL query string and bindings + * + * @author tiwe + * + */ +public class SQLBindings { + + private static final Logger log = Logger.getLogger(SQLBindings.class.getName()); + + private final String sql; + + private final List bindings; + + public SQLBindings(String sql, List bindings) { + this.sql = sql; + this.bindings = CollectionUtils.unmodifiableList(bindings); + } + + public String getSQL() { + return sql; + } + + public List getNullFriendlyBindings() { + return bindings; + } + +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/SQLCloseListener.java b/querydsl-sql/src/main/java/com/querydsl/sql/SQLCloseListener.java new file mode 100644 index 0000000000..040c2923cd --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/SQLCloseListener.java @@ -0,0 +1,42 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import java.sql.Connection; +import java.sql.SQLException; + +import com.querydsl.core.QueryException; + +/** + * {@code SQLCloseListener} closes the JDBC connection at the end of the query or clause execution + */ +public final class SQLCloseListener extends SQLBaseListener { + + public static final SQLCloseListener DEFAULT = new SQLCloseListener(); + + private SQLCloseListener() { } + + @Override + public void end(SQLListenerContext context) { + Connection connection = context.getConnection(); + if (connection != null && context.getData(AbstractSQLQuery.PARENT_CONTEXT) == null) { + try { + connection.close(); + } catch (SQLException e) { + throw new QueryException(e); + } + } + } + +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/SQLCommonQuery.java b/querydsl-sql/src/main/java/com/querydsl/sql/SQLCommonQuery.java new file mode 100644 index 0000000000..1106ba6b11 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/SQLCommonQuery.java @@ -0,0 +1,425 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import com.querydsl.core.JoinFlag; +import com.querydsl.core.Query; +import com.querydsl.core.QueryFlag.Position; +import com.querydsl.core.types.*; + +/** + * {@code SQLCommonQuery} is a common interface for SQLQuery and SQLSubQuery + * + * @author tiwe + * + * @param concrete type + */ +public interface SQLCommonQuery> extends Query { + + /** + * Add the given Expression as a query flag + * + * @param position position + * @param flag query flag + * @return the current object + */ + Q addFlag(Position position, Expression flag); + + /** + * Add the given String literal as query flag + * + * @param position position + * @param flag query flag + * @return the current object + */ + Q addFlag(Position position, String flag); + + /** + * Add the given prefix and expression as a general query flag + * + * @param position position of the flag + * @param prefix prefix for the flag + * @param expr expression of the flag + * @return the current object + */ + Q addFlag(Position position, String prefix, Expression expr); + + /** + * Add the given String literal as a join flag to the last added join with the + * position BEFORE_TARGET + * + * @param flag join flag + * @return the current object + */ + Q addJoinFlag(String flag); + + /** + * Add the given String literal as a join flag to the last added join + * + * @param flag join flag + * @param position position + * @return the current object + */ + Q addJoinFlag(String flag, JoinFlag.Position position); + + /** + * Defines the sources of the query + * + * @param o from + * @return the current object + */ + Q from(Expression... o); + + /** + * Adds a sub query source + * + * @param subQuery sub query + * @param alias alias + * @return the current object + */ + Q from(SubQueryExpression subQuery, Path alias); + + /** + * Adds a full join to the given target + * + * @param o full join target + * @return the current object + */ + Q fullJoin(EntityPath o); + + /** + * Adds a full join to the given target + * + * @param + * @param o full join target + * @param alias alias + * @return the current object + */ + Q fullJoin(EntityPath o, Path alias); + + /** + * Adds a full join to the given target + * + * @param + * @param o full join target + * @param alias alias + * @return the current object + */ + Q fullJoin(RelationalFunctionCall o, Path alias); + + /** + * Adds a full join to the given target + * + * @param + * @param key foreign key for join + * @param entity join target + * @return the current object + */ + Q fullJoin(ForeignKey key, RelationalPath entity); + + /** + * Adds a full join to the given target + * + * @param o subquery + * @param alias alias + * @return the current object + */ + Q fullJoin(SubQueryExpression o, Path alias); + + /** + * Adds an inner join to the given target + * + * @param o + * @return the current object + */ + Q innerJoin(EntityPath o); + + /** + * Adds an inner join to the given target + * + * @param + * @param o inner join target + * @param alias alias + * @return the current object + */ + Q innerJoin(EntityPath o, Path alias); + + /** + * Adds a inner join to the given target + * + * @param + * @param o relational function call + * @param alias alias + * @return the current object + */ + Q innerJoin(RelationalFunctionCall o, Path alias); + + /** + * Adds an inner join to the given target + * + * @param + * @param foreign foreign key to use for join + * @param entity join target + * @return the current object + */ + Q innerJoin(ForeignKey foreign, RelationalPath entity); + + /** + * Adds an inner join to the given target + * + * @param o subquery + * @param alias alias + * @return the current object + */ + Q innerJoin(SubQueryExpression o, Path alias); + + /** + * Adds a join to the given target + * + * @param o join target + * @return the current object + */ + Q join(EntityPath o); + + /** + * Adds a join to the given target + * + * @param + * @param o join target + * @param alias alias + * @return the current object + */ + Q join(EntityPath o, Path alias); + + /** + * Adds a join to the given target + * + * @param + * @param o join target + * @param alias alias + * @return the current object + */ + Q join(RelationalFunctionCall o, Path alias); + + /** + * Adds a join to the given target + * + * @param + * @param foreign foreign key to use for join + * @param entity join target + * @return the current object + */ + Q join(ForeignKey foreign, RelationalPath entity); + + /** + * Adds a join to the given target + * + * @param o subquery + * @param alias alias + * @return the current object + */ + Q join(SubQueryExpression o, Path alias); + + /** + * Adds a left join to the given target + * + * @param o join target + * @return the current object + */ + Q leftJoin(EntityPath o); + + /** + * Adds a left join to the given target + * + * @param + * @param o left join target + * @param alias alias + * @return the current object + */ + Q leftJoin(EntityPath o, Path alias); + + /** + * Adds a left join to the given target + * + * @param + * @param o relational function call + * @param alias alias + * @return the current object + */ + Q leftJoin(RelationalFunctionCall o, Path alias); + + /** + * Adds a left join to the given target + * + * @param + * @param foreign foreign key to use for join + * @param entity join target + * @return the current object + */ + Q leftJoin(ForeignKey foreign, RelationalPath entity); + + /** + * Adds a left join to the given target + * + * @param o subquery + * @param alias alias + * @return the current object + */ + Q leftJoin(SubQueryExpression o, Path alias); + + /** + * Defines a filter to the last added join + * + * @param conditions join conditions + * @return the current object + */ + Q on(Predicate... conditions); + + /** + * Adds a right join to the given target + * + * @param o join target + * @return the current object + */ + Q rightJoin(EntityPath o); + + /** + * Adds a right join to the given target + * + * @param + * @param o right join target + * @param alias alias + * @return the current object + */ + Q rightJoin(EntityPath o, Path alias); + + /** + * Adds a full join to the given target + * + * @param + * @param o relational function call + * @param alias alias + * @return the current object + */ + Q rightJoin(RelationalFunctionCall o, Path alias); + + /** + * Adds a right join to the given target + * + * @param + * @param foreign foreign key to use for join + * @param entity join target + * @return the current object + */ + Q rightJoin(ForeignKey foreign, RelationalPath entity); + + /** + * Adds a right join to the given target + * + * @param o subquery + * @param alias alias + * @return the current object + */ + Q rightJoin(SubQueryExpression o, Path alias); + + /** + * Adds a common table expression + * + *

Usage

+ *
+     * query.with(alias, subQuery)
+     *      .from(...)
+     * 
+ * + * @param alias alias for query + * @param o subquery + * @return the current object + */ + Q with(Path alias, SubQueryExpression o); + + /** + * Adds a common table expression + * + *

Usage

+ *
+     * query.with(alias, subQuery)
+     *      .from(...)
+     * 
+ * + * @param alias alias for query + * @param query subquery + * @return the current object + */ + Q with(Path alias, Expression query); + + /** + * Adds a common table expression + * + *

Usage

+ *
+     * query.with(alias, columns...).as(subQuery)
+     *      .from(...)
+     * 
+ * + * @param alias alias for query + * @param columns columns to use + * @return the current object + */ + WithBuilder with(Path alias, Path... columns); + + /** + * Adds a common table expression + * + *

Usage

+ *
+     * query.withRecursive(alias, subQuery)
+     *      .from(...)
+     * 
+ * + * @param alias alias for query + * @param o subquery + * @return the current object + */ + Q withRecursive(Path alias, SubQueryExpression o); + + /** + * Adds a common table expression + * + *

Usage

+ *
+     * query.withRecursive(alias, subQuery)
+     *      .from(...)
+     * 
+ * + * @param alias alias for query + * @param query subquery + * @return the current object + */ + Q withRecursive(Path alias, Expression query); + + /** + * Adds a common table expression + * + *

Usage

+ *
+     * query.withRecursive(alias, columns...).as(subQuery)
+     *      .from(...)
+     * 
+ * + * @param alias alias for query + * @param columns columns to use + * @return builder for with part + */ + WithBuilder withRecursive(Path alias, Path... columns); +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/SQLCommonQueryFactory.java b/querydsl-sql/src/main/java/com/querydsl/sql/SQLCommonQueryFactory.java new file mode 100644 index 0000000000..84a7179401 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/SQLCommonQueryFactory.java @@ -0,0 +1,108 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import com.querydsl.core.QueryFactory; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.SubQueryExpression; +import com.querydsl.sql.dml.SQLDeleteClause; +import com.querydsl.sql.dml.SQLInsertClause; +import com.querydsl.sql.dml.SQLMergeClause; +import com.querydsl.sql.dml.SQLUpdateClause; + +/** + * Factory interface for query and clause creation. + * + *

The default implementation is {@link SQLQueryFactory} and should be used for general + * query creation. Type specific variants are available if database specific queries need to be created.

+ * + * @author tiwe + * + * @param query type + * @param delete clause type + * @param update clause type + * @param insert clause type + * @param merge clause type + */ +public interface SQLCommonQueryFactory, // extends AbstractSQLQuery + D extends SQLDeleteClause, + U extends SQLUpdateClause, + I extends SQLInsertClause, + M extends SQLMergeClause> extends QueryFactory { + + /** + * Create a new DELETE clause + * + * @param path table to delete from + * @return delete clause + */ + D delete(RelationalPath path); + + /** + * Create a new SELECT query + * + * @param from query source + * @return query + */ + Q from(Expression from); + + /** + * Create a new SELECT query + * + * @param from query sources + * @return query + */ + Q from(Expression... from); + + /** + * Create a new SELECT query + * + * @param subQuery query source + * @param alias alias + * @return query + */ + Q from(SubQueryExpression subQuery, Path alias); + + /** + * Create a new INSERT INTO clause + * + * @param path table to insert to + * @return insert clause + */ + I insert(RelationalPath path); + + /** + * Create a new MERGE clause + * + * @param path table to merge into + * @return merge clause + */ + M merge(RelationalPath path); + + /** + * Create a new UPDATE clause + * + * @param path table to update + * @return update clause + */ + U update(RelationalPath path); + + /* (non-Javadoc) + * @see com.querydsl.core.QueryFactory#query() + */ + @Override + Q query(); + +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/SQLDetailedListener.java b/querydsl-sql/src/main/java/com/querydsl/sql/SQLDetailedListener.java new file mode 100644 index 0000000000..c7ef778f51 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/SQLDetailedListener.java @@ -0,0 +1,83 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +/** + * An extended listener interface that details much more about the preparation and execution of queries + */ +public interface SQLDetailedListener extends SQLListener { + /** + * Called at the start of a query. Most context parameters are empty at this stage + * + * @param context a context object that is progressively filled out as the query executes + */ + void start(SQLListenerContext context); + + /** + * Called at the start of SQL rendering. + * + * @param context a context object that is progressively filled out as the query executes + */ + void preRender(SQLListenerContext context); + + /** + * Called at the end of SQL rendering. The sql context value will not be available + * + * @param context a context object that is progressively filled out as the query executes + */ + void rendered(SQLListenerContext context); + + /** + * Called at the start of {@link java.sql.PreparedStatement} preparation. + * + * @param context a context object that is progressively filled out as the query executes + */ + void prePrepare(SQLListenerContext context); + + /** + * Called at the end of {@link java.sql.PreparedStatement} preparation. + * + * @param context a context object that is progressively filled out as the query executes + */ + void prepared(SQLListenerContext context); + + /** + * Called at the start of {@link java.sql.PreparedStatement} execution. + * + * @param context a context object that is progressively filled out as the query executes + */ + void preExecute(SQLListenerContext context); + + /** + * Called at the end of {@link java.sql.PreparedStatement} execution. + * + * @param context a context object that is progressively filled out as the query executes + */ + void executed(SQLListenerContext context); + + /** + * Called if an exception happens during query building and execution. The context exception values will + * now be available indicating the exception that occurred. + * + * @param context a context object that is progressively filled out as the query executes + */ + void exception(SQLListenerContext context); + + /** + * Called at the end of a query. + * + * @param context a context object that is progressively filled out as the query executes + */ + void end(SQLListenerContext context); +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/SQLExceptionTranslator.java b/querydsl-sql/src/main/java/com/querydsl/sql/SQLExceptionTranslator.java new file mode 100644 index 0000000000..cf1ebf3961 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/SQLExceptionTranslator.java @@ -0,0 +1,44 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import java.sql.SQLException; +import java.util.List; + +/** + * {@code SQLExceptionTranslator} translate SQLExceptions to runtime exceptions + * + * @author tiwe + * + */ +public interface SQLExceptionTranslator { + + /** + * Translate the given SQLException + * + * @param sql SQL string + * @param bindings binding + * @param e SQLException to translate + * @return translated exception + */ + RuntimeException translate(String sql, List bindings, SQLException e); + + /** + * Translate the given SQLException + * + * @param e SQLException to translate + * @return translated exception + */ + RuntimeException translate(SQLException e); +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/SQLExpressions.java b/querydsl-sql/src/main/java/com/querydsl/sql/SQLExpressions.java new file mode 100644 index 0000000000..85e0cca2e2 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/SQLExpressions.java @@ -0,0 +1,1251 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import java.util.EnumMap; +import java.util.List; +import java.util.Map; + +import com.querydsl.core.Tuple; +import com.querydsl.core.types.*; +import com.querydsl.core.types.dsl.*; + +/** + * Common SQL expressions + * + * @author tiwe + * + */ +@SuppressWarnings("rawtypes") +public final class SQLExpressions { + + private static final Map DATE_ADD_OPS + = new EnumMap(DatePart.class); + + private static final Map DATE_DIFF_OPS + = new EnumMap(DatePart.class); + + private static final Map DATE_TRUNC_OPS + = new EnumMap(DatePart.class); + + static { + DATE_ADD_OPS.put(DatePart.year, Ops.DateTimeOps.ADD_YEARS); + DATE_ADD_OPS.put(DatePart.month, Ops.DateTimeOps.ADD_MONTHS); + DATE_ADD_OPS.put(DatePart.week, Ops.DateTimeOps.ADD_WEEKS); + DATE_ADD_OPS.put(DatePart.day, Ops.DateTimeOps.ADD_DAYS); + DATE_ADD_OPS.put(DatePart.hour, Ops.DateTimeOps.ADD_HOURS); + DATE_ADD_OPS.put(DatePart.minute, Ops.DateTimeOps.ADD_MINUTES); + DATE_ADD_OPS.put(DatePart.second, Ops.DateTimeOps.ADD_SECONDS); + DATE_ADD_OPS.put(DatePart.millisecond, null); // TODO + + DATE_DIFF_OPS.put(DatePart.year, Ops.DateTimeOps.DIFF_YEARS); + DATE_DIFF_OPS.put(DatePart.month, Ops.DateTimeOps.DIFF_MONTHS); + DATE_DIFF_OPS.put(DatePart.week, Ops.DateTimeOps.DIFF_WEEKS); + DATE_DIFF_OPS.put(DatePart.day, Ops.DateTimeOps.DIFF_DAYS); + DATE_DIFF_OPS.put(DatePart.hour, Ops.DateTimeOps.DIFF_HOURS); + DATE_DIFF_OPS.put(DatePart.minute, Ops.DateTimeOps.DIFF_MINUTES); + DATE_DIFF_OPS.put(DatePart.second, Ops.DateTimeOps.DIFF_SECONDS); + DATE_DIFF_OPS.put(DatePart.millisecond, null); // TODO + + DATE_TRUNC_OPS.put(DatePart.year, Ops.DateTimeOps.TRUNC_YEAR); + DATE_TRUNC_OPS.put(DatePart.month, Ops.DateTimeOps.TRUNC_MONTH); + DATE_TRUNC_OPS.put(DatePart.week, Ops.DateTimeOps.TRUNC_WEEK); + DATE_TRUNC_OPS.put(DatePart.day, Ops.DateTimeOps.TRUNC_DAY); + DATE_TRUNC_OPS.put(DatePart.hour, Ops.DateTimeOps.TRUNC_HOUR); + DATE_TRUNC_OPS.put(DatePart.minute, Ops.DateTimeOps.TRUNC_MINUTE); + DATE_TRUNC_OPS.put(DatePart.second, Ops.DateTimeOps.TRUNC_SECOND); + + } + + private static final WindowOver cumeDist = new WindowOver(Double.class, SQLOps.CUMEDIST); + + private static final WindowOver rank = new WindowOver(Long.class, SQLOps.RANK); + + private static final WindowOver denseRank = new WindowOver(Long.class, SQLOps.DENSERANK); + + private static final WindowOver percentRank = new WindowOver(Double.class, SQLOps.PERCENTRANK); + + private static final WindowOver rowNumber = new WindowOver(Long.class, SQLOps.ROWNUMBER); + + private static Expression[] convertToExpressions(Object... args) { + Expression[] exprs = new Expression[args.length]; + for (int i = 0; i < args.length; i++) { + if (args[i] instanceof Expression) { + exprs[i] = (Expression) args[i]; + } else { + exprs[i] = ConstantImpl.create(args[i]); + } + } + return exprs; + } + + /** + * Wildcard expression + */ + public static final Expression all = Wildcard.all; + + /** + * Wildcard count expression + */ + public static final Expression countAll = Wildcard.count; + + /** + * Create an assignment expression + * + * @param target target expression + * @param value value to be set + * @param + * @return target = value + */ + public static Expression set(Path target, Expression value) { + if (value != null) { + return Expressions.operation(target.getType(), SQLOps.SET_PATH, target, value); + } else { + return Expressions.operation(target.getType(), SQLOps.SET_LITERAL, + target, Expressions.nullExpression()); + } + + } + + /** + * Create an assignment expression + * + * @param target target expression + * @param value value to be set + * @param + * @return target = value + */ + public static Expression set(Path target, T value) { + if (value != null) { + return Expressions.operation(target.getType(), SQLOps.SET_LITERAL, + target, Expressions.constant(value)); + } else { + return Expressions.operation(target.getType(), SQLOps.SET_LITERAL, + target, Expressions.nullExpression()); + } + + } + + /** + * Create a new detached SQLQuery instance with the given projection + * + * @param expr projection + * @param + * @return select(expr) + */ + public static SQLQuery select(Expression expr) { + return new SQLQuery().select(expr); + } + + /** + * Create a new detached SQLQuery instance with the given projection + * + * @param exprs projection + * @return select(exprs) + */ + public static SQLQuery select(Expression... exprs) { + return new SQLQuery().select(exprs); + } + + /** + * Create a new detached SQLQuery instance with the given projection + * + * @param expr distinct projection + * @param + * @return select(distinct expr) + */ + public static SQLQuery selectDistinct(Expression expr) { + return new SQLQuery().select(expr).distinct(); + } + + /** + * Create a new detached SQLQuery instance with the given projection + * + * @param exprs distinct projection + * @return select(distinct exprs) + */ + public static SQLQuery selectDistinct(Expression... exprs) { + return new SQLQuery().select(exprs).distinct(); + } + + /** + * Create a new detached SQLQuery instance with zero as the projection + * + * @return select(0) + */ + public static SQLQuery selectZero() { + return select(Expressions.ZERO); + } + + /** + * Create a new detached SQLQuery instance with one as the projection + * + * @return select(1) + */ + public static SQLQuery selectOne() { + return select(Expressions.ONE); + } + + /** + * Create a new detached SQLQuery instance with the given projection + * + * @param expr query source and projection + * @param + * @return select(expr).from(expr) + */ + public static SQLQuery selectFrom(RelationalPath expr) { + return select(expr).from(expr); + } + + /** + * Create a new UNION clause + * + * @param sq subqueries + * @param + * @return union + */ + public static Union union(SubQueryExpression... sq) { + return new SQLQuery().union(sq); + } + + /** + * Create a new UNION clause + * + * @param sq subqueries + * @param + * @return union + */ + public static Union union(List> sq) { + return new SQLQuery().union(sq); + } + + /** + * Create a new UNION ALL clause + * + * @param sq subqueries + * @param + * @return union + */ + public static Union unionAll(SubQueryExpression... sq) { + return new SQLQuery().unionAll(sq); + } + + /** + * Create a new UNION ALL clause + * + * @param sq subqueries + * @param + * @return union + */ + public static Union unionAll(List> sq) { + return new SQLQuery().unionAll(sq); + } + + /** + * Get an aggregate any expression for the given boolean expression + */ + public static BooleanExpression any(BooleanExpression expr) { + return Expressions.booleanOperation(Ops.AggOps.BOOLEAN_ANY, expr); + } + + /** + * Get an aggregate all expression for the given boolean expression + */ + public static BooleanExpression all(BooleanExpression expr) { + return Expressions.booleanOperation(Ops.AggOps.BOOLEAN_ALL, expr); + } + + /** + * Create a new RelationalFunctionCall for the given function and arguments + * + * @param type type + * @param function function name + * @param args arguments + * @param + * @return relational function call + */ + public static RelationalFunctionCall relationalFunctionCall(Class type, String function, Object... args) { + return new RelationalFunctionCall(type, function, args); + } + + /** + * Create a nextval(sequence) expression + * + *

Returns the next value from the give sequence

+ * + * @param sequence sequence name + * @return nextval(sequence) + */ + public static SimpleExpression nextval(String sequence) { + return nextval(Long.class, sequence); + } + + /** + * Create a nextval(sequence) expression of the given type + * + *

Returns the next value from the given sequence

+ * + * @param type type of call + * @param sequence sequence name + * @return nextval(sequence) + */ + public static SimpleExpression nextval(Class type, String sequence) { + return Expressions.operation(type, SQLOps.NEXTVAL, ConstantImpl.create(sequence)); + } + + /** + * Convert timestamp to date + * + * @param dateTime timestamp + * @return date + */ + public static DateExpression date(DateTimeExpression dateTime) { + return Expressions.dateOperation(dateTime.getType(), Ops.DateTimeOps.DATE, dateTime); + } + + /** + * Convert timestamp to date + * + * @param type type + * @param dateTime timestamp + * @return date + */ + public static DateExpression date(Class type, DateTimeExpression dateTime) { + return Expressions.dateOperation(type, Ops.DateTimeOps.DATE, dateTime); + } + + /** + * Create a dateadd(unit, date, amount) expression + * + * @param unit date part + * @param date date + * @param amount amount + * @return converted date + */ + public static DateTimeExpression dateadd(DatePart unit, DateTimeExpression date, int amount) { + return Expressions.dateTimeOperation(date.getType(), DATE_ADD_OPS.get(unit), date, ConstantImpl.create(amount)); + } + + /** + * Create a dateadd(unit, date, amount) expression + * + * @param unit date part + * @param date date + * @param amount amount + * @return converted date + */ + public static DateExpression dateadd(DatePart unit, DateExpression date, int amount) { + return Expressions.dateOperation(date.getType(), DATE_ADD_OPS.get(unit), date, ConstantImpl.create(amount)); + } + + /** + * Get a datediff(unit, start, end) expression + * + * @param unit date part + * @param start start + * @param end end + * @return difference in units + */ + public static NumberExpression datediff(DatePart unit, + DateExpression start, DateExpression end) { + return Expressions.numberOperation(Integer.class, DATE_DIFF_OPS.get(unit), start, end); + } + + /** + * Get a datediff(unit, start, end) expression + * + * @param unit date part + * @param start start + * @param end end + * @return difference in units + */ + public static NumberExpression datediff(DatePart unit, + D start, DateExpression end) { + return Expressions.numberOperation(Integer.class, DATE_DIFF_OPS.get(unit), ConstantImpl.create(start), end); + } + + /** + * Get a datediff(unit, start, end) expression + * + * @param unit date part + * @param start start + * @param end end + * @return difference in units + */ + public static NumberExpression datediff(DatePart unit, + DateExpression start, D end) { + return Expressions.numberOperation(Integer.class, DATE_DIFF_OPS.get(unit), start, ConstantImpl.create(end)); + } + + /** + * Get a datediff(unit, start, end) expression + * + * @param unit date part + * @param start start + * @param end end + * @return difference in units + */ + public static NumberExpression datediff(DatePart unit, + DateTimeExpression start, DateTimeExpression end) { + return Expressions.numberOperation(Integer.class, DATE_DIFF_OPS.get(unit), start, end); + } + + /** + * Get a datediff(unit, start, end) expression + * + * @param unit date part + * @param start start + * @param end end + * @return difference in units + */ + public static NumberExpression datediff(DatePart unit, + D start, DateTimeExpression end) { + return Expressions.numberOperation(Integer.class, DATE_DIFF_OPS.get(unit), ConstantImpl.create(start), end); + } + + /** + * Get a datediff(unit, start, end) expression + * + * @param unit date part + * @param start start + * @param end end + * @return difference in units + */ + public static NumberExpression datediff(DatePart unit, + DateTimeExpression start, D end) { + return Expressions.numberOperation(Integer.class, DATE_DIFF_OPS.get(unit), start, ConstantImpl.create(end)); + } + + /** + * Truncate the given date expression + * + * @param unit date part to truncate to + * @param expr truncated date + */ + public static DateExpression datetrunc(DatePart unit, DateExpression expr) { + return Expressions.dateOperation(expr.getType(), DATE_TRUNC_OPS.get(unit), expr); + } + + /** + * Truncate the given datetime expression + * + * @param unit datepart to truncate to + * @param expr truncated datetime + */ + public static DateTimeExpression datetrunc(DatePart unit, DateTimeExpression expr) { + return Expressions.dateTimeOperation(expr.getType(), DATE_TRUNC_OPS.get(unit), expr); + } + + /** + * Add the given amount of years to the date + * + * @param date datetime + * @param years years to add + * @return converted datetime + */ + public static DateTimeExpression addYears(DateTimeExpression date, int years) { + return Expressions.dateTimeOperation(date.getType(), Ops.DateTimeOps.ADD_YEARS, date, ConstantImpl.create(years)); + } + + /** + * Add the given amount of months to the date + * + * @param date datetime + * @param months months to add + * @return converted datetime + */ + public static DateTimeExpression addMonths(DateTimeExpression date, int months) { + return Expressions.dateTimeOperation(date.getType(), Ops.DateTimeOps.ADD_MONTHS, date, ConstantImpl.create(months)); + } + + /** + * Add the given amount of weeks to the date + * + * @param date datetime + * @param weeks weeks to add + * @return converted date + */ + public static DateTimeExpression addWeeks(DateTimeExpression date, int weeks) { + return Expressions.dateTimeOperation(date.getType(), Ops.DateTimeOps.ADD_WEEKS, date, ConstantImpl.create(weeks)); + } + + /** + * Add the given amount of days to the date + * + * @param date datetime + * @param days days to add + * @return converted datetime + */ + public static DateTimeExpression addDays(DateTimeExpression date, int days) { + return Expressions.dateTimeOperation(date.getType(), Ops.DateTimeOps.ADD_DAYS, date, ConstantImpl.create(days)); + } + + /** + * Add the given amount of hours to the date + * + * @param date datetime + * @param hours hours to add + * @return converted datetime + */ + public static DateTimeExpression addHours(DateTimeExpression date, int hours) { + return Expressions.dateTimeOperation(date.getType(), Ops.DateTimeOps.ADD_HOURS, date, ConstantImpl.create(hours)); + } + + /** + * Add the given amount of minutes to the date + * + * @param date datetime + * @param minutes minutes to add + * @return converted datetime + */ + public static DateTimeExpression addMinutes(DateTimeExpression date, int minutes) { + return Expressions.dateTimeOperation(date.getType(), Ops.DateTimeOps.ADD_MINUTES, date, ConstantImpl.create(minutes)); + } + + /** + * Add the given amount of seconds to the date + * + * @param date datetime + * @param seconds seconds to add + * @return converted datetime + */ + public static DateTimeExpression addSeconds(DateTimeExpression date, int seconds) { + return Expressions.dateTimeOperation(date.getType(), Ops.DateTimeOps.ADD_SECONDS, date, ConstantImpl.create(seconds)); + } + + /** + * Add the given amount of years to the date + * + * @param date date + * @param years years to add + * @return converted date + */ + public static DateExpression addYears(DateExpression date, int years) { + return Expressions.dateOperation(date.getType(), Ops.DateTimeOps.ADD_YEARS, date, ConstantImpl.create(years)); + } + + /** + * Add the given amount of months to the date + * + * @param date date + * @param months months to add + * @return converted date + */ + public static DateExpression addMonths(DateExpression date, int months) { + return Expressions.dateOperation(date.getType(), Ops.DateTimeOps.ADD_MONTHS, date, ConstantImpl.create(months)); + } + + /** + * Add the given amount of weeks to the date + * + * @param date date + * @param weeks weeks to add + * @return converted date + */ + public static DateExpression addWeeks(DateExpression date, int weeks) { + return Expressions.dateOperation(date.getType(), Ops.DateTimeOps.ADD_WEEKS, date, ConstantImpl.create(weeks)); + } + + /** + * Add the given amount of days to the date + * + * @param date date + * @param days days to add + * @return converted date + */ + public static DateExpression addDays(DateExpression date, int days) { + return Expressions.dateOperation(date.getType(), Ops.DateTimeOps.ADD_DAYS, date, ConstantImpl.create(days)); + } + + /** + * Start a window function expression + * + * @param expr expression + * @return sum(expr) + */ + public static WindowOver sum(Expression expr) { + return new WindowOver(expr.getType(), Ops.AggOps.SUM_AGG, expr); + } + + /** + * Start a window function expression + * + * @return count() + */ + public static WindowOver count() { + return new WindowOver(Long.class, Ops.AggOps.COUNT_ALL_AGG); + } + + /** + * Start a window function expression + * + * @param expr expression + * @return count(expr) + */ + public static WindowOver count(Expression expr) { + return new WindowOver(Long.class, Ops.AggOps.COUNT_AGG, expr); + } + + /** + * Start a window function expression + * + * @param expr expression + * @return count(distinct expr) + */ + public static WindowOver countDistinct(Expression expr) { + return new WindowOver(Long.class, Ops.AggOps.COUNT_DISTINCT_AGG, expr); + } + + /** + * Start a window function expression + * + * @param expr expression + * @return avg(expr) + */ + public static WindowOver avg(Expression expr) { + return new WindowOver(expr.getType(), Ops.AggOps.AVG_AGG, expr); + } + + /** + * Start a window function expression + * + * @param expr expression + * @return min(expr) + */ + public static WindowOver min(Expression expr) { + return new WindowOver(expr.getType(), Ops.AggOps.MIN_AGG, expr); + } + + /** + * Start a window function expression + * + * @param expr expression + * @return max(expr) + */ + public static WindowOver max(Expression expr) { + return new WindowOver(expr.getType(), Ops.AggOps.MAX_AGG, expr); + } + + /** + * expr evaluated at the row that is one row after the current row within the partition; + * + * @param expr expression + * @return lead(expr) + */ + public static WindowOver lead(Expression expr) { + return new WindowOver(expr.getType(), SQLOps.LEAD, expr); + } + + /** + * expr evaluated at the row that is one row before the current row within the partition + * + * @param expr expression + * @return lag(expr) + */ + public static WindowOver lag(Expression expr) { + return new WindowOver(expr.getType(), SQLOps.LAG, expr); + } + + /** + * LISTAGG orders data within each group specified in the ORDER BY clause and then concatenates + * the values of the measure column. + * + * @param expr measure column + * @param delimiter delimiter + * @return listagg(expr, delimiter) + */ + public static WithinGroup listagg(Expression expr, String delimiter) { + return new WithinGroup(String.class, SQLOps.LISTAGG, expr, ConstantImpl.create(delimiter)); + } + + + /** + * NTH_VALUE returns the expr value of the nth row in the window defined by the analytic clause. + * The returned value has the data type of the expr. + * + * @param expr measure expression + * @param n one based row index + * @return nth_value(expr, n) + */ + public static WindowOver nthValue(Expression expr, Number n) { + return nthValue(expr, ConstantImpl.create(n)); + } + + /** + * NTH_VALUE returns the expr value of the nth row in the window defined by the analytic clause. + * The returned value has the data type of the expr + * + * @param expr measure expression + * @param n one based row index + * @return nth_value(expr, n) + */ + public static WindowOver nthValue(Expression expr, Expression n) { + return new WindowOver(expr.getType(), SQLOps.NTHVALUE, expr, n); + } + + /** + * divides an ordered data set into a number of buckets indicated by expr and assigns the + * appropriate bucket number to each row + * + * @param num bucket size + * @return ntile(num) + */ + @SuppressWarnings("unchecked") + public static WindowOver ntile(T num) { + return new WindowOver((Class) num.getClass(), SQLOps.NTILE, ConstantImpl.create(num)); + } + + /** + * rank of the current row with gaps; same as row_number of its first peer + * + * @return rank() + */ + public static WindowOver rank() { + return rank; + } + + /** + * As an aggregate function, RANK calculates the rank of a hypothetical row identified by the + * arguments of the function with respect to a given sort specification. The arguments of the + * function must all evaluate to constant expressions within each aggregate group, because they + * identify a single row within each group. The constant argument expressions and the expressions + * in the ORDER BY clause of the aggregate match by position. Therefore, the number of arguments + * must be the same and their types must be compatible. + * + * @param args arguments + * @return rank(args) + */ + @SuppressWarnings("unchecked") + public static WithinGroup rank(Object... args) { + return rank(convertToExpressions(args)); + } + + /** + * As an aggregate function, RANK calculates the rank of a hypothetical row identified by the + * arguments of the function with respect to a given sort specification. The arguments of the + * function must all evaluate to constant expressions within each aggregate group, because they + * identify a single row within each group. The constant argument expressions and the expressions + * in the ORDER BY clause of the aggregate match by position. Therefore, the number of arguments + * must be the same and their types must be compatible. + * + * @param args arguments + * @return rank(args) + */ + public static WithinGroup rank(Expression... args) { + return new WithinGroup(Long.class, SQLOps.RANK2, args); + } + + /** + * rank of the current row without gaps; this function counts peer groups + * + * @return dense_rank() + */ + public static WindowOver denseRank() { + return denseRank; + } + + /** + * As an aggregate function, DENSE_RANK calculates the dense rank of a hypothetical row identified + * by the arguments of the function with respect to a given sort specification. The arguments of + * the function must all evaluate to constant expressions within each aggregate group, because they + * identify a single row within each group. The constant argument expressions and the expressions + * in the order_by_clause of the aggregate match by position. Therefore, the number of arguments + * must be the same and types must be compatible. + * + * @param args arguments + * @return dense_rank(args) + */ + @SuppressWarnings("unchecked") + public static WithinGroup denseRank(Object... args) { + return denseRank(convertToExpressions(args)); + } + + /** + * As an aggregate function, DENSE_RANK calculates the dense rank of a hypothetical row identified + * by the arguments of the function with respect to a given sort specification. The arguments of + * the function must all evaluate to constant expressions within each aggregate group, because they + * identify a single row within each group. The constant argument expressions and the expressions + * in the order_by_clause of the aggregate match by position. Therefore, the number of arguments + * must be the same and types must be compatible. + * + * @param args arguments + * @return dense_rank(args) + */ + public static WithinGroup denseRank(Expression... args) { + return new WithinGroup(Long.class, SQLOps.DENSERANK2, args); + } + + /** + * As an analytic function, for a row r, PERCENT_RANK calculates the rank of r minus 1, divided by + * 1 less than the number of rows being evaluated (the entire query result set or a partition). + * + * @return percent_rank() + */ + public static WindowOver percentRank() { + return percentRank; + } + + /** + * As an aggregate function, PERCENT_RANK calculates, for a hypothetical row r identified by the + * arguments of the function and a corresponding sort specification, the rank of row r minus 1 + * divided by the number of rows in the aggregate group. This calculation is made as if the + * hypothetical row r were inserted into the group of rows over which Oracle Database is to + * aggregate. The arguments of the function identify a single hypothetical row within each aggregate + * group. Therefore, they must all evaluate to constant expressions within each aggregate group. + * The constant argument expressions and the expressions in the ORDER BY clause of the aggregate + * match by position. Therefore the number of arguments must be the same and their types must be + * compatible. + * + * @param args arguments + * @return percent_rank(args) + */ + @SuppressWarnings("unchecked") + public static WithinGroup percentRank(Object... args) { + return percentRank(convertToExpressions(args)); + } + + /** + * As an aggregate function, PERCENT_RANK calculates, for a hypothetical row r identified by the + * arguments of the function and a corresponding sort specification, the rank of row r minus 1 + * divided by the number of rows in the aggregate group. This calculation is made as if the + * hypothetical row r were inserted into the group of rows over which Oracle Database is to aggregate. + * The arguments of the function identify a single hypothetical row within each aggregate group. + * Therefore, they must all evaluate to constant expressions within each aggregate group. The + * constant argument expressions and the expressions in the ORDER BY clause of the aggregate match + * by position. Therefore the number of arguments must be the same and their types must be compatible. + * + * @param args arguments + * @return percent_rank(args) + */ + public static WithinGroup percentRank(Expression... args) { + return new WithinGroup(Double.class, SQLOps.PERCENTRANK2, args); + } + + /** + * Calculates a percentile based on a continuous distribution of the column value + * + * @param arg argument + * @return percentile_cont(arg) + */ + public static WithinGroup percentileCont(T arg) { + if (arg.doubleValue() < 0.0 || arg.doubleValue() > 1.0) { + throw new IllegalArgumentException("The percentile value should be a number between 0 and 1"); + } + return percentileCont(ConstantImpl.create(arg)); + } + + /** + * Calculates a percentile based on a continuous distribution of the column value + * + * @param arg argument + * @return percentile_cont(arg) + */ + public static WithinGroup percentileCont(Expression arg) { + return new WithinGroup(arg.getType(), SQLOps.PERCENTILECONT, arg); + } + + /** + * PERCENTILE_DISC is an inverse distribution function that assumes a discrete distribution model. + * It takes a percentile value and a sort specification and returns an element from the set. + * Nulls are ignored in the calculation. + * + *

This function takes as an argument any numeric datatype or any nonnumeric datatype that can be + * implicitly converted to a numeric datatype. The function returns the same datatype as the numeric + * datatype of the argument.

+ * + * @param arg argument + * @return percentile_disc(arg) + */ + public static WithinGroup percentileDisc(T arg) { + if (arg.doubleValue() < 0.0 || arg.doubleValue() > 1.0) { + throw new IllegalArgumentException("The percentile value should be a number between 0 and 1"); + } + return percentileDisc(ConstantImpl.create(arg)); + } + + /** + * PERCENTILE_DISC is an inverse distribution function that assumes a discrete distribution model. + * It takes a percentile value and a sort specification and returns an element from the set. + * Nulls are ignored in the calculation. + * + *

This function takes as an argument any numeric datatype or any nonnumeric datatype that can be + * implicitly converted to a numeric datatype. The function returns the same datatype as the numeric + * datatype of the argument.

+ * + * @param arg argument + * @return percentile_disc(arg) + */ + public static WithinGroup percentileDisc(Expression arg) { + return new WithinGroup(arg.getType(), SQLOps.PERCENTILEDISC, arg); + } + + /** + * REGR_SLOPE returns the slope of the line + * + * @param arg1 first arg + * @param arg2 second arg + * @return regr_slope(arg1, arg2) + */ + public static WindowOver regrSlope(Expression arg1, Expression arg2) { + return new WindowOver(Double.class, SQLOps.REGR_SLOPE, arg1, arg2); + } + + /** + * REGR_INTERCEPT returns the y-intercept of the regression line. + * + * @param arg1 first arg + * @param arg2 second arg + * @return regr_intercept(arg1, arg2) + */ + public static WindowOver regrIntercept(Expression arg1, Expression arg2) { + return new WindowOver(Double.class, SQLOps.REGR_INTERCEPT, arg1, arg2); + } + + /** + * REGR_COUNT returns an integer that is the number of non-null number pairs used to fit the regression line. + * + * @param arg1 first arg + * @param arg2 second arg + * @return regr_count(arg1, arg2) + */ + public static WindowOver regrCount(Expression arg1, Expression arg2) { + return new WindowOver(Double.class, SQLOps.REGR_COUNT, arg1, arg2); + } + + /** + * REGR_R2 returns the coefficient of determination (also called R-squared or goodness of fit) for the regression. + * + * @param arg1 first arg + * @param arg2 second arg + * @return regr_r2(arg1, arg2) + */ + public static WindowOver regrR2(Expression arg1, Expression arg2) { + return new WindowOver(Double.class, SQLOps.REGR_R2, arg1, arg2); + } + + /** + * REGR_AVGX evaluates the average of the independent variable (arg2) of the regression line. + * + * @param arg1 first arg + * @param arg2 second arg + * @return regr_avgx(arg1, arg2) + */ + public static WindowOver regrAvgx(Expression arg1, Expression arg2) { + return new WindowOver(Double.class, SQLOps.REGR_AVGX, arg1, arg2); + } + + /** + * REGR_AVGY evaluates the average of the dependent variable (arg1) of the regression line. + * + * @param arg1 first arg + * @param arg2 second arg + * @return regr_avgy(arg1, arg2) + */ + public static WindowOver regrAvgy(Expression arg1, Expression arg2) { + return new WindowOver(Double.class, SQLOps.REGR_AVGY, arg1, arg2); + } + + /** + * REGR_SXX makes the following computation after the elimination of null (arg1, arg2) pairs: + * + *

{@code REGR_COUNT(arg1, arg2) * VAR_POP(arg2)}

+ * + * @param arg1 first arg + * @param arg2 second arg + * @return regr_sxx(arg1, arg2) + */ + public static WindowOver regrSxx(Expression arg1, Expression arg2) { + return new WindowOver(Double.class, SQLOps.REGR_SXX, arg1, arg2); + } + + /** + * REGR_SYY makes the following computation after the elimination of null (arg1, arg2) pairs: + * + *

{@code REGR_COUNT(arg1, arg2) * VAR_POP(arg1)}

+ * + * @param arg1 first arg + * @param arg2 second arg + * @return regr_syy(arg1, arg2) + */ + public static WindowOver regrSyy(Expression arg1, Expression arg2) { + return new WindowOver(Double.class, SQLOps.REGR_SYY, arg1, arg2); + } + + /** + * REGR_SXY makes the following computation after the elimination of null (arg1, arg2) pairs: + * + *

REGR_COUNT(arg1, arg2) * COVAR_POP(arg1, arg2)

+ * + * @param arg1 first arg + * @param arg2 second arg + * @return regr_sxy(arg1, arg2) + */ + public static WindowOver regrSxy(Expression arg1, Expression arg2) { + return new WindowOver(Double.class, SQLOps.REGR_SXY, arg1, arg2); + } + + /** + * CUME_DIST calculates the cumulative distribution of a value in a group of values. + * + * @return cume_dist() + */ + public static WindowOver cumeDist() { + return cumeDist; + } + + /** + * As an aggregate function, CUME_DIST calculates, for a hypothetical row r identified by the + * arguments of the function and a corresponding sort specification, the relative position of row + * r among the rows in the aggregation group. Oracle makes this calculation as if the hypothetical + * row r were inserted into the group of rows to be aggregated over. The arguments of the function + * identify a single hypothetical row within each aggregate group. Therefore, they must all + * evaluate to constant expressions within each aggregate group. The constant argument expressions + * and the expressions in the ORDER BY clause of the aggregate match by position. Therefore, + * the number of arguments must be the same and their types must be compatible. + * + * @param args arguments + * @return cume_dist(args) + */ + @SuppressWarnings("unchecked") + public static WithinGroup cumeDist(Object... args) { + return cumeDist(convertToExpressions(args)); + } + + /** + * As an aggregate function, CUME_DIST calculates, for a hypothetical row r identified by the + * arguments of the function and a corresponding sort specification, the relative position of row + * r among the rows in the aggregation group. Oracle makes this calculation as if the hypothetical + * row r were inserted into the group of rows to be aggregated over. The arguments of the function + * identify a single hypothetical row within each aggregate group. Therefore, they must all + * evaluate to constant expressions within each aggregate group. The constant argument expressions + * and the expressions in the ORDER BY clause of the aggregate match by position. Therefore, + * the number of arguments must be the same and their types must be compatible. + * + * @param args arguments + * @return cume_dist(args) + */ + public static WithinGroup cumeDist(Expression... args) { + return new WithinGroup(Double.class, SQLOps.CUMEDIST2, args); + } + + /** + * CORR returns the coefficient of correlation of a set of number pairs. + * + * @param expr1 first arg + * @param expr2 second arg + * @return corr(expr1, expr2) + */ + public static WindowOver corr(Expression expr1, Expression expr2) { + return new WindowOver(Double.class, SQLOps.CORR, expr1, expr2); + } + + /** + * CORR returns the coefficient of correlation of a set of number pairs. + * + * @param expr1 first arg + * @param expr2 second arg + * @return corr(expr1, expr2) + */ + public static WindowOver covarPop(Expression expr1, Expression expr2) { + return new WindowOver(Double.class, SQLOps.COVARPOP, expr1, expr2); + } + + /** + * CORR returns the coefficient of correlation of a set of number pairs. + * + * @param expr1 first arg + * @param expr2 second arg + * @return corr(expr1, expr2) + */ + public static WindowOver covarSamp(Expression expr1, Expression expr2) { + return new WindowOver(Double.class, SQLOps.COVARSAMP, expr1, expr2); + } + + /** + * computes the ratio of a value to the sum of a set of values. If expr evaluates to null, + * then the ratio-to-report value also evaluates to null. + * + * @return ratio_to_report(expr) + */ + public static WindowOver ratioToReport(Expression expr) { + return new WindowOver(expr.getType(), SQLOps.RATIOTOREPORT, expr); + } + + /** + * number of the current row within its partition, counting from 1 + * + * @return row_number() + */ + public static WindowOver rowNumber() { + return rowNumber; + } + + /** + * returns the sample standard deviation of expr, a set of numbers. + * + * @param expr argument + * @return stddev(expr) + */ + public static WindowOver stddev(Expression expr) { + return new WindowOver(expr.getType(), SQLOps.STDDEV, expr); + } + + /** + * returns the sample standard deviation of expr, a set of numbers. + * + * @param expr argument + * @return stddev(distinct expr) + */ + public static WindowOver stddevDistinct(Expression expr) { + return new WindowOver(expr.getType(), SQLOps.STDDEV_DISTINCT, expr); + } + + /** + * returns the population standard deviation and returns the square root of the population variance. + * + * @param expr argument + * @return stddev_pop(expr) + */ + public static WindowOver stddevPop(Expression expr) { + return new WindowOver(expr.getType(), SQLOps.STDDEVPOP, expr); + } + + /** + * returns the cumulative sample standard deviation and returns the square root of the sample variance. + * + * @param expr argument + * @return stddev_samp(expr) + */ + public static WindowOver stddevSamp(Expression expr) { + return new WindowOver(expr.getType(), SQLOps.STDDEVSAMP, expr); + } + + /** + * returns the variance of expr + * + * @param expr argument + * @return variance(expr) + */ + public static WindowOver variance(Expression expr) { + return new WindowOver(expr.getType(), SQLOps.VARIANCE, expr); + } + + /** + * returns the population variance of a set of numbers after discarding the nulls in this set. + * + * @param expr argument + * @return var_pop(expr) + */ + public static WindowOver varPop(Expression expr) { + return new WindowOver(expr.getType(), SQLOps.VARPOP, expr); + } + + /** + * returns the sample variance of a set of numbers after discarding the nulls in this set. + * + * @param expr argument + * @return var_samp(expr) + */ + public static WindowOver varSamp(Expression expr) { + return new WindowOver(expr.getType(), SQLOps.VARSAMP, expr); + } + + /** + * returns value evaluated at the row that is the first row of the window frame + * + * @param expr argument + * @return first_value(expr) + */ + public static WindowOver firstValue(Expression expr) { + return new WindowOver(expr.getType(), SQLOps.FIRSTVALUE, expr); + } + + /** + * returns value evaluated at the row that is the last row of the window frame + * + * @param expr argument + * @return last_value(expr) + */ + public static WindowOver lastValue(Expression expr) { + return new WindowOver(expr.getType(), SQLOps.LASTVALUE, expr); + } + + /** + * Get the rhs leftmost characters of lhs + * + * @param lhs string + * @param rhs character amount + * @return rhs leftmost characters + */ + public static StringExpression left(Expression lhs, int rhs) { + return left(lhs, ConstantImpl.create(rhs)); + } + + /** + * Get the rhs rightmost characters of lhs + * + * @param lhs string + * @param rhs character amount + * @return rhs rightmost characters + */ + public static StringExpression right(Expression lhs, int rhs) { + return right(lhs, ConstantImpl.create(rhs)); + } + + /** + * Get the rhs leftmost characters of lhs + * + * @param lhs string + * @param rhs character amount + * @return rhs leftmost characters + */ + public static StringExpression left(Expression lhs, Expression rhs) { + return Expressions.stringOperation(Ops.StringOps.LEFT, lhs, rhs); + } + + /** + * Get the rhs leftmost characters of lhs + * + * @param lhs string + * @param rhs character amount + * @return rhs rightmost characters + */ + public static StringExpression right(Expression lhs, Expression rhs) { + return Expressions.stringOperation(Ops.StringOps.RIGHT, lhs, rhs); + } + + /** + * Get a group_concat(expr) expression + * + * @param expr expression to be aggregated + * @return group_concat(expr) + */ + public static StringExpression groupConcat(Expression expr) { + return Expressions.stringOperation(SQLOps.GROUP_CONCAT, expr); + } + + /** + * Get a group_concat(expr, separator) expression + * + * @param expr expression to be aggregated + * @param separator separator string + * @return group_concat(expr, separator) + */ + public static StringExpression groupConcat(Expression expr, String separator) { + return Expressions.stringOperation(SQLOps.GROUP_CONCAT2, expr, Expressions.constant(separator)); + } + + private SQLExpressions() { } + +} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/SQLListener.java b/querydsl-sql/src/main/java/com/querydsl/sql/SQLListener.java similarity index 87% rename from querydsl-sql/src/main/java/com/mysema/query/sql/SQLListener.java rename to querydsl-sql/src/main/java/com/querydsl/sql/SQLListener.java index c0d689075d..5de4b0d6a4 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/SQLListener.java +++ b/querydsl-sql/src/main/java/com/querydsl/sql/SQLListener.java @@ -1,5 +1,5 @@ /* - * Copyright 2013, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,18 +11,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql; +package com.querydsl.sql; import java.util.List; +import java.util.Map; -import com.mysema.commons.lang.Pair; -import com.mysema.query.QueryMetadata; -import com.mysema.query.sql.dml.SQLInsertBatch; -import com.mysema.query.sql.dml.SQLMergeBatch; -import com.mysema.query.sql.dml.SQLUpdateBatch; -import com.mysema.query.types.Expression; -import com.mysema.query.types.Path; -import com.mysema.query.types.SubQueryExpression; +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.SubQueryExpression; +import com.querydsl.sql.dml.SQLInsertBatch; +import com.querydsl.sql.dml.SQLMergeBatch; +import com.querydsl.sql.dml.SQLUpdateBatch; /** * Listener interface for SQL queries and clauses @@ -106,7 +106,7 @@ void notifyInsert(RelationalPath entity, QueryMetadata md, List> colu * @param updates metadata of batches */ void notifyUpdate(RelationalPath entity, QueryMetadata md, - List, Expression>> updates); + Map, Expression> updates); /** * Notify about a batch update diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/SQLListenerAdapter.java b/querydsl-sql/src/main/java/com/querydsl/sql/SQLListenerAdapter.java new file mode 100644 index 0000000000..eae99368f5 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/SQLListenerAdapter.java @@ -0,0 +1,151 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import java.util.List; +import java.util.Map; + +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.SubQueryExpression; +import com.querydsl.sql.dml.SQLInsertBatch; +import com.querydsl.sql.dml.SQLMergeBatch; +import com.querydsl.sql.dml.SQLUpdateBatch; + +/** + * A simple adapter class that knows if the underlying listener is a simple or detailed SQL listener + */ +class SQLListenerAdapter implements SQLDetailedListener { + + private final SQLListener sqlListener; + private final SQLDetailedListener detailedListener; + + SQLListenerAdapter(final SQLListener sqlListener) { + this.detailedListener = sqlListener instanceof SQLDetailedListener ? (SQLDetailedListener) sqlListener : null; + this.sqlListener = sqlListener; + } + + public SQLListener getSqlListener() { + return sqlListener; + } + + @Override + public void start(final SQLListenerContext context) { + if (detailedListener != null) { + detailedListener.start(context); + } + } + + @Override + public void preRender(final SQLListenerContext context) { + if (detailedListener != null) { + detailedListener.preRender(context); + } + } + + @Override + public void rendered(final SQLListenerContext context) { + if (detailedListener != null) { + detailedListener.rendered(context); + } + } + + @Override + public void prePrepare(final SQLListenerContext context) { + if (detailedListener != null) { + detailedListener.prePrepare(context); + } + } + + @Override + public void prepared(final SQLListenerContext context) { + if (detailedListener != null) { + detailedListener.prepared(context); + } + } + + @Override + public void preExecute(final SQLListenerContext context) { + if (detailedListener != null) { + detailedListener.preExecute(context); + } + } + + @Override + public void executed(final SQLListenerContext context) { + if (detailedListener != null) { + detailedListener.executed(context); + } + } + + @Override + public void end(final SQLListenerContext context) { + if (detailedListener != null) { + detailedListener.end(context); + } + } + + @Override + public void exception(final SQLListenerContext context) { + if (detailedListener != null) { + detailedListener.exception(context); + } + } + + @Override + public void notifyQuery(final QueryMetadata md) { + sqlListener.notifyQuery(md); + } + + @Override + public void notifyDelete(final RelationalPath entity, final QueryMetadata md) { + sqlListener.notifyDelete(entity, md); + } + + @Override + public void notifyDeletes(final RelationalPath entity, final List batches) { + sqlListener.notifyDeletes(entity, batches); + } + + @Override + public void notifyMerge(final RelationalPath entity, final QueryMetadata md, final List> keys, final List> columns, final List> values, final SubQueryExpression subQuery) { + sqlListener.notifyMerge(entity, md, keys, columns, values, subQuery); + } + + @Override + public void notifyMerges(final RelationalPath entity, final QueryMetadata md, final List batches) { + sqlListener.notifyMerges(entity, md, batches); + } + + @Override + public void notifyInsert(final RelationalPath entity, final QueryMetadata md, final List> columns, final List> values, final SubQueryExpression subQuery) { + sqlListener.notifyInsert(entity, md, columns, values, subQuery); + } + + @Override + public void notifyInserts(final RelationalPath entity, final QueryMetadata md, final List batches) { + sqlListener.notifyInserts(entity, md, batches); + } + + @Override + public void notifyUpdate(final RelationalPath entity, final QueryMetadata md, final Map, Expression> updates) { + sqlListener.notifyUpdate(entity, md, updates); + } + + @Override + public void notifyUpdates(final RelationalPath entity, final List batches) { + sqlListener.notifyUpdates(entity, batches); + } +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/SQLListenerContext.java b/querydsl-sql/src/main/java/com/querydsl/sql/SQLListenerContext.java new file mode 100644 index 0000000000..02c4bb8cc3 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/SQLListenerContext.java @@ -0,0 +1,137 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.util.Collection; + +import com.querydsl.core.QueryMetadata; + +/** + * A context object that is progressively filled out during query execution and is passed to each {@link + * SQLDetailedListener} callback method + */ +public interface SQLListenerContext { + /** + * The context getData is a general purpose place that listeners can place objects. It allows listeners to pass + * context between themselves during callbacks. + *

+ * + * @param dataKey the key to look up + * @return the context object under that key + */ + Object getData(String dataKey); + + /** + * The context setData is a general purpose place that listeners can place objects. It allows listeners to pass + * context between themselves during callbacks. + *

+ * A good time to place objects into the context is during {@link com.querydsl.sql.SQLDetailedListener#start(SQLListenerContext)} + * and then access if after that. + * + * @param dataKey the key to use + * @param value the value to place under that key + */ + void setData(String dataKey, Object value); + + /** + * Return the underlying query metadata + * + * @return the underlying query metadata + */ + QueryMetadata getMetadata(); + + /** + * Return the underlying sql or first in a batch query + * + *

NOTE : This can be null depending on the stage of the query execution

+ * + * @return the underlying sql or first in a batch query + */ + String getSQL(); + + /** + * Return the underlying sql including bindings or first in a batch query + * + *

NOTE : This can be null depending on the stage of the query execution

+ * + * @return the underlying sql including bindings or first in a batch query + */ + SQLBindings getSQLBindings(); + + /** + * Return the underlying sql collection if the query is a batch query + * + *

NOTE : This can be empty depending on the stage of the query execution

+ * + * @return the underlying sql collection if the query is a batch query + */ + Collection getSQLStatements(); + + /** + * Return the underlying sql collection including bindings if the query is a batch query + * + *

NOTE : This can be empty depending on the stage of the query execution

+ * + * @return the underlying sql collection including bindings if the query is a batch query + */ + Collection getAllSQLBindings(); + + /** + * Return the underlying entity affected + * + *

NOTE : This can be null depending on the stage of the query execution

+ * + * @return the underlying entity affected + */ + RelationalPath getEntity(); + + /** + * Return the underlying connection if there is one + * + *

NOTE : This can be null depending on the stage of the query execution

+ * + * @return the underlying connection if there is one + */ + Connection getConnection(); + + /** + * Return the underlying exception that has happened during query execution + * + *

NOTE : This can be null depending on whether an exception occurred

+ * + * @return the underlying exception that has happened during query execution + */ + Exception getException(); + + /** + * Return the underlying prepared statement or the first if its batch query + * + *

NOTE : This can be null depending on the stage of the query execution

+ * + * @return the underlying prepared statement or the first if its batch query + */ + PreparedStatement getPreparedStatement(); + + /** + * Return the underlying set of prepared statements + * + *

NOTE : This can be empty depending on the stage of the query execution

+ * + * @return the underlying set of prepared statements + */ + Collection getPreparedStatements(); + +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/SQLListenerContextImpl.java b/querydsl-sql/src/main/java/com/querydsl/sql/SQLListenerContextImpl.java new file mode 100644 index 0000000000..56ae801558 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/SQLListenerContextImpl.java @@ -0,0 +1,163 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import com.querydsl.core.QueryMetadata; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * A mutable implementation of SQL listener context. + *

+ * INTERNAL USE ONLY - {@link com.querydsl.sql.SQLDetailedListener} implementations are not expected to use this + * class directly + */ +public class SQLListenerContextImpl implements SQLListenerContext { + private final Map contextMap; + + private final QueryMetadata md; + + private final List sqlStatements; + + private final List preparedStatements; + + private RelationalPath entity; + + private Connection connection; + + private Exception exception; + + public SQLListenerContextImpl(final QueryMetadata metadata, final Connection connection, final RelationalPath entity) { + this.contextMap = new HashMap<>(); + this.preparedStatements = new ArrayList<>(); + this.sqlStatements = new ArrayList<>(); + this.md = metadata; + this.connection = connection; + this.entity = entity; + } + + public SQLListenerContextImpl(final QueryMetadata metadata, final Connection connection) { + this(metadata, connection, null); + } + + public SQLListenerContextImpl(final QueryMetadata metadata) { + this(metadata, null, null); + } + + public void addSQL(final SQLBindings sql) { + this.sqlStatements.add(sql); + } + + public void setEntity(final RelationalPath entity) { + this.entity = entity; + } + + public void setConnection(final Connection connection) { + this.connection = connection; + } + + public void setException(final Exception exception) { + this.exception = exception; + } + + public void addPreparedStatement(final PreparedStatement preparedStatement) { + this.preparedStatements.add(preparedStatement); + } + + @Override + public QueryMetadata getMetadata() { + return md; + } + + @Override + public RelationalPath getEntity() { + return entity; + } + + @Override + public String getSQL() { + return sqlStatements.isEmpty() ? null : sqlStatements.get(0).getSQL(); + } + + @Override + public SQLBindings getSQLBindings() { + return sqlStatements.isEmpty() ? null : sqlStatements.get(0); + } + + @Override + public Collection getSQLStatements() { + return sqlStatements.stream().map(SQLBindings::getSQL).collect(Collectors.toList()); + } + + @Override + public Collection getAllSQLBindings() { + return sqlStatements; + } + + @Override + public Exception getException() { + return exception; + } + + @Override + public Connection getConnection() { + return connection; + } + + @Override + public Collection getPreparedStatements() { + return preparedStatements; + } + + @Override + public PreparedStatement getPreparedStatement() { + return preparedStatements.isEmpty() ? null : preparedStatements.get(0); + } + + @Override + public Object getData(final String dataKey) { + return contextMap.get(dataKey); + } + + @Override + public void setData(final String dataKey, final Object value) { + contextMap.put(dataKey, value); + } + + + @Override + public String toString() { + StringBuilder sb = new StringBuilder() + .append(" sql:").append(nicerSql(getSQL())) + .append(" connection:").append(connection == null ? "not connected" : "connected") + .append(" entity:").append(entity) + .append(" exception:").append(exception); + + for (Map.Entry entry : contextMap.entrySet()) { + sb.append(" [").append(entry.getKey()).append(":").append(entry.getValue()).append("]"); + } + return sb.toString(); + } + + private String nicerSql(final String sql) { + return "'" + (sql == null ? null : sql.replace('\n', ' ')) + "'"; + } +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/SQLListeners.java b/querydsl-sql/src/main/java/com/querydsl/sql/SQLListeners.java new file mode 100644 index 0000000000..ed03f0776a --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/SQLListeners.java @@ -0,0 +1,253 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.jetbrains.annotations.Nullable; + +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.SubQueryExpression; +import com.querydsl.sql.dml.SQLInsertBatch; +import com.querydsl.sql.dml.SQLMergeBatch; +import com.querydsl.sql.dml.SQLUpdateBatch; + +/** + * {@code SQLListeners} is a {@link SQLListener} implementation which dispatches the + * notifications to a list of SQLListener instances + * + * @author tiwe + */ +public class SQLListeners implements SQLDetailedListener { + + @Nullable + private final SQLDetailedListener parent; + + private final Set listeners = new LinkedHashSet<>(); + + public SQLListeners(SQLListener parent) { + this.parent = new SQLListenerAdapter(parent); + } + + public SQLListeners() { + this.parent = null; + } + + public void add(SQLListener listener) { + if (listener instanceof SQLListeners) { + for (SQLListener l : ((SQLListeners) listener).listeners) { + add(l); + } + } else if (listener instanceof SQLDetailedListener) { + listeners.add((SQLDetailedListener) listener); + } else { + listeners.add(new SQLListenerAdapter(listener)); + } + } + + @Override + public void notifyQuery(QueryMetadata md) { + if (parent != null) { + parent.notifyQuery(md); + } + for (SQLListener listener : listeners) { + listener.notifyQuery(md); + } + } + + @Override + public void notifyDelete(RelationalPath entity, QueryMetadata md) { + if (parent != null) { + parent.notifyDelete(entity, md); + } + for (SQLListener listener : listeners) { + listener.notifyDelete(entity, md); + } + } + + @Override + public void notifyDeletes(RelationalPath entity, List batches) { + if (parent != null) { + parent.notifyDeletes(entity, batches); + } + for (SQLListener listener : listeners) { + listener.notifyDeletes(entity, batches); + } + } + + @Override + public void notifyMerge(RelationalPath entity, QueryMetadata md, List> keys, + List> columns, List> values, SubQueryExpression subQuery) { + if (parent != null) { + parent.notifyMerge(entity, md, keys, columns, values, subQuery); + } + for (SQLListener listener : listeners) { + listener.notifyMerge(entity, md, keys, columns, values, subQuery); + } + } + + @Override + public void notifyMerges(RelationalPath entity, QueryMetadata md, List batches) { + if (parent != null) { + parent.notifyMerges(entity, md, batches); + } + for (SQLListener listener : listeners) { + listener.notifyMerges(entity, md, batches); + } + } + + @Override + public void notifyInsert(RelationalPath entity, QueryMetadata md, List> columns, + List> values, SubQueryExpression subQuery) { + if (parent != null) { + parent.notifyInsert(entity, md, columns, values, subQuery); + } + for (SQLListener listener : listeners) { + listener.notifyInsert(entity, md, columns, values, subQuery); + } + } + + @Override + public void notifyInserts(RelationalPath entity, QueryMetadata md, + List batches) { + if (parent != null) { + parent.notifyInserts(entity, md, batches); + } + for (SQLListener listener : listeners) { + listener.notifyInserts(entity, md, batches); + } + } + + @Override + public void notifyUpdate(RelationalPath entity, QueryMetadata md, + Map, Expression> updates) { + if (parent != null) { + parent.notifyUpdate(entity, md, updates); + } + for (SQLListener listener : listeners) { + listener.notifyUpdate(entity, md, updates); + } + } + + @Override + public void notifyUpdates(RelationalPath entity, List batches) { + if (parent != null) { + parent.notifyUpdates(entity, batches); + } + for (SQLListener listener : listeners) { + listener.notifyUpdates(entity, batches); + } + } + + + @Override + public void start(final SQLListenerContext context) { + if (parent != null) { + parent.start(context); + } + for (SQLDetailedListener listener : listeners) { + listener.start(context); + } + } + + @Override + public void preRender(final SQLListenerContext context) { + if (parent != null) { + parent.preRender(context); + } + for (SQLDetailedListener listener : listeners) { + listener.preRender(context); + } + } + + @Override + public void rendered(final SQLListenerContext context) { + if (parent != null) { + parent.rendered(context); + } + for (SQLDetailedListener listener : listeners) { + listener.rendered(context); + } + } + + @Override + public void prePrepare(final SQLListenerContext context) { + if (parent != null) { + parent.prePrepare(context); + } + for (SQLDetailedListener listener : listeners) { + listener.prePrepare(context); + } + } + + @Override + public void prepared(final SQLListenerContext context) { + if (parent != null) { + parent.prepared(context); + } + for (SQLDetailedListener listener : listeners) { + listener.prepared(context); + } + } + + @Override + public void preExecute(final SQLListenerContext context) { + if (parent != null) { + parent.preExecute(context); + } + for (SQLDetailedListener listener : listeners) { + listener.preExecute(context); + } + } + + @Override + public void executed(final SQLListenerContext context) { + if (parent != null) { + parent.executed(context); + } + for (SQLDetailedListener listener : listeners) { + listener.executed(context); + } + } + + @Override + public void end(final SQLListenerContext context) { + if (parent != null) { + parent.end(context); + } + for (SQLDetailedListener listener : listeners) { + listener.end(context); + } + } + + @Override + public void exception(final SQLListenerContext context) { + if (parent != null) { + parent.exception(context); + } + for (SQLDetailedListener listener : listeners) { + listener.exception(context); + } + } + + public Set getListeners() { + return listeners; + } + +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/SQLNoCloseListener.java b/querydsl-sql/src/main/java/com/querydsl/sql/SQLNoCloseListener.java new file mode 100644 index 0000000000..6e989155a0 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/SQLNoCloseListener.java @@ -0,0 +1,36 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +/** + * SQLNoCloseListener can be used to block {@link SQLCloseListener} from closing the connection, useful for + * helper query executions + */ +public final class SQLNoCloseListener extends SQLBaseListener { + + public static final SQLNoCloseListener DEFAULT = new SQLNoCloseListener(); + + private SQLNoCloseListener() { } + + @Override + public void start(SQLListenerContext context) { + context.setData(AbstractSQLQuery.PARENT_CONTEXT, context); + } + + @Override + public void end(SQLListenerContext context) { + context.setData(AbstractSQLQuery.PARENT_CONTEXT, null); + } + +} \ No newline at end of file diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/SQLOps.java b/querydsl-sql/src/main/java/com/querydsl/sql/SQLOps.java new file mode 100644 index 0000000000..6106ef23f4 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/SQLOps.java @@ -0,0 +1,107 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import com.querydsl.core.QueryFlag; +import com.querydsl.core.QueryFlag.Position; +import com.querydsl.core.types.ExpressionUtils; +import com.querydsl.core.types.Operator; + +import java.util.Collections; + +/** + * {@code SQLOps} provides SQL specific operators + * + * @author tiwe + * + */ +public enum SQLOps implements Operator { + ALL(Object.class), + CAST(Object.class), + CORR(Double.class), + COVARPOP(Double.class), + COVARSAMP(Double.class), + CUMEDIST(Double.class), + CUMEDIST2(Double.class), + DENSERANK(Long.class), + DENSERANK2(Long.class), + FIRSTVALUE(Object.class), + FOR_SHARE(Object.class), + FOR_UPDATE(Object.class), + LAG(Object.class), + LASTVALUE(Object.class), + LEAD(Object.class), + LISTAGG(Object.class), + NEXTVAL(Object.class), + NO_WAIT(Object.class), + NTHVALUE(Object.class), + NTILE(Object.class), + PERCENTRANK(Double.class), + PERCENTRANK2(Double.class), + PERCENTILECONT(Object.class), + PERCENTILEDISC(Object.class), + QUALIFY(Boolean.class), + RANK(Long.class), + RANK2(Long.class), + REGR_SLOPE(Object.class), + REGR_INTERCEPT(Object.class), + REGR_COUNT(Object.class), + REGR_R2(Object.class), + REGR_AVGX(Object.class), + REGR_AVGY(Object.class), + REGR_SXX(Object.class), + REGR_SYY(Object.class), + REGR_SXY(Object.class), + RATIOTOREPORT(Object.class), + ROWNUMBER(Long.class), + STDDEV(Object.class), + STDDEVPOP(Object.class), + STDDEVSAMP(Object.class), + STDDEV_DISTINCT(Object.class), + UNION(Object.class), + UNION_ALL(Object.class), + VARIANCE(Object.class), + VARPOP(Object.class), + VARSAMP(Object.class), + WITH_ALIAS(Object.class), + WITH_COLUMNS(Object.class), + LOCK_IN_SHARE_MODE(Object.class), + WITH_REPEATABLE_READ(Object.class), + GROUP_CONCAT(String.class), + GROUP_CONCAT2(String.class), + SET_PATH(Object.class), + SET_LITERAL(Object.class); + + private final Class type; + + SQLOps(Class type) { + this.type = type; + } + + @Override + public Class getType() { + return type; + } + + @Deprecated + public static final QueryFlag FOR_SHARE_FLAG = new QueryFlag(Position.END, ExpressionUtils.operation( + Object.class, FOR_SHARE, Collections.emptyList())); + @Deprecated + public static final QueryFlag FOR_UPDATE_FLAG = new QueryFlag(Position.END, ExpressionUtils.operation( + Object.class, FOR_UPDATE, Collections.emptyList())); + @Deprecated + public static final QueryFlag NO_WAIT_FLAG = new QueryFlag(Position.END, ExpressionUtils.operation( + Object.class, NO_WAIT, Collections.emptyList())); + +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/SQLQuery.java b/querydsl-sql/src/main/java/com/querydsl/sql/SQLQuery.java new file mode 100644 index 0000000000..bb09a3b464 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/SQLQuery.java @@ -0,0 +1,146 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import java.sql.Connection; +import java.util.function.Supplier; + +import com.querydsl.core.DefaultQueryMetadata; +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.Tuple; +import com.querydsl.core.types.Expression; + +/** + * {@code SQLQuery} is a JDBC based implementation of the {@link SQLCommonQuery} + * interface + * + * @param + * @author tiwe + */ +public class SQLQuery extends AbstractSQLQuery> { + + /** + * Create a detached SQLQuery instance The query can be attached via the + * clone method + */ + public SQLQuery() { + super((Connection) null, Configuration.DEFAULT, new DefaultQueryMetadata()); + } + + /** + * Create a detached SQLQuery instance The query can be attached via the + * clone method + * + * @param templates SQLTemplates to use + */ + public SQLQuery(SQLTemplates templates) { + super((Connection) null, new Configuration(templates), new DefaultQueryMetadata()); + } + + /** + * Create a new SQLQuery instance + * + * @param conn Connection to use + * @param templates SQLTemplates to use + */ + public SQLQuery(Connection conn, SQLTemplates templates) { + super(conn, new Configuration(templates), new DefaultQueryMetadata()); + } + + /** + * Create a new SQLQuery instance + * + * @param conn Connection to use + * @param templates SQLTemplates to use + * @param metadata metadata + */ + public SQLQuery(Connection conn, SQLTemplates templates, QueryMetadata metadata) { + super(conn, new Configuration(templates), metadata); + } + + /** + * Create a new SQLQuery instance + * + * @param configuration configuration + */ + public SQLQuery(Configuration configuration) { + this((Connection) null, configuration); + } + + /** + * Create a new SQLQuery instance + * + * @param conn Connection to use + * @param configuration configuration + */ + public SQLQuery(Connection conn, Configuration configuration) { + super(conn, configuration, new DefaultQueryMetadata()); + } + + /** + * Create a new SQLQuery instance + * + * @param conn Connection to use + * @param configuration configuration + * @param metadata metadata + */ + public SQLQuery(Connection conn, Configuration configuration, QueryMetadata metadata) { + super(conn, configuration, metadata); + } + + /** + * Create a new SQLQuery instance + * + * @param connProvider Connection to use + * @param configuration configuration + */ + public SQLQuery(Supplier connProvider, Configuration configuration) { + super(connProvider, configuration, new DefaultQueryMetadata()); + } + + /** + * Create a new SQLQuery instance + * + * @param connProvider Connection to use + * @param configuration configuration + * @param metadata metadata + */ + public SQLQuery(Supplier connProvider, Configuration configuration, QueryMetadata metadata) { + super(connProvider, configuration, metadata); + } + + + @Override + public SQLQuery clone(Connection conn) { + SQLQuery q = new SQLQuery(conn, getConfiguration(), getMetadata().clone()); + q.clone(this); + return q; + } + + @Override + public SQLQuery select(Expression expr) { + queryMixin.setProjection(expr); + @SuppressWarnings("unchecked") // This is the new type + SQLQuery newType = (SQLQuery) this; + return newType; + } + + @Override + public SQLQuery select(Expression... exprs) { + queryMixin.setProjection(exprs); + @SuppressWarnings("unchecked") // This is the new type + SQLQuery newType = (SQLQuery) this; + return newType; + } +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/SQLQueryFactory.java b/querydsl-sql/src/main/java/com/querydsl/sql/SQLQueryFactory.java new file mode 100644 index 0000000000..ddecc06bf1 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/SQLQueryFactory.java @@ -0,0 +1,112 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import java.sql.Connection; +import java.sql.SQLException; +import java.util.function.Supplier; + +import javax.sql.DataSource; + +import com.querydsl.core.Tuple; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.dsl.Expressions; + +/** + * Factory class for query and DML clause creation + * + * @author tiwe + * + */ +public class SQLQueryFactory extends AbstractSQLQueryFactory> { + + static class DataSourceProvider implements Supplier { + + private final DataSource ds; + + DataSourceProvider(DataSource ds) { + this.ds = ds; + } + + @Override + public Connection get() { + try { + return ds.getConnection(); + } catch (SQLException e) { + throw new RuntimeException(e.getMessage(), e); + } + } + + } + + public SQLQueryFactory(SQLTemplates templates, Supplier connection) { + this(new Configuration(templates), connection); + } + + public SQLQueryFactory(Configuration configuration, Supplier connProvider) { + super(configuration, connProvider); + } + + public SQLQueryFactory(Configuration configuration, DataSource dataSource) { + this(configuration, dataSource, true); + } + + public SQLQueryFactory(Configuration configuration, DataSource dataSource, boolean release) { + super(configuration, new DataSourceProvider(dataSource)); + if (release) { + configuration.addListener(SQLCloseListener.DEFAULT); + } + } + + @Override + public SQLQuery query() { + return new SQLQuery(connection, configuration); + } + + @Override + public SQLQuery select(Expression expr) { + return query().select(expr); + } + + @Override + public SQLQuery select(Expression... exprs) { + return query().select(exprs); + } + + @Override + public SQLQuery selectDistinct(Expression expr) { + return query().select(expr).distinct(); + } + + @Override + public SQLQuery selectDistinct(Expression... exprs) { + return query().select(exprs).distinct(); + } + + @Override + public SQLQuery selectZero() { + return select(Expressions.ZERO); + } + + @Override + public SQLQuery selectOne() { + return select(Expressions.ONE); + } + + @Override + public SQLQuery selectFrom(RelationalPath expr) { + return select(expr).from(expr); + } + +} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/SQLResultIterator.java b/querydsl-sql/src/main/java/com/querydsl/sql/SQLResultIterator.java similarity index 75% rename from querydsl-sql/src/main/java/com/mysema/query/sql/SQLResultIterator.java rename to querydsl-sql/src/main/java/com/querydsl/sql/SQLResultIterator.java index e9fbf982e2..fbc0a124d1 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/SQLResultIterator.java +++ b/querydsl-sql/src/main/java/com/querydsl/sql/SQLResultIterator.java @@ -1,5 +1,5 @@ /* - * Copyright 2011, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,20 +11,20 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql; +package com.querydsl.sql; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.NoSuchElementException; -import javax.annotation.Nullable; +import org.jetbrains.annotations.Nullable; import com.mysema.commons.lang.CloseableIterator; -import com.mysema.query.QueryException; +import com.querydsl.core.QueryException; /** - * SQLResultIterator is an Iterator adapter for JDBC result sets with customizable projections + * {@code SQLResultIterator} is an Iterator adapter for JDBC result sets with customizable projections * * @author tiwe * @@ -41,15 +41,26 @@ public abstract class SQLResultIterator implements CloseableIterator { private final Statement stmt; + private final SQLDetailedListener listener; + + private final SQLListenerContext context; + public SQLResultIterator(Configuration conf, Statement stmt, ResultSet rs) { + this(conf, stmt, rs, null, null); + } + + public SQLResultIterator(Configuration conf, Statement stmt, ResultSet rs, + SQLDetailedListener listener, SQLListenerContext context) { this.configuration = conf; this.stmt = stmt; this.rs = rs; + this.listener = listener; + this.context = context; } @Override public void close() { - try{ + try { try { if (rs != null) { rs.close(); @@ -59,8 +70,12 @@ public void close() { stmt.close(); } } - }catch(SQLException e) { + } catch (SQLException e) { throw configuration.translate(e); + } finally { + if (listener != null) { + listener.end(context); + } } } diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/SQLSerializer.java b/querydsl-sql/src/main/java/com/querydsl/sql/SQLSerializer.java new file mode 100644 index 0000000000..018d37857b --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/SQLSerializer.java @@ -0,0 +1,1044 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import java.sql.Types; +import java.util.*; + +import org.jetbrains.annotations.Nullable; + +import com.querydsl.core.JoinExpression; +import com.querydsl.core.JoinFlag; +import com.querydsl.core.QueryFlag; +import com.querydsl.core.QueryFlag.Position; +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.support.SerializerBase; +import com.querydsl.core.types.*; +import com.querydsl.core.types.Template.Element; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.util.CollectionUtils; +import com.querydsl.core.util.StringUtils; +import com.querydsl.sql.dml.SQLInsertBatch; +import com.querydsl.sql.types.Null; + +/** + * {@code SqlSerializer} serializes SQL clauses into SQL + * + * @author tiwe + */ +public class SQLSerializer extends SerializerBase { + + protected enum Stage { SELECT, FROM, WHERE, GROUP_BY, HAVING, ORDER_BY, MODIFIERS } + + protected static final Expression Q = Expressions.template(Object.class, "?"); + + protected static final String COMMA = ", "; + + protected final LinkedList> constantPaths = new LinkedList>(); + + protected final Set> withAliases = new HashSet<>(); + + protected final boolean dml; + + protected Stage stage = Stage.SELECT; + + protected boolean skipParent; + + protected boolean dmlWithSchema; + + protected RelationalPath entity; + + protected final Configuration configuration; + + protected final SQLTemplates templates; + + protected boolean inUnion = false; + + protected boolean inJoin = false; + + protected boolean inSubquery = false; + + protected boolean useLiterals = false; + + public SQLSerializer(Configuration conf) { + this(conf, false); + } + + public SQLSerializer(Configuration conf, boolean dml) { + super(conf.getTemplates()); + this.configuration = conf; + this.templates = conf.getTemplates(); + this.dml = dml; + } + + protected void appendAsColumnName(Path path, boolean precededByDot) { + String column = ColumnMetadata.getName(path); + if (path.getMetadata().getParent() instanceof RelationalPath) { + RelationalPath parent = (RelationalPath) path.getMetadata().getParent(); + column = configuration.getColumnOverride(parent.getSchemaAndTable(), column); + } + append(templates.quoteIdentifier(column, precededByDot)); + } + + protected SchemaAndTable getSchemaAndTable(RelationalPath path) { + return configuration.getOverride(path.getSchemaAndTable()); + } + + protected void appendSchemaName(String schema) { + append(templates.quoteIdentifier(schema)); + } + + protected void appendTableName(String table, boolean precededByDot) { + append(templates.quoteIdentifier(table, precededByDot)); + } + + public List> getConstantPaths() { + return constantPaths; + } + + /** + * Return a list of expressions that can be used to uniquely define the query sources + * + * @param joins + * @return identifier columns + */ + @SuppressWarnings("unchecked") + protected List> getIdentifierColumns(List joins, boolean alias) { + if (joins.size() == 1) { + JoinExpression join = joins.get(0); + if (join.getTarget() instanceof RelationalPath) { + return ((RelationalPath) join.getTarget()).getColumns(); + } else { + return Collections.emptyList(); + } + + } else { + List> rv = new ArrayList<>(); + int counter = 0; + for (JoinExpression join : joins) { + if (join.getTarget() instanceof RelationalPath) { + RelationalPath path = (RelationalPath) join.getTarget(); + List> columns; + if (path.getPrimaryKey() != null) { + columns = path.getPrimaryKey().getLocalColumns(); + } else { + columns = path.getColumns(); + } + if (alias) { + for (Expression column : columns) { + rv.add(ExpressionUtils.as(column, "col" + (++counter))); + } + } else { + rv.addAll(columns); + } + + } else { + // not able to provide a distinct list of columns + return Collections.emptyList(); + } + } + return rv; + } + + } + + protected SQLTemplates getTemplates() { + return templates; + } + + public void handle(String template, Object... args) { + handleTemplate(TemplateFactory.DEFAULT.create(template), Arrays.asList(args)); + } + + public final SQLSerializer handleSelect(final String sep, final List> expressions) { + if (inSubquery) { + Set names = new HashSet<>(); + List> replacements = new ArrayList<>(); + for (Expression expr : expressions) { + if (expr instanceof Path) { + String name = ColumnMetadata.getName((Path) expr); + if (!names.add(name.toLowerCase())) { + expr = ExpressionUtils.as(expr, "col__" + name + replacements.size()); + } + } + replacements.add(expr); + } + return handle(sep, replacements); + } else { + return handle(sep, expressions); + } + } + + protected void handleJoinTarget(JoinExpression je) { + // type specifier + if (je.getTarget() instanceof RelationalPath && templates.isSupportsAlias()) { + final RelationalPath pe = (RelationalPath) je.getTarget(); + if (pe.getMetadata().getParent() == null) { + if (withAliases.contains(pe)) { + appendTableName(pe.getMetadata().getName(), false); + append(templates.getTableAlias()); + } else { + SchemaAndTable schemaAndTable = getSchemaAndTable(pe); + boolean precededByDot; + if (templates.isPrintSchema()) { + appendSchemaName(schemaAndTable.getSchema()); + append("."); + precededByDot = true; + } else { + precededByDot = false; + } + appendTableName(schemaAndTable.getTable(), precededByDot); + append(templates.getTableAlias()); + } + } + } + inJoin = true; + handle(je.getTarget()); + inJoin = false; + } + + public void serialize(QueryMetadata metadata, boolean forCountRow) { + templates.serialize(metadata, forCountRow, this); + } + + protected void serializeForQuery(QueryMetadata metadata, boolean forCountRow) { + boolean oldInSubquery = inSubquery; + inSubquery = inSubquery || getLength() > 0; + boolean oldSkipParent = skipParent; + skipParent = false; + final Expression select = metadata.getProjection(); + final List joins = metadata.getJoins(); + final Predicate where = metadata.getWhere(); + final List> groupBy = metadata.getGroupBy(); + final Predicate having = metadata.getHaving(); + final List> orderBy = metadata.getOrderBy(); + final Set flags = metadata.getFlags(); + final boolean hasFlags = !flags.isEmpty(); + String suffix = null; + + List> sqlSelect; + if (select instanceof FactoryExpression) { + sqlSelect = ((FactoryExpression) select).getArgs(); + } else if (select != null) { + sqlSelect = Collections.singletonList(select); + } else { + sqlSelect = Collections.emptyList(); + } + + // with + if (hasFlags) { + List> withFlags = new ArrayList<>(); + boolean recursive = false; + for (QueryFlag flag : flags) { + if (flag.getPosition() == Position.WITH) { + if (flag.getFlag() == SQLTemplates.RECURSIVE) { + recursive = true; + continue; + } + withFlags.add(flag.getFlag()); + } + } + if (!withFlags.isEmpty()) { + if (recursive) { + append(templates.getWithRecursive()); + } else { + append(templates.getWith()); + } + handle(", ", withFlags); + append("\n"); + } + } + + // start + if (hasFlags) { + serialize(Position.START, flags); + } + + // select + Stage oldStage = stage; + stage = Stage.SELECT; + if (forCountRow) { + append(templates.getSelect()); + if (hasFlags) { + serialize(Position.AFTER_SELECT, flags); + } + + if (!metadata.isDistinct()) { + append(templates.getCountStar()); + if (!groupBy.isEmpty()) { + append(templates.getFrom()); + append("("); + append(templates.getSelect()); + append("1 as one "); + suffix = ") internal"; + } + + } else { + List> columns; + if (sqlSelect.isEmpty()) { + columns = getIdentifierColumns(joins, !templates.isCountDistinctMultipleColumns()); + } else { + columns = sqlSelect; + } + if (!groupBy.isEmpty()) { + // select count(*) from (select distinct ...) + append(templates.getCountStar()); + append(templates.getFrom()); + append("("); + append(templates.getSelectDistinct()); + handleSelect(COMMA, columns); + suffix = ") internal"; + } else if (columns.size() == 1) { + append(templates.getDistinctCountStart()); + handle(columns.get(0)); + append(templates.getDistinctCountEnd()); + } else if (templates.isCountDistinctMultipleColumns()) { + append(templates.getDistinctCountStart()); + append("(").handleSelect(COMMA, columns).append(")"); + append(templates.getDistinctCountEnd()); + } else { + // select count(*) from (select distinct ...) + append(templates.getCountStar()); + append(templates.getFrom()); + append("("); + append(templates.getSelectDistinct()); + handleSelect(COMMA, columns); + suffix = ") internal"; + } + } + + } else if (!sqlSelect.isEmpty()) { + if (!metadata.isDistinct()) { + append(templates.getSelect()); + } else { + append(templates.getSelectDistinct()); + } + if (hasFlags) { + serialize(Position.AFTER_SELECT, flags); + } + + handleSelect(COMMA, sqlSelect); + } + if (hasFlags) { + serialize(Position.AFTER_PROJECTION, flags); + } + + // from + stage = Stage.FROM; + serializeSources(joins); + + // where + if (hasFlags) { + serialize(Position.BEFORE_FILTERS, flags); + } + if (where != null) { + stage = Stage.WHERE; + append(templates.getWhere()).handle(where); + } + if (hasFlags) { + serialize(Position.AFTER_FILTERS, flags); + } + + // group by + if (hasFlags) { + serialize(Position.BEFORE_GROUP_BY, flags); + } + if (!groupBy.isEmpty()) { + stage = Stage.GROUP_BY; + append(templates.getGroupBy()).handle(COMMA, groupBy); + } + if (hasFlags) { + serialize(Position.AFTER_GROUP_BY, flags); + } + + // having + if (hasFlags) { + serialize(Position.BEFORE_HAVING, flags); + } + if (having != null) { + stage = Stage.HAVING; + append(templates.getHaving()).handle(having); + } + if (hasFlags) { + serialize(Position.AFTER_HAVING, flags); + } + + // order by + if (hasFlags) { + serialize(Position.BEFORE_ORDER, flags); + } + if (!orderBy.isEmpty() && !forCountRow) { + stage = Stage.ORDER_BY; + append(templates.getOrderBy()); + handleOrderBy(orderBy); + } + if (hasFlags) { + serialize(Position.AFTER_ORDER, flags); + } + + // modifiers + if (!forCountRow && metadata.getModifiers().isRestricting() && !joins.isEmpty()) { + stage = Stage.MODIFIERS; + templates.serializeModifiers(metadata, this); + } + + if (suffix != null) { + append(suffix); + } + + // reset stage + stage = oldStage; + skipParent = oldSkipParent; + inSubquery = oldInSubquery; + } + + protected void handleOrderBy(List> orderBy) { + boolean first = true; + for (final OrderSpecifier os : orderBy) { + if (!first) { + append(COMMA); + } + String order = os.getOrder() == Order.ASC ? templates.getAsc() : templates.getDesc(); + if (os.getNullHandling() == OrderSpecifier.NullHandling.NullsFirst) { + if (templates.getNullsFirst() != null) { + handle(os.getTarget()); + append(order); + append(templates.getNullsFirst()); + } else { + append("(case when "); + handle(os.getTarget()); + append(" is null then 0 else 1 end), "); + handle(os.getTarget()); + append(order); + } + } else if (os.getNullHandling() == OrderSpecifier.NullHandling.NullsLast) { + if (templates.getNullsLast() != null) { + handle(os.getTarget()); + append(order); + append(templates.getNullsLast()); + } else { + append("(case when "); + handle(os.getTarget()); + append(" is null then 1 else 0 end), "); + handle(os.getTarget()); + append(order); + } + + } else { + handle(os.getTarget()); + append(order); + } + first = false; + } + } + + public void serializeDelete(QueryMetadata metadata, RelationalPath entity) { + this.entity = entity; + templates.serializeDelete(metadata, entity, this); + } + + protected void serializeForDelete(QueryMetadata metadata, RelationalPath entity) { + serialize(Position.START, metadata.getFlags()); + + if (!serialize(Position.START_OVERRIDE, metadata.getFlags())) { + append(templates.getDelete()); + } + serialize(Position.AFTER_SELECT, metadata.getFlags()); + append("from "); + + boolean originalDmlWithSchema = dmlWithSchema; + dmlWithSchema = true; + handle(entity); + dmlWithSchema = originalDmlWithSchema; + + if (metadata.getWhere() != null) { + serializeForWhere(metadata); + } + } + + protected void serializeForWhere(QueryMetadata metadata) { + boolean requireSchemaInWhere = templates.isRequiresSchemaInWhere(); + boolean originalDmlWithSchema = dmlWithSchema; + + if (requireSchemaInWhere) { + dmlWithSchema = true; + } + append(templates.getWhere()).handle(metadata.getWhere()); + + if (requireSchemaInWhere) { + dmlWithSchema = originalDmlWithSchema; + } + } + + public void serializeMerge(QueryMetadata metadata, RelationalPath entity, List> keys, + List> columns, List> values, @Nullable SubQueryExpression subQuery) { + this.entity = entity; + templates.serializeMerge(metadata, entity, keys, columns, values, subQuery, this); + } + + protected void serializeForMerge(QueryMetadata metadata, RelationalPath entity, List> keys, + List> columns, List> values, @Nullable SubQueryExpression subQuery) { + serialize(Position.START, metadata.getFlags()); + + if (!serialize(Position.START_OVERRIDE, metadata.getFlags())) { + append(templates.getMergeInto()); + } + serialize(Position.AFTER_SELECT, metadata.getFlags()); + + boolean originalDmlWithSchema = dmlWithSchema; + dmlWithSchema = true; + handle(entity); + dmlWithSchema = originalDmlWithSchema; + append(" "); + // columns + if (!columns.isEmpty()) { + skipParent = true; + append("(").handle(COMMA, columns).append(") "); + skipParent = false; + } + // keys + if (!keys.isEmpty()) { + append(templates.getKey()); + skipParent = true; + append("(").handle(COMMA, keys).append(") "); + skipParent = false; + } + + if (subQuery != null) { + // subquery + append("\n"); + serialize(subQuery.getMetadata(), false); + } else { + if (!useLiterals) { + for (int i = 0; i < columns.size(); i++) { + if (values.get(i) instanceof Constant) { + constantPaths.add(columns.get(i)); + } + } + } + + // values + append(templates.getValues()); + append("(").handle(COMMA, values).append(") "); + } + } + + public void serializeInsert(QueryMetadata metadata, RelationalPath entity, List> columns, + List> values, @Nullable SubQueryExpression subQuery) { + this.entity = entity; + templates.serializeInsert(metadata, entity, columns, values, subQuery, this); + } + + + public void serializeInsert(QueryMetadata metadata, RelationalPath entity, List batches) { + this.entity = entity; + templates.serializeInsert(metadata, entity, batches, this); + } + + protected void serializeForInsert(QueryMetadata metadata, RelationalPath entity, List batches) { + serializeForInsert(metadata, entity, batches.get(0).getColumns(), batches.get(0).getValues(), null); + for (int i = 1; i < batches.size(); i++) { + append(COMMA); + append("("); + handle(COMMA, batches.get(i).getValues()); + append(")"); + } + } + + protected void serializeForInsert(QueryMetadata metadata, RelationalPath entity, List> columns, + List> values, @Nullable SubQueryExpression subQuery) { + serialize(Position.START, metadata.getFlags()); + + if (!serialize(Position.START_OVERRIDE, metadata.getFlags())) { + append(templates.getInsertInto()); + } + serialize(Position.AFTER_SELECT, metadata.getFlags()); + + boolean originalDmlWithSchema = dmlWithSchema; + dmlWithSchema = true; + handle(entity); + dmlWithSchema = originalDmlWithSchema; + // columns + if (!columns.isEmpty()) { + append(" ("); + skipParent = true; + handle(COMMA, columns); + skipParent = false; + append(")"); + } + + if (subQuery != null) { + append("\n"); + serialize(subQuery.getMetadata(), false); + + } else { + if (!useLiterals) { + for (int i = 0; i < columns.size(); i++) { + if (values.get(i) instanceof Constant) { + constantPaths.add(columns.get(i)); + } + } + } + + if (!values.isEmpty()) { + // values + append(templates.getValues()); + append("("); + handle(COMMA, values); + append(")"); + } else { + append(templates.getDefaultValues()); + } + } + + } + + public void serializeUpdate(QueryMetadata metadata, RelationalPath entity, + Map, Expression> updates) { + templates.serializeUpdate(metadata, entity, updates, this); + } + + protected void serializeForUpdate(QueryMetadata metadata, RelationalPath entity, + Map, Expression> updates) { + this.entity = entity; + + serialize(Position.START, metadata.getFlags()); + + if (!serialize(Position.START_OVERRIDE, metadata.getFlags())) { + append(templates.getUpdate()); + } + serialize(Position.AFTER_SELECT, metadata.getFlags()); + + boolean originalDmlWithSchema = dmlWithSchema; + dmlWithSchema = true; + handle(entity); + dmlWithSchema = originalDmlWithSchema; + append("\n"); + append(templates.getSet()); + boolean first = true; + skipParent = true; + for (final Map.Entry,Expression> update : updates.entrySet()) { + if (!first) { + append(COMMA); + } + handle(update.getKey()); + append(" = "); + if (!useLiterals && update.getValue() instanceof Constant) { + constantPaths.add(update.getKey()); + } + handle(update.getValue()); + first = false; + } + skipParent = false; + + serialize(Position.BEFORE_FILTERS, metadata.getFlags()); + if (metadata.getWhere() != null) { + serializeForWhere(metadata); + } + } + + protected void serializeSources(List joins) { + if (joins.isEmpty()) { + String dummyTable = templates.getDummyTable(); + if (!StringUtils.isNullOrEmpty(dummyTable)) { + append(templates.getFrom()); + append(dummyTable); + } + } else { + append(templates.getFrom()); + for (int i = 0; i < joins.size(); i++) { + final JoinExpression je = joins.get(i); + if (je.getFlags().isEmpty()) { + if (i > 0) { + append(templates.getJoinSymbol(je.getType())); + } + handleJoinTarget(je); + if (je.getCondition() != null) { + append(templates.getOn()).handle(je.getCondition()); + } + } else { + serialize(JoinFlag.Position.START, je.getFlags()); + if (!serialize(JoinFlag.Position.OVERRIDE, je.getFlags()) && i > 0) { + append(templates.getJoinSymbol(je.getType())); + } + serialize(JoinFlag.Position.BEFORE_TARGET, je.getFlags()); + handleJoinTarget(je); + serialize(JoinFlag.Position.BEFORE_CONDITION, je.getFlags()); + if (je.getCondition() != null) { + append(templates.getOn()).handle(je.getCondition()); + } + serialize(JoinFlag.Position.END, je.getFlags()); + } + } + } + } + + public void serializeUnion(Expression union, QueryMetadata metadata, boolean unionAll) { + final List> groupBy = metadata.getGroupBy(); + final Predicate having = metadata.getHaving(); + final List> orderBy = metadata.getOrderBy(); + final Set flags = metadata.getFlags(); + final boolean hasFlags = !flags.isEmpty(); + + // with + if (hasFlags) { + boolean handled = false; + boolean recursive = false; + for (QueryFlag flag : flags) { + if (flag.getPosition() == Position.WITH) { + if (flag.getFlag() == SQLTemplates.RECURSIVE) { + recursive = true; + continue; + } + if (handled) { + append(", "); + } + handle(flag.getFlag()); + handled = true; + } + } + if (handled) { + if (recursive) { + prepend(templates.getWithRecursive()); + } else { + prepend(templates.getWith()); + } + append("\n"); + } + } + + // union + Stage oldStage = stage; + handle(union); + + // group by + if (hasFlags) { + serialize(Position.BEFORE_GROUP_BY, flags); + } + if (!groupBy.isEmpty()) { + stage = Stage.GROUP_BY; + append(templates.getGroupBy()).handle(COMMA, groupBy); + } + if (hasFlags) { + serialize(Position.AFTER_GROUP_BY, flags); + } + + // having + if (hasFlags) { + serialize(Position.BEFORE_HAVING, flags); + } + if (having != null) { + stage = Stage.HAVING; + append(templates.getHaving()).handle(having); + } + if (hasFlags) { + serialize(Position.AFTER_HAVING, flags); + } + + // order by + if (hasFlags) { + serialize(Position.BEFORE_ORDER, flags); + } + if (!orderBy.isEmpty()) { + stage = Stage.ORDER_BY; + append(templates.getOrderBy()); + skipParent = true; + handleOrderBy(orderBy); + skipParent = false; + } + if (hasFlags) { + serialize(Position.AFTER_ORDER, flags); + } + + // end + if (hasFlags) { + serialize(Position.END, flags); + } + + // reset stage + stage = oldStage; + } + + @SuppressWarnings("unchecked") + @Override + public void visitConstant(Object constant) { + if (useLiterals) { + if (constant instanceof Collection) { + append("("); + boolean first = true; + for (Object o : ((Collection) constant)) { + if (!first) { + append(COMMA); + } + append(configuration.asLiteral(o)); + first = false; + } + append(")"); + } else { + append(configuration.asLiteral(constant)); + } + } else if (constant instanceof Collection) { + append("("); + boolean first = true; + for (Object o : ((Collection) constant)) { + if (!first) { + append(COMMA); + } + serializeConstant(constants.size() + 1, null); + constants.add(o); + if (first && (constantPaths.size() < constants.size())) { + constantPaths.add(null); + } + first = false; + } + append(")"); + + int size = ((Collection) constant).size() - 1; + Path lastPath = constantPaths.peekLast(); + for (int i = 0; i < size; i++) { + constantPaths.add(lastPath); + } + } else { + if (stage == Stage.SELECT + && !Null.class.isInstance(constant) + && configuration.getTemplates().isWrapSelectParameters()) { + String typeName = configuration.getTypeNameForCast(constant.getClass()); + Expression type = Expressions.constant(typeName); + super.visitOperation(constant.getClass(), SQLOps.CAST, Arrays.> asList(Q, type)); + } else { + serializeConstant(constants.size() + 1, null); + } + constants.add(constant); + if (constantPaths.size() < constants.size()) { + constantPaths.add(null); + } + } + } + + @Override + public Void visit(ParamExpression param, Void context) { + constants.add(param); + serializeConstant(constants.size(), null); + if (constantPaths.size() < constants.size()) { + constantPaths.add(null); + } + return null; + } + + @Override + protected void serializeConstant(int parameterIndex, String constantLabel) { + append("?"); + } + + @Override + public Void visit(Path path, Void context) { + if (dml) { + if (path.equals(entity) && path instanceof RelationalPath) { + SchemaAndTable schemaAndTable = getSchemaAndTable((RelationalPath) path); + boolean precededByDot; + if (dmlWithSchema && templates.isPrintSchema()) { + appendSchemaName(schemaAndTable.getSchema()); + append("."); + precededByDot = true; + } else { + precededByDot = false; + } + appendTableName(schemaAndTable.getTable(), precededByDot); + return null; + } else if (entity.equals(path.getMetadata().getParent()) && skipParent) { + appendAsColumnName(path, false); + return null; + } + } + final PathMetadata metadata = path.getMetadata(); + boolean precededByDot; + if (metadata.getParent() != null && (!skipParent || dml)) { + visit(metadata.getParent(), context); + append("."); + precededByDot = true; + } else { + precededByDot = false; + } + appendAsColumnName(path, precededByDot); + return null; + } + + @Override + public Void visit(SubQueryExpression query, Void context) { + boolean oldInSubsuery = inSubquery; + inSubquery = true; + if (inUnion && !templates.isUnionsWrapped()) { + serialize(query.getMetadata(), false); + } else { + append("("); + serialize(query.getMetadata(), false); + append(")"); + } + inSubquery = oldInSubsuery; + return null; + } + + @Override + public Void visit(TemplateExpression expr, Void context) { + if (expr.equals(Expressions.TRUE)) { + append(templates.serialize("1", Types.BOOLEAN)); + } else if (expr.equals(Expressions.FALSE)) { + append(templates.serialize("0", Types.BOOLEAN)); + } else if (inJoin && expr instanceof RelationalFunctionCall + && templates.isFunctionJoinsWrapped()) { + append("table("); + super.visit(expr, context); + append(")"); + } else { + super.visit(expr, context); + } + return null; + } + + @SuppressWarnings("unchecked") + @Override + protected void visitOperation(Class type, Operator operator, List> args) { + boolean pathAdded = false; + if (args.size() == 2 + && !useLiterals + && args.get(0) instanceof Path + && args.get(1) instanceof Constant + && operator != Ops.NUMCAST) { + Object constant = ((Constant) args.get(1)).getConstant(); + if (!Collection.class.isInstance(constant) || !((Collection) constant).isEmpty()) { + for (Element element : templates.getTemplate(operator).getElements()) { + if (element instanceof Template.ByIndex && ((Template.ByIndex) element).getIndex() == 1) { + constantPaths.add((Path) args.get(0)); + pathAdded = true; + break; + } + } + } + } + + if (operator == Ops.SET && args.get(0) instanceof SubQueryExpression) { + boolean oldUnion = inUnion; + inUnion = true; + super.visitOperation(type, SQLOps.UNION, args); + inUnion = oldUnion; + + } else if (operator == SQLOps.UNION || operator == SQLOps.UNION_ALL) { + boolean oldUnion = inUnion; + inUnion = true; + super.visitOperation(type, operator, args); + inUnion = oldUnion; + + } else if (operator == Ops.LIKE && args.get(1) instanceof Constant) { + final String escape = String.valueOf(templates.getEscapeChar()); + final String escaped = args.get(1).toString().replace(escape, escape + escape); + super.visitOperation(String.class, Ops.LIKE, + Arrays.asList(args.get(0), ConstantImpl.create(escaped))); + + } else if (operator == Ops.STRING_CAST) { + final String typeName = configuration.getTypeNameForCast(String.class); + super.visitOperation(String.class, SQLOps.CAST, + Arrays.asList(args.get(0), ConstantImpl.create(typeName))); + + } else if (operator == Ops.NUMCAST) { + @SuppressWarnings("unchecked") //this is the second argument's type + Constant> expectedConstant = (Constant>) args.get(1); + + final Class targetType = expectedConstant.getConstant(); + final String typeName = configuration.getTypeNameForCast(targetType); + super.visitOperation(targetType, SQLOps.CAST, + Arrays.asList(args.get(0), ConstantImpl.create(typeName))); + + } else if (operator == Ops.ALIAS) { + if (stage == Stage.SELECT || stage == Stage.FROM) { + if (args.get(1) instanceof Path && !((Path) args.get(1)).getMetadata().isRoot()) { + Path path = (Path) args.get(1); + args = Arrays.asList(args.get(0), + ExpressionUtils.path(path.getType(), path.getMetadata().getName())); + } + super.visitOperation(type, operator, args); + } else { + // handle only target + handle(args.get(1)); + } + + } else if ((operator == Ops.IN || operator == Ops.NOT_IN) + && args.get(0) instanceof Path + && args.get(1) instanceof Constant) { + //The type of the constant expression is compatible with the left + //expression, since the compile time checking mandates it to be. + @SuppressWarnings("unchecked") + Collection coll = ((Constant>) args.get(1)).getConstant(); + if (coll.isEmpty()) { + super.visitOperation(type, operator == Ops.IN ? Ops.EQ : Ops.NE, + Arrays.asList(Expressions.ONE, Expressions.TWO)); + } else { + if (templates.getListMaxSize() == 0 || coll.size() <= templates.getListMaxSize()) { + super.visitOperation(type, operator, args); + } else { + //The type of the path is compatible with the constant + //expression, since the compile time checking mandates it to be + @SuppressWarnings("unchecked") + Expression path = (Expression) args.get(0); + if (pathAdded) { + constantPaths.removeLast(); + } + Iterable> partitioned = CollectionUtils.partition(new ArrayList<>(coll), templates.getListMaxSize()); + Predicate result; + if (operator == Ops.IN) { + result = ExpressionUtils.inAny(path, partitioned); + } else { + result = ExpressionUtils.notInAny(path, partitioned); + } + append("("); + result.accept(this, null); + append(")"); + } + } + + } else if (operator == SQLOps.WITH_COLUMNS) { + boolean oldSkipParent = skipParent; + skipParent = true; + super.visitOperation(type, operator, args); + skipParent = oldSkipParent; + + } else if (operator == Ops.ORDER) { + List> order = ((Constant>>) args.get(0)).getConstant(); + handleOrderBy(order); + + } else { + super.visitOperation(type, operator, args); + } + + if (operator == SQLOps.WITH_ALIAS || operator == SQLOps.WITH_COLUMNS) { + if (args.get(0) instanceof Path) { + withAliases.add((Path) args.get(0)); + } else { + withAliases.add((Path) ((Operation) args.get(0)).getArg(0)); + } + } + } + + public void setUseLiterals(boolean useLiterals) { + this.useLiterals = useLiterals; + } + + protected void setSkipParent(boolean b) { + skipParent = b; + } + + protected void setDmlWithSchema(boolean b) { + dmlWithSchema = b; + } + +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/SQLServer2005Templates.java b/querydsl-sql/src/main/java/com/querydsl/sql/SQLServer2005Templates.java new file mode 100644 index 0000000000..24cbca1d5f --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/SQLServer2005Templates.java @@ -0,0 +1,154 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import java.util.Map; +import java.util.Set; + +import com.querydsl.core.QueryFlag; +import com.querydsl.core.QueryFlag.Position; +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.QueryModifiers; +import com.querydsl.core.types.*; +import com.querydsl.core.types.dsl.Expressions; + + +/** + * {@code SQLServer2005Templates} is an SQL dialect for Microsoft SQL Server 2005 + * + * @author tiwe + */ +public class SQLServer2005Templates extends SQLServerTemplates { + + @SuppressWarnings("FieldNameHidesFieldInSuperclass") //Intentional + public static final SQLServer2005Templates DEFAULT = new SQLServer2005Templates(); + + public static Builder builder() { + return new Builder() { + @Override + protected SQLTemplates build(char escape, boolean quote) { + return new SQLServer2005Templates(escape, quote); + } + }; + } + + private String topTemplate = "top ({0}) "; + + private String outerQueryStart = "select * from (\n "; + + private String outerQueryEnd = ") a where "; + + private String limitOffsetTemplate = "rn > {0} and rn <= {1}"; + + private String offsetTemplate = "rn > {0}"; + + private String outerQuerySuffix = " order by rn"; + + public SQLServer2005Templates() { + this(Keywords.SQLSERVER2005, '\\',false); + } + + public SQLServer2005Templates(boolean quote) { + this(Keywords.SQLSERVER2005, '\\',quote); + } + + public SQLServer2005Templates(char escape, boolean quote) { + this(Keywords.SQLSERVER2005, escape, quote); + } + + protected SQLServer2005Templates(Set keywords, char escape, boolean quote) { + super(keywords, escape, quote); + //The older MSSQL Server suite doesn't support logarithms with a base other + //than 10 and the natural logarithm, so we do it manually + add(Ops.MathOps.LOG, "(LOG({0}) / LOG({1}))"); + } + + @Override + public void serialize(QueryMetadata metadata, boolean forCountRow, SQLSerializer context) { + if (!forCountRow && metadata.getModifiers().isRestricting() && !metadata.getJoins().isEmpty()) { + QueryModifiers mod = metadata.getModifiers(); + if (mod.getOffset() == null) { + // select top ... + metadata = metadata.clone(); + metadata.addFlag(new QueryFlag(QueryFlag.Position.AFTER_SELECT, + Expressions.template(Integer.class, topTemplate, mod.getLimit()))); + context.serializeForQuery(metadata, forCountRow); + } else { + context.append(outerQueryStart); + metadata = metadata.clone(); + WindowFunction rn = SQLExpressions.rowNumber().over(); + for (OrderSpecifier os : metadata.getOrderBy()) { + rn.orderBy(os); + } + if (metadata.getOrderBy().isEmpty()) { + rn.orderBy(Expressions.currentTimestamp().asc()); + } + FactoryExpression pr = Projections.appending(metadata.getProjection(), rn.as("rn")); + metadata.setProjection(FactoryExpressionUtils.wrap(pr)); + metadata.clearOrderBy(); + context.serializeForQuery(metadata, forCountRow); + context.append(outerQueryEnd); + if (mod.getLimit() == null) { + context.handle(offsetTemplate, mod.getOffset()); + } else { + context.handle(limitOffsetTemplate, mod.getOffset(), mod.getLimit() + mod.getOffset()); + } + context.append(outerQuerySuffix); + } + + } else { + context.serializeForQuery(metadata, forCountRow); + } + + if (!metadata.getFlags().isEmpty()) { + context.serialize(Position.END, metadata.getFlags()); + } + } + + @Override + public void serializeDelete(QueryMetadata metadata, RelationalPath entity, SQLSerializer context) { + // limit + QueryModifiers mod = metadata.getModifiers(); + if (mod.isRestricting()) { + metadata = metadata.clone(); + metadata.addFlag(new QueryFlag(QueryFlag.Position.AFTER_SELECT, + Expressions.template(Integer.class, topTemplate, mod.getLimit()))); + } + + context.serializeForDelete(metadata, entity); + + if (!metadata.getFlags().isEmpty()) { + context.serialize(Position.END, metadata.getFlags()); + } + } + + @Override + public void serializeUpdate(QueryMetadata metadata, RelationalPath entity, + Map, Expression> updates, SQLSerializer context) { + // limit + QueryModifiers mod = metadata.getModifiers(); + if (mod.isRestricting()) { + metadata = metadata.clone(); + metadata.addFlag(new QueryFlag(QueryFlag.Position.AFTER_SELECT, + Expressions.template(Integer.class, topTemplate, mod.getLimit()))); + } + + context.serializeForUpdate(metadata, entity, updates); + + if (!metadata.getFlags().isEmpty()) { + context.serialize(Position.END, metadata.getFlags()); + } + } + +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/SQLServer2008Templates.java b/querydsl-sql/src/main/java/com/querydsl/sql/SQLServer2008Templates.java new file mode 100644 index 0000000000..09a06bec62 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/SQLServer2008Templates.java @@ -0,0 +1,55 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + + +import java.util.Set; + +/** + * {@code SQLServer2008Templates} is an SQL dialect for Microsoft SQL Server 2008 + * + * @author tiwe + * + */ +public class SQLServer2008Templates extends SQLServer2005Templates { + + @SuppressWarnings("FieldNameHidesFieldInSuperclass") //Intentional + public static final SQLServer2008Templates DEFAULT = new SQLServer2008Templates(); + + public static Builder builder() { + return new Builder() { + @Override + protected SQLTemplates build(char escape, boolean quote) { + return new SQLServer2008Templates(escape, quote); + } + }; + } + + public SQLServer2008Templates() { + this(Keywords.SQLSERVER2008, '\\',false); + } + + public SQLServer2008Templates(boolean quote) { + this(Keywords.SQLSERVER2008, '\\',quote); + } + + public SQLServer2008Templates(char escape, boolean quote) { + this(Keywords.SQLSERVER2008, escape, quote); + } + + protected SQLServer2008Templates(Set keywords, char escape, boolean quote) { + super(keywords, escape, quote); + } + +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/SQLServer2012Templates.java b/querydsl-sql/src/main/java/com/querydsl/sql/SQLServer2012Templates.java new file mode 100644 index 0000000000..012163e7f1 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/SQLServer2012Templates.java @@ -0,0 +1,142 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import java.util.Map; +import java.util.Set; + +import com.querydsl.core.QueryFlag; +import com.querydsl.core.QueryFlag.Position; +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.QueryModifiers; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.dsl.Expressions; + +/** + * {@code SQLServer2012Templates} is an SQL dialect for Microsoft SQL Server 2012 and later + * + * @author tiwe + * + */ +public class SQLServer2012Templates extends SQLServerTemplates { + + @SuppressWarnings("FieldNameHidesFieldInSuperclass") //Intentional + public static final SQLServer2012Templates DEFAULT = new SQLServer2012Templates(); + + private String topTemplate = "top {0s} "; + + private String limitOffsetTemplate = "\noffset {1} rows fetch next {0} rows only"; + + private String offsetTemplate = "\noffset {0} rows"; + + public static Builder builder() { + return new Builder() { + @Override + protected SQLTemplates build(char escape, boolean quote) { + return new SQLServer2012Templates(escape, quote); + } + }; + } + + public SQLServer2012Templates() { + this(Keywords.SQLSERVER2012, '\\',false); + } + + public SQLServer2012Templates(boolean quote) { + this(Keywords.SQLSERVER2012, '\\',quote); + } + + public SQLServer2012Templates(char escape, boolean quote) { + this(Keywords.SQLSERVER2012, escape, quote); + } + + protected SQLServer2012Templates(Set keywords, char escape, boolean quote) { + super(keywords, escape, quote); + add(SQLOps.NEXTVAL, "next value for {0s}"); + } + + @Override + public void serialize(QueryMetadata metadata, boolean forCountRow, SQLSerializer context) { + if (!forCountRow && metadata.getModifiers().isRestricting() && metadata.getOrderBy().isEmpty() + && !metadata.getJoins().isEmpty()) { + metadata = metadata.clone(); + QueryModifiers mod = metadata.getModifiers(); + // use top if order by is empty + if (mod.getOffset() == null) { + // select top ... + metadata.addFlag(new QueryFlag(QueryFlag.Position.AFTER_SELECT, + Expressions.template(Integer.class, topTemplate, mod.getLimit()))); + } else { + // order by first column + metadata.addOrderBy(Expressions.ONE.asc()); + } + } + context.serializeForQuery(metadata, forCountRow); + + if (!metadata.getFlags().isEmpty()) { + context.serialize(Position.END, metadata.getFlags()); + } + } + + @Override + public void serializeDelete(QueryMetadata metadata, RelationalPath entity, SQLSerializer context) { + // limit + QueryModifiers mod = metadata.getModifiers(); + if (mod.isRestricting()) { + metadata = metadata.clone(); + metadata.addFlag(new QueryFlag(QueryFlag.Position.AFTER_SELECT, + Expressions.template(Integer.class, topTemplate, mod.getLimit()))); + } + + context.serializeForDelete(metadata, entity); + + if (!metadata.getFlags().isEmpty()) { + context.serialize(Position.END, metadata.getFlags()); + } + } + + @Override + public void serializeUpdate(QueryMetadata metadata, RelationalPath entity, + Map, Expression> updates, SQLSerializer context) { + // limit + QueryModifiers mod = metadata.getModifiers(); + if (mod.isRestricting()) { + metadata = metadata.clone(); + metadata.addFlag(new QueryFlag(QueryFlag.Position.AFTER_SELECT, + Expressions.template(Integer.class, topTemplate, mod.getLimit()))); + } + + context.serializeForUpdate(metadata, entity, updates); + + if (!metadata.getFlags().isEmpty()) { + context.serialize(Position.END, metadata.getFlags()); + } + } + + @Override + protected void serializeModifiers(QueryMetadata metadata, SQLSerializer context) { + if (!metadata.getOrderBy().isEmpty()) { + QueryModifiers mod = metadata.getModifiers(); + if (mod.getLimit() == null) { + context.handle(offsetTemplate, mod.getOffset()); + } else if (mod.getOffset() == null) { + context.handle(limitOffsetTemplate, mod.getLimit(), 0); + } else { + context.handle(limitOffsetTemplate, mod.getLimit(), mod.getOffset()); + } + } + } + +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/SQLServerTemplates.java b/querydsl-sql/src/main/java/com/querydsl/sql/SQLServerTemplates.java new file mode 100644 index 0000000000..02ab19b25c --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/SQLServerTemplates.java @@ -0,0 +1,250 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import java.sql.Types; +import java.util.Collections; +import java.util.Set; + +import com.querydsl.core.QueryFlag; +import com.querydsl.core.QueryFlag.Position; +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.QueryModifiers; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.ExpressionUtils; +import com.querydsl.core.types.Ops; +import com.querydsl.core.types.dsl.Expressions; + +/** + * {@code SQLServerTemplates} is an SQL dialect for Microsoft SQL Server + * + * @author tiwe + * + */ +public class SQLServerTemplates extends SQLTemplates { + + protected static final Expression WITH_REPEATABLE_READ = ExpressionUtils.operation( + Object.class, SQLOps.WITH_REPEATABLE_READ, Collections.emptyList()); + + @SuppressWarnings("FieldNameHidesFieldInSuperclass") //Intentional + public static final SQLServerTemplates DEFAULT = new SQLServerTemplates(); + + public static Builder builder() { + return new Builder() { + @Override + protected SQLTemplates build(char escape, boolean quote) { + return new SQLServerTemplates(escape, quote); + } + }; + } + + private String topTemplate = "top {0s} "; + + public SQLServerTemplates() { + this('\\',false); + } + + public SQLServerTemplates(boolean quote) { + this('\\',quote); + } + + public SQLServerTemplates(char escape, boolean quote) { + this(Keywords.DEFAULT, escape, quote); + } + + protected SQLServerTemplates(Set keywords, char escape, boolean quote) { + super(keywords, "\"", escape, quote, false); + setDummyTable(""); + setNullsFirst(null); + setNullsLast(null); + setDefaultValues("\ndefault values"); + setArraysSupported(false); + setForUpdateFlag(new QueryFlag(Position.BEFORE_FILTERS, FOR_UPDATE)); + + setForShareSupported(true); + setForShareFlag(new QueryFlag(Position.BEFORE_FILTERS, WITH_REPEATABLE_READ)); + + setPrecedence(Precedence.ARITH_LOW, Ops.NEGATE); + setPrecedence(Precedence.COMPARISON, Ops.EQ, Ops.EQ_IGNORE_CASE, Ops.NE); + setPrecedence(Precedence.OR, Ops.BETWEEN, Ops.IN, Ops.NOT_IN, Ops.LIKE, Ops.LIKE_ESCAPE); + setPrecedence(Precedence.OR, OTHER_LIKE_CASES); + setPrecedence(Precedence.OR + 1, Ops.LIST, Ops.SET, Ops.SINGLETON); + + add(SQLOps.WITH_REPEATABLE_READ, "\nwith (repeatableread)"); + + // String + add(Ops.CONCAT, "{0} + {1}"); + add(Ops.CHAR_AT, "cast(substring({0},{1+'1'},1) as char)"); + add(Ops.INDEX_OF, "charindex({1},{0})-1", Precedence.ARITH_LOW); + add(Ops.INDEX_OF_2ARGS, "charindex({1},{0},{2})-1", Precedence.ARITH_LOW); + // NOTE : needs to be replaced with real regular expression + add(Ops.MATCHES, "{0} like {1}", Precedence.OR); + add(Ops.STRING_IS_EMPTY, "len({0}) = 0", Precedence.COMPARISON); + add(Ops.STRING_LENGTH, "len({0})"); + add(Ops.SUBSTR_1ARG, "substring({0},{1+'1'},255)"); + add(Ops.SUBSTR_2ARGS, "substring({0},{1+'1'},{2-1s})"); + add(Ops.TRIM, "ltrim(rtrim({0}))"); + + add(SQLOps.FOR_UPDATE, "\nwith (updlock)"); + + add(Ops.StringOps.LOCATE, "charindex({0},{1})"); + add(Ops.StringOps.LOCATE2, "charindex({0},{1},{2})"); + add(Ops.StringOps.LPAD, "right(replicate(' ', {1}) + left({0}, {1}), {1})"); + add(Ops.StringOps.LPAD2, "right(replicate({2}, {1}) + left({0}, {1}), {1})"); + add(Ops.StringOps.RPAD, "left(left({0}, {1}) + replicate(' ', {1}), {1})"); + add(Ops.StringOps.RPAD2, "left(left({0}, {1}) + replicate({2}, {1}), {1})"); + + add(SQLOps.NEXTVAL, "{0s}.nextval"); + + add(Ops.MOD, "{0} % {1}", Precedence.ARITH_HIGH); + add(Ops.MathOps.COSH, "(exp({0}) + exp({0*'-1'})) / 2"); + add(Ops.MathOps.COTH, "(exp({0*'2'}) + 1) / (exp({0*'2'}) - 1)"); + add(Ops.MathOps.LN, "log({0})"); + add(Ops.MathOps.LOG, "log({0}, {1})"); + add(Ops.MathOps.POWER, "power({0}, {1})"); + add(Ops.MathOps.ROUND, "round({0}, 0)"); + add(Ops.MathOps.SINH, "(exp({0}) - exp({0*'-1'})) / 2"); + add(Ops.MathOps.TANH, "(exp({0*'2'}) - 1) / (exp({0*'2'}) + 1)"); + + // Date / time + add(Ops.DateTimeOps.YEAR, "datepart(year, {0})"); + add(Ops.DateTimeOps.MONTH, "datepart(month, {0})"); + add(Ops.DateTimeOps.WEEK, "datepart(week, {0})"); + add(Ops.DateTimeOps.DAY_OF_MONTH, "datepart(day, {0})"); + add(Ops.DateTimeOps.DAY_OF_WEEK, "datepart(weekday, {0})"); + add(Ops.DateTimeOps.DAY_OF_YEAR, "datepart(dayofyear, {0})"); + add(Ops.DateTimeOps.HOUR, "datepart(hour, {0})"); + add(Ops.DateTimeOps.MINUTE, "datepart(minute, {0})"); + add(Ops.DateTimeOps.SECOND, "datepart(second, {0})"); + add(Ops.DateTimeOps.MILLISECOND, "datepart(millisecond, {0})"); + + add(Ops.DateTimeOps.YEAR_MONTH, "(datepart(year, {0}) * 100 + datepart(month, {0}))"); + add(Ops.DateTimeOps.YEAR_WEEK, "(datepart(year, {0}) * 100 + datepart(isowk, {0}))"); + + add(Ops.DateTimeOps.ADD_YEARS, "dateadd(year, {1s}, {0})"); + add(Ops.DateTimeOps.ADD_MONTHS, "dateadd(month, {1s}, {0})"); + add(Ops.DateTimeOps.ADD_WEEKS, "dateadd(week, {1s}, {0})"); + add(Ops.DateTimeOps.ADD_DAYS, "dateadd(day, {1s}, {0})"); + add(Ops.DateTimeOps.ADD_HOURS, "dateadd(hour, {1s}, {0})"); + add(Ops.DateTimeOps.ADD_MINUTES, "dateadd(minute, {1s}, {0})"); + add(Ops.DateTimeOps.ADD_SECONDS, "dateadd(second, {1s}, {0})"); + + add(Ops.DateTimeOps.DIFF_YEARS, "datediff(year,{0},{1})"); + add(Ops.DateTimeOps.DIFF_MONTHS, "datediff(month,{0},{1})"); + add(Ops.DateTimeOps.DIFF_WEEKS, "datediff(week,{0},{1})"); + add(Ops.DateTimeOps.DIFF_DAYS, "datediff(day,{0},{1})"); + add(Ops.DateTimeOps.DIFF_HOURS, "datediff(hour,{0},{1})"); + add(Ops.DateTimeOps.DIFF_MINUTES, "datediff(minute,{0},{1})"); + add(Ops.DateTimeOps.DIFF_SECONDS, "datediff(second,{0},{1})"); + + // truncates timestamps by replacing suffix + add(Ops.DateTimeOps.TRUNC_YEAR, "CONVERT(DATETIME, CONVERT(VARCHAR(4), {0}, 120) + '-01-01')"); + add(Ops.DateTimeOps.TRUNC_MONTH, "CONVERT(DATETIME, CONVERT(VARCHAR(7), {0}, 120) + '-01')"); + add(Ops.DateTimeOps.TRUNC_WEEK, "DATEADD(WEEK, DATEDIFF(WEEK, 0, {0} - 1), 0)"); + add(Ops.DateTimeOps.TRUNC_DAY, "CONVERT(DATETIME, CONVERT(VARCHAR(10), {0}, 120))"); + add(Ops.DateTimeOps.TRUNC_HOUR, "CONVERT(DATETIME, CONVERT(VARCHAR(13), {0}, 120) + ':00:00')"); + add(Ops.DateTimeOps.TRUNC_MINUTE, "CONVERT(DATETIME, CONVERT(VARCHAR(16), {0}, 120) + ':00')"); + add(Ops.DateTimeOps.TRUNC_SECOND, "CONVERT(DATETIME, CONVERT(VARCHAR(19), {0}, 120))"); + + add(Ops.DateTimeOps.DATE, "cast({0} as date)"); + add(Ops.DateTimeOps.CURRENT_DATE, "cast(getdate() as date)"); + + addTypeNameToCode("bit", Types.BOOLEAN, true); + addTypeNameToCode("decimal", Types.DOUBLE, true); + addTypeNameToCode("tinyint identity", Types.TINYINT); + addTypeNameToCode("bigint identity", Types.BIGINT); + addTypeNameToCode("timestamp", Types.BINARY); + addTypeNameToCode("nchar", Types.CHAR); + addTypeNameToCode("uniqueidentifier", Types.CHAR); + addTypeNameToCode("numeric() identity", Types.NUMERIC); + addTypeNameToCode("money", Types.DECIMAL); + addTypeNameToCode("smallmoney", Types.DECIMAL); + addTypeNameToCode("decimal() identity", Types.DECIMAL); + addTypeNameToCode("int", Types.INTEGER); + addTypeNameToCode("int identity", Types.INTEGER); + addTypeNameToCode("smallint identity", Types.SMALLINT); + addTypeNameToCode("float", Types.DOUBLE); + addTypeNameToCode("nvarchar", Types.VARCHAR); + addTypeNameToCode("date", Types.VARCHAR); + addTypeNameToCode("time", Types.VARCHAR); + addTypeNameToCode("datetime2", Types.VARCHAR); + addTypeNameToCode("datetimeoffset", Types.VARCHAR); + addTypeNameToCode("sysname", Types.VARCHAR); + addTypeNameToCode("sql_variant", Types.VARCHAR); + addTypeNameToCode("datetime", Types.TIMESTAMP); + addTypeNameToCode("smalldatetime", Types.TIMESTAMP); + addTypeNameToCode("image", Types.BLOB); + addTypeNameToCode("ntext", Types.CLOB); + addTypeNameToCode("xml", Types.CLOB); + addTypeNameToCode("text", Types.CLOB); + } + + @Override + public String serialize(String literal, int jdbcType) { + switch (jdbcType) { + case Types.TIMESTAMP: + return "CAST('" + literal + "' AS DATETIME2)"; + case TIMESTAMP_WITH_TIMEZONE: + return "CAST('" + literal + "' AS DATETIMEOFFSET)"; + case Types.DATE: + return "CAST('" + literal + "' AS DATE)"; + case Types.TIME: + case TIME_WITH_TIMEZONE: + return "CAST('" + literal + "' AS TIME)"; + default: + return super.serialize(literal, jdbcType); + } + } + + @Override + protected String escapeForLike(String str) { + final StringBuilder rv = new StringBuilder(str.length() + 3); + for (char ch : str.toCharArray()) { + if (ch == getEscapeChar() || ch == '%' || ch == '_' || ch == '[') { + rv.append(getEscapeChar()); + } + rv.append(ch); + } + return rv.toString(); + } + + @Override + public void serialize(QueryMetadata metadata, boolean forCountRow, SQLSerializer context) { + if (!forCountRow && metadata.getModifiers().isRestricting() && !metadata.getJoins().isEmpty()) { + QueryModifiers mod = metadata.getModifiers(); + if (mod.getOffset() == null) { + // select top ... + metadata = metadata.clone(); + metadata.addFlag(new QueryFlag(QueryFlag.Position.AFTER_SELECT, + Expressions.template(Integer.class, topTemplate, mod.getLimit()))); + context.serializeForQuery(metadata, forCountRow); + } else { + throw new IllegalStateException("offset not supported"); + } + + } else { + context.serializeForQuery(metadata, forCountRow); + } + + if (!metadata.getFlags().isEmpty()) { + context.serialize(Position.END, metadata.getFlags()); + } + } + + @Override + protected void serializeModifiers(QueryMetadata metadata, SQLSerializer context) { + // do nothing + } + +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/SQLTemplates.java b/querydsl-sql/src/main/java/com/querydsl/sql/SQLTemplates.java new file mode 100644 index 0000000000..8cc34b7a31 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/SQLTemplates.java @@ -0,0 +1,1213 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import java.lang.reflect.Field; +import java.sql.Types; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.EnumSet; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import com.querydsl.core.*; +import com.querydsl.core.QueryFlag.Position; +import com.querydsl.core.types.*; +import com.querydsl.sql.dml.SQLInsertBatch; +import com.querydsl.sql.types.Type; + +/** + * {@code SQLTemplates} extends {@link Templates} to provides SQL specific extensions + * and acts as database specific Dialect for Querydsl SQL + * + * @author tiwe + */ +public class SQLTemplates extends Templates { + + protected static final Expression FOR_SHARE = ExpressionUtils.operation( + Object.class, SQLOps.FOR_SHARE, Collections.emptyList()); + protected static final Expression FOR_UPDATE = ExpressionUtils.operation( + Object.class, SQLOps.FOR_UPDATE, Collections.emptyList()); + protected static final Expression NO_WAIT = ExpressionUtils.operation( + Object.class, SQLOps.NO_WAIT, Collections.emptyList()); + + protected static final int TIME_WITH_TIMEZONE = 2013; + + protected static final int TIMESTAMP_WITH_TIMEZONE = 2014; + + public static final Expression RECURSIVE = ExpressionUtils.template(Object.class, ""); + + @SuppressWarnings("FieldNameHidesFieldInSuperclass") //Intentional + public static final SQLTemplates DEFAULT = new SQLTemplates("\"",'\\',false); + + protected static final Set OTHER_LIKE_CASES + = Collections.unmodifiableSet(EnumSet.of(Ops.ENDS_WITH, Ops.ENDS_WITH_IC, + Ops.LIKE_IC, Ops.LIKE_ESCAPE_IC, + Ops.STARTS_WITH, Ops.STARTS_WITH_IC, + Ops.STRING_CONTAINS, Ops.STRING_CONTAINS_IC)); + + private final Set reservedWords; + + /** + * Fluent builder for {@code SQLTemplates} instances * + */ + public abstract static class Builder { + + protected boolean printSchema, quote, newLineToSingleSpace; + + protected char escape = '\\'; + + public Builder printSchema() { + printSchema = true; + return this; + } + + public Builder quote() { + quote = true; + return this; + } + + public Builder newLineToSingleSpace() { + newLineToSingleSpace = true; + return this; + } + + public Builder escape(char ch) { + escape = ch; + return this; + } + + protected abstract SQLTemplates build(char escape, boolean quote); + + public SQLTemplates build() { + SQLTemplates templates = build(escape, quote); + if (newLineToSingleSpace) { + templates.newLineToSingleSpace(); + } + templates.setPrintSchema(printSchema); + return templates; + } + + } + + private final Map typeNameToCode = new HashMap<>(); + + private final Map codeToTypeName = new HashMap<>(); + + private final Map tableOverrides = new HashMap<>(); + + private final List> customTypes = new ArrayList<>(); + + private final String quoteStr; + + private final boolean useQuotes; + + private final boolean requiresSchemaInWhere; + + private boolean printSchema; + + private String createTable = "create table "; + + private String asc = " asc"; + + private String autoIncrement = " auto_increment"; + + private String columnAlias = " "; + + private String count = "count "; + + private String countStar = "count(*)"; + + private String crossJoin = ", "; + + private String delete = "delete "; + + private String desc = " desc"; + + private String distinctCountEnd = ")"; + + private String distinctCountStart = "count(distinct "; + + private String dummyTable = "dual"; + + private String from = "\nfrom "; + + private String fullJoin = "\nfull join "; + + private String groupBy = "\ngroup by "; + + private String having = "\nhaving "; + + private String innerJoin = "\ninner join "; + + private String insertInto = "insert into "; + + private String join = "\njoin "; + + private String key = "key"; + + private String leftJoin = "\nleft join "; + + private String rightJoin = "\nright join "; + + private String limitTemplate = "\nlimit {0}"; + + private String mergeInto = "merge into "; + + private boolean nativeMerge; + + private String notNull = " not null"; + + private String offsetTemplate = "\noffset {0}"; + + private String on = "\non "; + + private String orderBy = "\norder by "; + + private String select = "select "; + + private String selectDistinct = "select distinct "; + + private String set = "set "; + + private String tableAlias = " "; + + private String update = "update "; + + private String values = "\nvalues "; + + private String defaultValues = "\nvalues ()"; + + private String where = "\nwhere "; + + private String with = "with "; + + private String withRecursive = "with recursive "; + + private String createIndex = "create index "; + + private String createUniqueIndex = "create unique index "; + + private String nullsFirst = " nulls first"; + + private String nullsLast = " nulls last"; + + private boolean parameterMetadataAvailable = true; + + private boolean batchCountViaGetUpdateCount = false; + + private boolean unionsWrapped = true; + + private boolean functionJoinsWrapped = false; + + private boolean limitRequired = false; + + private boolean countDistinctMultipleColumns = false; + + private boolean countViaAnalytics = false; + + private boolean wrapSelectParameters = false; + + private boolean arraysSupported = true; + + private boolean forShareSupported = false; + + private boolean batchToBulkSupported = true; + + private int listMaxSize = 0; + + private boolean supportsUnquotedReservedWordsAsIdentifier = false; + + private int maxLimit = Integer.MAX_VALUE; + + private QueryFlag forShareFlag = new QueryFlag(Position.END, FOR_SHARE); + + private QueryFlag forUpdateFlag = new QueryFlag(Position.END, FOR_UPDATE); + + private QueryFlag noWaitFlag = new QueryFlag(Position.END, NO_WAIT); + + @Deprecated + protected SQLTemplates(String quoteStr, char escape, boolean useQuotes) { + this(Keywords.DEFAULT, quoteStr, escape, useQuotes, false); + } + + protected SQLTemplates(Set reservedKeywords, String quoteStr, char escape, boolean useQuotes) { + this(reservedKeywords, quoteStr, escape, useQuotes, false); + } + + protected SQLTemplates(Set reservedKeywords, String quoteStr, char escape, boolean useQuotes, boolean requiresSchemaInWhere) { + super(escape); + this.reservedWords = reservedKeywords; + this.quoteStr = quoteStr; + this.useQuotes = useQuotes; + this.requiresSchemaInWhere = requiresSchemaInWhere; + + add(SQLOps.ALL, "{0}.*"); + + // flags + add(SQLOps.WITH_ALIAS, "{0} as {1}", 0); + add(SQLOps.WITH_COLUMNS, "{0} {1}", 0); + add(SQLOps.FOR_UPDATE, "\nfor update"); + add(SQLOps.FOR_SHARE, "\nfor share"); + add(SQLOps.NO_WAIT, " nowait"); + add(SQLOps.QUALIFY, "\nqualify {0}"); + + // boolean + add(Ops.AND, "{0} and {1}"); + add(Ops.NOT, "not {0}", Precedence.NOT); + add(Ops.OR, "{0} or {1}"); + + // math + add(Ops.MathOps.RANDOM, "rand()"); + add(Ops.MathOps.RANDOM2, "rand({0})"); + add(Ops.MathOps.CEIL, "ceiling({0})"); + add(Ops.MathOps.POWER, "power({0},{1})"); + add(Ops.MOD, "mod({0},{1})", Precedence.HIGHEST); + + // date time + add(Ops.DateTimeOps.CURRENT_DATE, "current_date"); + add(Ops.DateTimeOps.CURRENT_TIME, "current_time"); + add(Ops.DateTimeOps.CURRENT_TIMESTAMP, "current_timestamp"); + + add(Ops.DateTimeOps.MILLISECOND, "0"); + add(Ops.DateTimeOps.SECOND, "extract(second from {0})"); + add(Ops.DateTimeOps.MINUTE, "extract(minute from {0})"); + add(Ops.DateTimeOps.HOUR, "extract(hour from {0})"); + add(Ops.DateTimeOps.WEEK, "extract(week from {0})"); + add(Ops.DateTimeOps.MONTH, "extract(month from {0})"); + add(Ops.DateTimeOps.YEAR, "extract(year from {0})"); + add(Ops.DateTimeOps.YEAR_MONTH, "extract(year from {0}) * 100 + extract(month from {0})", Precedence.ARITH_LOW); + add(Ops.DateTimeOps.YEAR_WEEK, "extract(year from {0}) * 100 + extract(week from {0})", Precedence.ARITH_LOW); + add(Ops.DateTimeOps.DAY_OF_WEEK, "extract(day_of_week from {0})"); + add(Ops.DateTimeOps.DAY_OF_MONTH, "extract(day from {0})"); + add(Ops.DateTimeOps.DAY_OF_YEAR, "extract(day_of_year from {0})"); + + add(Ops.DateTimeOps.ADD_YEARS, "dateadd('year',{1},{0})"); + add(Ops.DateTimeOps.ADD_MONTHS, "dateadd('month',{1},{0})"); + add(Ops.DateTimeOps.ADD_WEEKS, "dateadd('week',{1},{0})"); + add(Ops.DateTimeOps.ADD_DAYS, "dateadd('day',{1},{0})"); + add(Ops.DateTimeOps.ADD_HOURS, "dateadd('hour',{1},{0})"); + add(Ops.DateTimeOps.ADD_MINUTES, "dateadd('minute',{1},{0})"); + add(Ops.DateTimeOps.ADD_SECONDS, "dateadd('second',{1},{0})"); + + add(Ops.DateTimeOps.DIFF_YEARS, "datediff('year',{0},{1})"); + add(Ops.DateTimeOps.DIFF_MONTHS, "datediff('month',{0},{1})"); + add(Ops.DateTimeOps.DIFF_WEEKS, "datediff('week',{0},{1})"); + add(Ops.DateTimeOps.DIFF_DAYS, "datediff('day',{0},{1})"); + add(Ops.DateTimeOps.DIFF_HOURS, "datediff('hour',{0},{1})"); + add(Ops.DateTimeOps.DIFF_MINUTES, "datediff('minute',{0},{1})"); + add(Ops.DateTimeOps.DIFF_SECONDS, "datediff('second',{0},{1})"); + + add(Ops.DateTimeOps.TRUNC_YEAR, "date_trunc('year',{0})"); + add(Ops.DateTimeOps.TRUNC_MONTH, "date_trunc('month',{0})"); + add(Ops.DateTimeOps.TRUNC_WEEK, "date_trunc('week',{0})"); + add(Ops.DateTimeOps.TRUNC_DAY, "date_trunc('day',{0})"); + add(Ops.DateTimeOps.TRUNC_HOUR, "date_trunc('hour',{0})"); + add(Ops.DateTimeOps.TRUNC_MINUTE, "date_trunc('minute',{0})"); + add(Ops.DateTimeOps.TRUNC_SECOND, "date_trunc('second',{0})"); + + // string + add(Ops.CONCAT, "{0} || {1}", Precedence.ARITH_LOW); + add(Ops.MATCHES, "{0} regexp {1}", Precedence.COMPARISON); + add(Ops.CHAR_AT, "cast(substr({0},{1+'1's},1) as char)"); + add(Ops.EQ_IGNORE_CASE, "{0l} = {1l}"); + add(Ops.INDEX_OF, "locate({1},{0})-1", Precedence.ARITH_LOW); + add(Ops.INDEX_OF_2ARGS, "locate({1},{0},{2+'1's})-1", Precedence.ARITH_LOW); + add(Ops.STRING_IS_EMPTY, "length({0}) = 0"); + add(Ops.SUBSTR_1ARG, "substr({0},{1s}+1)", Precedence.ARITH_LOW); + add(Ops.SUBSTR_2ARGS, "substr({0},{1+'1's},{2-1s})", Precedence.ARITH_LOW); + add(Ops.StringOps.LOCATE, "locate({0},{1})"); + add(Ops.StringOps.LOCATE2, "locate({0},{1},{2})"); + + // like with escape + add(Ops.LIKE, "{0} like {1} escape '" + escape + "'", Precedence.COMPARISON); + add(Ops.ENDS_WITH, "{0} like {%1} escape '" + escape + "'", Precedence.COMPARISON); + add(Ops.ENDS_WITH_IC, "{0l} like {%%1} escape '" + escape + "'", Precedence.COMPARISON); + add(Ops.STARTS_WITH, "{0} like {1%} escape '" + escape + "'", Precedence.COMPARISON); + add(Ops.STARTS_WITH_IC, "{0l} like {1%%} escape '" + escape + "'", Precedence.COMPARISON); + add(Ops.STRING_CONTAINS, "{0} like {%1%} escape '" + escape + "'", Precedence.COMPARISON); + add(Ops.STRING_CONTAINS_IC, "{0l} like {%%1%%} escape '" + escape + "'", Precedence.COMPARISON); + + add(SQLOps.CAST, "cast({0} as {1s})"); + add(SQLOps.UNION, "{0}\nunion\n{1}", Precedence.OR + 1); + add(SQLOps.UNION_ALL, "{0}\nunion all\n{1}", Precedence.OR + 1); + add(SQLOps.NEXTVAL, "nextval('{0s}')"); + + // analytic functions + add(SQLOps.CORR, "corr({0},{1})"); + add(SQLOps.COVARPOP, "covar_pop({0},{1})"); + add(SQLOps.COVARSAMP, "covar_samp({0},{1})"); + add(SQLOps.CUMEDIST, "cume_dist()"); + add(SQLOps.CUMEDIST2, "cume_dist({0})"); + add(SQLOps.DENSERANK, "dense_rank()"); + add(SQLOps.DENSERANK2, "dense_rank({0})"); + add(SQLOps.FIRSTVALUE, "first_value({0})"); + add(SQLOps.LAG, "lag({0})"); + add(SQLOps.LASTVALUE, "last_value({0})"); + add(SQLOps.LEAD, "lead({0})"); + add(SQLOps.LISTAGG, "listagg({0},'{1s}')"); + add(SQLOps.NTHVALUE, "nth_value({0}, {1})"); + add(SQLOps.NTILE, "ntile({0})"); + add(SQLOps.PERCENTILECONT, "percentile_cont({0})"); + add(SQLOps.PERCENTILEDISC, "percentile_disc({0})"); + add(SQLOps.PERCENTRANK, "percent_rank()"); + add(SQLOps.PERCENTRANK2, "percent_rank({0})"); + add(SQLOps.RANK, "rank()"); + add(SQLOps.RANK2, "rank({0})"); + add(SQLOps.RATIOTOREPORT, "ratio_to_report({0})"); + add(SQLOps.REGR_SLOPE, "regr_slope({0}, {1})"); + add(SQLOps.REGR_INTERCEPT, "regr_intercept({0}, {1})"); + add(SQLOps.REGR_COUNT, "regr_count({0}, {1})"); + add(SQLOps.REGR_R2, "regr_r2({0}, {1})"); + add(SQLOps.REGR_AVGX, "regr_avgx({0}, {1})"); + add(SQLOps.REGR_AVGY, "regr_avgy({0}, {1})"); + add(SQLOps.REGR_SXX, "regr_sxx({0}, {1})"); + add(SQLOps.REGR_SYY, "regr_syy({0}, {1})"); + add(SQLOps.REGR_SXY, "regr_sxy({0}, {1})"); + add(SQLOps.ROWNUMBER, "row_number()"); + add(SQLOps.STDDEV, "stddev({0})"); + add(SQLOps.STDDEVPOP, "stddev_pop({0})"); + add(SQLOps.STDDEVSAMP, "stddev_samp({0})"); + add(SQLOps.STDDEV_DISTINCT, "stddev(distinct {0})"); + add(SQLOps.VARIANCE, "variance({0})"); + add(SQLOps.VARPOP, "var_pop({0})"); + add(SQLOps.VARSAMP, "var_samp({0})"); + + add(SQLOps.GROUP_CONCAT, "group_concat({0})"); + add(SQLOps.GROUP_CONCAT2, "group_concat({0} separator {1})"); + + add(Ops.AggOps.BOOLEAN_ANY, "some({0})"); + add(Ops.AggOps.BOOLEAN_ALL, "every({0})"); + + add(SQLOps.SET_LITERAL, "{0} = {1}"); + add(SQLOps.SET_PATH, "{0} = values({1})"); + + // default type names + addTypeNameToCode("null", Types.NULL); + addTypeNameToCode("char", Types.CHAR); + addTypeNameToCode("datalink", Types.DATALINK); + addTypeNameToCode("numeric", Types.NUMERIC); + addTypeNameToCode("decimal", Types.DECIMAL); + addTypeNameToCode("integer", Types.INTEGER); + addTypeNameToCode("smallint", Types.SMALLINT); + addTypeNameToCode("float", Types.FLOAT); + addTypeNameToCode("real", Types.REAL); + addTypeNameToCode("double", Types.DOUBLE); + addTypeNameToCode("varchar", Types.VARCHAR); + addTypeNameToCode("longnvarchar", Types.LONGNVARCHAR); + addTypeNameToCode("nchar", Types.NCHAR); + addTypeNameToCode("boolean", Types.BOOLEAN); + addTypeNameToCode("nvarchar", Types.NVARCHAR); + addTypeNameToCode("rowid", Types.ROWID); + addTypeNameToCode("timestamp", Types.TIMESTAMP); + addTypeNameToCode("timestamp", TIMESTAMP_WITH_TIMEZONE); + addTypeNameToCode("bit", Types.BIT); + addTypeNameToCode("time", Types.TIME); + addTypeNameToCode("time", TIME_WITH_TIMEZONE); + addTypeNameToCode("tinyint", Types.TINYINT); + addTypeNameToCode("other", Types.OTHER); + addTypeNameToCode("bigint", Types.BIGINT); + addTypeNameToCode("longvarbinary", Types.LONGVARBINARY); + addTypeNameToCode("varbinary", Types.VARBINARY); + addTypeNameToCode("date", Types.DATE); + addTypeNameToCode("binary", Types.BINARY); + addTypeNameToCode("longvarchar", Types.LONGVARCHAR); + addTypeNameToCode("struct", Types.STRUCT); + addTypeNameToCode("array", Types.ARRAY); + addTypeNameToCode("java_object", Types.JAVA_OBJECT); + addTypeNameToCode("distinct", Types.DISTINCT); + addTypeNameToCode("ref", Types.REF); + addTypeNameToCode("blob", Types.BLOB); + addTypeNameToCode("clob", Types.CLOB); + addTypeNameToCode("nclob", Types.NCLOB); + addTypeNameToCode("sqlxml", Types.SQLXML); + } + + public String serialize(String literal, int jdbcType) { + switch (jdbcType) { + case Types.TIMESTAMP: + case TIMESTAMP_WITH_TIMEZONE: + return "(timestamp '" + literal + "')"; + case Types.DATE: + return "(date '" + literal + "')"; + case Types.TIME: + case TIME_WITH_TIMEZONE: + return "(time '" + literal + "')"; + case Types.CHAR: + case Types.CLOB: + case Types.LONGNVARCHAR: + case Types.LONGVARCHAR: + case Types.NCHAR: + case Types.NCLOB: + case Types.NVARCHAR: + case Types.VARCHAR: + return "'" + escapeLiteral(literal) + "'"; + case Types.BIGINT: + case Types.BIT: + case Types.BOOLEAN: + case Types.DECIMAL: + case Types.DOUBLE: + case Types.FLOAT: + case Types.INTEGER: + case Types.NULL: + case Types.NUMERIC: + case Types.SMALLINT: + case Types.TINYINT: + return literal; + default: + // for other JDBC types the Type instance is expected to provide + // the necessary quoting + return literal; + } + } + + public String escapeLiteral(String str) { + StringBuilder builder = new StringBuilder(); + for (char ch : str.toCharArray()) { + if (ch == '\'') { + builder.append("''"); + continue; + } + builder.append(ch); + } + return builder.toString(); + } + + protected void addTypeNameToCode(String type, int code, boolean override) { + if (!typeNameToCode.containsKey(type)) { + typeNameToCode.put(type, code); + } + if (override || !codeToTypeName.containsKey(code)) { + codeToTypeName.put(code, type); + } + } + + protected void addTypeNameToCode(String type, int code) { + addTypeNameToCode(type, code, false); + } + + protected void addTableOverride(SchemaAndTable from, SchemaAndTable to) { + tableOverrides.put(from, to); + } + + public final List> getCustomTypes() { + return customTypes; + } + + public final String getAsc() { + return asc; + } + + public final String getAutoIncrement() { + return autoIncrement; + } + + public final String getColumnAlias() { + return columnAlias; + } + + public final String getCount() { + return count; + } + + public final String getCountStar() { + return countStar; + } + + public final String getCrossJoin() { + return crossJoin; + } + + public final String getDelete() { + return delete; + } + + public final String getDesc() { + return desc; + } + + public final String getDistinctCountEnd() { + return distinctCountEnd; + } + + public final String getDistinctCountStart() { + return distinctCountStart; + } + + public final String getDummyTable() { + return dummyTable; + } + + public final String getFrom() { + return from; + } + + public final String getFullJoin() { + return fullJoin; + } + + public final String getGroupBy() { + return groupBy; + } + + public final String getHaving() { + return having; + } + + public final String getInnerJoin() { + return innerJoin; + } + + public final String getInsertInto() { + return insertInto; + } + + public final String getJoin() { + return join; + } + + public final String getJoinSymbol(JoinType joinType) { + switch (joinType) { + case JOIN: return join; + case INNERJOIN: return innerJoin; + case FULLJOIN: return fullJoin; + case LEFTJOIN: return leftJoin; + case RIGHTJOIN: return rightJoin; + default: return crossJoin; + } + } + + public final String getKey() { + return key; + } + + public final String getLeftJoin() { + return leftJoin; + } + + public final String getRightJoin() { + return rightJoin; + } + + public final String getLimitTemplate() { + return limitTemplate; + } + + public final String getMergeInto() { + return mergeInto; + } + + public final String getNotNull() { + return notNull; + } + + public final String getOffsetTemplate() { + return offsetTemplate; + } + + public final String getOn() { + return on; + } + + public final String getOrderBy() { + return orderBy; + } + + public final String getSelect() { + return select; + } + + public final String getSelectDistinct() { + return selectDistinct; + } + + public final String getSet() { + return set; + } + + public final String getTableAlias() { + return tableAlias; + } + + public final Map getTableOverrides() { + return tableOverrides; + } + + public String getTypeNameForCode(int code) { + return codeToTypeName.get(code); + } + + public String getCastTypeNameForCode(int code) { + return getTypeNameForCode(code); + } + + public Integer getCodeForTypeName(String type) { + return typeNameToCode.get(type); + } + + public final String getUpdate() { + return update; + } + + public final String getValues() { + return values; + } + + public final String getDefaultValues() { + return defaultValues; + } + + public final String getWhere() { + return where; + } + + public final boolean isNativeMerge() { + return nativeMerge; + } + + public final boolean isSupportsAlias() { + return true; + } + + public final String getCreateIndex() { + return createIndex; + } + + public final String getCreateUniqueIndex() { + return createUniqueIndex; + } + + public final String getCreateTable() { + return createTable; + } + + public final String getWith() { + return with; + } + + public final String getWithRecursive() { + return withRecursive; + } + + public final boolean isCountDistinctMultipleColumns() { + return countDistinctMultipleColumns; + } + + public final boolean isRequiresSchemaInWhere() { + return requiresSchemaInWhere; + } + + public final boolean isPrintSchema() { + return printSchema; + } + + public final boolean isParameterMetadataAvailable() { + return parameterMetadataAvailable; + } + + public final boolean isBatchCountViaGetUpdateCount() { + return batchCountViaGetUpdateCount; + } + + public final boolean isUseQuotes() { + return useQuotes; + } + + public final boolean isUnionsWrapped() { + return unionsWrapped; + } + + public boolean isForShareSupported() { + return forShareSupported; + } + + public final boolean isFunctionJoinsWrapped() { + return functionJoinsWrapped; + } + + public final boolean isLimitRequired() { + return limitRequired; + } + + public final String getNullsFirst() { + return nullsFirst; + } + + public final String getNullsLast() { + return nullsLast; + } + + public final boolean isCountViaAnalytics() { + return countViaAnalytics; + } + + public final boolean isWrapSelectParameters() { + return wrapSelectParameters; + } + + public final boolean isArraysSupported() { + return arraysSupported; + } + + public final int getListMaxSize() { + return listMaxSize; + } + + public final boolean isSupportsUnquotedReservedWordsAsIdentifier() { + return supportsUnquotedReservedWordsAsIdentifier; + } + + public final boolean isBatchToBulkSupported() { + return batchToBulkSupported; + } + + public final QueryFlag getForShareFlag() { + return forShareFlag; + } + + public final QueryFlag getForUpdateFlag() { + return forUpdateFlag; + } + + public final QueryFlag getNoWaitFlag() { + return noWaitFlag; + } + + protected void newLineToSingleSpace() { + for (Class cl : Arrays.>asList(getClass(), SQLTemplates.class)) { + for (Field field : cl.getDeclaredFields()) { + try { + if (field.getType().equals(String.class)) { + field.setAccessible(true); + Object val = field.get(this); + if (val != null) { + field.set(this, val.toString().replace('\n',' ')); + } + + } + } catch (IllegalAccessException e) { + throw new QueryException(e.getMessage(), e); + } + } + } + } + + public final String quoteIdentifier(String identifier) { + return quoteIdentifier(identifier, false); + } + + public final String quoteIdentifier(String identifier, boolean precededByDot) { + if (useQuotes || requiresQuotes(identifier, precededByDot)) { + return quoteStr + identifier + quoteStr; + } else { + return identifier; + } + } + + protected boolean requiresQuotes(final String identifier, final boolean precededByDot) { + if (identifier.matches(".*[^A-z0-9_].*")) { + return true; + } else if (identifier.matches("^[^A-z_].*")) { + return true; + } else if (precededByDot && supportsUnquotedReservedWordsAsIdentifier) { + return false; + } else { + return isReservedWord(identifier); + } + } + + private boolean isReservedWord(String identifier) { + return reservedWords.contains(identifier.toUpperCase()); + } + + /** + * template method for SELECT serialization + * + * @param metadata + * @param forCountRow + * @param context + */ + public void serialize(QueryMetadata metadata, boolean forCountRow, SQLSerializer context) { + context.serializeForQuery(metadata, forCountRow); + + if (!metadata.getFlags().isEmpty()) { + context.serialize(Position.END, metadata.getFlags()); + } + } + + /** + * template method for DELETE serialization + * + * @param metadata + * @param entity + * @param context + */ + public void serializeDelete(QueryMetadata metadata, RelationalPath entity, SQLSerializer context) { + context.serializeForDelete(metadata, entity); + + // limit + if (metadata.getModifiers().isRestricting()) { + serializeModifiers(metadata, context); + } + + if (!metadata.getFlags().isEmpty()) { + context.serialize(Position.END, metadata.getFlags()); + } + } + + /** + * template method for INSERT serialization + * + * @param metadata + * @param entity + * @param columns + * @param values + * @param subQuery + * @param context + */ + public void serializeInsert(QueryMetadata metadata, RelationalPath entity, + List> columns, List> values, SubQueryExpression subQuery, + SQLSerializer context) { + context.serializeForInsert(metadata, entity, columns, values, subQuery); + + if (!metadata.getFlags().isEmpty()) { + context.serialize(Position.END, metadata.getFlags()); + } + } + + /** + * template method for INSERT serialization + * + * @param metadata + * @param batches + * @param context + */ + public void serializeInsert(QueryMetadata metadata, RelationalPath entity, + List batches, SQLSerializer context) { + context.serializeForInsert(metadata, entity, batches); + + if (!metadata.getFlags().isEmpty()) { + context.serialize(Position.END, metadata.getFlags()); + } + } + + /** + * template method for MERGE serialization + * + * @param metadata + * @param entity + * @param keys + * @param columns + * @param values + * @param subQuery + * @param context + */ + public void serializeMerge(QueryMetadata metadata, RelationalPath entity, + List> keys, List> columns, List> values, + SubQueryExpression subQuery, SQLSerializer context) { + context.serializeForMerge(metadata, entity, keys, columns, values, subQuery); + + if (!metadata.getFlags().isEmpty()) { + context.serialize(Position.END, metadata.getFlags()); + } + } + + /** + * template method for UPDATE serialization + * + * @param metadata + * @param entity + * @param updates + * @param context + */ + public void serializeUpdate(QueryMetadata metadata, RelationalPath entity, + Map, Expression> updates, SQLSerializer context) { + context.serializeForUpdate(metadata, entity, updates); + + // limit + if (metadata.getModifiers().isRestricting()) { + serializeModifiers(metadata, context); + } + + if (!metadata.getFlags().isEmpty()) { + context.serialize(Position.END, metadata.getFlags()); + } + } + + /** + * template method for LIMIT and OFFSET serialization + * + * @param metadata + * @param context + */ + protected void serializeModifiers(QueryMetadata metadata, SQLSerializer context) { + QueryModifiers mod = metadata.getModifiers(); + if (mod.getLimit() != null) { + context.handle(limitTemplate, mod.getLimit()); + } else if (limitRequired) { + context.handle(limitTemplate, maxLimit); + } + if (mod.getOffset() != null) { + context.handle(offsetTemplate, mod.getOffset()); + } + } + + protected void addCustomType(Type type) { + customTypes.add(type); + } + + protected void setAsc(String asc) { + this.asc = asc; + } + + protected void setAutoIncrement(String autoIncrement) { + this.autoIncrement = autoIncrement; + } + + protected void setColumnAlias(String columnAlias) { + this.columnAlias = columnAlias; + } + + protected void setCount(String count) { + this.count = count; + } + + protected void setCountStar(String countStar) { + this.countStar = countStar; + } + + protected void setCrossJoin(String crossJoin) { + this.crossJoin = crossJoin; + } + + protected void setDelete(String delete) { + this.delete = delete; + } + + protected void setDesc(String desc) { + this.desc = desc; + } + + protected void setDistinctCountEnd(String distinctCountEnd) { + this.distinctCountEnd = distinctCountEnd; + } + + protected void setDistinctCountStart(String distinctCountStart) { + this.distinctCountStart = distinctCountStart; + } + + protected void setDummyTable(String dummyTable) { + this.dummyTable = dummyTable; + } + + protected void setForShareSupported(boolean forShareSupported) { + this.forShareSupported = forShareSupported; + } + + protected void setFrom(String from) { + this.from = from; + } + + protected void setFullJoin(String fullJoin) { + this.fullJoin = fullJoin; + } + + protected void setGroupBy(String groupBy) { + this.groupBy = groupBy; + } + + protected void setHaving(String having) { + this.having = having; + } + + protected void setInnerJoin(String innerJoin) { + this.innerJoin = innerJoin; + } + + protected void setInsertInto(String insertInto) { + this.insertInto = insertInto; + } + + protected void setJoin(String join) { + this.join = join; + } + + protected void setKey(String key) { + this.key = key; + } + + protected void setLeftJoin(String leftJoin) { + this.leftJoin = leftJoin; + } + + protected void setRightJoin(String rightJoin) { + this.rightJoin = rightJoin; + } + + protected void setMergeInto(String mergeInto) { + this.mergeInto = mergeInto; + } + + protected void setNativeMerge(boolean nativeMerge) { + this.nativeMerge = nativeMerge; + } + + protected void setNotNull(String notNull) { + this.notNull = notNull; + } + + protected void setOffsetTemplate(String offsetTemplate) { + this.offsetTemplate = offsetTemplate; + } + + protected void setOn(String on) { + this.on = on; + } + + protected void setOrderBy(String orderBy) { + this.orderBy = orderBy; + } + + protected void setSelect(String select) { + this.select = select; + } + + protected void setSelectDistinct(String selectDistinct) { + this.selectDistinct = selectDistinct; + } + + protected void setSet(String set) { + this.set = set; + } + + protected void setTableAlias(String tableAlias) { + this.tableAlias = tableAlias; + } + + protected void setUpdate(String update) { + this.update = update; + } + + protected void setValues(String values) { + this.values = values; + } + + protected void setDefaultValues(String defaultValues) { + this.defaultValues = defaultValues; + } + + protected void setWhere(String where) { + this.where = where; + } + + protected void setWith(String with) { + this.with = with; + } + + protected void setWithRecursive(String withRecursive) { + this.withRecursive = withRecursive; + } + + protected void setCreateIndex(String createIndex) { + this.createIndex = createIndex; + } + + protected void setCreateUniqueIndex(String createUniqueIndex) { + this.createUniqueIndex = createUniqueIndex; + } + + protected void setCreateTable(String createTable) { + this.createTable = createTable; + } + + protected void setPrintSchema(boolean printSchema) { + this.printSchema = printSchema; + } + + protected void setParameterMetadataAvailable(boolean parameterMetadataAvailable) { + this.parameterMetadataAvailable = parameterMetadataAvailable; + } + + protected void setBatchCountViaGetUpdateCount(boolean batchCountViaGetUpdateCount) { + this.batchCountViaGetUpdateCount = batchCountViaGetUpdateCount; + } + + protected void setUnionsWrapped(boolean unionsWrapped) { + this.unionsWrapped = unionsWrapped; + } + + protected void setFunctionJoinsWrapped(boolean functionJoinsWrapped) { + this.functionJoinsWrapped = functionJoinsWrapped; + } + + protected void setNullsFirst(String nullsFirst) { + this.nullsFirst = nullsFirst; + } + + protected void setNullsLast(String nullsLast) { + this.nullsLast = nullsLast; + } + + protected void setLimitRequired(boolean limitRequired) { + this.limitRequired = limitRequired; + } + + protected void setCountDistinctMultipleColumns(boolean countDistinctMultipleColumns) { + this.countDistinctMultipleColumns = countDistinctMultipleColumns; + } + + protected void setCountViaAnalytics(boolean countViaAnalytics) { + this.countViaAnalytics = countViaAnalytics; + } + + protected void setWrapSelectParameters(boolean b) { + this.wrapSelectParameters = b; + } + + protected void setArraysSupported(boolean b) { + this.arraysSupported = b; + } + + protected void setListMaxSize(int i) { + listMaxSize = i; + } + + protected void setSupportsUnquotedReservedWordsAsIdentifier(boolean b) { + this.supportsUnquotedReservedWordsAsIdentifier = b; + } + + protected void setMaxLimit(int i) { + this.maxLimit = i; + } + + protected void setBatchToBulkSupported(boolean b) { + this.batchToBulkSupported = b; + } + + protected void setForShareFlag(QueryFlag flag) { + forShareFlag = flag; + } + + protected void setForUpdateFlag(QueryFlag flag) { + forUpdateFlag = flag; + } + + protected void setNoWaitFlag(QueryFlag flag) { + noWaitFlag = flag; + } + +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/SQLTemplatesRegistry.java b/querydsl-sql/src/main/java/com/querydsl/sql/SQLTemplatesRegistry.java new file mode 100644 index 0000000000..f9f3c8cf2c --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/SQLTemplatesRegistry.java @@ -0,0 +1,95 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import java.sql.DatabaseMetaData; +import java.sql.SQLException; + +/** + * {@code SQLTemplatesRegistry} is a registry for SQLTemplates instances + */ +public class SQLTemplatesRegistry { + + /** + * Get the SQLTemplates instance that matches best the SQL engine of the + * given database metadata + * + * @param md database metadata + * @return templates + * @throws SQLException + */ + public SQLTemplates getTemplates(DatabaseMetaData md) throws SQLException { + return getBuilder(md).build(); + } + + /** + * Get a SQLTemplates.Builder instance that matches best the SQL engine of the + * given database metadata + * + * @param md database metadata + * @return templates + * @throws SQLException + */ + public SQLTemplates.Builder getBuilder(DatabaseMetaData md) throws SQLException { + String name = md.getDatabaseProductName().toLowerCase(); + if (name.equals("cubrid")) { + return CUBRIDTemplates.builder(); + } else if (name.equals("apache derby")) { + return DerbyTemplates.builder(); + } else if (name.startsWith("firebird")) { + return FirebirdTemplates.builder(); + } else if (name.equals("h2")) { + return H2Templates.builder(); + } else if (name.equals("hsql")) { + return HSQLDBTemplates.builder(); + } else if (name.equals("mysql")) { + return MySQLTemplates.builder(); + } else if (name.equals("oracle")) { + return OracleTemplates.builder(); + } else if (name.equals("postgresql")) { + return PostgreSQLTemplates.builder(); + } else if (name.equals("sqlite")) { + return SQLiteTemplates.builder(); + } else if (name.startsWith("teradata")) { + return TeradataTemplates.builder(); + } else if (name.equals("microsoft sql server")) { + return getMssqlSqlTemplates(md); + } else { + return new SQLTemplates.Builder() { + @Override + protected SQLTemplates build(char escape, boolean quote) { + return new SQLTemplates(Keywords.DEFAULT, "\"", escape, quote, false); + } + }; + } + } + + private SQLTemplates.Builder getMssqlSqlTemplates(DatabaseMetaData md) throws SQLException { + int databaseMajorVersion = md.getDatabaseMajorVersion(); + + if (databaseMajorVersion < 9) { + return SQLServerTemplates.builder(); + } + + if (databaseMajorVersion == 9) { + return SQLServer2005Templates.builder(); + } + + if (databaseMajorVersion == 10) { + return SQLServer2008Templates.builder(); + } + + return SQLServer2012Templates.builder(); + } +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/SQLiteTemplates.java b/querydsl-sql/src/main/java/com/querydsl/sql/SQLiteTemplates.java new file mode 100644 index 0000000000..6b9d0eb1b0 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/SQLiteTemplates.java @@ -0,0 +1,144 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import com.querydsl.core.types.Ops; +import com.querydsl.sql.types.BigDecimalAsDoubleType; +import com.querydsl.sql.types.BigIntegerAsLongType; + +import java.sql.Types; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.ZoneOffset; +import java.time.format.DateTimeFormatter; +import java.time.temporal.ChronoField; + +/** + * {@code SQLiteTemplates} is a SQL dialect for SQLite + * + * @author tiwe + * + */ +public class SQLiteTemplates extends SQLTemplates { + + private static final DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + + private static final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + + private static final DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm:ss"); + + @SuppressWarnings("FieldNameHidesFieldInSuperclass") //Intentional + public static final SQLiteTemplates DEFAULT = new SQLiteTemplates(); + + public static Builder builder() { + return new Builder() { + @Override + protected SQLTemplates build(char escape, boolean quote) { + return new SQLiteTemplates(escape, quote); + } + }; + } + + public SQLiteTemplates() { + this('\\', false); + } + + public SQLiteTemplates(boolean quote) { + this('\\', quote); + } + + public SQLiteTemplates(char escape, boolean quote) { + super(Keywords.SQLITE, "\"", escape, quote, false); + setDummyTable(null); + addCustomType(BigDecimalAsDoubleType.DEFAULT); + addCustomType(BigIntegerAsLongType.DEFAULT); + setUnionsWrapped(false); + setLimitRequired(true); + setNullsFirst(null); + setNullsLast(null); + setDefaultValues("\ndefault values"); + setArraysSupported(false); + setBatchToBulkSupported(false); + + setPrecedence(Precedence.COMPARISON - 1, Ops.LT, Ops.GT, Ops.LOE, Ops.GOE); + setPrecedence(Precedence.COMPARISON, Ops.EQ, Ops.EQ_IGNORE_CASE, Ops.NE); + + add(Ops.MOD, "{0} % {1}", Precedence.ARITH_HIGH); + + add(Ops.INDEX_OF, "charindex({1},{0},1)-1", Precedence.ARITH_LOW); + add(Ops.INDEX_OF_2ARGS, "charindex({1},{0},{2s}+1)-1", Precedence.ARITH_LOW); + + add(Ops.StringOps.LOCATE, "charindex({0},{1})"); + add(Ops.StringOps.LOCATE2, "charindex({0},{1},{2s})"); + + // TODO : optimize + add(Ops.DateTimeOps.YEAR, "cast(strftime('%Y',{0} / 1000, 'unixepoch', 'localtime') as integer)"); + add(Ops.DateTimeOps.MONTH, "cast(strftime('%m',{0} / 1000, 'unixepoch', 'localtime') as integer)"); + add(Ops.DateTimeOps.WEEK, "cast(strftime('%W',{0} / 1000, 'unixepoch', 'localtime') as integer) + 1"); + add(Ops.DateTimeOps.DAY_OF_MONTH, "cast(strftime('%d',{0} / 1000, 'unixepoch', 'localtime') as integer)"); + add(Ops.DateTimeOps.DAY_OF_WEEK, "cast(strftime('%w',{0} / 1000, 'unixepoch', 'localtime') as integer) + 1"); + add(Ops.DateTimeOps.DAY_OF_YEAR, "cast(strftime('%j',{0} / 1000, 'unixepoch', 'localtime') as integer)"); + add(Ops.DateTimeOps.HOUR, "cast(strftime('%H',{0} / 1000, 'unixepoch', 'localtime') as integer)"); + add(Ops.DateTimeOps.MINUTE, "cast(strftime('%M',{0} / 1000, 'unixepoch', 'localtime') as integer)"); + add(Ops.DateTimeOps.SECOND, "cast(strftime('%S',{0} / 1000, 'unixepoch', 'localtime') as integer)"); + + add(Ops.DateTimeOps.YEAR_MONTH, "cast(strftime('%Y',{0} / 1000, 'unixepoch', 'localtime') * 100 + strftime('%m',{0} / 1000, 'unixepoch', 'localtime') as integer)"); + add(Ops.DateTimeOps.YEAR_WEEK, "cast(strftime('%Y%W',{0} / 1000, 'unixepoch', 'localtime') as integer)"); + + add(Ops.DateTimeOps.ADD_YEARS, "date({0}, '+{1s} year')"); + add(Ops.DateTimeOps.ADD_MONTHS, "date({0}, '+{1s} month')"); + add(Ops.DateTimeOps.ADD_WEEKS, "date({0}, '+{1s} week')"); + add(Ops.DateTimeOps.ADD_DAYS, "date({0}, '+{1s} day')"); + add(Ops.DateTimeOps.ADD_HOURS, "date({0}, '+{1s} hour')"); + add(Ops.DateTimeOps.ADD_MINUTES, "date({0}, '+{1s} minute')"); + add(Ops.DateTimeOps.ADD_SECONDS, "date({0}, '+{1s} second')"); + + add(Ops.MathOps.RANDOM, "random()"); + add(Ops.MathOps.RANDOM2, "random({0})"); + add(Ops.MathOps.LN, "log({0})"); + add(Ops.MathOps.LOG, "log({0}) / log({1})", Precedence.ARITH_HIGH); + + add(SQLOps.GROUP_CONCAT2, "group_concat({0},{1})"); + + addTypeNameToCode("text", Types.VARCHAR); + } + + @Override + public String serialize(String literal, int jdbcType) { + // XXX doesn't work with LocalDate, LocalDateTime and LocalTime + switch (jdbcType) { + case Types.TIMESTAMP: + case TIMESTAMP_WITH_TIMEZONE: + return String.valueOf( + dateTimeFormatter.parse(literal, LocalDateTime::from) + .toInstant(ZoneOffset.UTC) + .toEpochMilli()); + case Types.DATE: + return String.valueOf( + dateFormatter.parse(literal, LocalDate::from) + .atStartOfDay(ZoneOffset.UTC) + .toInstant() + .toEpochMilli()); + case Types.TIME: + case TIME_WITH_TIMEZONE: + return String.valueOf( + timeFormatter.parse(literal, LocalTime::from) + .get(ChronoField.MILLI_OF_DAY)); + default: + return super.serialize(literal, jdbcType); + } + } + +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/SchemaAndTable.java b/querydsl-sql/src/main/java/com/querydsl/sql/SchemaAndTable.java new file mode 100644 index 0000000000..cd75ba2380 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/SchemaAndTable.java @@ -0,0 +1,60 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import java.io.Serializable; +import java.util.Objects; + +/** + * {@code SchemaAndTable} combines schema and table into a single value type + */ +public class SchemaAndTable implements Serializable { + + private final String schema, table; + + public SchemaAndTable(String schema, String table) { + this.schema = schema; + this.table = table; + } + + public String getSchema() { + return schema; + } + + public String getTable() { + return table; + } + + @Override + public boolean equals(Object o) { + if (o == this) { + return true; + } else if (o instanceof SchemaAndTable) { + SchemaAndTable st = (SchemaAndTable) o; + return Objects.equals(st.schema, schema) && Objects.equals(st.table, table); + } else { + return false; + } + } + + @Override + public int hashCode() { + return (schema != null ? 31 * schema.hashCode() : 0) + table.hashCode(); + } + + @Override + public String toString() { + return "(" + schema + " " + table + ")"; + } +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/StatementOptions.java b/querydsl-sql/src/main/java/com/querydsl/sql/StatementOptions.java new file mode 100644 index 0000000000..1d86fe4c50 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/StatementOptions.java @@ -0,0 +1,96 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ + +package com.querydsl.sql; + +import java.sql.Statement; + +import com.querydsl.core.annotations.Immutable; + +/** + * {@code StatementOptions} holds parameters that should be applied to {@link Statement}s. + */ +@Immutable +public class StatementOptions { + + public static final StatementOptions DEFAULT = new StatementOptions(null, null, null, null); + + private final Integer maxFieldSize; + private final Integer maxRows; + private final Integer queryTimeout; + private final Integer fetchSize; + + public StatementOptions(Integer maxFieldSize, Integer maxRows, Integer queryTimeout, Integer fetchSize) { + this.maxFieldSize = maxFieldSize; + this.maxRows = maxRows; + this.queryTimeout = queryTimeout; + this.fetchSize = fetchSize; + } + + public Integer getMaxFieldSize() { + return maxFieldSize; + } + + public Integer getMaxRows() { + return maxRows; + } + + public Integer getQueryTimeout() { + return queryTimeout; + } + + public Integer getFetchSize() { + return fetchSize; + } + + public static Builder builder() { + return new Builder(); + } + + /** + * Builder for {@link StatementOptions} + */ + public static final class Builder { + private Integer maxFieldSize; + private Integer maxRows; + private Integer queryTimeout; + private Integer fetchSize; + + private Builder() { } + + public Builder setMaxFieldSize(Integer maxFieldSize) { + this.maxFieldSize = maxFieldSize; + return this; + } + + public Builder setMaxRows(Integer maxRows) { + this.maxRows = maxRows; + return this; + } + + public Builder setQueryTimeout(Integer queryTimeout) { + this.queryTimeout = queryTimeout; + return this; + } + + public Builder setFetchSize(Integer fetchSize) { + this.fetchSize = fetchSize; + return this; + } + + public StatementOptions build() { + return new StatementOptions(maxFieldSize, maxRows, queryTimeout, fetchSize); + } + } +} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/TeradataTemplates.java b/querydsl-sql/src/main/java/com/querydsl/sql/TeradataTemplates.java similarity index 75% rename from querydsl-sql/src/main/java/com/mysema/query/sql/TeradataTemplates.java rename to querydsl-sql/src/main/java/com/querydsl/sql/TeradataTemplates.java index 17217e9fe1..bef91f5c0a 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/TeradataTemplates.java +++ b/querydsl-sql/src/main/java/com/querydsl/sql/TeradataTemplates.java @@ -1,5 +1,5 @@ /* - * Copyright 2013, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,21 +11,26 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql; +package com.querydsl.sql; -import com.mysema.query.QueryMetadata; -import com.mysema.query.QueryModifiers; -import com.mysema.query.types.Ops; +import java.sql.Types; + +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.QueryModifiers; +import com.querydsl.core.types.Ops; /** - * TeradataTemplates is a SQL dialect for Teradata + * {@code TeradataTemplates} is a SQL dialect for Teradata * * @author tiwe * */ public class TeradataTemplates extends SQLTemplates { + @SuppressWarnings("FieldNameHidesFieldInSuperclass") //Intentional + public static final TeradataTemplates DEFAULT = new TeradataTemplates(); + public static Builder builder() { return new Builder() { @Override @@ -58,17 +63,18 @@ public TeradataTemplates(char escape, boolean quote) { setDummyTable(null); setCountViaAnalytics(true); setDefaultValues("\ndefault values"); + setBatchToBulkSupported(false); - addClass2TypeMappings("byteint", Byte.class); - addClass2TypeMappings("double precision", Double.class); - addClass2TypeMappings("varchar(4000)", String.class); + setPrecedence(Precedence.ARITH_LOW + 1, Ops.CONCAT); + setPrecedence(Precedence.COMPARISON, Ops.EQ, Ops.EQ_IGNORE_CASE, Ops.NE); add(Ops.NE, "{0} <> {1}"); + add(Ops.MOD, "{0} % {1}", Precedence.ARITH_HIGH); // String add(Ops.STRING_LENGTH, "character_length({0})"); add(Ops.INDEX_OF, "(instr({0},{1})-1)"); - add(Ops.INDEX_OF_2ARGS, "(instr({0},{1},{2}+1)-1)"); + add(Ops.INDEX_OF_2ARGS, "(instr({0},{1},{2+'1'})-1)"); add(Ops.STRING_CAST, "cast({0} as varchar(255))"); add(Ops.StringOps.LOCATE, "instr({1},{0})"); add(Ops.StringOps.LOCATE2, "instr({1},{0},{2s})"); @@ -82,7 +88,7 @@ public TeradataTemplates(char escape, boolean quote) { add(Ops.MathOps.LOG, "(ln({0}) / ln({1}))"); add(Ops.MathOps.RANDOM, "cast(random(0, 1000000000) as numeric(20,10))/1000000000"); add(Ops.MathOps.COT, "(cos({0}) / sin({0}))"); - add(Ops.MathOps.COTH, "(exp({0} * 2) + 1) / (exp({0} * 2) - 1)"); + add(Ops.MathOps.COTH, "(exp({0*'2'}) + 1) / (exp({0*'2'}) - 1)"); // Date / time add(Ops.DateTimeOps.DATE, "cast({0} as date)"); @@ -103,10 +109,23 @@ public TeradataTemplates(char escape, boolean quote) { add(Ops.DateTimeOps.TRUNC_YEAR, "trunc({0}, 'year')"); add(Ops.DateTimeOps.TRUNC_MONTH, "trunc({0}, 'month')"); add(Ops.DateTimeOps.TRUNC_WEEK, "trunc({0}, 'w')"); - add(Ops.DateTimeOps.TRUNC_DAY, "trunc({0}, 'day')"); - add(Ops.DateTimeOps.TRUNC_HOUR, "trunc({0}, 'hh')"); + add(Ops.DateTimeOps.TRUNC_DAY, "trunc({0}, 'dd')"); + add(Ops.DateTimeOps.TRUNC_HOUR, "trunc({0}, 'hh24')"); add(Ops.DateTimeOps.TRUNC_MINUTE, "trunc({0}, 'mi')"); add(Ops.DateTimeOps.TRUNC_SECOND, "{0}"); // not truncated + + addTypeNameToCode("byteint", Types.BIT, true); + addTypeNameToCode("byteint", Types.BOOLEAN, true); + addTypeNameToCode("byteint", Types.TINYINT, true); + addTypeNameToCode("float", Types.DOUBLE, true); + } + + @Override + public String getCastTypeNameForCode(int code) { + switch (code) { + case Types.VARCHAR: return "varchar(4000)"; + default: return super.getCastTypeNameForCode(code); + } } @Override diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/Union.java b/querydsl-sql/src/main/java/com/querydsl/sql/Union.java new file mode 100644 index 0000000000..aaad3688c1 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/Union.java @@ -0,0 +1,86 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import java.util.List; + +import com.mysema.commons.lang.CloseableIterator; +import com.querydsl.core.Fetchable; +import com.querydsl.core.types.*; + +/** + * {@code Union} defines an interface for Union queries + * + * @author tiwe + * + * @param return type of projection + */ +public interface Union extends SubQueryExpression, Fetchable { + + /** + * Get the projection as a typed List + * + * @deprecated Use {@link Union#fetch()} + */ + @Deprecated + List list(); + + /** + * Get the projection as a typed Iterator + * + * @return result iterator + */ + CloseableIterator iterate(); + + /** + * Defines the grouping/aggregation expressions + * + * @param o group by + * @return the current object + */ + Union groupBy(Expression... o); + + /** + * Defines the filters for aggregation + * + * @param o having conditions + * @return the current object + */ + Union having(Predicate... o); + + + /** + * Define the ordering of the query results + * + * @param o order + * @return the current object + */ + Union orderBy(OrderSpecifier... o); + + /** + * Create an alias for the expression + * + * @param alias alias + * @return this as alias + */ + Expression as(String alias); + + /** + * Create an alias for the expression + * + * @param alias alias + * @return this as alias + */ + Expression as(Path alias); +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/UnionImpl.java b/querydsl-sql/src/main/java/com/querydsl/sql/UnionImpl.java new file mode 100644 index 0000000000..01bc68e0e9 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/UnionImpl.java @@ -0,0 +1,133 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import java.util.List; +import java.util.stream.Stream; + +import org.jetbrains.annotations.Nullable; + +import com.mysema.commons.lang.CloseableIterator; +import com.querydsl.core.NonUniqueResultException; +import com.querydsl.core.Query; +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.QueryResults; +import com.querydsl.core.types.*; + +/** + * Default implementation of the Union interface + * + * @param result type + * @param concrete query type + * + * @author tiwe + */ +public class UnionImpl & Query> implements Union { + + private final Q query; + + public UnionImpl(Q query) { + this.query = query; + } + + @Override + public List list() { + return query.fetch(); + } + + @Override + public List fetch() { + return query.fetch(); + } + + @Override + public T fetchFirst() { + return query.fetchFirst(); + } + + @Override + public T fetchOne() throws NonUniqueResultException { + return query.fetchOne(); + } + + @Override + public CloseableIterator iterate() { + return query.iterate(); + } + + @Override + public Stream stream() { + return query.stream(); + } + + @Override + public QueryResults fetchResults() { + return query.fetchResults(); + } + + @Override + public long fetchCount() { + return query.fetchCount(); + } + + @Override + public Union groupBy(Expression... o) { + query.groupBy(o); + return this; + } + + @Override + public Union having(Predicate... o) { + query.having(o); + return this; + } + + @Override + public Union orderBy(OrderSpecifier... o) { + query.orderBy(o); + return this; + } + + @Override + public Expression as(String alias) { + return ExpressionUtils.as(this, alias); + } + + @Override + public Expression as(Path alias) { + return ExpressionUtils.as(this, alias); + } + + @Override + public String toString() { + return query.toString(); + } + + @Nullable + @Override + public R accept(Visitor v, @Nullable C context) { + return query.accept(v, context); + } + + @Override + public Class getType() { + return query.getType(); + } + + @Override + public QueryMetadata getMetadata() { + return query.getMetadata(); + } + +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/UnionUtils.java b/querydsl-sql/src/main/java/com/querydsl/sql/UnionUtils.java new file mode 100644 index 0000000000..880ae41ca1 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/UnionUtils.java @@ -0,0 +1,45 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import java.util.List; + +import com.querydsl.core.types.*; + +/** + * UnionUtils provides static utility methods for Union handling + * + * @author tiwe + * + */ +final class UnionUtils { + + public static Expression union(List> union, boolean unionAll) { + final Operator operator = unionAll ? SQLOps.UNION_ALL : SQLOps.UNION; + Expression rv = union.get(0); + for (int i = 1; i < union.size(); i++) { + rv = ExpressionUtils.operation(rv.getType(), operator, rv, union.get(i)); + } + return rv; + } + + public static Expression union(List> union, Path alias, + boolean unionAll) { + final Expression rv = union(union, unionAll); + return ExpressionUtils.as(rv, alias); + } + + private UnionUtils() { } + +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/WindowFirstLast.java b/querydsl-sql/src/main/java/com/querydsl/sql/WindowFirstLast.java new file mode 100644 index 0000000000..f63fc7ad5c --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/WindowFirstLast.java @@ -0,0 +1,111 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.jetbrains.annotations.Nullable; + +import com.querydsl.core.types.*; +import com.querydsl.core.types.dsl.ComparableExpressionBase; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.SimpleExpression; +import com.querydsl.core.util.CollectionUtils; + +/** + * {@code WindowFirstLast} is a builder for window function expressions + * + * @author tiwe + * + * @param + */ +public class WindowFirstLast extends MutableExpressionBase { + + private static final long serialVersionUID = 4107262569593794721L; + + private static final String ORDER_BY = "order by "; + + private final List> orderBy = new ArrayList>(); + + @Nullable + private transient volatile SimpleExpression value; + + private final Expression target; + + private final boolean first; + + public WindowFirstLast(WindowOver target, boolean first) { + super(target.getType()); + this.target = target; + this.first = first; + } + + @Override + public R accept(Visitor v, C context) { + return getValue().accept(v, context); + } + + public WindowFirstLast orderBy(ComparableExpressionBase orderBy) { + value = null; + this.orderBy.add(orderBy.asc()); + return this; + } + + public WindowFirstLast orderBy(ComparableExpressionBase... orderBy) { + value = null; + for (ComparableExpressionBase e : orderBy) { + this.orderBy.add(e.asc()); + } + return this; + } + + public WindowFirstLast orderBy(OrderSpecifier orderBy) { + value = null; + this.orderBy.add(orderBy); + return this; + } + + public WindowFirstLast orderBy(OrderSpecifier... orderBy) { + value = null; + Collections.addAll(this.orderBy, orderBy); + return this; + } + + SimpleExpression getValue() { + if (value == null) { + if (orderBy.isEmpty()) { + // TODO this check should be static + throw new IllegalStateException("No order by arguments given"); + } + List> args = new ArrayList<>(); + StringBuilder builder = new StringBuilder(); + builder.append("{0} keep (dense_rank "); + args.add(target); + builder.append(first ? "first " : "last "); + builder.append(ORDER_BY); + builder.append("{1}"); + args.add(ExpressionUtils.orderBy(orderBy)); + builder.append(")"); + value = Expressions.template(target.getType(), builder.toString(), CollectionUtils.unmodifiableList(args)); + } + return value; + } + + public WindowFunction over() { + return new WindowFunction(getValue()); + } + +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/WindowFunction.java b/querydsl-sql/src/main/java/com/querydsl/sql/WindowFunction.java new file mode 100644 index 0000000000..b63f70c6a4 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/WindowFunction.java @@ -0,0 +1,202 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.jetbrains.annotations.Nullable; + +import com.querydsl.core.types.*; +import com.querydsl.core.types.dsl.BooleanExpression; +import com.querydsl.core.types.dsl.ComparableExpressionBase; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.SimpleExpression; + +/** + * {@code WindowFunction} is a builder for window function expressions + * + * @param expression type + * + * @author tiwe + */ +public class WindowFunction extends MutableExpressionBase { + + private static final String ORDER_BY = "order by "; + + private static final String PARTITION_BY = "partition by "; + + private static final long serialVersionUID = -4130672293308756779L; + + private final List> orderBy = new ArrayList>(); + + private final List> partitionBy = new ArrayList>(); + + private final Expression target; + + @Nullable + private transient volatile SimpleExpression value; + + private String rowsOrRange; + + private List> rowsOrRangeArgs; + + public WindowFunction(Expression expr) { + super(expr.getType()); + this.target = expr; + } + + public SimpleExpression getValue() { + if (value == null) { + int size = 0; + List> args = new ArrayList<>(); + StringBuilder builder = new StringBuilder(); + builder.append("{0} over ("); + args.add(target); + size++; + if (!partitionBy.isEmpty()) { + builder.append(PARTITION_BY); + boolean first = true; + for (Expression expr : partitionBy) { + if (!first) { + builder.append(", "); + } + builder.append("{").append(size).append("}"); + args.add(expr); + size++; + first = false; + } + + } + if (!orderBy.isEmpty()) { + if (!partitionBy.isEmpty()) { + builder.append(" "); + } + builder.append(ORDER_BY); + builder.append("{").append(size).append("}"); + args.add(ExpressionUtils.orderBy(orderBy)); + size++; + } + if (rowsOrRange != null) { + builder.append(rowsOrRange); + args.addAll(rowsOrRangeArgs); + size += rowsOrRangeArgs.size(); + } + builder.append(")"); + value = Expressions.template(target.getType(), builder.toString(), Collections.unmodifiableList(args)); + } + return value; + } + + @SuppressWarnings("unchecked") + public SimpleExpression as(Expression alias) { + return Expressions.operation(getType(), Ops.ALIAS, this, alias); + } + + public SimpleExpression as(String alias) { + return Expressions.operation(getType(), Ops.ALIAS, this, ExpressionUtils.path(getType(), alias)); + } + + @Override + public R accept(Visitor v, C context) { + return getValue().accept(v, context); + } + + @Override + public boolean equals(Object o) { + if (o == this) { + return true; + } else if (o instanceof WindowFunction) { + WindowFunction so = (WindowFunction) o; + return so.target.equals(target) + && so.partitionBy.equals(partitionBy) + && so.orderBy.equals(orderBy); + } else { + return false; + } + } + + public BooleanExpression eq(Expression expr) { + return getValue().eq(expr); + } + + public BooleanExpression eq(A arg) { + return getValue().eq(arg); + } + + public BooleanExpression ne(Expression expr) { + return getValue().ne(expr); + } + + public BooleanExpression ne(A arg) { + return getValue().ne(arg); + } + + public WindowFunction orderBy(ComparableExpressionBase orderBy) { + value = null; + this.orderBy.add(orderBy.asc()); + return this; + } + + public WindowFunction orderBy(ComparableExpressionBase... orderBy) { + value = null; + for (ComparableExpressionBase e : orderBy) { + this.orderBy.add(e.asc()); + } + return this; + } + + public WindowFunction orderBy(OrderSpecifier orderBy) { + value = null; + this.orderBy.add(orderBy); + return this; + } + + public WindowFunction orderBy(OrderSpecifier... orderBy) { + value = null; + Collections.addAll(this.orderBy, orderBy); + return this; + } + + public WindowFunction partitionBy(Expression partitionBy) { + value = null; + this.partitionBy.add(partitionBy); + return this; + } + + public WindowFunction partitionBy(Expression... partitionBy) { + value = null; + Collections.addAll(this.partitionBy, partitionBy); + return this; + } + + WindowFunction withRowsOrRange(String s, List> args) { + rowsOrRange = s; + rowsOrRangeArgs = args; + return this; + } + + public WindowRows rows() { + value = null; + int offset = orderBy.size() + partitionBy.size() + 1; + return new WindowRows(this, " rows", offset); + } + + public WindowRows range() { + value = null; + int offset = orderBy.size() + partitionBy.size() + 1; + return new WindowRows(this, " range", offset); + } +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/WindowOver.java b/querydsl-sql/src/main/java/com/querydsl/sql/WindowOver.java new file mode 100644 index 0000000000..4a64a972b6 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/WindowOver.java @@ -0,0 +1,58 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.Operator; +import com.querydsl.core.types.dsl.SimpleOperation; + +import java.util.Arrays; +import java.util.Collections; + +/** + * {@code WindowOver} is the first part of a WindowFunction construction + * + * @author tiwe + * + * @param + */ +public class WindowOver extends SimpleOperation { + + private static final long serialVersionUID = 464583892898579544L; + + public WindowOver(Class type, Operator op) { + super(type, op, Collections.emptyList()); + } + + public WindowOver(Class type, Operator op, Expression arg) { + super(type, op, Collections.singletonList(arg)); + } + + public WindowOver(Class type, Operator op, Expression arg1, Expression arg2) { + super(type, op, Arrays.asList(arg1, arg2)); + } + + public WindowFirstLast keepFirst() { + return new WindowFirstLast(this, true); + } + + public WindowFirstLast keepLast() { + return new WindowFirstLast(this, false); + } + + public WindowFunction over() { + return new WindowFunction(this); + } + +} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/WindowRows.java b/querydsl-sql/src/main/java/com/querydsl/sql/WindowRows.java similarity index 83% rename from querydsl-sql/src/main/java/com/mysema/query/sql/WindowRows.java rename to querydsl-sql/src/main/java/com/querydsl/sql/WindowRows.java index 1796d4bf50..15ac4b7396 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/WindowRows.java +++ b/querydsl-sql/src/main/java/com/querydsl/sql/WindowRows.java @@ -1,5 +1,5 @@ /* - * Copyright 2013, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,20 +11,20 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql; +package com.querydsl.sql; +import java.util.ArrayList; import java.util.List; -import com.google.common.collect.Lists; -import com.mysema.query.types.ConstantImpl; -import com.mysema.query.types.Expression; +import com.querydsl.core.types.ConstantImpl; +import com.querydsl.core.types.Expression; /** - * WindowRows provides the building of the rows/range part of the window function expression + * {@code WindowRows} provides the building of the rows/range part of the window function expression * - * @author tiwe + * @param expression type * - * @param + * @author tiwe */ public class WindowRows { @@ -40,6 +40,9 @@ public class WindowRows { private static final String UNBOUNDED = " unbounded"; + /** + * Intermediate step + */ public class Between { public BetweenAnd unboundedPreceding() { @@ -56,7 +59,7 @@ public BetweenAnd currentRow() { public BetweenAnd preceding(Expression expr) { args.add(expr); str.append(PRECEDING); - str.append(" {" + (offset++) + "}"); + str.append(" {").append(offset++).append("}"); return new BetweenAnd(); } @@ -67,7 +70,7 @@ public BetweenAnd preceding(int i) { public BetweenAnd following(Expression expr) { args.add(expr); str.append(FOLLOWING); - str.append(" {" + (offset++) + "}"); + str.append(" {").append(offset++).append("}"); return new BetweenAnd(); } @@ -76,6 +79,9 @@ public BetweenAnd following(int i) { } } + /** + * Intermediate step + */ public class BetweenAnd { public BetweenAnd() { @@ -96,7 +102,7 @@ public WindowFunction currentRow() { public WindowFunction preceding(Expression expr) { args.add(expr); str.append(PRECEDING); - str.append(" {" + (offset++) + "}"); + str.append(" {").append(offset++).append("}"); return rv.withRowsOrRange(str.toString(), args); } @@ -107,7 +113,7 @@ public WindowFunction preceding(int i) { public WindowFunction following(Expression expr) { args.add(expr); str.append(FOLLOWING); - str.append(" {" + (offset++) + "}"); + str.append(" {").append(offset++).append("}"); return rv.withRowsOrRange(str.toString(), args); } @@ -120,7 +126,7 @@ public WindowFunction following(int i) { private final StringBuilder str = new StringBuilder(); - private final List> args = Lists.newArrayList(); + private final List> args = new ArrayList<>(); private int offset; @@ -149,7 +155,7 @@ public WindowFunction currentRow() { public WindowFunction preceding(Expression expr) { args.add(expr); str.append(PRECEDING); - str.append(" {" + (offset++) + "}"); + str.append(" {").append(offset++).append("}"); return rv.withRowsOrRange(str.toString(), args); } diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/WithBuilder.java b/querydsl-sql/src/main/java/com/querydsl/sql/WithBuilder.java new file mode 100644 index 0000000000..4c0c7b81f2 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/WithBuilder.java @@ -0,0 +1,44 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import com.querydsl.core.QueryFlag; +import com.querydsl.core.support.QueryMixin; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.ExpressionUtils; + +/** + * {@code WithBuilder} is a builder for common table expressions + * + * @author tiwe + * + * @param + */ +public class WithBuilder { + + private final QueryMixin queryMixin; + + private final Expression alias; + + public WithBuilder(QueryMixin queryMixin, Expression alias) { + this.queryMixin = queryMixin; + this.alias = alias; + } + + public R as(Expression expr) { + Expression flag = ExpressionUtils.operation(alias.getType(), SQLOps.WITH_ALIAS, alias, expr); + return queryMixin.addFlag(new QueryFlag(QueryFlag.Position.WITH, flag)); + } + +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/WithinGroup.java b/querydsl-sql/src/main/java/com/querydsl/sql/WithinGroup.java new file mode 100644 index 0000000000..e6e1e1b898 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/WithinGroup.java @@ -0,0 +1,139 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.jetbrains.annotations.Nullable; + +import com.querydsl.core.types.*; +import com.querydsl.core.types.dsl.ComparableExpressionBase; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.SimpleExpression; +import com.querydsl.core.types.dsl.SimpleOperation; +import com.querydsl.core.util.CollectionUtils; + +/** + * {@code WithinGroup} is a builder for {@code WITHIN GROUP} constructs + * + * @param expression type + * + * @author tiwe + */ +public class WithinGroup extends SimpleOperation { + + private static final long serialVersionUID = 464583892898579544L; + + private static Expression merge(Expression... args) { + if (args.length == 1) { + return args[0]; + } else { + return ExpressionUtils.list(Object.class, args); + } + } + + /** + * Intermediate step + */ + public class OrderBy extends MutableExpressionBase { + + private static final long serialVersionUID = -4936481493030913621L; + + private static final String ORDER_BY = "order by "; + + @Nullable + private transient volatile SimpleExpression value; + + private final List> orderBy = new ArrayList>(); + + public OrderBy() { + super(WithinGroup.this.getType()); + } + + @SuppressWarnings("unchecked") + public SimpleExpression getValue() { + if (value == null) { + int size = 0; + List> args = new ArrayList<>(); + StringBuilder builder = new StringBuilder(); + builder.append("{0} within group ("); + args.add(WithinGroup.this); + size++; + if (!orderBy.isEmpty()) { + builder.append(ORDER_BY); + builder.append("{").append(size).append("}"); + args.add(ExpressionUtils.orderBy(orderBy)); + } + builder.append(")"); + value = Expressions.template((Class) WithinGroup.this.getType(), builder.toString(), CollectionUtils.unmodifiableList(args)); + } + return value; + } + + @Override + public R accept(Visitor v, C context) { + return getValue().accept(v, context); + } + + public OrderBy orderBy(ComparableExpressionBase orderBy) { + value = null; + this.orderBy.add(orderBy.asc()); + return this; + } + + public OrderBy orderBy(ComparableExpressionBase... orderBy) { + value = null; + for (ComparableExpressionBase e : orderBy) { + this.orderBy.add(e.asc()); + } + return this; + } + + public OrderBy orderBy(OrderSpecifier orderBy) { + value = null; + this.orderBy.add(orderBy); + return this; + } + + public OrderBy orderBy(OrderSpecifier... orderBy) { + value = null; + Collections.addAll(this.orderBy, orderBy); + return this; + } + } + + public WithinGroup(Class type, Operator op) { + super(type, op, Collections.emptyList()); + } + + public WithinGroup(Class type, Operator op, Expression arg) { + super(type, op, Collections.singletonList(arg)); + } + + public WithinGroup(Class type, Operator op, Expression arg1, Expression arg2) { + super(type, op, Arrays.asList(arg1, arg2)); + } + + public WithinGroup(Class type, Operator op, Expression... args) { + super(type, op, merge(args)); + } + + public OrderBy withinGroup() { + return new OrderBy(); + } + +} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/dml/AbstractMapper.java b/querydsl-sql/src/main/java/com/querydsl/sql/dml/AbstractMapper.java similarity index 81% rename from querydsl-sql/src/main/java/com/mysema/query/sql/dml/AbstractMapper.java rename to querydsl-sql/src/main/java/com/querydsl/sql/dml/AbstractMapper.java index e05d906175..4e65a8299a 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/dml/AbstractMapper.java +++ b/querydsl-sql/src/main/java/com/querydsl/sql/dml/AbstractMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2011, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,13 +11,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql.dml; +package com.querydsl.sql.dml; +import java.util.LinkedHashMap; import java.util.Map; -import com.google.common.collect.Maps; -import com.mysema.query.sql.RelationalPath; -import com.mysema.query.types.Path; +import com.querydsl.core.types.Path; +import com.querydsl.sql.RelationalPath; /** * Abstract base class for Mapper implementations @@ -29,7 +29,7 @@ public abstract class AbstractMapper implements Mapper { protected Map> getColumns(RelationalPath path) { - Map> columns = Maps.newHashMap(); + Map> columns = new LinkedHashMap<>(); for (Path column : path.getColumns()) { columns.put(column.getMetadata().getName(), column); } diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/dml/AbstractSQLClause.java b/querydsl-sql/src/main/java/com/querydsl/sql/dml/AbstractSQLClause.java new file mode 100644 index 0000000000..227440cd3a --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/dml/AbstractSQLClause.java @@ -0,0 +1,254 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.dml; + +import java.sql.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.function.Supplier; + +import org.jetbrains.annotations.Nullable; + +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.dml.DMLClause; +import com.querydsl.core.types.ParamExpression; +import com.querydsl.core.types.ParamNotSetException; +import com.querydsl.core.types.Path; +import com.querydsl.sql.*; + +/** + * {@code AbstractSQLClause} is a superclass for SQL based DMLClause implementations + * + * @param concrete subtype + * + * @author tiwe + */ +public abstract class AbstractSQLClause> implements DMLClause { + + protected final Configuration configuration; + + protected final SQLListeners listeners; + + protected boolean useLiterals; + + protected SQLListenerContextImpl context; + + @Nullable + private Supplier connProvider; + + @Nullable + private Connection conn; + + public AbstractSQLClause(Configuration configuration) { + this.configuration = configuration; + this.listeners = new SQLListeners(configuration.getListeners()); + this.useLiterals = configuration.getUseLiterals(); + } + + public AbstractSQLClause(Configuration configuration, Supplier connProvider) { + this(configuration); + this.connProvider = connProvider; + } + + public AbstractSQLClause(Configuration configuration, Connection conn) { + this(configuration); + this.conn = conn; + } + + /** + * Add a listener + * + * @param listener listener to add + */ + public void addListener(SQLListener listener) { + listeners.add(listener); + } + + /** + * Clear the internal state of the clause + */ + public abstract void clear(); + + /** + * Called to create and start a new SQL Listener context + * + * @param connection the database connection + * @param metadata the meta data for that context + * @param entity the entity for that context + * @return the newly started context + */ + protected SQLListenerContextImpl startContext(Connection connection, QueryMetadata metadata, RelationalPath entity) { + SQLListenerContextImpl context = new SQLListenerContextImpl(metadata, connection, entity); + listeners.start(context); + return context; + } + + /** + * Called to make the call back to listeners when an exception happens + * + * @param context the current context in play + * @param e the exception + */ + protected void onException(SQLListenerContextImpl context, Exception e) { + context.setException(e); + listeners.exception(context); + } + + /** + * Called to end a SQL listener context + * + * @param context the listener context to end + */ + protected void endContext(SQLListenerContextImpl context) { + listeners.end(context); + this.context = null; + } + + + protected SQLBindings createBindings(QueryMetadata metadata, SQLSerializer serializer) { + String queryString = serializer.toString(); + List args = new ArrayList<>(); + Map, Object> params = metadata.getParams(); + for (Object o : serializer.getConstants()) { + if (o instanceof ParamExpression) { + if (!params.containsKey(o)) { + throw new ParamNotSetException((ParamExpression) o); + } + o = metadata.getParams().get(o); + } + args.add(o); + } + return new SQLBindings(queryString, args); + } + + protected SQLSerializer createSerializer() { + SQLSerializer serializer = new SQLSerializer(configuration, true); + serializer.setUseLiterals(useLiterals); + return serializer; + } + + /** + * Get the SQL string and bindings + * + * @return SQL and bindings + */ + public abstract List getSQL(); + + /** + * Set the parameters to the given PreparedStatement + * + * @param stmt preparedStatement to be populated + * @param objects list of constants + * @param constantPaths list of paths related to the constants + * @param params map of param to value for param resolving + */ + protected void setParameters(PreparedStatement stmt, List objects, + List> constantPaths, Map, ?> params) { + if (objects.size() != constantPaths.size()) { + throw new IllegalArgumentException("Expected " + objects.size() + " paths, " + + "but got " + constantPaths.size()); + } + for (int i = 0; i < objects.size(); i++) { + Object o = objects.get(i); + try { + if (o instanceof ParamExpression) { + if (!params.containsKey(o)) { + throw new ParamNotSetException((ParamExpression) o); + } + o = params.get(o); + } + configuration.set(stmt, constantPaths.get(i), i + 1, o); + } catch (SQLException e) { + throw configuration.translate(e); + } + } + } + + private long executeBatch(PreparedStatement stmt) throws SQLException { + if (configuration.getUseLiterals()) { + return stmt.executeUpdate(); + } else if (configuration.getTemplates().isBatchCountViaGetUpdateCount()) { + stmt.executeBatch(); + return stmt.getUpdateCount(); + } else { + long rv = 0; + for (int i : stmt.executeBatch()) { + rv += i; + } + return rv; + } + } + + protected long executeBatch(Collection stmts) throws SQLException { + long rv = 0; + for (PreparedStatement stmt : stmts) { + rv += executeBatch(stmt); + } + return rv; + } + + protected void close(Statement stmt) { + try { + stmt.close(); + } catch (SQLException e) { + throw configuration.translate(e); + } + } + + protected void close(Collection stmts) { + for (Statement stmt : stmts) { + close(stmt); + } + } + + protected void close(ResultSet rs) { + try { + rs.close(); + } catch (SQLException e) { + throw configuration.translate(e); + } + } + + protected void logQuery(Logger logger, String queryString, Collection parameters) { + if (logger.isLoggable(Level.FINE)) { + String normalizedQuery = queryString.replace('\n', ' '); + logger.fine(normalizedQuery); + } + } + + protected void reset() { + } + + protected Connection connection() { + if (conn == null) { + if (connProvider != null) { + conn = connProvider.get(); + } else { + throw new IllegalStateException("No connection provided"); + } + } + return conn; + } + + public void setUseLiterals(boolean useLiterals) { + this.useLiterals = useLiterals; + } + + public abstract int getBatchCount(); + +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/dml/AbstractSQLDeleteClause.java b/querydsl-sql/src/main/java/com/querydsl/sql/dml/AbstractSQLDeleteClause.java new file mode 100644 index 0000000000..214628941b --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/dml/AbstractSQLDeleteClause.java @@ -0,0 +1,275 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.dml; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.util.*; +import java.util.logging.Logger; +import java.util.function.Supplier; + +import org.jetbrains.annotations.Range; + +import com.querydsl.core.*; +import com.querydsl.core.QueryFlag.Position; +import com.querydsl.core.dml.DeleteClause; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.Predicate; +import com.querydsl.core.types.ValidatingVisitor; +import com.querydsl.sql.Configuration; +import com.querydsl.sql.RelationalPath; +import com.querydsl.sql.SQLBindings; +import com.querydsl.sql.SQLSerializer; + +/** + * Provides a base class for dialect-specific DELETE clauses. + * + * @author tiwe + * @param The type extending this class. + * + */ +public abstract class AbstractSQLDeleteClause> extends AbstractSQLClause implements DeleteClause { + + protected static final Logger logger = Logger.getLogger(AbstractSQLDeleteClause.class.getName()); + + protected static final ValidatingVisitor validatingVisitor = new ValidatingVisitor("Undeclared path '%s'. " + + "A delete operation can only reference a single table. " + + "Consider this alternative: DELETE ... WHERE EXISTS (subquery)"); + + protected final RelationalPath entity; + + protected final List batches = new ArrayList(); + + protected DefaultQueryMetadata metadata = new DefaultQueryMetadata(); + + protected transient String queryString; + + protected transient List constants; + + public AbstractSQLDeleteClause(Connection connection, Configuration configuration, RelationalPath entity) { + super(configuration, connection); + this.entity = entity; + metadata.addJoin(JoinType.DEFAULT, entity); + metadata.setValidatingVisitor(validatingVisitor); + } + + public AbstractSQLDeleteClause(Supplier connection, Configuration configuration, RelationalPath entity) { + super(configuration, connection); + this.entity = entity; + metadata.addJoin(JoinType.DEFAULT, entity); + metadata.setValidatingVisitor(validatingVisitor); + } + + /** + * Add the given String literal at the given position as a query flag + * + * @param position position + * @param flag query flag + * @return the current object + */ + public C addFlag(Position position, String flag) { + metadata.addFlag(new QueryFlag(position, flag)); + return (C) this; + } + + /** + * Add the given Expression at the given position as a query flag + * + * @param position position + * @param flag query flag + * @return the current object + */ + public C addFlag(Position position, Expression flag) { + metadata.addFlag(new QueryFlag(position, flag)); + return (C) this; + } + + /** + * Add current state of bindings as a batch item + * + * @return the current object + */ + public C addBatch() { + batches.add(metadata); + metadata = new DefaultQueryMetadata(); + metadata.addJoin(JoinType.DEFAULT, entity); + metadata.setValidatingVisitor(validatingVisitor); + return (C) this; + } + + @Override + public void clear() { + batches.clear(); + metadata = new DefaultQueryMetadata(); + metadata.addJoin(JoinType.DEFAULT, entity); + metadata.setValidatingVisitor(validatingVisitor); + } + + protected PreparedStatement createStatement() throws SQLException { + listeners.preRender(context); + SQLSerializer serializer = createSerializer(); + serializer.serializeDelete(metadata, entity); + queryString = serializer.toString(); + constants = serializer.getConstants(); + logQuery(logger, queryString, constants); + context.addSQL(createBindings(metadata, serializer)); + listeners.rendered(context); + + listeners.prePrepare(context); + PreparedStatement stmt = connection().prepareStatement(queryString); + setParameters(stmt, serializer.getConstants(), serializer.getConstantPaths(), metadata.getParams()); + + context.addPreparedStatement(stmt); + listeners.prepared(context); + + return stmt; + } + + protected Collection createStatements() throws SQLException { + boolean addBatches = !configuration.getUseLiterals(); + listeners.preRender(context); + SQLSerializer serializer = createSerializer(); + serializer.serializeDelete(batches.get(0), entity); + queryString = serializer.toString(); + constants = serializer.getConstants(); + logQuery(logger, queryString, constants); + context.addSQL(createBindings(metadata, serializer)); + listeners.rendered(context); + + Map stmts = new HashMap<>(); + + // add first batch + listeners.prePrepare(context); + PreparedStatement stmt = connection().prepareStatement(queryString); + setParameters(stmt, serializer.getConstants(), serializer.getConstantPaths(), metadata.getParams()); + if (addBatches) { + stmt.addBatch(); + } + stmts.put(queryString, stmt); + context.addPreparedStatement(stmt); + listeners.prepared(context); + + + // add other batches + for (int i = 1; i < batches.size(); i++) { + listeners.preRender(context); + serializer = createSerializer(); + serializer.serializeDelete(batches.get(i), entity); + context.addSQL(createBindings(metadata, serializer)); + listeners.rendered(context); + + stmt = stmts.get(serializer.toString()); + if (stmt == null) { + listeners.prePrepare(context); + stmt = connection().prepareStatement(serializer.toString()); + stmts.put(serializer.toString(), stmt); + context.addPreparedStatement(stmt); + listeners.prepared(context); + } + setParameters(stmt, serializer.getConstants(), serializer.getConstantPaths(), metadata.getParams()); + if (addBatches) { + stmt.addBatch(); + } + } + + return stmts.values(); + } + + @Override + public long execute() { + context = startContext(connection(), metadata, entity); + PreparedStatement stmt = null; + Collection stmts = null; + try { + if (batches.isEmpty()) { + stmt = createStatement(); + listeners.notifyDelete(entity, metadata); + + listeners.preExecute(context); + int rc = stmt.executeUpdate(); + listeners.executed(context); + return rc; + } else { + stmts = createStatements(); + listeners.notifyDeletes(entity, batches); + + listeners.preExecute(context); + long rc = executeBatch(stmts); + listeners.executed(context); + return rc; + } + } catch (SQLException e) { + onException(context,e); + throw configuration.translate(queryString, constants, e); + } finally { + if (stmt != null) { + close(stmt); + } + if (stmts != null) { + close(stmts); + } + reset(); + endContext(context); + } + } + + @Override + public List getSQL() { + if (batches.isEmpty()) { + SQLSerializer serializer = createSerializer(); + serializer.serializeDelete(metadata, entity); + return Collections.singletonList(createBindings(metadata, serializer)); + } else { + List builder = new ArrayList<>(); + for (QueryMetadata metadata : batches) { + SQLSerializer serializer = createSerializer(); + serializer.serializeDelete(metadata, entity); + builder.add(createBindings(metadata, serializer)); + } + return Collections.unmodifiableList(builder); + } + } + + public C where(Predicate p) { + metadata.addWhere(p); + return (C) this; + } + + @Override + public C where(Predicate... o) { + for (Predicate p : o) { + metadata.addWhere(p); + } + return (C) this; + } + + public C limit(@Range(from = 0, to = Integer.MAX_VALUE) long limit) { + metadata.setModifiers(QueryModifiers.limit(limit)); + return (C) this; + } + + @Override + public int getBatchCount() { + return batches.size(); + } + + @Override + public String toString() { + SQLSerializer serializer = createSerializer(); + serializer.serializeDelete(metadata, entity); + return serializer.toString(); + } + +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/dml/AbstractSQLInsertClause.java b/querydsl-sql/src/main/java/com/querydsl/sql/dml/AbstractSQLInsertClause.java new file mode 100644 index 0000000000..dd04f40134 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/dml/AbstractSQLInsertClause.java @@ -0,0 +1,562 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.dml; + +import java.sql.*; +import java.util.*; +import java.util.logging.Logger; +import java.util.function.Supplier; +import org.jetbrains.annotations.Nullable; + +import com.querydsl.core.util.CollectionUtils; + +import com.querydsl.core.DefaultQueryMetadata; +import com.querydsl.core.JoinType; +import com.querydsl.core.QueryFlag; +import com.querydsl.core.QueryFlag.Position; +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.dml.InsertClause; +import com.querydsl.core.types.*; +import com.querydsl.core.util.ResultSetAdapter; +import com.querydsl.sql.*; +import com.querydsl.sql.types.Null; + +/** + * Provides a base class for dialect-specific INSERT clauses. + * + * @author tiwe + * @param The type extending this class. + * + */ +public abstract class AbstractSQLInsertClause> extends AbstractSQLClause implements InsertClause { + + protected static final Logger logger = Logger.getLogger(AbstractSQLInsertClause.class.getName()); + + protected final RelationalPath entity; + + protected final QueryMetadata metadata = new DefaultQueryMetadata(); + + @Nullable + protected SubQueryExpression subQuery; + + @Nullable + protected SQLQuery subQueryBuilder; + + protected final List batches = new ArrayList(); + + protected final List> columns = new ArrayList>(); + + protected final List> values = new ArrayList>(); + + protected transient String queryString; + + protected transient List constants; + + protected transient boolean batchToBulk; + + public AbstractSQLInsertClause(Connection connection, Configuration configuration, RelationalPath entity, SQLQuery subQuery) { + this(connection, configuration, entity); + this.subQueryBuilder = subQuery; + } + + public AbstractSQLInsertClause(Connection connection, Configuration configuration, RelationalPath entity) { + super(configuration, connection); + this.entity = entity; + metadata.addJoin(JoinType.DEFAULT, entity); + } + + public AbstractSQLInsertClause(Supplier connection, Configuration configuration, RelationalPath entity, SQLQuery subQuery) { + this(connection, configuration, entity); + this.subQueryBuilder = subQuery; + } + + public AbstractSQLInsertClause(Supplier connection, Configuration configuration, RelationalPath entity) { + super(configuration, connection); + this.entity = entity; + metadata.addJoin(JoinType.DEFAULT, entity); + } + + /** + * Add the given String literal at the given position as a query flag + * + * @param position position + * @param flag query flag + * @return the current object + */ + public C addFlag(Position position, String flag) { + metadata.addFlag(new QueryFlag(position, flag)); + return (C) this; + } + + /** + * Add the given Expression at the given position as a query flag + * + * @param position position + * @param flag query flag + * @return the current object + */ + public C addFlag(Position position, Expression flag) { + metadata.addFlag(new QueryFlag(position, flag)); + return (C) this; + } + + /** + * Add the current state of bindings as a batch item + * + * @return the current object + */ + public C addBatch() { + if (subQueryBuilder != null) { + subQuery = subQueryBuilder.select(values.toArray(new Expression[0])).clone(); + values.clear(); + } + batches.add(new SQLInsertBatch(columns, values, subQuery)); + columns.clear(); + values.clear(); + subQuery = null; + return (C) this; + } + + /** + * Set whether batches should be optimized into a single bulk operation. + * Will revert to batches, if bulk is not supported + */ + public void setBatchToBulk(boolean b) { + this.batchToBulk = b && configuration.getTemplates().isBatchToBulkSupported(); + } + + @Override + public void clear() { + batches.clear(); + columns.clear(); + values.clear(); + subQuery = null; + } + + @Override + public C columns(Path... columns) { + this.columns.addAll(Arrays.asList(columns)); + return (C) this; + } + + /** + * Execute the clause and return the generated key with the type of the + * given path. If no rows were created, null is returned, otherwise the key + * of the first row is returned. + * + * @param + * @param path path for key + * @return generated key + */ + @SuppressWarnings("unchecked") + @Nullable + public T executeWithKey(Path path) { + return executeWithKey((Class) path.getType(), path); + } + + /** + * Execute the clause and return the generated key cast to the given type. + * If no rows were created, null is returned, otherwise the key of the first + * row is returned. + * + * @param + * @param type type of key + * @return generated key + */ + public T executeWithKey(Class type) { + return executeWithKey(type, null); + } + + protected T executeWithKey(Class type, @Nullable Path path) { + ResultSet rs = null; + try { + rs = executeWithKeys(); + if (rs.next()) { + return configuration.get(rs, path, 1, type); + } else { + return null; + } + } catch (SQLException e) { + throw configuration.translate(e); + } finally { + if (rs != null) { + close(rs); + } + reset(); + } + } + + /** + * Execute the clause and return the generated key with the type of the + * given path. If no rows were created, or the referenced column is not a + * generated key, null is returned. Otherwise, the key of the first row is + * returned. + * + * @param + * @param path path for key + * @return generated keys + */ + @SuppressWarnings("unchecked") + public List executeWithKeys(Path path) { + return executeWithKeys((Class) path.getType(), path); + } + + public List executeWithKeys(Class type) { + return executeWithKeys(type, null); + } + + protected List executeWithKeys(Class type, @Nullable Path path) { + ResultSet rs = null; + try { + rs = executeWithKeys(); + List rv = new ArrayList(); + while (rs.next()) { + rv.add(configuration.get(rs, path, 1, type)); + } + return rv; + } catch (SQLException e) { + throw configuration.translate(e); + } finally { + if (rs != null) { + close(rs); + } + reset(); + } + } + + protected PreparedStatement createStatement(boolean withKeys) throws SQLException { + listeners.preRender(context); + SQLSerializer serializer = createSerializer(); + if (subQueryBuilder != null) { + subQuery = subQueryBuilder.select(values.toArray(new Expression[0])).clone(); + values.clear(); + } + + if (!batches.isEmpty() && batchToBulk) { + serializer.serializeInsert(metadata, entity, batches); + } else { + serializer.serializeInsert(metadata, entity, columns, values, subQuery); + } + context.addSQL(createBindings(metadata, serializer)); + listeners.rendered(context); + return prepareStatementAndSetParameters(serializer, withKeys); + } + + protected Collection createStatements(boolean withKeys) throws SQLException { + boolean addBatches = !configuration.getUseLiterals(); + listeners.preRender(context); + + if (subQueryBuilder != null) { + subQuery = subQueryBuilder.select(values.toArray(new Expression[0])).clone(); + values.clear(); + } + + Map stmts = new HashMap<>(); + + // add first batch + SQLSerializer serializer = createSerializer(); + serializer.serializeInsert(metadata, entity, batches.get(0).getColumns(), batches + .get(0).getValues(), batches.get(0).getSubQuery()); + PreparedStatement stmt = prepareStatementAndSetParameters(serializer, withKeys); + if (addBatches) { + stmt.addBatch(); + } + stmts.put(serializer.toString(), stmt); + context.addSQL(createBindings(metadata, serializer)); + listeners.rendered(context); + + // add other batches + for (int i = 1; i < batches.size(); i++) { + SQLInsertBatch batch = batches.get(i); + + listeners.preRender(context); + serializer = createSerializer(); + serializer.serializeInsert(metadata, entity, batch.getColumns(), + batch.getValues(), batch.getSubQuery()); + context.addSQL(createBindings(metadata, serializer)); + listeners.rendered(context); + + stmt = stmts.get(serializer.toString()); + if (stmt == null) { + stmt = prepareStatementAndSetParameters(serializer, withKeys); + stmts.put(serializer.toString(), stmt); + } else { + setParameters(stmt, serializer.getConstants(), serializer.getConstantPaths(), + metadata.getParams()); + } + if (addBatches) { + stmt.addBatch(); + } + } + + return stmts.values(); + } + + protected PreparedStatement prepareStatementAndSetParameters(SQLSerializer serializer, + boolean withKeys) throws SQLException { + listeners.prePrepare(context); + + queryString = serializer.toString(); + constants = serializer.getConstants(); + logQuery(logger, queryString, constants); + PreparedStatement stmt; + if (withKeys) { + if (entity.getPrimaryKey() != null) { + String[] target = new String[entity.getPrimaryKey().getLocalColumns().size()]; + for (int i = 0; i < target.length; i++) { + Path path = entity.getPrimaryKey().getLocalColumns().get(i); + String column = ColumnMetadata.getName(path); + column = configuration.getColumnOverride(entity.getSchemaAndTable(), column); + target[i] = column; + } + stmt = connection().prepareStatement(queryString, target); + } else { + stmt = connection().prepareStatement(queryString, Statement.RETURN_GENERATED_KEYS); + } + } else { + stmt = connection().prepareStatement(queryString); + } + setParameters(stmt, serializer.getConstants(), serializer.getConstantPaths(), + metadata.getParams()); + + context.addPreparedStatement(stmt); + listeners.prepared(context); + return stmt; + } + + /** + * Execute the clause and return the generated keys as a ResultSet + * + * @return result set with generated keys + */ + public ResultSet executeWithKeys() { + context = startContext(connection(), metadata, entity); + try { + PreparedStatement stmt = null; + if (batches.isEmpty()) { + stmt = createStatement(true); + listeners.notifyInsert(entity, metadata, columns, values, subQuery); + + listeners.preExecute(context); + stmt.executeUpdate(); + listeners.executed(context); + } else if (batchToBulk) { + stmt = createStatement(true); + listeners.notifyInserts(entity, metadata, batches); + + listeners.preExecute(context); + stmt.executeUpdate(); + listeners.executed(context); + } else { + Collection stmts = createStatements(true); + if (stmts != null && stmts.size() > 1) { + throw new IllegalStateException("executeWithKeys called with batch statement and multiple SQL strings"); + } + stmt = stmts.iterator().next(); + listeners.notifyInserts(entity, metadata, batches); + + listeners.preExecute(context); + stmt.executeBatch(); + listeners.executed(context); + } + + final Statement stmt2 = stmt; + ResultSet rs = stmt.getGeneratedKeys(); + return new ResultSetAdapter(rs) { + @Override + public void close() throws SQLException { + try { + super.close(); + } finally { + stmt2.close(); + reset(); + endContext(context); + } + } + }; + } catch (SQLException e) { + onException(context, e); + reset(); + endContext(context); + throw configuration.translate(queryString, constants, e); + } + } + + @Override + public long execute() { + context = startContext(connection(), metadata,entity); + PreparedStatement stmt = null; + Collection stmts = null; + try { + if (batches.isEmpty()) { + stmt = createStatement(false); + listeners.notifyInsert(entity, metadata, columns, values, subQuery); + + listeners.preExecute(context); + int rc = stmt.executeUpdate(); + listeners.executed(context); + return rc; + } else if (batchToBulk) { + stmt = createStatement(false); + listeners.notifyInserts(entity, metadata, batches); + + listeners.preExecute(context); + int rc = stmt.executeUpdate(); + listeners.executed(context); + return rc; + } else { + stmts = createStatements(false); + listeners.notifyInserts(entity, metadata, batches); + + listeners.preExecute(context); + long rc = executeBatch(stmts); + listeners.executed(context); + return rc; + } + } catch (SQLException e) { + onException(context,e); + throw configuration.translate(queryString, constants, e); + } finally { + if (stmt != null) { + close(stmt); + } + if (stmts != null) { + close(stmts); + } + reset(); + endContext(context); + } + } + + @Override + public List getSQL() { + if (batches.isEmpty()) { + SQLSerializer serializer = createSerializer(); + serializer.serializeInsert(metadata, entity, columns, values, subQuery); + return Collections.singletonList(createBindings(metadata, serializer)); + } else if (batchToBulk) { + SQLSerializer serializer = createSerializer(); + serializer.serializeInsert(metadata, entity, batches); + return Collections.singletonList(createBindings(metadata, serializer)); + } else { + List builder = new ArrayList<>(); + for (SQLInsertBatch batch : batches) { + SQLSerializer serializer = createSerializer(); + serializer.serializeInsert(metadata, entity, batch.getColumns(), batch.getValues(), batch.getSubQuery()); + builder.add(createBindings(metadata, serializer)); + } + return CollectionUtils.unmodifiableList(builder); + } + } + + @Override + public C select(SubQueryExpression sq) { + subQuery = sq; + for (Map.Entry, Object> entry : sq.getMetadata().getParams().entrySet()) { + metadata.setParam((ParamExpression) entry.getKey(), entry.getValue()); + } + return (C) this; + } + + @Override + public C set(Path path, T value) { + columns.add(path); + if (value instanceof Expression) { + values.add((Expression) value); + } else if (value != null) { + values.add(ConstantImpl.create(value)); + } else { + values.add(Null.CONSTANT); + } + return (C) this; + } + + @Override + public C set(Path path, Expression expression) { + columns.add(path); + values.add(expression); + return (C) this; + } + + @Override + public C setNull(Path path) { + columns.add(path); + values.add(Null.CONSTANT); + return (C) this; + } + + @Override + public C values(Object... v) { + for (Object value : v) { + if (value instanceof Expression) { + values.add((Expression) value); + } else if (value != null) { + values.add(ConstantImpl.create(value)); + } else { + values.add(Null.CONSTANT); + } + } + return (C) this; + } + + @Override + public String toString() { + SQLSerializer serializer = createSerializer(); + if (!batches.isEmpty() && batchToBulk) { + serializer.serializeInsert(metadata, entity, batches); + } else { + serializer.serializeInsert(metadata, entity, columns, values, subQuery); + } + return serializer.toString(); + } + + /** + * Populate the INSERT clause with the properties of the given bean. The + * properties need to match the fields of the clause's entity instance. + * + * @param bean bean to use for population + * @return the current object + */ + public C populate(Object bean) { + return populate(bean, DefaultMapper.DEFAULT); + } + + /** + * Populate the INSERT clause with the properties of the given bean using + * the given Mapper. + * + * @param obj object to use for population + * @param mapper mapper to use + * @return the current object + */ + @SuppressWarnings("rawtypes") + public C populate(T obj, Mapper mapper) { + Map, Object> values = mapper.createMap(entity, obj); + for (Map.Entry, Object> entry : values.entrySet()) { + set((Path) entry.getKey(), entry.getValue()); + } + return (C) this; + } + + @Override + public boolean isEmpty() { + return values.isEmpty() && batches.isEmpty(); + } + + @Override + public int getBatchCount() { + return batches.size(); + } + +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/dml/AbstractSQLUpdateClause.java b/querydsl-sql/src/main/java/com/querydsl/sql/dml/AbstractSQLUpdateClause.java new file mode 100644 index 0000000000..3e11ef7b52 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/dml/AbstractSQLUpdateClause.java @@ -0,0 +1,353 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.dml; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.util.*; +import java.util.logging.Logger; +import java.util.function.Supplier; + +import org.jetbrains.annotations.Range; + +import com.querydsl.core.*; +import com.querydsl.core.QueryFlag.Position; +import com.querydsl.core.dml.UpdateClause; +import com.querydsl.core.types.ConstantImpl; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.Predicate; +import com.querydsl.sql.Configuration; +import com.querydsl.sql.RelationalPath; +import com.querydsl.sql.SQLBindings; +import com.querydsl.sql.SQLSerializer; +import com.querydsl.sql.types.Null; + +/** + * Provides a base class for dialect-specific UPDATE clauses. + * + * @author tiwe + * @param The type extending this class. + * + */ +public abstract class AbstractSQLUpdateClause> extends AbstractSQLClause implements UpdateClause { + + protected static final Logger logger = Logger.getLogger(AbstractSQLUpdateClause.class.getName()); + + protected final RelationalPath entity; + + protected final List batches = new ArrayList(); + + protected Map, Expression> updates = new LinkedHashMap<>(); + + protected QueryMetadata metadata = new DefaultQueryMetadata(); + + protected transient String queryString; + + protected transient List constants; + + public AbstractSQLUpdateClause(Connection connection, Configuration configuration, RelationalPath entity) { + super(configuration, connection); + this.entity = entity; + metadata.addJoin(JoinType.DEFAULT, entity); + } + + public AbstractSQLUpdateClause(Supplier connection, Configuration configuration, RelationalPath entity) { + super(configuration, connection); + this.entity = entity; + metadata.addJoin(JoinType.DEFAULT, entity); + } + + /** + * Add the given String literal at the given position as a query flag + * + * @param position position + * @param flag query flag + * @return the current object + */ + public C addFlag(Position position, String flag) { + metadata.addFlag(new QueryFlag(position, flag)); + return (C) this; + } + + /** + * Add the given Expression at the given position as a query flag + * + * @param position position + * @param flag query flag + * @return the current object + */ + public C addFlag(Position position, Expression flag) { + metadata.addFlag(new QueryFlag(position, flag)); + return (C) this; + } + + /** + * Add the current state of bindings as a batch item + * + * @return the current object + */ + public C addBatch() { + batches.add(new SQLUpdateBatch(metadata, updates)); + updates = new LinkedHashMap<>(); + metadata = new DefaultQueryMetadata(); + metadata.addJoin(JoinType.DEFAULT, entity); + return (C) this; + } + + @Override + public void clear() { + batches.clear(); + updates = new LinkedHashMap<>(); + metadata = new DefaultQueryMetadata(); + metadata.addJoin(JoinType.DEFAULT, entity); + } + + protected PreparedStatement createStatement() throws SQLException { + listeners.preRender(context); + SQLSerializer serializer = createSerializer(); + serializer.serializeUpdate(metadata, entity, updates); + queryString = serializer.toString(); + constants = serializer.getConstants(); + logQuery(logger, queryString, constants); + context.addSQL(createBindings(metadata, serializer)); + listeners.prepared(context); + + listeners.prePrepare(context); + PreparedStatement stmt = connection().prepareStatement(queryString); + setParameters(stmt, serializer.getConstants(), serializer.getConstantPaths(), metadata.getParams()); + context.addPreparedStatement(stmt); + listeners.prepared(context); + + return stmt; + } + + protected Collection createStatements() throws SQLException { + boolean addBatches = !configuration.getUseLiterals(); + listeners.preRender(context); + SQLSerializer serializer = createSerializer(); + serializer.serializeUpdate(batches.get(0).getMetadata(), entity, batches.get(0).getUpdates()); + queryString = serializer.toString(); + constants = serializer.getConstants(); + logQuery(logger, queryString, constants); + context.addSQL(createBindings(metadata, serializer)); + listeners.rendered(context); + + Map stmts = new HashMap<>(); + + // add first batch + listeners.prePrepare(context); + PreparedStatement stmt = connection().prepareStatement(queryString); + setParameters(stmt, serializer.getConstants(), serializer.getConstantPaths(), metadata.getParams()); + if (addBatches) { + stmt.addBatch(); + } + stmts.put(serializer.toString(), stmt); + context.addPreparedStatement(stmt); + listeners.prepared(context); + + + // add other batches + for (int i = 1; i < batches.size(); i++) { + listeners.preRender(context); + serializer = createSerializer(); + serializer.serializeUpdate(batches.get(i).getMetadata(), entity, batches.get(i).getUpdates()); + context.addSQL(createBindings(metadata, serializer)); + listeners.rendered(context); + + stmt = stmts.get(serializer.toString()); + if (stmt == null) { + listeners.prePrepare(context); + stmt = connection().prepareStatement(serializer.toString()); + stmts.put(serializer.toString(), stmt); + context.addPreparedStatement(stmt); + listeners.prepared(context); + } + setParameters(stmt, serializer.getConstants(), serializer.getConstantPaths(), metadata.getParams()); + if (addBatches) { + stmt.addBatch(); + } + } + + return stmts.values(); + } + + @Override + public long execute() { + context = startContext(connection(), metadata, entity); + + PreparedStatement stmt = null; + Collection stmts = null; + try { + if (batches.isEmpty()) { + stmt = createStatement(); + listeners.notifyUpdate(entity, metadata, updates); + + listeners.preExecute(context); + int rc = stmt.executeUpdate(); + listeners.executed(context); + return rc; + } else { + stmts = createStatements(); + listeners.notifyUpdates(entity, batches); + + listeners.preExecute(context); + long rc = executeBatch(stmts); + listeners.executed(context); + return rc; + } + } catch (SQLException e) { + onException(context,e); + throw configuration.translate(queryString, constants, e); + } finally { + if (stmt != null) { + close(stmt); + } + if (stmts != null) { + close(stmts); + } + reset(); + endContext(context); + } + } + + @Override + public List getSQL() { + if (batches.isEmpty()) { + SQLSerializer serializer = createSerializer(); + serializer.serializeUpdate(metadata, entity, updates); + return Collections.singletonList(createBindings(metadata, serializer)); + } else { + List builder = new ArrayList<>(); + for (SQLUpdateBatch batch : batches) { + SQLSerializer serializer = createSerializer(); + serializer.serializeUpdate(batch.getMetadata(), entity, batch.getUpdates()); + builder.add(createBindings(metadata, serializer)); + } + return Collections.unmodifiableList(builder); + } + } + + @Override + public C set(Path path, T value) { + if (value instanceof Expression) { + updates.put(path, (Expression) value); + } else if (value != null) { + updates.put(path, ConstantImpl.create(value)); + } else { + setNull(path); + } + return (C) this; + } + + @Override + public C set(Path path, Expression expression) { + if (expression != null) { + updates.put(path, expression); + } else { + setNull(path); + } + return (C) this; + } + + @Override + public C setNull(Path path) { + updates.put(path, Null.CONSTANT); + return (C) this; + } + + @Override + public C set(List> paths, List values) { + for (int i = 0; i < paths.size(); i++) { + if (values.get(i) instanceof Expression) { + updates.put(paths.get(i), (Expression) values.get(i)); + } else if (values.get(i) != null) { + updates.put(paths.get(i), ConstantImpl.create(values.get(i))); + } else { + updates.put(paths.get(i), Null.CONSTANT); + } + } + return (C) this; + } + + public C where(Predicate p) { + metadata.addWhere(p); + return (C) this; + } + + @Override + public C where(Predicate... o) { + for (Predicate p : o) { + metadata.addWhere(p); + } + return (C) this; + } + + public C limit(@Range(from = 0, to = Integer.MAX_VALUE) long limit) { + metadata.setModifiers(QueryModifiers.limit(limit)); + return (C) this; + } + + @Override + public String toString() { + SQLSerializer serializer = createSerializer(); + serializer.serializeUpdate(metadata, entity, updates); + return serializer.toString(); + } + + /** + * Populate the UPDATE clause with the properties of the given bean. + * The properties need to match the fields of the clause's entity instance. + * Primary key columns are skipped in the population. + * + * @param bean bean to use for population + * @return the current object + */ + @SuppressWarnings("unchecked") + public C populate(Object bean) { + return populate(bean, DefaultMapper.DEFAULT); + } + + /** + * Populate the UPDATE clause with the properties of the given bean using the given Mapper. + * + * @param obj object to use for population + * @param mapper mapper to use + * @return the current object + */ + @SuppressWarnings({ "rawtypes", "unchecked" }) + public C populate(T obj, Mapper mapper) { + Collection> primaryKeyColumns = entity.getPrimaryKey() != null + ? entity.getPrimaryKey().getLocalColumns() + : Collections.>emptyList(); + Map, Object> values = mapper.createMap(entity, obj); + for (Map.Entry, Object> entry : values.entrySet()) { + if (!primaryKeyColumns.contains(entry.getKey())) { + set((Path) entry.getKey(), entry.getValue()); + } + } + return (C) this; + } + + @Override + public boolean isEmpty() { + return updates.isEmpty() && batches.isEmpty(); + } + + @Override + public int getBatchCount() { + return batches.size(); + } +} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/dml/AnnotationMapper.java b/querydsl-sql/src/main/java/com/querydsl/sql/dml/AnnotationMapper.java similarity index 87% rename from querydsl-sql/src/main/java/com/mysema/query/sql/dml/AnnotationMapper.java rename to querydsl-sql/src/main/java/com/querydsl/sql/dml/AnnotationMapper.java index 3528f4f0be..0da642bbb9 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/dml/AnnotationMapper.java +++ b/querydsl-sql/src/main/java/com/querydsl/sql/dml/AnnotationMapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2011, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,19 +11,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql.dml; +package com.querydsl.sql.dml; import java.lang.reflect.Field; import java.util.HashMap; import java.util.Map; -import com.mysema.query.QueryException; -import com.mysema.query.sql.Column; -import com.mysema.query.sql.ColumnMetadata; -import com.mysema.query.sql.RelationalPath; -import com.mysema.query.sql.types.Null; -import com.mysema.query.types.Path; -import com.mysema.util.ReflectionUtils; +import com.querydsl.core.QueryException; +import com.querydsl.core.types.Path; +import com.querydsl.core.util.ReflectionUtils; +import com.querydsl.sql.Column; +import com.querydsl.sql.ColumnMetadata; +import com.querydsl.sql.RelationalPath; +import com.querydsl.sql.types.Null; /** * Creates the mapping via @Column annotated fields in the object. Field names don't have to match those in the RelationalPath. diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/dml/BeanMapper.java b/querydsl-sql/src/main/java/com/querydsl/sql/dml/BeanMapper.java new file mode 100644 index 0000000000..9d68461118 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/dml/BeanMapper.java @@ -0,0 +1,69 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.dml; + +import java.util.LinkedHashMap; +import java.util.Map; + +import com.querydsl.core.types.Path; +import com.querydsl.core.util.BeanMap; +import com.querydsl.sql.RelationalPath; +import com.querydsl.sql.types.Null; + +/** + * Creates the mapping by inspecting object via bean inspection. + * Given bean doesn't need to have @Column metadata, but the fields need to have the same + * name as in the given relational path. + * + * @author tiwe + * + */ +public class BeanMapper extends AbstractMapper { + + public static final BeanMapper DEFAULT = new BeanMapper(false); + + public static final BeanMapper WITH_NULL_BINDINGS = new BeanMapper(true); + + private final boolean withNullBindings; + + public BeanMapper() { + this(false); + } + + public BeanMapper(boolean withNullBindings) { + this.withNullBindings = withNullBindings; + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Override + public Map, Object> createMap(RelationalPath entity, Object bean) { + Map, Object> values = new LinkedHashMap<>(); + Map map = new BeanMap(bean); + Map> columns = getColumns(entity); + // populate in column order + for (Map.Entry> entry : columns.entrySet()) { + Path path = entry.getValue(); + if (map.containsKey(entry.getKey())) { + Object value = map.get(entry.getKey()); + if (value != null) { + values.put(path, value); + } else if (withNullBindings && !isPrimaryKeyColumn(entity, path)) { + values.put(path, Null.DEFAULT); + } + } + } + return values; + } + +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/dml/DefaultMapper.java b/querydsl-sql/src/main/java/com/querydsl/sql/dml/DefaultMapper.java new file mode 100644 index 0000000000..e3a4163a36 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/dml/DefaultMapper.java @@ -0,0 +1,79 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.dml; + +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.LinkedHashMap; +import java.util.Map; + +import com.querydsl.core.QueryException; +import com.querydsl.core.types.Path; +import com.querydsl.core.util.ReflectionUtils; +import com.querydsl.sql.RelationalPath; +import com.querydsl.sql.types.Null; + +/** + * Creates the mapping by inspecting the RelationalPath and Object via reflection. + * Given bean doesn't need to have @Column metadata, but the fields need to have the same + * name as in the given relational path. + * + * @author tiwe + * + */ +public class DefaultMapper extends AbstractMapper { + + public static final DefaultMapper DEFAULT = new DefaultMapper(false); + + public static final DefaultMapper WITH_NULL_BINDINGS = new DefaultMapper(true); + + private final boolean withNullBindings; + + public DefaultMapper() { + this(false); + } + + public DefaultMapper(boolean withNullBindings) { + this.withNullBindings = withNullBindings; + } + + @Override + public Map, Object> createMap(RelationalPath entity, Object bean) { + try { + Map, Object> values = new LinkedHashMap<>(); + Class beanClass = bean.getClass(); + Map> columns = getColumns(entity); + // populate in column order + for (Map.Entry> entry : columns.entrySet()) { + Path path = entry.getValue(); + Field beanField = ReflectionUtils.getFieldOrNull(beanClass, entry.getKey()); + if (beanField != null && !Modifier.isStatic(beanField.getModifiers())) { + beanField.setAccessible(true); + Object propertyValue = beanField.get(bean); + if (propertyValue != null) { + values.put(path, propertyValue); + } else if (withNullBindings && !isPrimaryKeyColumn(entity, path)) { + values.put(path, Null.DEFAULT); + } + } + } + return values; + } catch (IllegalAccessException e) { + throw new QueryException(e); + } + } + + + +} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/dml/EmptyResultSet.java b/querydsl-sql/src/main/java/com/querydsl/sql/dml/EmptyResultSet.java similarity index 97% rename from querydsl-sql/src/main/java/com/mysema/query/sql/dml/EmptyResultSet.java rename to querydsl-sql/src/main/java/com/querydsl/sql/dml/EmptyResultSet.java index d5eeee5602..1ff3965ed9 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/dml/EmptyResultSet.java +++ b/querydsl-sql/src/main/java/com/querydsl/sql/dml/EmptyResultSet.java @@ -1,5 +1,5 @@ /* - * Copyright 2013, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,32 +11,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql.dml; +package com.querydsl.sql.dml; import java.io.InputStream; import java.io.Reader; import java.math.BigDecimal; import java.net.URL; -import java.sql.Array; -import java.sql.Blob; -import java.sql.Clob; -import java.sql.Date; -import java.sql.NClob; -import java.sql.Ref; -import java.sql.ResultSet; -import java.sql.ResultSetMetaData; -import java.sql.RowId; -import java.sql.SQLException; -import java.sql.SQLWarning; -import java.sql.SQLXML; -import java.sql.Statement; -import java.sql.Time; -import java.sql.Timestamp; +import java.sql.*; import java.util.Calendar; import java.util.Map; /** - * Empty implementation of the ResulSet interface + * Empty implementation of the ResultSet interface * * @author tiwe * @@ -45,7 +31,7 @@ public final class EmptyResultSet implements ResultSet { public static final ResultSet DEFAULT = new EmptyResultSet(); - private EmptyResultSet() {} + private EmptyResultSet() { } @Override public T unwrap(Class iface) throws SQLException { diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/dml/Mapper.java b/querydsl-sql/src/main/java/com/querydsl/sql/dml/Mapper.java new file mode 100644 index 0000000000..adcb245961 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/dml/Mapper.java @@ -0,0 +1,39 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.dml; + +import java.util.Map; + +import com.querydsl.core.types.Path; +import com.querydsl.sql.RelationalPath; + +/** + * Create a Map of updates for a given domain object + * + * @param object type + * + * @author tiwe + */ +public interface Mapper { + + /** + * Create a map of updates for the given path and instance + * + * @param path path + * @param object instance + * @return bindings + */ + Map, Object> createMap(RelationalPath path, T object); + +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/dml/SQLDeleteClause.java b/querydsl-sql/src/main/java/com/querydsl/sql/dml/SQLDeleteClause.java new file mode 100644 index 0000000000..fe0983c3d8 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/dml/SQLDeleteClause.java @@ -0,0 +1,42 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.dml; + +import java.sql.Connection; +import java.util.function.Supplier; + +import com.querydsl.sql.Configuration; +import com.querydsl.sql.RelationalPath; +import com.querydsl.sql.SQLTemplates; + +/** + * {@code SQLDeleteClause} defines a DELETE clause. + * If you need to subtype this, use {@link AbstractSQLDeleteClause} instead. + * + * @author tiwe + * + */ +public class SQLDeleteClause extends AbstractSQLDeleteClause { + public SQLDeleteClause(Connection connection, SQLTemplates templates, RelationalPath entity) { + super(connection, new Configuration(templates), entity); + } + + public SQLDeleteClause(Connection connection, Configuration configuration, RelationalPath entity) { + super(connection, configuration, entity); + } + + public SQLDeleteClause(Supplier connection, Configuration configuration, RelationalPath entity) { + super(connection, configuration, entity); + } +} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/dml/SQLInsertBatch.java b/querydsl-sql/src/main/java/com/querydsl/sql/dml/SQLInsertBatch.java similarity index 76% rename from querydsl-sql/src/main/java/com/mysema/query/sql/dml/SQLInsertBatch.java rename to querydsl-sql/src/main/java/com/querydsl/sql/dml/SQLInsertBatch.java index 3d48d4e7c2..0c15b70f91 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/dml/SQLInsertBatch.java +++ b/querydsl-sql/src/main/java/com/querydsl/sql/dml/SQLInsertBatch.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,32 +11,32 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql.dml; +package com.querydsl.sql.dml; import java.util.ArrayList; import java.util.List; -import javax.annotation.Nullable; +import org.jetbrains.annotations.Nullable; -import com.mysema.query.types.Expression; -import com.mysema.query.types.Path; -import com.mysema.query.types.SubQueryExpression; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.SubQueryExpression; /** - * SQLInsertBatch defines the state of an SQL INSERT batch item - * + * {@code SQLInsertBatch} defines the state of an SQL INSERT batch item + * * @author tiwe * */ -public class SQLInsertBatch { - +public class SQLInsertBatch { + private final List> columns; - + private final List> values; - + @Nullable private final SubQueryExpression subQuery; - + public SQLInsertBatch(List> c, List> v, @Nullable SubQueryExpression sq) { columns = new ArrayList>(c); values = new ArrayList>(v); @@ -54,6 +54,6 @@ public List> getValues() { public SubQueryExpression getSubQuery() { return subQuery; } - - + + } \ No newline at end of file diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/dml/SQLInsertClause.java b/querydsl-sql/src/main/java/com/querydsl/sql/dml/SQLInsertClause.java new file mode 100644 index 0000000000..61299a5c8a --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/dml/SQLInsertClause.java @@ -0,0 +1,55 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.dml; + +import java.sql.Connection; +import java.util.function.Supplier; + +import com.querydsl.sql.Configuration; +import com.querydsl.sql.RelationalPath; +import com.querydsl.sql.SQLQuery; +import com.querydsl.sql.SQLTemplates; + +/** + * SQLInsertClause defines an INSERT INTO clause + * If you need to subtype this, use {@link AbstractSQLInsertClause} instead. + * + * @author tiwe + * + */ +public class SQLInsertClause extends AbstractSQLInsertClause { + public SQLInsertClause(Connection connection, SQLTemplates templates, RelationalPath entity) { + this(connection, new Configuration(templates), entity); + } + + public SQLInsertClause(Connection connection, SQLTemplates templates, RelationalPath entity, SQLQuery subQuery) { + this(connection, new Configuration(templates), entity, subQuery); + } + + public SQLInsertClause(Connection connection, Configuration configuration, RelationalPath entity, SQLQuery subQuery) { + super(connection, configuration, entity, subQuery); + } + + public SQLInsertClause(Connection connection, Configuration configuration, RelationalPath entity) { + super(connection, configuration, entity); + } + + public SQLInsertClause(Supplier connection, Configuration configuration, RelationalPath entity, SQLQuery subQuery) { + super(connection, configuration, entity, subQuery); + } + + public SQLInsertClause(Supplier connection, Configuration configuration, RelationalPath entity) { + super(connection, configuration, entity); + } +} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/dml/SQLMergeBatch.java b/querydsl-sql/src/main/java/com/querydsl/sql/dml/SQLMergeBatch.java similarity index 80% rename from querydsl-sql/src/main/java/com/mysema/query/sql/dml/SQLMergeBatch.java rename to querydsl-sql/src/main/java/com/querydsl/sql/dml/SQLMergeBatch.java index 0aa29b34de..3afc44f9b0 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/dml/SQLMergeBatch.java +++ b/querydsl-sql/src/main/java/com/querydsl/sql/dml/SQLMergeBatch.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,41 +11,41 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql.dml; +package com.querydsl.sql.dml; import java.util.ArrayList; import java.util.List; -import javax.annotation.Nullable; +import org.jetbrains.annotations.Nullable; -import com.mysema.query.types.Expression; -import com.mysema.query.types.Path; -import com.mysema.query.types.SubQueryExpression; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.SubQueryExpression; /** - * SQLMergeBatch defines the state of an SQL MERGE batch item - * + * {@code SQLMergeBatch} defines the state of an SQL MERGE batch item + * * @author tiwe * */ public class SQLMergeBatch { - + private final List> keys; - + private final List> columns; - + private final List> values; - + @Nullable private final SubQueryExpression subQuery; - + public SQLMergeBatch(List> k, List> c, List> v, @Nullable SubQueryExpression sq) { keys = new ArrayList>(k); columns = new ArrayList>(c); values = new ArrayList>(v); subQuery = sq; } - + public List> getKeys() { return keys; } diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/dml/SQLMergeClause.java b/querydsl-sql/src/main/java/com/querydsl/sql/dml/SQLMergeClause.java new file mode 100644 index 0000000000..b4a7eb395d --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/dml/SQLMergeClause.java @@ -0,0 +1,593 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.dml; + +import java.sql.*; +import java.util.*; +import java.util.logging.Logger; +import java.util.function.Supplier; + +import org.jetbrains.annotations.Nullable; + +import com.querydsl.core.util.CollectionUtils; + +import com.querydsl.core.*; +import com.querydsl.core.QueryFlag.Position; +import com.querydsl.core.dml.StoreClause; +import com.querydsl.core.types.*; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.util.ResultSetAdapter; +import com.querydsl.sql.*; +import com.querydsl.sql.types.Null; + +/** + * {@code SQLMergeClause} defines an MERGE INTO clause + * + * @author tiwe + * + */ +public class SQLMergeClause extends AbstractSQLClause implements StoreClause { + + protected static final Logger logger = Logger.getLogger(SQLMergeClause.class.getName()); + + protected final List> columns = new ArrayList>(); + + protected final RelationalPath entity; + + protected final QueryMetadata metadata = new DefaultQueryMetadata(); + + protected final List> keys = new ArrayList>(); + + @Nullable + protected SubQueryExpression subQuery; + + protected final List batches = new ArrayList(); + + protected final List> values = new ArrayList>(); + + protected transient String queryString; + + protected transient List constants; + + public SQLMergeClause(Connection connection, SQLTemplates templates, RelationalPath entity) { + this(connection, new Configuration(templates), entity); + } + + public SQLMergeClause(Connection connection, Configuration configuration, RelationalPath entity) { + super(configuration, connection); + this.entity = entity; + metadata.addJoin(JoinType.DEFAULT, entity); + } + + public SQLMergeClause(Supplier connection, Configuration configuration, RelationalPath entity) { + super(configuration, connection); + this.entity = entity; + metadata.addJoin(JoinType.DEFAULT, entity); + } + + /** + * Add the given String literal at the given position as a query flag + * + * @param position position + * @param flag query flag + * @return the current object + */ + public SQLMergeClause addFlag(Position position, String flag) { + metadata.addFlag(new QueryFlag(position, flag)); + return this; + } + + /** + * Add the given Expression at the given position as a query flag + * + * @param position position + * @param flag query flag + * @return the current object + */ + public SQLMergeClause addFlag(Position position, Expression flag) { + metadata.addFlag(new QueryFlag(position, flag)); + return this; + } + + protected List> getKeys() { + if (!keys.isEmpty()) { + return keys; + } else if (entity.getPrimaryKey() != null) { + return entity.getPrimaryKey().getLocalColumns(); + } else { + throw new IllegalStateException("No keys were defined, invoke keys(..) to add keys"); + } + } + + /** + * Add the current state of bindings as a batch item + * + * @return the current object + */ + public SQLMergeClause addBatch() { + if (!configuration.getTemplates().isNativeMerge()) { + throw new IllegalStateException("batch only supported for databases that support native merge"); + } + + batches.add(new SQLMergeBatch(keys, columns, values, subQuery)); + columns.clear(); + values.clear(); + keys.clear(); + subQuery = null; + return this; + } + + @Override + public void clear() { + batches.clear(); + columns.clear(); + values.clear(); + keys.clear(); + subQuery = null; + } + + public SQLMergeClause columns(Path... columns) { + this.columns.addAll(Arrays.asList(columns)); + return this; + } + + /** + * Execute the clause and return the generated key with the type of the given path. + * If no rows were created, null is returned, otherwise the key of the first row is returned. + * + * @param + * @param path path for key + * @return generated key + */ + @SuppressWarnings("unchecked") + @Nullable + public T executeWithKey(Path path) { + return executeWithKey((Class) path.getType(), path); + } + + /** + * Execute the clause and return the generated key cast to the given type. + * If no rows were created, null is returned, otherwise the key of the first row is returned. + * + * @param + * @param type type of key + * @return generated key + */ + public T executeWithKey(Class type) { + return executeWithKey(type, null); + } + + protected T executeWithKey(Class type, @Nullable Path path) { + ResultSet rs = executeWithKeys(); + try { + if (rs.next()) { + return configuration.get(rs, path, 1, type); + } else { + return null; + } + } catch (SQLException e) { + throw configuration.translate(e); + } finally { + close(rs); + } + } + + /** + * Execute the clause and return the generated key with the type of the given path. + * If no rows were created, or the referenced column is not a generated key, null is returned. + * Otherwise, the key of the first row is returned. + * + * @param + * @param path path for key + * @return generated keys + */ + @SuppressWarnings("unchecked") + public List executeWithKeys(Path path) { + return executeWithKeys((Class) path.getType(), path); + } + + public List executeWithKeys(Class type) { + return executeWithKeys(type, null); + } + + protected List executeWithKeys(Class type, @Nullable Path path) { + ResultSet rs = null; + try { + rs = executeWithKeys(); + List rv = new ArrayList(); + while (rs.next()) { + rv.add(configuration.get(rs, path, 1, type)); + } + return rv; + } catch (SQLException e) { + throw configuration.translate(e); + } finally { + if (rs != null) { + close(rs); + } + reset(); + } + } + + /** + * Execute the clause and return the generated keys as a ResultSet + * + * @return result set with generated keys + */ + public ResultSet executeWithKeys() { + context = startContext(connection(), metadata, entity); + try { + if (configuration.getTemplates().isNativeMerge()) { + PreparedStatement stmt = null; + if (batches.isEmpty()) { + stmt = createStatement(true); + listeners.notifyMerge(entity, metadata, keys, columns, values, subQuery); + + listeners.preExecute(context); + stmt.executeUpdate(); + listeners.executed(context); + } else { + Collection stmts = createStatements(true); + if (stmts != null && stmts.size() > 1) { + throw new IllegalStateException("executeWithKeys called with batch statement and multiple SQL strings"); + } + stmt = stmts.iterator().next(); + listeners.notifyMerges(entity, metadata, batches); + + listeners.preExecute(context); + stmt.executeBatch(); + listeners.executed(context); + } + + final Statement stmt2 = stmt; + ResultSet rs = stmt.getGeneratedKeys(); + return new ResultSetAdapter(rs) { + @Override + public void close() throws SQLException { + try { + super.close(); + } finally { + stmt2.close(); + reset(); + endContext(context); + } + } + }; + } else { + if (hasRow()) { + // update + SQLUpdateClause update = new SQLUpdateClause(connection(), configuration, entity); + update.addListener(listeners); + populate(update); + addKeyConditions(update); + reset(); + endContext(context); + return EmptyResultSet.DEFAULT; + } else { + // insert + SQLInsertClause insert = new SQLInsertClause(connection(), configuration, entity); + insert.addListener(listeners); + populate(insert); + return insert.executeWithKeys(); + } + } + } catch (SQLException e) { + onException(context,e); + reset(); + endContext(context); + throw configuration.translate(queryString, constants, e); + } + } + + @Override + public long execute() { + if (configuration.getTemplates().isNativeMerge()) { + return executeNativeMerge(); + } else { + return executeCompositeMerge(); + } + } + + @Override + public List getSQL() { + if (batches.isEmpty()) { + SQLSerializer serializer = createSerializer(); + serializer.serializeMerge(metadata, entity, keys, columns, values, subQuery); + return Collections.singletonList(createBindings(metadata, serializer)); + } else { + List builder = new ArrayList<>(); + for (SQLMergeBatch batch : batches) { + SQLSerializer serializer = createSerializer(); + serializer.serializeMerge(metadata, entity, batch.getKeys(), batch.getColumns(), batch.getValues(), batch.getSubQuery()); + builder.add(createBindings(metadata, serializer)); + } + return CollectionUtils.unmodifiableList(builder); + } + } + + protected boolean hasRow() { + SQLQuery query = new SQLQuery(connection(), configuration).from(entity); + for (SQLListener listener : listeners.getListeners()) { + query.addListener(listener); + } + query.addListener(SQLNoCloseListener.DEFAULT); + addKeyConditions(query); + return query.select(Expressions.ONE).fetchFirst() != null; + } + + @SuppressWarnings("unchecked") + protected void addKeyConditions(FilteredClause query) { + List> keys = getKeys(); + for (int i = 0; i < columns.size(); i++) { + if (keys.contains(columns.get(i))) { + if (values.get(i) instanceof NullExpression) { + query.where(ExpressionUtils.isNull(columns.get(i))); + } else { + query.where(ExpressionUtils.eq(columns.get(i),(Expression) values.get(i))); + } + } + } + } + + @SuppressWarnings("unchecked") + protected long executeCompositeMerge() { + if (hasRow()) { + // update + SQLUpdateClause update = new SQLUpdateClause(connection(), configuration, entity); + populate(update); + addListeners(update); + addKeyConditions(update); + return update.execute(); + } else { + // insert + SQLInsertClause insert = new SQLInsertClause(connection(), configuration, entity); + addListeners(insert); + populate(insert); + return insert.execute(); + + } + } + + protected void addListeners(AbstractSQLClause clause) { + for (SQLListener listener : listeners.getListeners()) { + clause.addListener(listener); + } + } + + @SuppressWarnings("unchecked") + protected void populate(StoreClause clause) { + for (int i = 0; i < columns.size(); i++) { + clause.set((Path) columns.get(i), (Object) values.get(i)); + } + } + + protected PreparedStatement createStatement(boolean withKeys) throws SQLException { + boolean addBatches = !configuration.getUseLiterals(); + listeners.preRender(context); + SQLSerializer serializer = createSerializer(); + PreparedStatement stmt = null; + if (batches.isEmpty()) { + serializer.serializeMerge(metadata, entity, keys, columns, values, subQuery); + context.addSQL(createBindings(metadata, serializer)); + listeners.rendered(context); + + listeners.prePrepare(context); + stmt = prepareStatementAndSetParameters(serializer, withKeys); + context.addPreparedStatement(stmt); + listeners.prepared(context); + } else { + serializer.serializeMerge(metadata, entity, + batches.get(0).getKeys(), batches.get(0).getColumns(), + batches.get(0).getValues(), batches.get(0).getSubQuery()); + context.addSQL(createBindings(metadata, serializer)); + listeners.rendered(context); + + stmt = prepareStatementAndSetParameters(serializer, withKeys); + + // add first batch + if (addBatches) { + stmt.addBatch(); + } + + // add other batches + for (int i = 1; i < batches.size(); i++) { + SQLMergeBatch batch = batches.get(i); + listeners.preRender(context); + serializer = createSerializer(); + serializer.serializeMerge(metadata, entity, batch.getKeys(), batch.getColumns(), batch.getValues(), batch.getSubQuery()); + context.addSQL(createBindings(metadata, serializer)); + listeners.rendered(context); + + setParameters(stmt, serializer.getConstants(), serializer.getConstantPaths(), metadata.getParams()); + if (addBatches) { + stmt.addBatch(); + } + } + } + return stmt; + } + + protected Collection createStatements(boolean withKeys) throws SQLException { + boolean addBatches = !configuration.getUseLiterals(); + Map stmts = new HashMap<>(); + + // add first batch + listeners.preRender(context); + SQLSerializer serializer = createSerializer(); + serializer.serializeMerge(metadata, entity, + batches.get(0).getKeys(), batches.get(0).getColumns(), + batches.get(0).getValues(), batches.get(0).getSubQuery()); + context.addSQL(createBindings(metadata, serializer)); + listeners.rendered(context); + + PreparedStatement stmt = prepareStatementAndSetParameters(serializer, withKeys); + stmts.put(serializer.toString(), stmt); + if (addBatches) { + stmt.addBatch(); + } + + // add other batches + for (int i = 1; i < batches.size(); i++) { + SQLMergeBatch batch = batches.get(i); + serializer = createSerializer(); + serializer.serializeMerge(metadata, entity, + batch.getKeys(), batch.getColumns(), batch.getValues(), batch.getSubQuery()); + stmt = stmts.get(serializer.toString()); + if (stmt == null) { + stmt = prepareStatementAndSetParameters(serializer, withKeys); + stmts.put(serializer.toString(), stmt); + } else { + setParameters(stmt, serializer.getConstants(), serializer.getConstantPaths(), metadata.getParams()); + } + if (addBatches) { + stmt.addBatch(); + } + } + + return stmts.values(); + } + + protected PreparedStatement prepareStatementAndSetParameters(SQLSerializer serializer, + boolean withKeys) throws SQLException { + listeners.prePrepare(context); + + queryString = serializer.toString(); + constants = serializer.getConstants(); + logQuery(logger, queryString, constants); + PreparedStatement stmt; + if (withKeys) { + String[] target = new String[keys.size()]; + for (int i = 0; i < target.length; i++) { + target[i] = ColumnMetadata.getName(getKeys().get(i)); + } + stmt = connection().prepareStatement(queryString, target); + } else { + stmt = connection().prepareStatement(queryString); + } + setParameters(stmt, serializer.getConstants(), serializer.getConstantPaths(), metadata.getParams()); + context.addPreparedStatement(stmt); + listeners.prepared(context); + + return stmt; + } + + protected long executeNativeMerge() { + context = startContext(connection(), metadata, entity); + PreparedStatement stmt = null; + Collection stmts = null; + try { + if (batches.isEmpty()) { + stmt = createStatement(false); + listeners.notifyMerge(entity, metadata, keys, columns, values, subQuery); + + listeners.preExecute(context); + int rc = stmt.executeUpdate(); + listeners.executed(context); + return rc; + } else { + stmts = createStatements(false); + listeners.notifyMerges(entity, metadata, batches); + + listeners.preExecute(context); + long rc = executeBatch(stmts); + listeners.executed(context); + return rc; + } + } catch (SQLException e) { + onException(context,e); + throw configuration.translate(queryString, constants, e); + } finally { + if (stmt != null) { + close(stmt); + } + if (stmts != null) { + close(stmts); + } + reset(); + endContext(context); + } + } + + /** + * Set the keys to be used in the MERGE clause + * + * @param paths keys + * @return the current object + */ + public SQLMergeClause keys(Path... paths) { + keys.addAll(Arrays.asList(paths)); + return this; + } + + public SQLMergeClause select(SubQueryExpression subQuery) { + this.subQuery = subQuery; + return this; + } + + @Override + public SQLMergeClause set(Path path, @Nullable T value) { + columns.add(path); + if (value != null) { + values.add(ConstantImpl.create(value)); + } else { + values.add(Null.CONSTANT); + } + return this; + } + + @Override + public SQLMergeClause set(Path path, Expression expression) { + columns.add(path); + values.add(expression); + return this; + } + + @Override + public SQLMergeClause setNull(Path path) { + columns.add(path); + values.add(Null.CONSTANT); + return this; + } + + @Override + public String toString() { + SQLSerializer serializer = createSerializer(); + serializer.serializeMerge(metadata, entity, keys, columns, values, subQuery); + return serializer.toString(); + } + + public SQLMergeClause values(Object... v) { + for (Object value : v) { + if (value instanceof Expression) { + values.add((Expression) value); + } else if (value != null) { + values.add(ConstantImpl.create(value)); + } else { + values.add(Null.CONSTANT); + } + } + return this; + } + + @Override + public boolean isEmpty() { + return values.isEmpty() && batches.isEmpty(); + } + + @Override + public int getBatchCount() { + return batches.size(); + } + +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/dml/SQLUpdateBatch.java b/querydsl-sql/src/main/java/com/querydsl/sql/dml/SQLUpdateBatch.java new file mode 100644 index 0000000000..1ff45743ff --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/dml/SQLUpdateBatch.java @@ -0,0 +1,47 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.dml; + +import java.util.Map; + +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.Path; + +/** + * {@code SQLUpdateBatch} defines the state of an SQL UPDATE batch item + * + * @author tiwe + * + */ +public class SQLUpdateBatch { + + private final QueryMetadata metadata; + + private final Map,Expression> updates; + + public SQLUpdateBatch(QueryMetadata metadata, Map,Expression> updates) { + this.metadata = metadata; + this.updates = updates; + } + + public QueryMetadata getMetadata() { + return metadata; + } + + public Map, Expression> getUpdates() { + return updates; + } + +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/dml/SQLUpdateClause.java b/querydsl-sql/src/main/java/com/querydsl/sql/dml/SQLUpdateClause.java new file mode 100644 index 0000000000..6f9e48c507 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/dml/SQLUpdateClause.java @@ -0,0 +1,39 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.dml; + +import java.sql.Connection; +import java.util.function.Supplier; + +import com.querydsl.sql.Configuration; +import com.querydsl.sql.RelationalPath; +import com.querydsl.sql.SQLTemplates; + +/** + * Defines an UPDATE clause. + * If you need to subtype this, use {@link AbstractSQLUpdateClause} instead. + */ +public class SQLUpdateClause extends AbstractSQLUpdateClause { + public SQLUpdateClause(Connection connection, SQLTemplates templates, RelationalPath entity) { + super(connection, new Configuration(templates), entity); + } + + public SQLUpdateClause(Connection connection, Configuration configuration, RelationalPath entity) { + super(connection, configuration, entity); + } + + public SQLUpdateClause(Supplier connection, Configuration configuration, RelationalPath entity) { + super(connection, configuration, entity); + } +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/dml/package-info.java b/querydsl-sql/src/main/java/com/querydsl/sql/dml/package-info.java new file mode 100644 index 0000000000..46ac409471 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/dml/package-info.java @@ -0,0 +1,19 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ + + +/** + * DML operations support + */ +package com.querydsl.sql.dml; diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/mssql/AbstractSQLServerQuery.java b/querydsl-sql/src/main/java/com/querydsl/sql/mssql/AbstractSQLServerQuery.java new file mode 100644 index 0000000000..07f2e9d782 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/mssql/AbstractSQLServerQuery.java @@ -0,0 +1,54 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.mssql; + +import java.sql.Connection; +import java.util.function.Supplier; + +import com.querydsl.core.JoinFlag; +import com.querydsl.core.QueryMetadata; +import com.querydsl.sql.AbstractSQLQuery; +import com.querydsl.sql.Configuration; + +/** + * {@code AbstractSQLServerQuery} provides SQL Server related extensions to SQLQuery + * + * @param result type + * @param the concrete subtype + * + * @author tiwe + */ +public abstract class AbstractSQLServerQuery> extends AbstractSQLQuery { + public AbstractSQLServerQuery(Connection conn, Configuration configuration, QueryMetadata metadata) { + super(conn, configuration, metadata); + } + + public AbstractSQLServerQuery(Supplier connProvider, Configuration configuration, QueryMetadata metadata) { + super(connProvider, configuration, metadata); + } + + /** + * Set the table hints + * + * @param tableHints table hints + * @return the current object + */ + public C tableHints(SQLServerTableHints... tableHints) { + if (tableHints.length > 0) { + String hints = SQLServerGrammar.tableHints(tableHints); + addJoinFlag(hints, JoinFlag.Position.BEFORE_CONDITION); + } + return (C) this; + } +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/mssql/SQLServerGrammar.java b/querydsl-sql/src/main/java/com/querydsl/sql/mssql/SQLServerGrammar.java new file mode 100644 index 0000000000..d768b8eac0 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/mssql/SQLServerGrammar.java @@ -0,0 +1,39 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.mssql; + + +/** + * Convenience functions and constants for SQL Server usage + * + * @author tiwe + * + */ +final class SQLServerGrammar { + + private SQLServerGrammar() { } + + static String tableHints(SQLServerTableHints... tableHints) { + StringBuilder hints = new StringBuilder(" with ").append("("); + for (int i = 0; i < tableHints.length; i++) { + if (i > 0) { + hints.append(", "); + } + hints.append(tableHints[i].name()); + } + hints.append(")"); + return hints.toString(); + } + +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/mssql/SQLServerQuery.java b/querydsl-sql/src/main/java/com/querydsl/sql/mssql/SQLServerQuery.java new file mode 100644 index 0000000000..91e39188bf --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/mssql/SQLServerQuery.java @@ -0,0 +1,89 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.mssql; + +import java.sql.Connection; +import java.util.function.Supplier; + +import com.querydsl.core.DefaultQueryMetadata; +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.Tuple; +import com.querydsl.core.types.Expression; +import com.querydsl.sql.Configuration; +import com.querydsl.sql.SQLServerTemplates; +import com.querydsl.sql.SQLTemplates; + +/** + * {@code SQLServerQuery} provides SQL Server related extensions to SQLQuery + * + * If you need to subtype this, use the base class instead. + * + * @param result type + * + * @author tiwe + */ +public class SQLServerQuery extends AbstractSQLServerQuery> { + + public SQLServerQuery(Connection conn) { + this(conn, SQLServerTemplates.DEFAULT, new DefaultQueryMetadata()); + } + + public SQLServerQuery(Connection conn, SQLTemplates templates) { + this(conn, templates, new DefaultQueryMetadata()); + } + + protected SQLServerQuery(Connection conn, SQLTemplates templates, QueryMetadata metadata) { + super(conn, new Configuration(templates), metadata); + } + + public SQLServerQuery(Connection conn, Configuration configuration, QueryMetadata metadata) { + super(conn, configuration, metadata); + } + + public SQLServerQuery(Connection conn, Configuration configuration) { + super(conn, configuration, new DefaultQueryMetadata()); + } + + public SQLServerQuery(Supplier connProvider, Configuration configuration, QueryMetadata metadata) { + super(connProvider, configuration, metadata); + } + + public SQLServerQuery(Supplier connProvider, Configuration configuration) { + super(connProvider, configuration, new DefaultQueryMetadata()); + } + + @Override + public SQLServerQuery clone(Connection conn) { + SQLServerQuery q = new SQLServerQuery(conn, getConfiguration(), getMetadata().clone()); + q.clone(this); + return q; + } + + @Override + public SQLServerQuery select(Expression expr) { + queryMixin.setProjection(expr); + @SuppressWarnings("unchecked") // This is the new type + SQLServerQuery newType = (SQLServerQuery) this; + return newType; + } + + @Override + public SQLServerQuery select(Expression... exprs) { + queryMixin.setProjection(exprs); + @SuppressWarnings("unchecked") // This is the new type + SQLServerQuery newType = (SQLServerQuery) this; + return newType; + } + +} \ No newline at end of file diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/mssql/SQLServerQueryFactory.java b/querydsl-sql/src/main/java/com/querydsl/sql/mssql/SQLServerQueryFactory.java new file mode 100644 index 0000000000..da935102ad --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/mssql/SQLServerQueryFactory.java @@ -0,0 +1,84 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.mssql; + +import java.sql.Connection; +import java.util.function.Supplier; + +import com.querydsl.core.Tuple; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.sql.*; + +/** + * SQL Server specific implementation of SQLQueryFactory + * + * @author tiwe + * + */ +public class SQLServerQueryFactory extends AbstractSQLQueryFactory> { + + public SQLServerQueryFactory(Configuration configuration, Supplier connection) { + super(configuration, connection); + } + + public SQLServerQueryFactory(Supplier connection) { + this(new Configuration(new SQLServerTemplates()), connection); + } + + public SQLServerQueryFactory(SQLTemplates templates, Supplier connection) { + this(new Configuration(templates), connection); + } + + @Override + public SQLServerQuery query() { + return new SQLServerQuery(connection, configuration); + } + + @Override + public SQLServerQuery select(Expression expr) { + return query().select(expr); + } + + @Override + public SQLServerQuery select(Expression... exprs) { + return query().select(exprs); + } + + @Override + public SQLServerQuery selectDistinct(Expression expr) { + return query().select(expr).distinct(); + } + + @Override + public SQLServerQuery selectDistinct(Expression... exprs) { + return query().select(exprs).distinct(); + } + + @Override + public SQLServerQuery selectZero() { + return select(Expressions.ZERO); + } + + @Override + public SQLServerQuery selectOne() { + return select(Expressions.ONE); + } + + @Override + public SQLServerQuery selectFrom(RelationalPath expr) { + return select(expr).from(expr); + } + +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/mssql/SQLServerTableHints.java b/querydsl-sql/src/main/java/com/querydsl/sql/mssql/SQLServerTableHints.java new file mode 100644 index 0000000000..c89d0f622f --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/mssql/SQLServerTableHints.java @@ -0,0 +1,40 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.mssql; + +/** + * Table hints constants for SQLServerQuery + * + * @author tiwe + */ +public enum SQLServerTableHints { + NOEXPAND, + FASTFIRSTROW, + FORCESEEK, + HOLDLOCK, + NOLOCK, + NOWAIT, + PAGLOCK, + READCOMMITTED, + READCOMMITTEDLOCK, + READPAST, + READUNCOMMITTED, + REPEATABLEREAD, + ROWLOCK, + SERIALIZABLE, + TABLOCK, + TABLOCKX, + UPDLOCK, + XLOCK +} \ No newline at end of file diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/mssql/package-info.java b/querydsl-sql/src/main/java/com/querydsl/sql/mssql/package-info.java new file mode 100644 index 0000000000..beb86de28a --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/mssql/package-info.java @@ -0,0 +1,19 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ + + +/** + * SQL Server support + */ +package com.querydsl.sql.mssql; diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/mysql/AbstractMySQLQuery.java b/querydsl-sql/src/main/java/com/querydsl/sql/mysql/AbstractMySQLQuery.java new file mode 100644 index 0000000000..1afcaff810 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/mysql/AbstractMySQLQuery.java @@ -0,0 +1,235 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.mysql; + +import java.io.File; +import java.sql.Connection; +import java.util.function.Supplier; + +import com.querydsl.core.JoinFlag; +import com.querydsl.core.QueryFlag.Position; +import com.querydsl.core.QueryMetadata; +import com.querydsl.sql.AbstractSQLQuery; +import com.querydsl.sql.Configuration; +import com.querydsl.sql.SQLQuery; + +/** + * {@code MySQLQuery} provides MySQL related extensions to SQLQuery. + * + * @author tiwe + * @see SQLQuery + * @param result type + * @param the concrete subtype + */ +public abstract class AbstractMySQLQuery> extends AbstractSQLQuery { + + protected static final String WITH_ROLLUP = "\nwith rollup "; + + protected static final String STRAIGHT_JOIN = "straight_join "; + + protected static final String SQL_SMALL_RESULT = "sql_small_result "; + + protected static final String SQL_NO_CACHE = "sql_no_cache "; + + protected static final String LOCK_IN_SHARE_MODE = "\nlock in share mode "; + + protected static final String HIGH_PRIORITY = "high_priority "; + + protected static final String SQL_CALC_FOUND_ROWS = "sql_calc_found_rows "; + + protected static final String SQL_CACHE = "sql_cache "; + + protected static final String SQL_BUFFER_RESULT = "sql_buffer_result "; + + protected static final String SQL_BIG_RESULT = "sql_big_result "; + + public AbstractMySQLQuery(Connection conn, Configuration configuration, QueryMetadata metadata) { + super(conn, configuration, metadata); + } + + public AbstractMySQLQuery(Supplier connProvider, Configuration configuration, QueryMetadata metadata) { + super(connProvider, configuration, metadata); + } + + /** + * For SQL_BIG_RESULT, MySQL directly uses disk-based temporary tables if needed, and prefers + * sorting to using a temporary table with a key on the GROUP BY elements. + * + * @return the current object + */ + public C bigResult() { + return addFlag(Position.AFTER_SELECT, SQL_BIG_RESULT); + } + + /** + * SQL_BUFFER_RESULT forces the result to be put into a temporary table. This helps MySQL free + * the table locks early and helps in cases where it takes a long time to send the result set + * to the client. This option can be used only for top-level SELECT statements, not for + * subqueries or following UNION. + * + * @return the current object + */ + public C bufferResult() { + return addFlag(Position.AFTER_SELECT, SQL_BUFFER_RESULT); + } + + /** + * SQL_CACHE tells MySQL to store the result in the query cache if it is cacheable and the value + * of the query_cache_type system variable is 2 or DEMAND. + * + * @return the current object + */ + public C cache() { + return addFlag(Position.AFTER_SELECT, SQL_CACHE); + } + + /** + * SQL_CALC_FOUND_ROWS tells MySQL to calculate how many rows there would be in the result set, + * disregarding any LIMIT clause. The number of rows can then be retrieved with SELECT FOUND_ROWS(). + * + * @return the current object + */ + public C calcFoundRows() { + return addFlag(Position.AFTER_SELECT, SQL_CALC_FOUND_ROWS); + } + + /** + * HIGH_PRIORITY gives the SELECT higher priority than a statement that updates a table. + * You should use this only for queries that are very fast and must be done at once. + * + * @return the current object + */ + public C highPriority() { + return addFlag(Position.AFTER_SELECT, HIGH_PRIORITY); + } + + /** + * SELECT ... INTO var_list selects column values and stores them into variables. + * + * @param var variable name + * @return the current object + */ + public C into(String var) { + return addFlag(Position.END, "\ninto " + var); + } + + /** + * SELECT ... INTO DUMPFILE writes a single row to a file without any formatting. + * + * @param file file to write to + * @return the current object + */ + public C intoDumpfile(File file) { + return addFlag(Position.END, "\ninto dumpfile '" + file.getPath() + "'"); + } + + /** + * SELECT ... INTO OUTFILE writes the selected rows to a file. Column and line terminators c + * an be specified to produce a specific output format. + * + * @param file file to write to + * @return the current object + */ + public C intoOutfile(File file) { + return addFlag(Position.END, "\ninto outfile '" + file.getPath() + "'"); + } + + /** + * Using LOCK IN SHARE MODE sets a shared lock that permits other transactions to read the examined + * rows but not to update or delete them. + * + * @return the current object + */ + public C lockInShareMode() { + return addFlag(Position.END, LOCK_IN_SHARE_MODE); + } + + /** + * With SQL_NO_CACHE, the server does not use the query cache. It neither checks the query cache + * to see whether the result is already cached, nor does it cache the query result. + * + * @return the current object + */ + public C noCache() { + return addFlag(Position.AFTER_SELECT, SQL_NO_CACHE); + } + + /** + * For SQL_SMALL_RESULT, MySQL uses fast temporary tables to store the resulting table instead + * of using sorting. This should not normally be needed. + * + * @return the current object + */ + public C smallResult() { + return addFlag(Position.AFTER_SELECT, SQL_SMALL_RESULT); + } + + /** + * STRAIGHT_JOIN forces the optimizer to join the tables in the order in which they are listed + * in the FROM clause. You can use this to speed up a query if the optimizer joins the tables + * in nonoptimal order. STRAIGHT_JOIN also can be used in the table_references list. + * + * @return the current object + */ + public C straightJoin() { + return addFlag(Position.AFTER_SELECT, STRAIGHT_JOIN); + } + + /** + * You can use FORCE INDEX, which acts like USE INDEX (index_list) but with the addition that a + * table scan is assumed to be very expensive. In other words, a table scan is used only if there + * is no way to use one of the given indexes to find rows in the table. + * + * @param indexes index names + * @return the current object + */ + public C forceIndex(String... indexes) { + return addJoinFlag(" force index (" + String.join(", ", indexes) + ")", JoinFlag.Position.END); + } + + /** + * The alternative syntax IGNORE INDEX (index_list) can be used to tell MySQL to not use some + * particular index or indexes. + * + * @param indexes index names + * @return the current object + */ + public C ignoreIndex(String... indexes) { + return addJoinFlag(" ignore index (" + String.join(", ", indexes) + ")", JoinFlag.Position.END); + } + + /** + * By specifying USE INDEX (index_list), you can tell MySQL to use only one of the named indexes + * to find rows in the table. + * + * @param indexes index names + * @return the current object + */ + public C useIndex(String... indexes) { + return addJoinFlag(" use index (" + String.join(", ", indexes) + ")", JoinFlag.Position.END); + } + + /** + * The GROUP BY clause permits a WITH ROLLUP modifier that causes extra rows to be added to the + * summary output. These rows represent higher-level (or super-aggregate) summary operations. + * ROLLUP thus enables you to answer questions at multiple levels of analysis with a single query. + * It can be used, for example, to provide support for OLAP (Online Analytical Processing) operations. + * + * @return the current object + */ + public C withRollup() { + return addFlag(Position.AFTER_GROUP_BY, WITH_ROLLUP); + } + +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/mysql/MySQLQuery.java b/querydsl-sql/src/main/java/com/querydsl/sql/mysql/MySQLQuery.java new file mode 100644 index 0000000000..2d0d1e3c4d --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/mysql/MySQLQuery.java @@ -0,0 +1,84 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.mysql; + +import java.sql.Connection; +import java.util.function.Supplier; + +import com.querydsl.core.DefaultQueryMetadata; +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.Tuple; +import com.querydsl.core.types.Expression; +import com.querydsl.sql.Configuration; +import com.querydsl.sql.MySQLTemplates; +import com.querydsl.sql.SQLTemplates; + +/** + * {@code MySQLQuery} provides MySQL related extensions to SQLQuery. + * + * If you need to subtype this, use the base class instead. + * + * @param the result type + */ +public class MySQLQuery extends AbstractMySQLQuery> { + public MySQLQuery(Connection conn) { + this(conn, new Configuration(MySQLTemplates.DEFAULT), new DefaultQueryMetadata()); + } + + public MySQLQuery(Connection conn, SQLTemplates templates) { + this(conn, new Configuration(templates), new DefaultQueryMetadata()); + } + + public MySQLQuery(Connection conn, Configuration configuration) { + this(conn, configuration, new DefaultQueryMetadata()); + } + + public MySQLQuery(Connection conn, Configuration configuration, QueryMetadata metadata) { + super(conn, configuration, metadata); + } + + public MySQLQuery(Supplier connProvider, Configuration configuration, QueryMetadata metadata) { + super(connProvider, configuration, metadata); + } + + public MySQLQuery(Supplier connProvider, Configuration configuration) { + super(connProvider, configuration, new DefaultQueryMetadata()); + } + + @Override + public MySQLQuery clone(Connection conn) { + MySQLQuery q = new MySQLQuery(conn, getConfiguration(), getMetadata().clone()); + q.clone(this); + return q; + } + + @Override + public MySQLQuery select(Expression expr) { + queryMixin.setProjection(expr); + + @SuppressWarnings("unchecked") + MySQLQuery res = (MySQLQuery) this; + return res; + } + + @Override + public MySQLQuery select(Expression... exprs) { + queryMixin.setProjection(exprs); + + @SuppressWarnings("unchecked") + MySQLQuery res = (MySQLQuery) this; + return res; + } + +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/mysql/MySQLQueryFactory.java b/querydsl-sql/src/main/java/com/querydsl/sql/mysql/MySQLQueryFactory.java new file mode 100644 index 0000000000..813e366cf3 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/mysql/MySQLQueryFactory.java @@ -0,0 +1,146 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.mysql; + +import java.sql.Connection; +import java.util.function.Supplier; + +import com.querydsl.core.QueryFlag.Position; +import com.querydsl.core.Tuple; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.ExpressionUtils; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.sql.*; +import com.querydsl.sql.dml.SQLInsertClause; + +/** + * MySQL specific implementation of SQLQueryFactory + * + * @author tiwe + * + */ +public class MySQLQueryFactory extends AbstractSQLQueryFactory> { + + public MySQLQueryFactory(Configuration configuration, Supplier connection) { + super(configuration, connection); + } + + public MySQLQueryFactory(Supplier connection) { + this(new Configuration(new MySQLTemplates()), connection); + } + + public MySQLQueryFactory(SQLTemplates templates, Supplier connection) { + this(new Configuration(templates), connection); + } + + /** + * Create a INSERT IGNORE INTO clause + * + * @param entity table to insert to + * @return insert clause + */ + public SQLInsertClause insertIgnore(RelationalPath entity) { + SQLInsertClause insert = insert(entity); + insert.addFlag(Position.START_OVERRIDE, "insert ignore into "); + return insert; + } + + /** + * Create a INSERT ... ON DUPLICATE KEY UPDATE clause + * + * @param entity table to insert to + * @param clause clause + * @return insert clause + */ + public SQLInsertClause insertOnDuplicateKeyUpdate(RelationalPath entity, String clause) { + SQLInsertClause insert = insert(entity); + insert.addFlag(Position.END, " on duplicate key update " + clause); + return insert; + } + + /** + * Create a INSERT ... ON DUPLICATE KEY UPDATE clause + * + * @param entity table to insert to + * @param clause clause + * @return insert clause + */ + public SQLInsertClause insertOnDuplicateKeyUpdate(RelationalPath entity, Expression clause) { + SQLInsertClause insert = insert(entity); + insert.addFlag(Position.END, ExpressionUtils.template(String.class, " on duplicate key update {0}", clause)); + return insert; + } + + /** + * Create a INSERT ... ON DUPLICATE KEY UPDATE clause + * + * @param entity table to insert to + * @param clauses clauses + * @return insert clause + */ + public SQLInsertClause insertOnDuplicateKeyUpdate(RelationalPath entity, Expression... clauses) { + SQLInsertClause insert = insert(entity); + StringBuilder flag = new StringBuilder(" on duplicate key update "); + for (int i = 0; i < clauses.length; i++) { + flag.append(i > 0 ? ", " : "").append("{").append(i).append("}"); + } + insert.addFlag(Position.END, ExpressionUtils.template(String.class, flag.toString(), clauses)); + return insert; + } + + @Override + public MySQLQuery query() { + return new MySQLQuery(connection, configuration); + } + + public MySQLReplaceClause replace(RelationalPath entity) { + return new MySQLReplaceClause(connection.get(), configuration, entity); + } + + @Override + public MySQLQuery select(Expression expr) { + return query().select(expr); + } + + @Override + public MySQLQuery select(Expression... exprs) { + return query().select(exprs); + } + + @Override + public MySQLQuery selectDistinct(Expression expr) { + return query().select(expr).distinct(); + } + + @Override + public MySQLQuery selectDistinct(Expression... exprs) { + return query().select(exprs).distinct(); + } + + @Override + public MySQLQuery selectZero() { + return select(Expressions.ZERO); + } + + @Override + public MySQLQuery selectOne() { + return select(Expressions.ONE); + } + + @Override + public MySQLQuery selectFrom(RelationalPath expr) { + return select(expr).from(expr); + } + +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/mysql/MySQLReplaceClause.java b/querydsl-sql/src/main/java/com/querydsl/sql/mysql/MySQLReplaceClause.java new file mode 100644 index 0000000000..a255347621 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/mysql/MySQLReplaceClause.java @@ -0,0 +1,47 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.mysql; + +import java.sql.Connection; + +import com.querydsl.core.QueryFlag.Position; +import com.querydsl.sql.Configuration; +import com.querydsl.sql.RelationalPath; +import com.querydsl.sql.SQLTemplates; +import com.querydsl.sql.dml.SQLInsertClause; + +/** + * {@code MySQLReplaceClause} is a REPLACE INTO clause + * + *

REPLACE works exactly like INSERT, except that if an old row in the table has the same value + * as a new row for a PRIMARY KEY or a UNIQUE index, the old row is deleted before the new row is inserted.

+ * + * @author tiwe + * + */ +public class MySQLReplaceClause extends SQLInsertClause { + + protected static final String REPLACE_INTO = "replace into "; + + public MySQLReplaceClause(Connection connection, SQLTemplates templates, RelationalPath entity) { + super(connection, templates, entity); + addFlag(Position.START_OVERRIDE, REPLACE_INTO); + } + + public MySQLReplaceClause(Connection connection, Configuration configuration, RelationalPath entity) { + super(connection, configuration, entity); + addFlag(Position.START_OVERRIDE, REPLACE_INTO); + } + +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/mysql/package-info.java b/querydsl-sql/src/main/java/com/querydsl/sql/mysql/package-info.java new file mode 100644 index 0000000000..28f547be78 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/mysql/package-info.java @@ -0,0 +1,19 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ + + +/** + * MySQL support + */ +package com.querydsl.sql.mysql; diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/namemapping/ChainedNameMapping.java b/querydsl-sql/src/main/java/com/querydsl/sql/namemapping/ChainedNameMapping.java new file mode 100644 index 0000000000..a6ae84dfda --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/namemapping/ChainedNameMapping.java @@ -0,0 +1,62 @@ +/* + * Copyright 2018, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.namemapping; + +import com.querydsl.sql.SchemaAndTable; + +import java.util.Optional; + +/** + * A {@link NameMapping} implementation that accepts zero or more + * {@link NameMapping}s and returns the first non-null mapping result. + */ +public class ChainedNameMapping implements NameMapping { + + private NameMapping[] nameMappings; + + public ChainedNameMapping(NameMapping... nameMappings) { + if (nameMappings == null) { + throw new NullPointerException("Name mapping array must not be null"); + } + for (NameMapping nameMapping : nameMappings) { + if (nameMapping == null) { + throw new NullPointerException("Name mapping array must not contain null element"); + } + } + this.nameMappings = nameMappings.clone(); + } + + @Override + public Optional getColumnOverride(SchemaAndTable key, String column) { + for (NameMapping nameMapping : nameMappings) { + Optional overriddenColumnName = nameMapping.getColumnOverride(key, column); + if (overriddenColumnName.isPresent()) { + return overriddenColumnName; + } + } + return Optional.empty(); + } + + @Override + public Optional getOverride(SchemaAndTable key) { + for (NameMapping nameMapping : nameMappings) { + Optional overridden = nameMapping.getOverride(key); + if (overridden.isPresent()) { + return overridden; + } + } + return Optional.empty(); + } + +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/namemapping/ChangeLetterCaseNameMapping.java b/querydsl-sql/src/main/java/com/querydsl/sql/namemapping/ChangeLetterCaseNameMapping.java new file mode 100644 index 0000000000..d190bfd713 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/namemapping/ChangeLetterCaseNameMapping.java @@ -0,0 +1,72 @@ +/* + * Copyright 2018, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.namemapping; + +import java.util.Locale; +import java.util.Objects; +import java.util.Optional; + +import com.querydsl.sql.SchemaAndTable; + +/** + * Simple implementation of {@link NameMapping} that changes the letter-case + * (lower-case or upper-case) of the schema, table and column names. The + * information how the database stores the identifiers are available normally + * from the stores*Identifiers function of the + * {@link java.sql.DatabaseMetaData} + */ +public class ChangeLetterCaseNameMapping implements NameMapping { + + /** + * The target character-case (lower or upper) that the + * {@link ChangeLetterCaseNameMapping} should use to convert the identifiers + * names. + */ + public enum LetterCase { + LOWER, UPPER + } + + private Locale locale; + + private final LetterCase targetCase; + + /** + * Constructor. + * @param targetCase The characters of all table and column names will be converted to the specified letter-case. + * @param locale The locale that is used for the letter-case conversion. + */ + public ChangeLetterCaseNameMapping(LetterCase targetCase, Locale locale) { + this.locale = Objects.requireNonNull(locale); + this.targetCase = Objects.requireNonNull(targetCase); + } + + @Override + public Optional getColumnOverride(SchemaAndTable key, String column) { + return Optional.ofNullable(targetCaseOrNull(column)); + } + + @Override + public Optional getOverride(SchemaAndTable key) { + return Optional.of(new SchemaAndTable(targetCaseOrNull(key.getSchema()), targetCaseOrNull(key.getTable()))); + } + + private String targetCaseOrNull(String text) { + if (targetCase == LetterCase.LOWER) { + return text.toLowerCase(locale); + } else { + return text.toUpperCase(locale); + } + } + +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/namemapping/NameMapping.java b/querydsl-sql/src/main/java/com/querydsl/sql/namemapping/NameMapping.java new file mode 100644 index 0000000000..51e396717a --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/namemapping/NameMapping.java @@ -0,0 +1,30 @@ +/* + * Copyright 2018, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.namemapping; + +import com.querydsl.sql.SchemaAndTable; + +import java.util.Optional; + +/** + * By implementing this interface, it is possible to programmatically override + * schema, table and column names. + */ +public interface NameMapping { + + Optional getColumnOverride(SchemaAndTable key, String column); + + Optional getOverride(SchemaAndTable key); + +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/namemapping/PreConfiguredNameMapping.java b/querydsl-sql/src/main/java/com/querydsl/sql/namemapping/PreConfiguredNameMapping.java new file mode 100644 index 0000000000..eec0ffdd98 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/namemapping/PreConfiguredNameMapping.java @@ -0,0 +1,82 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.namemapping; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +import com.querydsl.sql.SchemaAndTable; + +/** + * {@link NameMapping} implementation that allows specifying exact schema, table and column name mappings. + */ +public class PreConfiguredNameMapping implements NameMapping { + + private final Map schemaTables = new HashMap<>(); + + private final Map tables = new HashMap<>(); + + private final Map> schemaTableColumns = new HashMap<>(); + + private final Map> tableColumns = new HashMap<>(); + + public Optional getOverride(SchemaAndTable key) { + if (!schemaTables.isEmpty() && key.getSchema() != null) { + if (schemaTables.containsKey(key)) { + return Optional.ofNullable(schemaTables.get(key)); + } + } + + if (tables.containsKey(key.getTable())) { + String table = tables.get(key.getTable()); + return Optional.of(new SchemaAndTable(key.getSchema(), table)); + } + return Optional.empty(); + } + + public Optional getColumnOverride(SchemaAndTable key, String column) { + Map columnOverrides; + String newColumn = null; + columnOverrides = schemaTableColumns.get(key); + if (columnOverrides != null && (newColumn = columnOverrides.get(column)) != null) { + return Optional.of(newColumn); + } + columnOverrides = tableColumns.get(key.getTable()); + if (columnOverrides != null && (newColumn = columnOverrides.get(column)) != null) { + return Optional.of(newColumn); + } + return Optional.empty(); + } + + public String registerTableOverride(String oldTable, String newTable) { + return tables.put(oldTable, newTable); + } + + public SchemaAndTable registerTableOverride(SchemaAndTable from, SchemaAndTable to) { + return schemaTables.put(from, to); + } + + public String registerColumnOverride(String schema, String table, String oldColumn, String newColumn) { + SchemaAndTable key = new SchemaAndTable(schema, table); + Map columnOverrides = schemaTableColumns.computeIfAbsent(key, k -> new HashMap()); + return columnOverrides.put(oldColumn, newColumn); + } + + public String registerColumnOverride(String table, String oldColumn, String newColumn) { + Map columnOverrides = tableColumns.computeIfAbsent(table, k -> new HashMap()); + return columnOverrides.put(oldColumn, newColumn); + } + +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/namemapping/package-info.java b/querydsl-sql/src/main/java/com/querydsl/sql/namemapping/package-info.java new file mode 100644 index 0000000000..b9d9fcc57c --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/namemapping/package-info.java @@ -0,0 +1,18 @@ +/* + * Copyright 2018, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ + +/** + * Changing database identifier names in serialized SQL queries. + */ +package com.querydsl.sql.namemapping; diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/oracle/AbstractOracleQuery.java b/querydsl-sql/src/main/java/com/querydsl/sql/oracle/AbstractOracleQuery.java new file mode 100644 index 0000000000..b6ffd99fe2 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/oracle/AbstractOracleQuery.java @@ -0,0 +1,113 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.oracle; + +import java.sql.Connection; +import java.util.function.Supplier; + +import com.querydsl.core.QueryFlag.Position; +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.Predicate; +import com.querydsl.sql.AbstractSQLQuery; +import com.querydsl.sql.Configuration; + +/** + * {@code OracleQuery} provides Oracle specific extensions to the base SQL query type + * + * @author tiwe + * @param result type + * @param the concrete subtype + */ +public abstract class AbstractOracleQuery> extends AbstractSQLQuery { + + protected static final String CONNECT_BY = "\nconnect by "; + + protected static final String CONNECT_BY_NOCYCLE_PRIOR = "\nconnect by nocycle prior "; + + protected static final String CONNECT_BY_PRIOR = "\nconnect by prior "; + + protected static final String ORDER_SIBLINGS_BY = "\norder siblings by "; + + protected static final String START_WITH = "\nstart with "; + + public AbstractOracleQuery(Connection conn, Configuration configuration, QueryMetadata metadata) { + super(conn, configuration, metadata); + } + + public AbstractOracleQuery(Supplier connProvider, Configuration configuration, QueryMetadata metadata) { + super(connProvider, configuration, metadata); + } + + /** + * CONNECT BY specifies the relationship between parent rows and child rows of the hierarchy. + * + * @param cond condition + * @return the current object + */ + public C connectByPrior(Predicate cond) { + return addFlag(Position.BEFORE_ORDER, CONNECT_BY_PRIOR, cond); + } + + /** + * CONNECT BY specifies the relationship between parent rows and child rows of the hierarchy. + * + * @param cond condition + * @return the current object + */ + public C connectBy(Predicate cond) { + return addFlag(Position.BEFORE_ORDER, CONNECT_BY, cond); + } + + /** + * CONNECT BY specifies the relationship between parent rows and child rows of the hierarchy. + * + * @param cond condition + * @return the current object + */ + public C connectByNocyclePrior(Predicate cond) { + return addFlag(Position.BEFORE_ORDER, CONNECT_BY_NOCYCLE_PRIOR, cond); + } + + /** + * START WITH specifies the root row(s) of the hierarchy. + * + * @param cond condition + * @return the current object + */ + public C startWith(Predicate cond) { + return addFlag(Position.BEFORE_ORDER, START_WITH, cond); + } + + /** + * ORDER SIBLINGS BY preserves any ordering specified in the hierarchical query clause and then + * applies the order_by_clause to the siblings of the hierarchy. + * + * @param path path + * @return the current object + */ + public C orderSiblingsBy(Expression path) { + return addFlag(Position.BEFORE_ORDER, ORDER_SIBLINGS_BY, path); + } + + // TODO : connect by root + + // TODO : connect by iscycle + + // TODO : connect by isleaf (pseudocolumn) + + // TODO : sys connect path +} + + diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/oracle/OracleGrammar.java b/querydsl-sql/src/main/java/com/querydsl/sql/oracle/OracleGrammar.java new file mode 100644 index 0000000000..3a9e04892f --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/oracle/OracleGrammar.java @@ -0,0 +1,39 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.oracle; + +import java.util.Date; + +import com.querydsl.core.types.dsl.DateExpression; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberExpression; + +/** + * Convenience functions and constants for Oracle DB usage + * + * @author tiwe + */ +public final class OracleGrammar { + + private OracleGrammar() { } + + public static final NumberExpression level = Expressions.numberTemplate(Integer.class, "level"); + + public static final NumberExpression rownum = Expressions.numberTemplate(Integer.class, "rownum"); + + public static final NumberExpression rowid = Expressions.numberTemplate(Integer.class, "rowid"); + + public static final DateExpression sysdate = Expressions.dateTemplate(Date.class, "sysdate"); + +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/oracle/OracleQuery.java b/querydsl-sql/src/main/java/com/querydsl/sql/oracle/OracleQuery.java new file mode 100644 index 0000000000..67fcd8e6a2 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/oracle/OracleQuery.java @@ -0,0 +1,87 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.oracle; + +import java.sql.Connection; +import java.util.function.Supplier; + +import com.querydsl.core.DefaultQueryMetadata; +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.Tuple; +import com.querydsl.core.types.Expression; +import com.querydsl.sql.Configuration; +import com.querydsl.sql.OracleTemplates; +import com.querydsl.sql.SQLTemplates; + +/** + * {@code OracleQuery} provides Oracle specific extensions to the base SQL query type + * + * If you need to subtype this, use the base class instead. + * + * @author tiwe + * @param result type + */ +public class OracleQuery extends AbstractOracleQuery> { + public OracleQuery(Connection conn) { + this(conn, OracleTemplates.DEFAULT, new DefaultQueryMetadata()); + } + + public OracleQuery(Connection conn, SQLTemplates templates) { + this(conn, templates, new DefaultQueryMetadata()); + } + + public OracleQuery(Connection conn, Configuration configuration) { + super(conn, configuration, new DefaultQueryMetadata()); + } + + public OracleQuery(Connection conn, Configuration configuration, QueryMetadata metadata) { + super(conn, configuration, metadata); + } + + protected OracleQuery(Connection conn, SQLTemplates templates, QueryMetadata metadata) { + super(conn, new Configuration(templates), metadata); + } + + public OracleQuery(Supplier connProvider, Configuration configuration, QueryMetadata metadata) { + super(connProvider, configuration, metadata); + } + + public OracleQuery(Supplier connProvider, Configuration configuration) { + super(connProvider, configuration, new DefaultQueryMetadata()); + } + + + @Override + public OracleQuery clone(Connection conn) { + OracleQuery q = new OracleQuery(conn, getConfiguration(), getMetadata().clone()); + q.clone(this); + return q; + } + + @Override + public OracleQuery select(Expression expr) { + queryMixin.setProjection(expr); + @SuppressWarnings("unchecked") // This is the new type + OracleQuery newType = (OracleQuery) this; + return newType; + } + + @Override + public OracleQuery select(Expression... exprs) { + queryMixin.setProjection(exprs); + @SuppressWarnings("unchecked") // This is the new type + OracleQuery newType = (OracleQuery) this; + return newType; + } +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/oracle/OracleQueryFactory.java b/querydsl-sql/src/main/java/com/querydsl/sql/oracle/OracleQueryFactory.java new file mode 100644 index 0000000000..71417271da --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/oracle/OracleQueryFactory.java @@ -0,0 +1,84 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.oracle; + +import java.sql.Connection; +import java.util.function.Supplier; + +import com.querydsl.core.Tuple; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.sql.*; + +/** + * Oracle specific implementation of SQLQueryFactory + * + * @author tiwe + * + */ +public class OracleQueryFactory extends AbstractSQLQueryFactory> { + + public OracleQueryFactory(Configuration configuration, Supplier connection) { + super(configuration, connection); + } + + public OracleQueryFactory(Supplier connection) { + this(new Configuration(new OracleTemplates()), connection); + } + + public OracleQueryFactory(SQLTemplates templates, Supplier connection) { + this(new Configuration(templates), connection); + } + + @Override + public OracleQuery query() { + return new OracleQuery(connection, configuration); + } + + @Override + public OracleQuery select(Expression expr) { + return query().select(expr); + } + + @Override + public OracleQuery select(Expression... exprs) { + return query().select(exprs); + } + + @Override + public OracleQuery selectDistinct(Expression expr) { + return query().select(expr).distinct(); + } + + @Override + public OracleQuery selectDistinct(Expression... exprs) { + return query().select(exprs).distinct(); + } + + @Override + public OracleQuery selectZero() { + return select(Expressions.ZERO); + } + + @Override + public OracleQuery selectOne() { + return select(Expressions.ONE); + } + + @Override + public OracleQuery selectFrom(RelationalPath expr) { + return select(expr).from(expr); + } + +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/oracle/package-info.java b/querydsl-sql/src/main/java/com/querydsl/sql/oracle/package-info.java new file mode 100644 index 0000000000..0eeb1e87b0 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/oracle/package-info.java @@ -0,0 +1,19 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ + + +/** + * Oracle support + */ +package com.querydsl.sql.oracle; diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/package-info.java b/querydsl-sql/src/main/java/com/querydsl/sql/package-info.java new file mode 100644 index 0000000000..db299054a4 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/package-info.java @@ -0,0 +1,18 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ + +/** + * SQL/JDBC support + */ +package com.querydsl.sql; diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/postgresql/AbstractPostgreSQLQuery.java b/querydsl-sql/src/main/java/com/querydsl/sql/postgresql/AbstractPostgreSQLQuery.java new file mode 100644 index 0000000000..145bca917b --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/postgresql/AbstractPostgreSQLQuery.java @@ -0,0 +1,98 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.postgresql; + +import java.sql.Connection; +import java.util.function.Supplier; + +import com.querydsl.core.QueryFlag; +import com.querydsl.core.QueryFlag.Position; +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.ExpressionUtils; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.sql.AbstractSQLQuery; +import com.querydsl.sql.Configuration; +import com.querydsl.sql.RelationalPath; +import com.querydsl.sql.SQLQuery; + +/** + * {@code PostgreSQLQuery} provides PostgreSQL related extensions to SQLQuery + * + * @param result type + * @param the concrete subtype + * + * @see SQLQuery + * @author tiwe + */ +public abstract class AbstractPostgreSQLQuery> extends AbstractSQLQuery { + public AbstractPostgreSQLQuery(Connection conn, Configuration configuration, QueryMetadata metadata) { + super(conn, configuration, metadata); + } + + public AbstractPostgreSQLQuery(Supplier connProvider, Configuration configuration, QueryMetadata metadata) { + super(connProvider, configuration, metadata); + } + + /** + * FOR SHARE causes the rows retrieved by the SELECT statement to be locked as though for update. + * + * @return the current object + */ + public C forShare() { + // global forShare support was added later, delegating to super implementation + return super.forShare(); + } + + /** + * With NOWAIT, the statement reports an error, rather than waiting, if a selected row cannot + * be locked immediately. + * + * @return the current object + */ + public C noWait() { + QueryFlag noWaitFlag = configuration.getTemplates().getNoWaitFlag(); + return addFlag(noWaitFlag); + } + + /** + * FOR UPDATE / FOR SHARE OF tables + * + * @param paths tables + * @return the current object + */ + public C of(RelationalPath... paths) { + StringBuilder builder = new StringBuilder(" of "); + for (RelationalPath path : paths) { + if (builder.length() > 4) { + builder.append(", "); + } + builder.append(getConfiguration().getTemplates().quoteIdentifier(path.getTableName())); + } + return addFlag(Position.END, builder.toString()); + } + + /** + * adds a DISTINCT ON clause + * + * @param exprs + * @return + */ + public C distinctOn(Expression... exprs) { + return addFlag(Position.AFTER_SELECT, + Expressions.template(Object.class, "distinct on({0}) ", + ExpressionUtils.list(Object.class, exprs))); + } + +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/postgresql/PostgreSQLQuery.java b/querydsl-sql/src/main/java/com/querydsl/sql/postgresql/PostgreSQLQuery.java new file mode 100644 index 0000000000..014bfaa0f5 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/postgresql/PostgreSQLQuery.java @@ -0,0 +1,83 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.postgresql; + +import java.sql.Connection; +import java.util.function.Supplier; + +import com.querydsl.core.DefaultQueryMetadata; +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.Tuple; +import com.querydsl.core.types.Expression; +import com.querydsl.sql.Configuration; +import com.querydsl.sql.PostgreSQLTemplates; +import com.querydsl.sql.SQLTemplates; + +/** + * {@code PostgreSQLQuery} provides Postgres related extensions to SQLQuery. + * + * If you need to subtype this, use the base class instead. + * + * @param the result type + */ +public class PostgreSQLQuery extends AbstractPostgreSQLQuery> { + + public PostgreSQLQuery(Connection conn) { + this(conn, new Configuration(PostgreSQLTemplates.DEFAULT), new DefaultQueryMetadata()); + } + + public PostgreSQLQuery(Connection conn, SQLTemplates templates) { + this(conn, new Configuration(templates), new DefaultQueryMetadata()); + } + + public PostgreSQLQuery(Connection conn, Configuration configuration) { + this(conn, configuration, new DefaultQueryMetadata()); + } + + public PostgreSQLQuery(Connection conn, Configuration configuration, QueryMetadata metadata) { + super(conn, configuration, metadata); + } + + public PostgreSQLQuery(Supplier connProvider, Configuration configuration, QueryMetadata metadata) { + super(connProvider, configuration, metadata); + } + + public PostgreSQLQuery(Supplier connProvider, Configuration configuration) { + super(connProvider, configuration, new DefaultQueryMetadata()); + } + + + @Override + public PostgreSQLQuery clone(Connection conn) { + PostgreSQLQuery q = new PostgreSQLQuery(conn, getConfiguration(), getMetadata().clone()); + q.clone(this); + return q; + } + + @Override + public PostgreSQLQuery select(Expression expr) { + queryMixin.setProjection(expr); + @SuppressWarnings("unchecked") // This is the new type + PostgreSQLQuery newType = (PostgreSQLQuery) this; + return newType; + } + + @Override + public PostgreSQLQuery select(Expression... exprs) { + queryMixin.setProjection(exprs); + @SuppressWarnings("unchecked") // This is the new type + PostgreSQLQuery newType = (PostgreSQLQuery) this; + return newType; + } +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/postgresql/PostgreSQLQueryFactory.java b/querydsl-sql/src/main/java/com/querydsl/sql/postgresql/PostgreSQLQueryFactory.java new file mode 100644 index 0000000000..cbd9ba3d3e --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/postgresql/PostgreSQLQueryFactory.java @@ -0,0 +1,85 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.postgresql; + +import java.sql.Connection; +import java.util.function.Supplier; + +import com.querydsl.core.Tuple; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.sql.*; + +/** + * PostgreSQL specific implementation of SQLQueryFactory + * + * @author tiwe + * + */ +public class PostgreSQLQueryFactory extends AbstractSQLQueryFactory> { + + public PostgreSQLQueryFactory(Configuration configuration, Supplier connection) { + super(configuration, connection); + } + + public PostgreSQLQueryFactory(Supplier connection) { + this(new Configuration(new PostgreSQLTemplates()), connection); + } + + public PostgreSQLQueryFactory(SQLTemplates templates, Supplier connection) { + this(new Configuration(templates), connection); + } + + @Override + public PostgreSQLQuery query() { + return new PostgreSQLQuery(connection, configuration); + } + + @Override + public PostgreSQLQuery select(Expression expr) { + return query().select(expr); + } + + @Override + public PostgreSQLQuery select(Expression... exprs) { + return query().select(exprs); + } + + @Override + public PostgreSQLQuery selectDistinct(Expression expr) { + return query().select(expr).distinct(); + } + + @Override + public PostgreSQLQuery selectDistinct(Expression... exprs) { + return query().select(exprs).distinct(); + } + + @Override + public PostgreSQLQuery selectZero() { + return select(Expressions.ZERO); + } + + @Override + public PostgreSQLQuery selectOne() { + return select(Expressions.ONE); + } + + @Override + public PostgreSQLQuery selectFrom(RelationalPath expr) { + return select(expr).from(expr); + } + + +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/postgresql/package-info.java b/querydsl-sql/src/main/java/com/querydsl/sql/postgresql/package-info.java new file mode 100644 index 0000000000..64276ea316 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/postgresql/package-info.java @@ -0,0 +1,18 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ + +/** + * PostgreSQL support + */ +package com.querydsl.sql.postgresql; diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/support/JavaSE7SQLExceptionWrapper.java b/querydsl-sql/src/main/java/com/querydsl/sql/support/JavaSE7SQLExceptionWrapper.java new file mode 100644 index 0000000000..59ecbdfb35 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/support/JavaSE7SQLExceptionWrapper.java @@ -0,0 +1,50 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.support; + +import java.sql.SQLException; + +import com.querydsl.core.QueryException; + +/** + * A {@link SQLExceptionWrapper} that adds the additional + * {@code SQLException}s as suppressed exceptions. + * + * @author Shredder121 + */ +class JavaSE7SQLExceptionWrapper extends SQLExceptionWrapper { + + @Override + public RuntimeException wrap(SQLException exception) { + QueryException rv = new QueryException(exception); + SQLException linkedException = exception.getNextException(); + while (linkedException != null) { + rv.addSuppressed(linkedException); + linkedException = linkedException.getNextException(); + } + return rv; + } + + @Override + public RuntimeException wrap(String message, SQLException exception) { + QueryException rv = new QueryException(message, exception); + SQLException linkedException = exception.getNextException(); + while (linkedException != null) { + rv.addSuppressed(linkedException); + linkedException = linkedException.getNextException(); + } + return rv; + } + +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/support/SQLExceptionWrapper.java b/querydsl-sql/src/main/java/com/querydsl/sql/support/SQLExceptionWrapper.java new file mode 100644 index 0000000000..111a31242f --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/support/SQLExceptionWrapper.java @@ -0,0 +1,32 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.support; + +import java.sql.SQLException; + +/** + * A {@code SQLExceptionWrapper} is used to accommodate for + * Java™ 7's suppressed exceptions. + * + * @author Shredder121 + */ +public abstract class SQLExceptionWrapper { + + public static final SQLExceptionWrapper INSTANCE = new JavaSE7SQLExceptionWrapper(); + + public abstract RuntimeException wrap(SQLException exception); + + public abstract RuntimeException wrap(String message, SQLException exception); + +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/support/package-info.java b/querydsl-sql/src/main/java/com/querydsl/sql/support/package-info.java new file mode 100644 index 0000000000..a0dfea3e32 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/support/package-info.java @@ -0,0 +1,18 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ + +/** + * Support classes + */ +package com.querydsl.sql.support; diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/teradata/AbstractTeradataQuery.java b/querydsl-sql/src/main/java/com/querydsl/sql/teradata/AbstractTeradataQuery.java new file mode 100644 index 0000000000..ad7a4ea0e3 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/teradata/AbstractTeradataQuery.java @@ -0,0 +1,59 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.teradata; + +import java.sql.Connection; +import java.util.function.Supplier; + +import com.querydsl.core.DefaultQueryMetadata; +import com.querydsl.core.QueryMetadata; +import com.querydsl.sql.AbstractSQLQuery; +import com.querydsl.sql.Configuration; +import com.querydsl.sql.SQLTemplates; +import com.querydsl.sql.TeradataTemplates; + +/** + * {@code AbstractTeradataQuery} provides Teradata related extensions to SQLQuery + * + * @param result type + * @param the concrete subtype. + * + * @author tiwe + */ +public abstract class AbstractTeradataQuery> extends AbstractSQLQuery { + public AbstractTeradataQuery(Connection conn) { + this(conn, new Configuration(TeradataTemplates.DEFAULT), new DefaultQueryMetadata()); + } + + public AbstractTeradataQuery(Connection conn, SQLTemplates templates) { + this(conn, new Configuration(templates), new DefaultQueryMetadata()); + } + + public AbstractTeradataQuery(Connection conn, Configuration configuration) { + this(conn, configuration, new DefaultQueryMetadata()); + } + + public AbstractTeradataQuery(Connection conn, Configuration configuration, QueryMetadata metadata) { + super(conn, configuration, metadata); + } + + public AbstractTeradataQuery(Supplier connProvider, Configuration configuration, QueryMetadata metadata) { + super(connProvider, configuration, metadata); + } + + public AbstractTeradataQuery(Supplier connProvider, Configuration configuration) { + super(connProvider, configuration); + } + +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/teradata/SetQueryBandClause.java b/querydsl-sql/src/main/java/com/querydsl/sql/teradata/SetQueryBandClause.java new file mode 100644 index 0000000000..c2df9f3376 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/teradata/SetQueryBandClause.java @@ -0,0 +1,143 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.teradata; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Supplier; + +import com.querydsl.sql.Configuration; +import com.querydsl.sql.SQLBindings; +import com.querydsl.sql.SQLTemplates; +import com.querydsl.sql.dml.AbstractSQLClause; + +/** + * {@code SetQueryBandClause} provides support for Teradata specific set query_band executions. + * + * @author tiwe + * + */ +public class SetQueryBandClause extends AbstractSQLClause { + + private boolean forSession = true; + + private final Map values = new LinkedHashMap<>(); + + private transient String queryString; + + private transient String parameter; + + public SetQueryBandClause(Connection connection, SQLTemplates templates) { + this(connection, new Configuration(templates)); + } + + public SetQueryBandClause(Connection connection, Configuration configuration) { + super(configuration, connection); + } + + public SetQueryBandClause(Supplier connection, Configuration configuration) { + super(configuration, connection); + } + + public SetQueryBandClause forSession() { + queryString = null; + forSession = true; + return this; + } + + public SetQueryBandClause forTransaction() { + queryString = null; + forSession = false; + return this; + } + + public SetQueryBandClause set(String key, String value) { + queryString = null; + values.put(key, value); + return this; + } + + public SetQueryBandClause set(Map values) { + queryString = null; + this.values.putAll(values); + return this; + } + + @Override + public void clear() { + values.clear(); + } + + @Override + public long execute() { + PreparedStatement stmt = null; + try { + stmt = connection().prepareStatement(toString()); + if (parameter != null) { + stmt.setString(1, parameter); + } + return 1; + } catch (SQLException e) { + List bindings = parameter != null ? Collections.singletonList(parameter) : Collections.emptyList(); + throw configuration.translate(queryString, bindings, e); + } finally { + if (stmt != null) { + close(stmt); + } + } + } + + @Override + public List getSQL() { + SQLBindings bindings; + if (configuration.getUseLiterals() || forSession) { + bindings = new SQLBindings(toString(), Collections.emptyList()); + } else { + bindings = new SQLBindings(toString(), Collections.singletonList(parameter)); + } + return Collections.singletonList(bindings); + } + + @Override + public String toString() { + if (queryString == null) { + StringBuilder builder = new StringBuilder(); + for (Map.Entry entry : values.entrySet()) { + builder.append(entry.getKey()).append("=").append(entry.getValue()); + builder.append(";"); + } + if (configuration.getUseLiterals() || forSession) { + queryString = "set query_band='" + + configuration.getTemplates().escapeLiteral(builder.toString()) + + (forSession ? "' for session" : "' for transaction"); + parameter = null; + } else { + queryString = "set query_band=? for transaction"; + parameter = builder.toString(); + } + + } + return queryString; + } + + @Override + public int getBatchCount() { + return 0; + } +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/teradata/TeradataQuery.java b/querydsl-sql/src/main/java/com/querydsl/sql/teradata/TeradataQuery.java new file mode 100644 index 0000000000..e58a219889 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/teradata/TeradataQuery.java @@ -0,0 +1,100 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.teradata; + +import java.sql.Connection; +import java.util.function.Supplier; + +import com.querydsl.core.DefaultQueryMetadata; +import com.querydsl.core.QueryFlag; +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.Tuple; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.ExpressionUtils; +import com.querydsl.core.types.Predicate; +import com.querydsl.sql.Configuration; +import com.querydsl.sql.SQLOps; +import com.querydsl.sql.SQLTemplates; +import com.querydsl.sql.TeradataTemplates; + +/** + * {@code TeradataQuery} provides Teradata related extensions to SQLQuery + * + * If you need to subtype this, use the base class instead. + * + * @param result type + * + * @author tiwe + */ +public class TeradataQuery extends AbstractTeradataQuery> { + + public TeradataQuery(Connection conn) { + this(conn, new Configuration(TeradataTemplates.DEFAULT), new DefaultQueryMetadata()); + } + + public TeradataQuery(Connection conn, SQLTemplates templates) { + this(conn, new Configuration(templates), new DefaultQueryMetadata()); + } + + public TeradataQuery(Connection conn, Configuration configuration) { + this(conn, configuration, new DefaultQueryMetadata()); + } + + public TeradataQuery(Connection conn, Configuration configuration, QueryMetadata metadata) { + super(conn, configuration, metadata); + } + + public TeradataQuery(Supplier connProvider, Configuration configuration, QueryMetadata metadata) { + super(connProvider, configuration, metadata); + } + + public TeradataQuery(Supplier connProvider, Configuration configuration) { + super(connProvider, configuration); + } + + /** + * Adds a qualify expression + * + * @param predicate qualify expression + * @return the current object + */ + public TeradataQuery qualify(Predicate predicate) { + predicate = ExpressionUtils.predicate(SQLOps.QUALIFY, predicate); + return queryMixin.addFlag(new QueryFlag(QueryFlag.Position.BEFORE_ORDER, predicate)); + } + + @Override + public TeradataQuery clone(Connection conn) { + TeradataQuery q = new TeradataQuery(conn, getConfiguration(), getMetadata().clone()); + q.clone(this); + return q; + } + + @Override + public TeradataQuery select(Expression expr) { + queryMixin.setProjection(expr); + @SuppressWarnings("unchecked") // This is the new type + TeradataQuery newType = (TeradataQuery) this; + return newType; + } + + @Override + public TeradataQuery select(Expression... exprs) { + queryMixin.setProjection(exprs); + @SuppressWarnings("unchecked") // This is the new type + TeradataQuery newType = (TeradataQuery) this; + return newType; + } + +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/teradata/TeradataQueryFactory.java b/querydsl-sql/src/main/java/com/querydsl/sql/teradata/TeradataQueryFactory.java new file mode 100644 index 0000000000..06da58ddf3 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/teradata/TeradataQueryFactory.java @@ -0,0 +1,85 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.teradata; + +import java.sql.Connection; +import java.util.function.Supplier; + +import com.querydsl.core.Tuple; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.sql.*; + +/** + * Teradata specific implementation of SQLQueryFactory + * + * @author tiwe + * + */ +public class TeradataQueryFactory extends AbstractSQLQueryFactory> { + + public TeradataQueryFactory(Configuration configuration, Supplier connection) { + super(configuration, connection); + } + + public TeradataQueryFactory(Supplier connection) { + this(new Configuration(new TeradataTemplates()), connection); + } + + public TeradataQueryFactory(SQLTemplates templates, Supplier connection) { + this(new Configuration(templates), connection); + } + + @Override + public TeradataQuery query() { + return new TeradataQuery(connection, configuration); + } + + @Override + public TeradataQuery select(Expression expr) { + return query().select(expr); + } + + @Override + public TeradataQuery select(Expression... exprs) { + return query().select(exprs); + } + + @Override + public TeradataQuery selectDistinct(Expression expr) { + return query().select(expr).distinct(); + } + + @Override + public TeradataQuery selectDistinct(Expression... exprs) { + return query().select(exprs).distinct(); + } + + @Override + public TeradataQuery selectZero() { + return select(Expressions.ZERO); + } + + @Override + public TeradataQuery selectOne() { + return select(Expressions.ONE); + } + + @Override + public TeradataQuery selectFrom(RelationalPath expr) { + return select(expr).from(expr); + } + + +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/teradata/package-info.java b/querydsl-sql/src/main/java/com/querydsl/sql/teradata/package-info.java new file mode 100644 index 0000000000..3a0b0ca952 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/teradata/package-info.java @@ -0,0 +1,18 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ + +/** + * Teradata support + */ +package com.querydsl.sql.teradata; diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/types/AbstractDateTimeType.java b/querydsl-sql/src/main/java/com/querydsl/sql/types/AbstractDateTimeType.java new file mode 100644 index 0000000000..381862a8ad --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/types/AbstractDateTimeType.java @@ -0,0 +1,55 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.types; + +import java.time.format.DateTimeFormatter; +import java.util.Calendar; +import java.util.TimeZone; + +/** + * Common abstract superclass for Type implementations + * + * @author tiwe + * + * @param + */ +public abstract class AbstractDateTimeType extends AbstractType { + + private static final Calendar UTC = Calendar.getInstance(TimeZone.getTimeZone("UTC")); + + static { + UTC.setTimeInMillis(0); + } + + protected static Calendar utc() { + return (Calendar) UTC.clone(); + } + + protected static final DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + + protected static final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + + protected static final DateTimeFormatter dateTimeOffsetFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss xxx"); + + protected static final DateTimeFormatter dateTimeZoneFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss VV"); + + protected static final DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm:ss"); + + protected static final DateTimeFormatter timeOffsetFormatter = DateTimeFormatter.ofPattern("HH:mm:ss xxx"); + + public AbstractDateTimeType(int type) { + super(type); + } + +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/types/AbstractJSR310DateTimeType.java b/querydsl-sql/src/main/java/com/querydsl/sql/types/AbstractJSR310DateTimeType.java new file mode 100644 index 0000000000..66a9e37809 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/types/AbstractJSR310DateTimeType.java @@ -0,0 +1,16 @@ +package com.querydsl.sql.types; + +import java.time.temporal.Temporal; + +/** + * Common abstract superclass for Type implementations for Java Time API (JSR310) + * + * @param + */ +public abstract class AbstractJSR310DateTimeType extends AbstractDateTimeType { + + public AbstractJSR310DateTimeType(int type) { + super(type); + } + +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/types/AbstractJodaTimeDateTimeType.java b/querydsl-sql/src/main/java/com/querydsl/sql/types/AbstractJodaTimeDateTimeType.java new file mode 100644 index 0000000000..636e4c3a9d --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/types/AbstractJodaTimeDateTimeType.java @@ -0,0 +1,35 @@ +package com.querydsl.sql.types; + +import org.joda.time.format.DateTimeFormat; +import org.joda.time.format.DateTimeFormatter; + +import java.util.Calendar; +import java.util.TimeZone; + +/** + * Common abstract superclass for Type implementations for Joda-Time + * + * @param + */ +public abstract class AbstractJodaTimeDateTimeType extends AbstractType { + + private static final Calendar UTC = Calendar.getInstance(TimeZone.getTimeZone("UTC")); + + static { + UTC.setTimeInMillis(0); + } + + protected static Calendar utc() { + return (Calendar) UTC.clone(); + } + + protected static final DateTimeFormatter dateFormatter = DateTimeFormat.forPattern("yyyy-MM-dd"); + + protected static final DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss"); + + protected static final DateTimeFormatter timeFormatter = DateTimeFormat.forPattern("HH:mm:ss"); + + public AbstractJodaTimeDateTimeType(int type) { + super(type); + } +} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/types/AbstractType.java b/querydsl-sql/src/main/java/com/querydsl/sql/types/AbstractType.java similarity index 89% rename from querydsl-sql/src/main/java/com/mysema/query/sql/types/AbstractType.java rename to querydsl-sql/src/main/java/com/querydsl/sql/types/AbstractType.java index e248a472df..ff5638f0cf 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/types/AbstractType.java +++ b/querydsl-sql/src/main/java/com/querydsl/sql/types/AbstractType.java @@ -1,5 +1,5 @@ /* - * Copyright 2011, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql.types; +package com.querydsl.sql.types; /** * Common abstract superclass for Type implementations @@ -33,6 +33,7 @@ public final int[] getSQLTypes() { return new int[]{type}; } + @Override public String getLiteral(T value) { return value.toString(); } diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/types/ArrayType.java b/querydsl-sql/src/main/java/com/querydsl/sql/types/ArrayType.java new file mode 100644 index 0000000000..a2e723b10f --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/types/ArrayType.java @@ -0,0 +1,107 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.types; + +import java.sql.*; + +import org.jetbrains.annotations.Nullable; + +import com.querydsl.core.util.PrimitiveUtils; + +/** + *{@code ArrayType} maps Java arrays to JDBC arrays + * + * @param + */ +public class ArrayType extends AbstractType { + + private static void copy(Object source, Object target, int length) { + // Note: System.arrayCopy doesn't handle copying from/to primitive arrays properly + for (int i = 0; i < length; i++) { + Object val = java.lang.reflect.Array.get(source, i); + java.lang.reflect.Array.set(target, i, val); + } + } + + private final Class type; + + private final String typeName; + + private final boolean convertPrimitives; + + public ArrayType(Class type, String typeName) { + super(Types.ARRAY); + this.type = type; + this.typeName = typeName; + this.convertPrimitives = type.getComponentType().isPrimitive(); + } + + @Override + public Class getReturnedClass() { + return type; + } + + @SuppressWarnings("unchecked") + @Nullable + @Override + public T getValue(ResultSet rs, int startIndex) throws SQLException { + Array arr = rs.getArray(startIndex); + if (arr != null) { + /* + * The Javadoc for getArray() is annoyingly ambiguous about what it returns. + * + * It says that the method can return a primitive array. + * + * But it does not say anything about the type of the array when the method + * returns an array of objects. + * + * In that case, it could return T[] (Postgres appears to do this) + * or it could return Object[] (H2 and HSQLDB appear to do this). + * + * The JDBC specification does not offer any additional clarity. + * + * In any case, what we need to return is T[]. Otherwise the caller will get + * ClassCastExceptions at runtime. + * + * Note that we cannot cast arr.getArray() to Object[] because, if the returned + * array is a primitive array, that would cause ClassCastException. + */ + Object rv = arr.getArray(); + if (!type.isAssignableFrom(rv.getClass())) { + int length = java.lang.reflect.Array.getLength(rv); + Object rv2 = java.lang.reflect.Array.newInstance(type.getComponentType(), length); + copy(rv, rv2, length); + return (T) rv2; + } else { + return (T) rv; + } + } else { + return null; + } + } + + @SuppressWarnings("unchecked") + @Override + public void setValue(PreparedStatement st, int startIndex, T value) throws SQLException { + if (convertPrimitives) { + // primitives in + int length = java.lang.reflect.Array.getLength(value); + Object value2 = java.lang.reflect.Array.newInstance(PrimitiveUtils.wrap(type.getComponentType()), length); + copy(value, value2, length); + value = (T) value2; + } + Array arr = st.getConnection().createArrayOf(typeName, (Object[]) value); + st.setArray(startIndex, arr); + } +} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/types/BigDecimalAsDoubleType.java b/querydsl-sql/src/main/java/com/querydsl/sql/types/BigDecimalAsDoubleType.java similarity index 83% rename from querydsl-sql/src/main/java/com/mysema/query/sql/types/BigDecimalAsDoubleType.java rename to querydsl-sql/src/main/java/com/querydsl/sql/types/BigDecimalAsDoubleType.java index b95abd511a..f25e10a21a 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/types/BigDecimalAsDoubleType.java +++ b/querydsl-sql/src/main/java/com/querydsl/sql/types/BigDecimalAsDoubleType.java @@ -1,5 +1,5 @@ /* - * Copyright 2011, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql.types; +package com.querydsl.sql.types; import java.math.BigDecimal; import java.sql.PreparedStatement; @@ -20,7 +20,7 @@ import java.sql.Types; /** - * BigDecimalAsDoubleType maps BigDecimal to Double on the JDBC level + * {@code BigDecimalAsDoubleType} maps BigDecimal to Double on the JDBC level * * @author tiwe * @@ -39,7 +39,8 @@ public BigDecimalAsDoubleType(int type) { @Override public BigDecimal getValue(ResultSet rs, int startIndex) throws SQLException { - return BigDecimal.valueOf(rs.getDouble(startIndex)); + double val = rs.getDouble(startIndex); + return rs.wasNull() ? null : BigDecimal.valueOf(val); } @Override diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/types/BigDecimalType.java b/querydsl-sql/src/main/java/com/querydsl/sql/types/BigDecimalType.java similarity index 88% rename from querydsl-sql/src/main/java/com/mysema/query/sql/types/BigDecimalType.java rename to querydsl-sql/src/main/java/com/querydsl/sql/types/BigDecimalType.java index 40b842a7b4..2ee3e1dc38 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/types/BigDecimalType.java +++ b/querydsl-sql/src/main/java/com/querydsl/sql/types/BigDecimalType.java @@ -1,5 +1,5 @@ /* - * Copyright 2011, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql.types; +package com.querydsl.sql.types; import java.math.BigDecimal; import java.sql.PreparedStatement; @@ -20,7 +20,7 @@ import java.sql.Types; /** - * BigDecimalType maps BigDecimal to BigDecimal on the JDBC level + * {@code BigDecimalType} maps BigDecimal to BigDecimal on the JDBC level * * @author tiwe * diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/types/BigIntegerAsLongType.java b/querydsl-sql/src/main/java/com/querydsl/sql/types/BigIntegerAsLongType.java new file mode 100644 index 0000000000..ba51122688 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/types/BigIntegerAsLongType.java @@ -0,0 +1,57 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.types; + +import java.math.BigInteger; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Types; + +/** + * {@code BigIntegerType} maps BigInteger to Long on the JDBC level + * + * @author tiwe + * + */ +public class BigIntegerAsLongType extends AbstractType { + + public static final BigIntegerAsLongType DEFAULT = new BigIntegerAsLongType(); + + public BigIntegerAsLongType() { + super(Types.NUMERIC); + } + + public BigIntegerAsLongType(int type) { + super(type); + } + + @Override + public BigInteger getValue(ResultSet rs, int startIndex) throws SQLException { + long val = rs.getLong(startIndex); + return rs.wasNull() ? null : BigInteger.valueOf(val); + } + + @Override + public Class getReturnedClass() { + return BigInteger.class; + } + + @Override + public void setValue(PreparedStatement st, int startIndex, BigInteger value) + throws SQLException { + st.setLong(startIndex, value.longValue()); + } + +} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/types/BigIntegerType.java b/querydsl-sql/src/main/java/com/querydsl/sql/types/BigIntegerType.java similarity index 89% rename from querydsl-sql/src/main/java/com/mysema/query/sql/types/BigIntegerType.java rename to querydsl-sql/src/main/java/com/querydsl/sql/types/BigIntegerType.java index 683cf021af..acefe0aa36 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/types/BigIntegerType.java +++ b/querydsl-sql/src/main/java/com/querydsl/sql/types/BigIntegerType.java @@ -1,5 +1,5 @@ /* - * Copyright 2013, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql.types; +package com.querydsl.sql.types; import java.math.BigDecimal; import java.math.BigInteger; @@ -21,7 +21,7 @@ import java.sql.Types; /** - * BigIntegerType maps BigInteger to BigDecimal on the JDBC level + * {@code BigIntegerType} maps BigInteger to BigDecimal on the JDBC level * * @author tiwe * diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/types/BlobType.java b/querydsl-sql/src/main/java/com/querydsl/sql/types/BlobType.java similarity index 82% rename from querydsl-sql/src/main/java/com/mysema/query/sql/types/BlobType.java rename to querydsl-sql/src/main/java/com/querydsl/sql/types/BlobType.java index dcbaa665c3..4387a4a777 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/types/BlobType.java +++ b/querydsl-sql/src/main/java/com/querydsl/sql/types/BlobType.java @@ -1,5 +1,5 @@ /* - * Copyright 2011, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,16 +11,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql.types; +package com.querydsl.sql.types; -import java.sql.Blob; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Types; +import java.sql.*; /** - * BlobType maps Blob to Blob on the JDBC level + * {@code BlobType} maps Blob to Blob on the JDBC level * * @author tiwe * diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/types/BooleanType.java b/querydsl-sql/src/main/java/com/querydsl/sql/types/BooleanType.java similarity index 77% rename from querydsl-sql/src/main/java/com/mysema/query/sql/types/BooleanType.java rename to querydsl-sql/src/main/java/com/querydsl/sql/types/BooleanType.java index 264b6c8573..1f2197c3aa 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/types/BooleanType.java +++ b/querydsl-sql/src/main/java/com/querydsl/sql/types/BooleanType.java @@ -1,5 +1,5 @@ /* - * Copyright 2011, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql.types; +package com.querydsl.sql.types; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -19,7 +19,7 @@ import java.sql.Types; /** - * BooleanType maps Boolean to Boolean on the JDBC level + * {@code BooleanType} maps Boolean to Boolean on the JDBC level * * @author tiwe * @@ -36,8 +36,8 @@ public BooleanType(int type) { @Override public Boolean getValue(ResultSet rs, int startIndex) throws SQLException { - final boolean value = rs.getBoolean(startIndex); - return rs.wasNull() ? null : value; + boolean val = rs.getBoolean(startIndex); + return rs.wasNull() ? null : val; } @Override @@ -45,6 +45,11 @@ public Class getReturnedClass() { return Boolean.class; } + @Override + public String getLiteral(Boolean value) { + return value ? "1" : "0"; + } + @Override public void setValue(PreparedStatement st, int startIndex, Boolean value) throws SQLException { st.setBoolean(startIndex, value); diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/types/ByteType.java b/querydsl-sql/src/main/java/com/querydsl/sql/types/ByteType.java new file mode 100644 index 0000000000..560484e192 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/types/ByteType.java @@ -0,0 +1,53 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.types; + +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Types; + +/** + * {@code ByteType} maps Byte to Byte on the JDBC level + * + * @author tiwe + * + */ +public class ByteType extends AbstractType { + + public ByteType() { + super(Types.TINYINT); + } + + public ByteType(int type) { + super(type); + } + + @Override + public Class getReturnedClass() { + return Byte.class; + } + + @Override + public Byte getValue(ResultSet rs, int startIndex) throws SQLException { + byte val = rs.getByte(startIndex); + return rs.wasNull() ? null : val; + } + + @Override + public void setValue(PreparedStatement st, int startIndex, Byte value) throws SQLException { + st.setByte(startIndex, value); + } + +} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/types/BytesType.java b/querydsl-sql/src/main/java/com/querydsl/sql/types/BytesType.java similarity index 88% rename from querydsl-sql/src/main/java/com/mysema/query/sql/types/BytesType.java rename to querydsl-sql/src/main/java/com/querydsl/sql/types/BytesType.java index 082344c6f5..d76ecae27e 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/types/BytesType.java +++ b/querydsl-sql/src/main/java/com/querydsl/sql/types/BytesType.java @@ -1,5 +1,5 @@ /* - * Copyright 2011, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql.types; +package com.querydsl.sql.types; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -19,7 +19,7 @@ import java.sql.Types; /** - * BytesType maps byte[] to byte[] on the JDBC level + * {@code BytesType} maps byte[] to byte[] on the JDBC level * * @author tiwe * diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/types/CalendarType.java b/querydsl-sql/src/main/java/com/querydsl/sql/types/CalendarType.java similarity index 81% rename from querydsl-sql/src/main/java/com/mysema/query/sql/types/CalendarType.java rename to querydsl-sql/src/main/java/com/querydsl/sql/types/CalendarType.java index 3dd6289424..ce54ff8cf0 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/types/CalendarType.java +++ b/querydsl-sql/src/main/java/com/querydsl/sql/types/CalendarType.java @@ -1,5 +1,5 @@ /* - * Copyright 2011, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,17 +11,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql.types; +package com.querydsl.sql.types; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Timestamp; -import java.sql.Types; +import java.sql.*; +import java.time.LocalDateTime; +import java.time.ZoneOffset; import java.util.Calendar; /** - * CalendarType maps Calendar to Timestamp on the JDBC level + * {@code CalendarType} maps Calendar to Timestamp on the JDBC level * * @author tiwe * @@ -38,7 +36,7 @@ public CalendarType(int type) { @Override public String getLiteral(Calendar value) { - return dateTimeFormatter.print(value.getTimeInMillis()); + return dateTimeFormatter.format(LocalDateTime.ofInstant(value.toInstant(), ZoneOffset.UTC)); } @Override diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/types/CharacterType.java b/querydsl-sql/src/main/java/com/querydsl/sql/types/CharacterType.java similarity index 89% rename from querydsl-sql/src/main/java/com/mysema/query/sql/types/CharacterType.java rename to querydsl-sql/src/main/java/com/querydsl/sql/types/CharacterType.java index 894d79093a..c717876874 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/types/CharacterType.java +++ b/querydsl-sql/src/main/java/com/querydsl/sql/types/CharacterType.java @@ -1,5 +1,5 @@ /* - * Copyright 2011, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql.types; +package com.querydsl.sql.types; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -19,7 +19,7 @@ import java.sql.Types; /** - * CharacterType maps Character to Character on the JDBC level + * {@code CharacterType} maps Character to Character on the JDBC level * * @author tiwe * diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/types/ClobType.java b/querydsl-sql/src/main/java/com/querydsl/sql/types/ClobType.java similarity index 82% rename from querydsl-sql/src/main/java/com/mysema/query/sql/types/ClobType.java rename to querydsl-sql/src/main/java/com/querydsl/sql/types/ClobType.java index 6d115f0b94..d2acf5dbad 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/types/ClobType.java +++ b/querydsl-sql/src/main/java/com/querydsl/sql/types/ClobType.java @@ -1,5 +1,5 @@ /* - * Copyright 2011, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,16 +11,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql.types; +package com.querydsl.sql.types; -import java.sql.Clob; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Types; +import java.sql.*; /** - * ClobType maps Clob to Clob on the JDBC level + * {@code ClobType} maps Clob to Clob on the JDBC level * * @author tiwe * diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/types/CurrencyType.java b/querydsl-sql/src/main/java/com/querydsl/sql/types/CurrencyType.java similarity index 87% rename from querydsl-sql/src/main/java/com/mysema/query/sql/types/CurrencyType.java rename to querydsl-sql/src/main/java/com/querydsl/sql/types/CurrencyType.java index 378d7f662c..26757bb085 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/types/CurrencyType.java +++ b/querydsl-sql/src/main/java/com/querydsl/sql/types/CurrencyType.java @@ -1,5 +1,5 @@ /* - * Copyright 2013, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql.types; +package com.querydsl.sql.types; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -19,10 +19,10 @@ import java.sql.Types; import java.util.Currency; -import javax.annotation.Nullable; +import org.jetbrains.annotations.Nullable; /** - * CurrencyType maps Currency to String on the JDBC level + * {@code CurrencyType} maps Currency to String on the JDBC level * * @author tiwe * diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/types/DateTimeType.java b/querydsl-sql/src/main/java/com/querydsl/sql/types/DateTimeType.java similarity index 82% rename from querydsl-sql/src/main/java/com/mysema/query/sql/types/DateTimeType.java rename to querydsl-sql/src/main/java/com/querydsl/sql/types/DateTimeType.java index 3b004681e4..c757359a60 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/types/DateTimeType.java +++ b/querydsl-sql/src/main/java/com/querydsl/sql/types/DateTimeType.java @@ -1,5 +1,5 @@ /* - * Copyright 2011, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,19 +11,20 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql.types; - -import org.joda.time.DateTime; +package com.querydsl.sql.types; import java.sql.*; +import org.joda.time.DateTime; + /** - * DateTimeType maps DateTime to Timestamp on the JDBC level + * {@code DateTimeType} maps {@linkplain org.joda.time.DateTime} + * to {@linkplain java.sql.Timestamp} on the JDBC level * * @author tiwe * */ -public class DateTimeType extends AbstractDateTimeType { +public class DateTimeType extends AbstractJodaTimeDateTimeType { public DateTimeType() { super(Types.TIMESTAMP); diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/types/DateType.java b/querydsl-sql/src/main/java/com/querydsl/sql/types/DateType.java similarity index 85% rename from querydsl-sql/src/main/java/com/mysema/query/sql/types/DateType.java rename to querydsl-sql/src/main/java/com/querydsl/sql/types/DateType.java index e2dd345f7e..50af30aba1 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/types/DateType.java +++ b/querydsl-sql/src/main/java/com/querydsl/sql/types/DateType.java @@ -1,5 +1,5 @@ /* - * Copyright 2011, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,12 +11,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql.types; +package com.querydsl.sql.types; import java.sql.*; /** - * DateType maps Date to Date on the JDBC level + * {@code DateType} maps Date to Date on the JDBC level * * @author tiwe * @@ -33,7 +33,7 @@ public DateType(int type) { @Override public String getLiteral(Date value) { - return dateFormatter.print(value.getTime()); + return dateFormatter.format(value.toLocalDate()); } @Override diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/types/DoubleType.java b/querydsl-sql/src/main/java/com/querydsl/sql/types/DoubleType.java new file mode 100644 index 0000000000..87ca936dfe --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/types/DoubleType.java @@ -0,0 +1,53 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.types; + +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Types; + +/** + * {@code DoubleType} maps Double to Double on the JDBC level + * + * @author tiwe + * + */ +public class DoubleType extends AbstractType { + + public DoubleType() { + super(Types.DOUBLE); + } + + public DoubleType(int type) { + super(type); + } + + @Override + public Class getReturnedClass() { + return Double.class; + } + + @Override + public Double getValue(ResultSet rs, int startIndex) throws SQLException { + double val = rs.getDouble(startIndex); + return rs.wasNull() ? null : val; + } + + @Override + public void setValue(PreparedStatement st, int startIndex, Double value) throws SQLException { + st.setDouble(startIndex, value); + } + +} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/types/EnumAsObjectType.java b/querydsl-sql/src/main/java/com/querydsl/sql/types/EnumAsObjectType.java similarity index 89% rename from querydsl-sql/src/main/java/com/mysema/query/sql/types/EnumAsObjectType.java rename to querydsl-sql/src/main/java/com/querydsl/sql/types/EnumAsObjectType.java index d3a10904c2..8fa6665175 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/types/EnumAsObjectType.java +++ b/querydsl-sql/src/main/java/com/querydsl/sql/types/EnumAsObjectType.java @@ -1,5 +1,5 @@ /* - * Copyright 2012, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql.types; +package com.querydsl.sql.types; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -19,7 +19,7 @@ import java.sql.Types; /** - * EnumAsObjectType maps Enum types to Object on the JDBC level + * {@code EnumAsObjectType} maps Enum types to Object on the JDBC level * * @author tiwe * diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/types/EnumByNameType.java b/querydsl-sql/src/main/java/com/querydsl/sql/types/EnumByNameType.java similarity index 89% rename from querydsl-sql/src/main/java/com/mysema/query/sql/types/EnumByNameType.java rename to querydsl-sql/src/main/java/com/querydsl/sql/types/EnumByNameType.java index bf555d5415..4ecefe63d2 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/types/EnumByNameType.java +++ b/querydsl-sql/src/main/java/com/querydsl/sql/types/EnumByNameType.java @@ -1,5 +1,5 @@ /* - * Copyright 2011, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql.types; +package com.querydsl.sql.types; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -19,7 +19,7 @@ import java.sql.Types; /** - * EnumByNameType maps Enum types to their String names on the JDBC level + * {@code EnumByNameType} maps Enum types to their String names on the JDBC level * * @author tiwe * diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/types/EnumByOrdinalType.java b/querydsl-sql/src/main/java/com/querydsl/sql/types/EnumByOrdinalType.java similarity index 81% rename from querydsl-sql/src/main/java/com/mysema/query/sql/types/EnumByOrdinalType.java rename to querydsl-sql/src/main/java/com/querydsl/sql/types/EnumByOrdinalType.java index e45220ac68..f4f529f078 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/types/EnumByOrdinalType.java +++ b/querydsl-sql/src/main/java/com/querydsl/sql/types/EnumByOrdinalType.java @@ -1,5 +1,5 @@ /* - * Copyright 2011, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql.types; +package com.querydsl.sql.types; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -19,7 +19,7 @@ import java.sql.Types; /** - * EnumByOrdinalType maps Enum types to their Integer ordinals on the JDBC level + * {@code EnumByOrdinalType} maps Enum types to their Integer ordinals on the JDBC level * * @author tiwe * @@ -45,8 +45,8 @@ public Class getReturnedClass() { @Override public T getValue(ResultSet rs, int startIndex) throws SQLException { - Integer ordinal = (Integer)rs.getObject(startIndex); - return ordinal != null ? type.getEnumConstants()[ordinal.intValue()] : null; + int ordinal = rs.getInt(startIndex); + return rs.wasNull() ? null : type.getEnumConstants()[ordinal]; } @Override diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/types/FloatType.java b/querydsl-sql/src/main/java/com/querydsl/sql/types/FloatType.java new file mode 100644 index 0000000000..c874f9ce67 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/types/FloatType.java @@ -0,0 +1,53 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.types; + +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Types; + +/** + * {@code FloatType} maps Float to Float on the JDBC level + * + * @author tiwe + * + */ +public class FloatType extends AbstractType { + + public FloatType() { + super(Types.FLOAT); + } + + public FloatType(int type) { + super(type); + } + + @Override + public Class getReturnedClass() { + return Float.class; + } + + @Override + public Float getValue(ResultSet rs, int startIndex) throws SQLException { + float val = rs.getFloat(startIndex); + return rs.wasNull() ? null : val; + } + + @Override + public void setValue(PreparedStatement st, int startIndex, Float value) throws SQLException { + st.setFloat(startIndex, value); + } + +} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/types/InputStreamType.java b/querydsl-sql/src/main/java/com/querydsl/sql/types/InputStreamType.java similarity index 88% rename from querydsl-sql/src/main/java/com/mysema/query/sql/types/InputStreamType.java rename to querydsl-sql/src/main/java/com/querydsl/sql/types/InputStreamType.java index d48e701752..6b6c5801d2 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/types/InputStreamType.java +++ b/querydsl-sql/src/main/java/com/querydsl/sql/types/InputStreamType.java @@ -1,5 +1,5 @@ /* - * Copyright 2011, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql.types; +package com.querydsl.sql.types; import java.io.InputStream; import java.sql.PreparedStatement; @@ -20,7 +20,7 @@ import java.sql.Types; /** - * InputStreamType maps InputStream to InputStream on the JDBC level + * {@code InputStreamType} maps InputStream to InputStream on the JDBC level * * @author tiwe * diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/types/IntegerType.java b/querydsl-sql/src/main/java/com/querydsl/sql/types/IntegerType.java new file mode 100644 index 0000000000..68219e676f --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/types/IntegerType.java @@ -0,0 +1,53 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.types; + +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Types; + +/** + * {@code IntegerType} maps Integer to Integer on the JDBC level + * + * @author tiwe + * + */ +public class IntegerType extends AbstractType { + + public IntegerType() { + super(Types.INTEGER); + } + + public IntegerType(int type) { + super(type); + } + + @Override + public Class getReturnedClass() { + return Integer.class; + } + + @Override + public Integer getValue(ResultSet rs, int startIndex) throws SQLException { + int val = rs.getInt(startIndex); + return rs.wasNull() ? null : val; + } + + @Override + public void setValue(PreparedStatement st, int startIndex, Integer value) throws SQLException { + st.setInt(startIndex, value); + } + +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/types/JSR310InstantType.java b/querydsl-sql/src/main/java/com/querydsl/sql/types/JSR310InstantType.java new file mode 100644 index 0000000000..da5b5d3f65 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/types/JSR310InstantType.java @@ -0,0 +1,42 @@ +package com.querydsl.sql.types; + +import java.sql.*; +import java.time.Instant; + +import org.jetbrains.annotations.Nullable; + +public class JSR310InstantType extends AbstractJSR310DateTimeType { + + // JDBC 4.2 does not define any support for Instant, unlike most other JSR-310 types + // few drivers support it natively, so go through Timestamp to handle it + + public JSR310InstantType() { + super(Types.TIMESTAMP); + } + + public JSR310InstantType(int type) { + super(type); + } + + @Override + public String getLiteral(Instant value) { + return dateTimeFormatter.format(Timestamp.from(value).toLocalDateTime()); + } + + @Override + public Class getReturnedClass() { + return Instant.class; + } + + @Nullable + @Override + public Instant getValue(ResultSet rs, int startIndex) throws SQLException { + Timestamp timestamp = rs.getTimestamp(startIndex); + return timestamp != null ? timestamp.toInstant() : null; + } + + @Override + public void setValue(PreparedStatement st, int startIndex, Instant value) throws SQLException { + st.setTimestamp(startIndex, Timestamp.from(value)); + } +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/types/JSR310LocalDateTimeType.java b/querydsl-sql/src/main/java/com/querydsl/sql/types/JSR310LocalDateTimeType.java new file mode 100644 index 0000000000..1eb0b54a80 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/types/JSR310LocalDateTimeType.java @@ -0,0 +1,40 @@ +package com.querydsl.sql.types; + +import org.jetbrains.annotations.Nullable; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Types; +import java.time.LocalDateTime; + +public class JSR310LocalDateTimeType extends AbstractJSR310DateTimeType { + + public JSR310LocalDateTimeType() { + super(Types.TIMESTAMP); + } + + public JSR310LocalDateTimeType(int type) { + super(type); + } + + @Override + public String getLiteral(LocalDateTime value) { + return dateTimeFormatter.format(value); + } + + @Override + public Class getReturnedClass() { + return LocalDateTime.class; + } + + @Nullable + @Override + public LocalDateTime getValue(ResultSet rs, int startIndex) throws SQLException { + return rs.getObject(startIndex, LocalDateTime.class); + } + + @Override + public void setValue(PreparedStatement st, int startIndex, LocalDateTime value) throws SQLException { + st.setObject(startIndex, value); + } +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/types/JSR310LocalDateType.java b/querydsl-sql/src/main/java/com/querydsl/sql/types/JSR310LocalDateType.java new file mode 100644 index 0000000000..08d3963753 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/types/JSR310LocalDateType.java @@ -0,0 +1,38 @@ +package com.querydsl.sql.types; + +import java.sql.*; +import java.time.LocalDate; + +import org.jetbrains.annotations.Nullable; + +public class JSR310LocalDateType extends AbstractJSR310DateTimeType { + + public JSR310LocalDateType() { + super(Types.DATE); + } + + public JSR310LocalDateType(int type) { + super(type); + } + + @Override + public String getLiteral(LocalDate value) { + return dateFormatter.format(value); + } + + @Override + public Class getReturnedClass() { + return LocalDate.class; + } + + @Nullable + @Override + public LocalDate getValue(ResultSet rs, int startIndex) throws SQLException { + return rs.getObject(startIndex, LocalDate.class); + } + + @Override + public void setValue(PreparedStatement st, int startIndex, LocalDate value) throws SQLException { + st.setObject(startIndex, value); + } +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/types/JSR310LocalTimeType.java b/querydsl-sql/src/main/java/com/querydsl/sql/types/JSR310LocalTimeType.java new file mode 100644 index 0000000000..b0160cf38c --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/types/JSR310LocalTimeType.java @@ -0,0 +1,38 @@ +package com.querydsl.sql.types; + +import java.sql.*; +import java.time.LocalTime; + +import org.jetbrains.annotations.Nullable; + +public class JSR310LocalTimeType extends AbstractJSR310DateTimeType { + + public JSR310LocalTimeType() { + super(Types.TIME); + } + + public JSR310LocalTimeType(int type) { + super(type); + } + + @Override + public String getLiteral(LocalTime value) { + return timeFormatter.format(value); + } + + @Override + public Class getReturnedClass() { + return LocalTime.class; + } + + @Nullable + @Override + public LocalTime getValue(ResultSet rs, int startIndex) throws SQLException { + return rs.getObject(startIndex, LocalTime.class); + } + + @Override + public void setValue(PreparedStatement st, int startIndex, LocalTime value) throws SQLException { + st.setObject(startIndex, value); + } +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/types/JSR310OffsetDateTimeType.java b/querydsl-sql/src/main/java/com/querydsl/sql/types/JSR310OffsetDateTimeType.java new file mode 100644 index 0000000000..ed800673ca --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/types/JSR310OffsetDateTimeType.java @@ -0,0 +1,41 @@ +package com.querydsl.sql.types; + +import org.jetbrains.annotations.Nullable; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Types; +import java.time.OffsetDateTime; + +public class JSR310OffsetDateTimeType extends AbstractJSR310DateTimeType { + + + public JSR310OffsetDateTimeType() { + super(Types.TIMESTAMP_WITH_TIMEZONE); + } + + public JSR310OffsetDateTimeType(int type) { + super(type); + } + + @Override + public String getLiteral(OffsetDateTime value) { + return dateTimeOffsetFormatter.format(value); + } + + @Override + public Class getReturnedClass() { + return OffsetDateTime.class; + } + + @Nullable + @Override + public OffsetDateTime getValue(ResultSet rs, int startIndex) throws SQLException { + return rs.getObject(startIndex, OffsetDateTime.class); + } + + @Override + public void setValue(PreparedStatement st, int startIndex, OffsetDateTime value) throws SQLException { + st.setObject(startIndex, value); + } +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/types/JSR310OffsetTimeType.java b/querydsl-sql/src/main/java/com/querydsl/sql/types/JSR310OffsetTimeType.java new file mode 100644 index 0000000000..b55e88de09 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/types/JSR310OffsetTimeType.java @@ -0,0 +1,38 @@ +package com.querydsl.sql.types; + +import java.sql.*; +import java.time.OffsetTime; + +import org.jetbrains.annotations.Nullable; + +public class JSR310OffsetTimeType extends AbstractJSR310DateTimeType { + + public JSR310OffsetTimeType() { + super(Types.TIME_WITH_TIMEZONE); + } + + public JSR310OffsetTimeType(int type) { + super(type); + } + + @Override + public String getLiteral(OffsetTime value) { + return timeOffsetFormatter.format(value); + } + + @Override + public Class getReturnedClass() { + return OffsetTime.class; + } + + @Nullable + @Override + public OffsetTime getValue(ResultSet rs, int startIndex) throws SQLException { + return rs.getObject(startIndex, OffsetTime.class); + } + + @Override + public void setValue(PreparedStatement st, int startIndex, OffsetTime value) throws SQLException { + st.setObject(startIndex, value); + } +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/types/JSR310ZonedDateTimeType.java b/querydsl-sql/src/main/java/com/querydsl/sql/types/JSR310ZonedDateTimeType.java new file mode 100644 index 0000000000..f74a4bf820 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/types/JSR310ZonedDateTimeType.java @@ -0,0 +1,40 @@ +package com.querydsl.sql.types; + +import org.jetbrains.annotations.Nullable; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Types; +import java.time.ZonedDateTime; + +public class JSR310ZonedDateTimeType extends AbstractJSR310DateTimeType { + + public JSR310ZonedDateTimeType() { + super(Types.TIMESTAMP_WITH_TIMEZONE); + } + + public JSR310ZonedDateTimeType(int type) { + super(type); + } + + @Override + public String getLiteral(ZonedDateTime value) { + return dateTimeZoneFormatter.format(value); + } + + @Override + public Class getReturnedClass() { + return ZonedDateTime.class; + } + + @Nullable + @Override + public ZonedDateTime getValue(ResultSet rs, int startIndex) throws SQLException { + return rs.getObject(startIndex, ZonedDateTime.class); + } + + @Override + public void setValue(PreparedStatement st, int startIndex, ZonedDateTime value) throws SQLException { + st.setObject(startIndex, value); + } +} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/types/LocalDateTimeType.java b/querydsl-sql/src/main/java/com/querydsl/sql/types/LocalDateTimeType.java similarity index 83% rename from querydsl-sql/src/main/java/com/mysema/query/sql/types/LocalDateTimeType.java rename to querydsl-sql/src/main/java/com/querydsl/sql/types/LocalDateTimeType.java index 89827c4788..fe6be87a39 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/types/LocalDateTimeType.java +++ b/querydsl-sql/src/main/java/com/querydsl/sql/types/LocalDateTimeType.java @@ -1,5 +1,5 @@ /* - * Copyright 2011, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,21 +11,22 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql.types; +package com.querydsl.sql.types; + +import java.sql.*; import org.joda.time.DateTime; import org.joda.time.DateTimeZone; import org.joda.time.LocalDateTime; -import java.sql.*; - /** - * LocalDateTimeType maps LocalDateTime to Timestamp on the JDBC level + * {@code LocalDateTimeType} maps {@linkplain org.joda.time.LocalDateTime} + * to {@linkplain java.sql.Timestamp} on the JDBC level * * @author tiwe * */ -public class LocalDateTimeType extends AbstractDateTimeType { +public class LocalDateTimeType extends AbstractJodaTimeDateTimeType { public LocalDateTimeType() { super(Types.TIMESTAMP); diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/types/LocalDateType.java b/querydsl-sql/src/main/java/com/querydsl/sql/types/LocalDateType.java similarity index 83% rename from querydsl-sql/src/main/java/com/mysema/query/sql/types/LocalDateType.java rename to querydsl-sql/src/main/java/com/querydsl/sql/types/LocalDateType.java index ff2a6e87d2..f26d308b16 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/types/LocalDateType.java +++ b/querydsl-sql/src/main/java/com/querydsl/sql/types/LocalDateType.java @@ -1,5 +1,5 @@ /* - * Copyright 2011, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,20 +11,21 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql.types; +package com.querydsl.sql.types; + +import java.sql.*; import org.joda.time.DateTimeZone; import org.joda.time.LocalDate; -import java.sql.*; - /** - * LocalDateType maps LocalDate to Date on the JDBC level + * {@code LocalDateType} maps {@linkplain org.joda.time.LocalDate} + * to {@linkplain java.sql.Date} on the JDBC level * * @author tiwe * */ -public class LocalDateType extends AbstractDateTimeType { +public class LocalDateType extends AbstractJodaTimeDateTimeType { public LocalDateType() { super(Types.DATE); diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/types/LocalTimeType.java b/querydsl-sql/src/main/java/com/querydsl/sql/types/LocalTimeType.java similarity index 83% rename from querydsl-sql/src/main/java/com/mysema/query/sql/types/LocalTimeType.java rename to querydsl-sql/src/main/java/com/querydsl/sql/types/LocalTimeType.java index ec7ea96cec..47a1d1205e 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/types/LocalTimeType.java +++ b/querydsl-sql/src/main/java/com/querydsl/sql/types/LocalTimeType.java @@ -1,5 +1,5 @@ /* - * Copyright 2011, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,20 +11,21 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql.types; +package com.querydsl.sql.types; + +import java.sql.*; import org.joda.time.DateTimeZone; import org.joda.time.LocalTime; -import java.sql.*; - /** - * LocalTimeType maps LocalTime to Time on the JDBC level + * {@code LocalTimeType} maps {@linkplain org.joda.time.LocalTime} + * to {@linkplain java.sql.Time} on the JDBC level * * @author tiwe * */ -public class LocalTimeType extends AbstractDateTimeType { +public class LocalTimeType extends AbstractJodaTimeDateTimeType { public LocalTimeType() { super(Types.TIME); diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/types/LocaleType.java b/querydsl-sql/src/main/java/com/querydsl/sql/types/LocaleType.java similarity index 89% rename from querydsl-sql/src/main/java/com/mysema/query/sql/types/LocaleType.java rename to querydsl-sql/src/main/java/com/querydsl/sql/types/LocaleType.java index 3b946df861..7dff25cf74 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/types/LocaleType.java +++ b/querydsl-sql/src/main/java/com/querydsl/sql/types/LocaleType.java @@ -1,5 +1,5 @@ /* - * Copyright 2013, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql.types; +package com.querydsl.sql.types; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -20,10 +20,10 @@ import java.util.Locale; import java.util.regex.Pattern; -import javax.annotation.Nullable; +import org.jetbrains.annotations.Nullable; /** - * LocaleType maps Locale to String on the JDBC level + * {@code LocaleType} maps Locale to String on the JDBC level * * @author tiwe * diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/types/LongType.java b/querydsl-sql/src/main/java/com/querydsl/sql/types/LongType.java new file mode 100644 index 0000000000..292655b5ae --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/types/LongType.java @@ -0,0 +1,53 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.types; + +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Types; + +/** + * {@code LongType} maps Long to Long on the JDBC level + * + * @author tiwe + * + */ +public class LongType extends AbstractType { + + public LongType() { + super(Types.BIGINT); + } + + public LongType(int type) { + super(type); + } + + @Override + public Class getReturnedClass() { + return Long.class; + } + + @Override + public Long getValue(ResultSet rs, int startIndex) throws SQLException { + long val = rs.getLong(startIndex); + return rs.wasNull() ? null : val; + } + + @Override + public void setValue(PreparedStatement st, int startIndex, Long value) throws SQLException { + st.setLong(startIndex, value); + } + +} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/types/LongVarBinaryBytesType.java b/querydsl-sql/src/main/java/com/querydsl/sql/types/LongVarBinaryBytesType.java similarity index 80% rename from querydsl-sql/src/main/java/com/mysema/query/sql/types/LongVarBinaryBytesType.java rename to querydsl-sql/src/main/java/com/querydsl/sql/types/LongVarBinaryBytesType.java index 4b04409a25..c7f44057c6 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/types/LongVarBinaryBytesType.java +++ b/querydsl-sql/src/main/java/com/querydsl/sql/types/LongVarBinaryBytesType.java @@ -1,5 +1,5 @@ /* - * Copyright 2011, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,11 +11,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql.types; +package com.querydsl.sql.types; import java.sql.Types; /** + * {@code LongVarBinaryBytesType} uses {@code LONGVARBINARY} as the JDBC type + * * @author tiwe * */ diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/types/Null.java b/querydsl-sql/src/main/java/com/querydsl/sql/types/Null.java new file mode 100644 index 0000000000..a295bc2d49 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/types/Null.java @@ -0,0 +1,33 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.types; + +import com.querydsl.core.types.Constant; +import com.querydsl.core.types.ConstantImpl; + +/** + * {@code Null} is a singleton value replacement for null + * + * @author tiwe + * + */ +public final class Null { + + public static final Null DEFAULT = new Null(); + + public static final Constant CONSTANT = ConstantImpl.create(DEFAULT); + + private Null() { } + +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/types/NumericBooleanType.java b/querydsl-sql/src/main/java/com/querydsl/sql/types/NumericBooleanType.java new file mode 100644 index 0000000000..0f71859fc6 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/types/NumericBooleanType.java @@ -0,0 +1,63 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.types; + +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Types; + +import org.jetbrains.annotations.Nullable; + +/** + * {@code NumericBooleanType} maps Boolean to 1/0 (Integer) on the JDBC level + * + * @author tiwe + * + */ +public class NumericBooleanType extends AbstractType { + + public static final NumericBooleanType DEFAULT = new NumericBooleanType(); + + public NumericBooleanType() { + super(Types.INTEGER); + } + + public NumericBooleanType(int type) { + super(type); + } + + @Override + public Class getReturnedClass() { + return Boolean.class; + } + + @Override + public String getLiteral(Boolean value) { + return value ? "1" : "0"; + } + + @Override + @Nullable + public Boolean getValue(ResultSet rs, int startIndex) throws SQLException { + Number num = (Number) rs.getObject(startIndex); + return num != null ? num.intValue() == 1 : null; + } + + @Override + public void setValue(PreparedStatement st, int startIndex, Boolean value) throws SQLException { + st.setInt(startIndex, value ? 1 : 0); + } + +} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/types/ObjectType.java b/querydsl-sql/src/main/java/com/querydsl/sql/types/ObjectType.java similarity index 88% rename from querydsl-sql/src/main/java/com/mysema/query/sql/types/ObjectType.java rename to querydsl-sql/src/main/java/com/querydsl/sql/types/ObjectType.java index 66b6f80751..7bfb05bdfa 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/types/ObjectType.java +++ b/querydsl-sql/src/main/java/com/querydsl/sql/types/ObjectType.java @@ -1,5 +1,5 @@ /* - * Copyright 2011, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql.types; +package com.querydsl.sql.types; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -19,7 +19,7 @@ import java.sql.Types; /** - * ObjectType maps Object to Object on the JDBC level + * {@code ObjectType} maps Object to Object on the JDBC level * * @author tiwe * diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/types/SQLXMLType.java b/querydsl-sql/src/main/java/com/querydsl/sql/types/SQLXMLType.java new file mode 100644 index 0000000000..b29855d4fe --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/types/SQLXMLType.java @@ -0,0 +1,51 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.types; + +import java.sql.*; + +/** + * {@code SQLXMLType} maps SQLXML to SQLXML on the JDBC level + * + * @author tiwe + * + */ +public class SQLXMLType extends AbstractType { + + public SQLXMLType() { + super(Types.SQLXML); + } + + public SQLXMLType(int type) { + super(type); + } + + @Override + public SQLXML getValue(ResultSet rs, int startIndex) throws SQLException { + return rs.getSQLXML(startIndex); + } + + @Override + public Class getReturnedClass() { + return SQLXML.class; + } + + @Override + public void setValue(PreparedStatement st, int startIndex, SQLXML value) + throws SQLException { + st.setSQLXML(startIndex, value); + + } + +} diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/types/ShortType.java b/querydsl-sql/src/main/java/com/querydsl/sql/types/ShortType.java new file mode 100644 index 0000000000..50a19ad6f9 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/types/ShortType.java @@ -0,0 +1,53 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.types; + +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Types; + +/** + * {@code ShortType} maps Short to Short on the JDBC level + * + * @author tiwe + * + */ +public class ShortType extends AbstractType { + + public ShortType() { + super(Types.SMALLINT); + } + + public ShortType(int type) { + super(type); + } + + @Override + public Class getReturnedClass() { + return Short.class; + } + + @Override + public Short getValue(ResultSet rs, int startIndex) throws SQLException { + short val = rs.getShort(startIndex); + return rs.wasNull() ? null : val; + } + + @Override + public void setValue(PreparedStatement st, int startIndex, Short value) throws SQLException { + st.setShort(startIndex, value); + } + +} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/types/StringAsObjectType.java b/querydsl-sql/src/main/java/com/querydsl/sql/types/StringAsObjectType.java similarity index 82% rename from querydsl-sql/src/main/java/com/mysema/query/sql/types/StringAsObjectType.java rename to querydsl-sql/src/main/java/com/querydsl/sql/types/StringAsObjectType.java index 926db4a0f0..3be14cb0fc 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/types/StringAsObjectType.java +++ b/querydsl-sql/src/main/java/com/querydsl/sql/types/StringAsObjectType.java @@ -1,5 +1,5 @@ /* - * Copyright 2011, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,16 +11,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql.types; +package com.querydsl.sql.types; -import java.sql.Clob; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Types; +import java.sql.*; /** - * StringAsObjectType maps String to String on the JDBC level + * {@code StringAsObjectType} maps String to String on the JDBC level * * @author tiwe * @@ -41,9 +37,9 @@ public StringAsObjectType(int type) { public String getValue(ResultSet rs, int startIndex) throws SQLException { Object o = rs.getObject(startIndex); if (o instanceof String) { - return (String)o; + return (String) o; } else if (o instanceof Clob) { - Clob clob = (Clob)o; + Clob clob = (Clob) o; return clob.getSubString(1, (int) clob.length()); } else if (o != null) { return o.toString(); diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/types/StringType.java b/querydsl-sql/src/main/java/com/querydsl/sql/types/StringType.java similarity index 88% rename from querydsl-sql/src/main/java/com/mysema/query/sql/types/StringType.java rename to querydsl-sql/src/main/java/com/querydsl/sql/types/StringType.java index d966b8c991..077960737b 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/types/StringType.java +++ b/querydsl-sql/src/main/java/com/querydsl/sql/types/StringType.java @@ -1,5 +1,5 @@ /* - * Copyright 2011, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql.types; +package com.querydsl.sql.types; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -19,7 +19,7 @@ import java.sql.Types; /** - * StringType maps String to String on the JDBC level + * {@code StringType} maps String to String on the JDBC level * * @author tiwe * diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/types/TimeType.java b/querydsl-sql/src/main/java/com/querydsl/sql/types/TimeType.java similarity index 85% rename from querydsl-sql/src/main/java/com/mysema/query/sql/types/TimeType.java rename to querydsl-sql/src/main/java/com/querydsl/sql/types/TimeType.java index cee289505e..7e9c00705f 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/types/TimeType.java +++ b/querydsl-sql/src/main/java/com/querydsl/sql/types/TimeType.java @@ -1,5 +1,5 @@ /* - * Copyright 2011, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,12 +11,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql.types; +package com.querydsl.sql.types; import java.sql.*; /** - * TimeType maps Time to Time on the JDBC level + * {@code TimeType} maps Time to Time on the JDBC level * * @author tiwe * @@ -33,7 +33,7 @@ public TimeType(int type) { @Override public String getLiteral(Time value) { - return timeFormatter.print(value.getTime()); + return timeFormatter.format(value.toLocalTime()); } @Override diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/types/TimestampType.java b/querydsl-sql/src/main/java/com/querydsl/sql/types/TimestampType.java similarity index 84% rename from querydsl-sql/src/main/java/com/mysema/query/sql/types/TimestampType.java rename to querydsl-sql/src/main/java/com/querydsl/sql/types/TimestampType.java index a03603ea05..e808f0b76f 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/types/TimestampType.java +++ b/querydsl-sql/src/main/java/com/querydsl/sql/types/TimestampType.java @@ -1,5 +1,5 @@ /* - * Copyright 2011, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,12 +11,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql.types; +package com.querydsl.sql.types; import java.sql.*; /** - * TimestampType maps Timestamp to Timestamp on the JDBC level + * {@code TimestampType} maps Timestamp to Timestamp on the JDBC level * * @author tiwe * @@ -33,7 +33,7 @@ public TimestampType(int type) { @Override public String getLiteral(Timestamp value) { - return dateTimeFormatter.print(value.getTime()); + return dateTimeFormatter.format(value.toLocalDateTime()); } @Override diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/types/TrueFalseType.java b/querydsl-sql/src/main/java/com/querydsl/sql/types/TrueFalseType.java similarity index 83% rename from querydsl-sql/src/main/java/com/mysema/query/sql/types/TrueFalseType.java rename to querydsl-sql/src/main/java/com/querydsl/sql/types/TrueFalseType.java index d70e66e200..58961a2a14 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/types/TrueFalseType.java +++ b/querydsl-sql/src/main/java/com/querydsl/sql/types/TrueFalseType.java @@ -1,5 +1,5 @@ /* - * Copyright 2013, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,17 +11,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql.types; +package com.querydsl.sql.types; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Types; -import javax.annotation.Nullable; +import org.jetbrains.annotations.Nullable; /** - * TrueFalseType maps Boolean to 'T'/'F' on the JDBC level + * {@code TrueFalseType} maps Boolean to 'T'/'F' on the JDBC level * * @author tiwe * @@ -50,7 +50,7 @@ public Boolean getValue(ResultSet rs, int startIndex) throws SQLException { @Override public void setValue(PreparedStatement st, int startIndex, Boolean value) throws SQLException { - st.setString(startIndex, value.booleanValue() ? "T" : "F"); + st.setString(startIndex, value ? "T" : "F"); } diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/types/Type.java b/querydsl-sql/src/main/java/com/querydsl/sql/types/Type.java new file mode 100644 index 0000000000..d88f60f299 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/types/Type.java @@ -0,0 +1,77 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.types; + +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; + +import org.jetbrains.annotations.Nullable; + +/** + * Defines the de/serialization of a typed Java object from a ResultSet or to a PreparedStatement + * + *

getValue(ResultSet, int) is used for extraction and setValue(PreparedStatement, int, T) is + * used for population

+ * + * @author tiwe + * + * @param + */ +public interface Type { + + /** + * Get the SQL supported SQL types + * + * @return sql types + */ + int[] getSQLTypes(); + + /** + * Get the returned type + * + * @return returned class + */ + Class getReturnedClass(); + + /** + * Get the literal representation + * + * @param value value + * @return literal representation + */ + String getLiteral(T value); + + /** + * Get the object from the result set + * + * @param rs result set + * @param startIndex column index in result set + * @return value + * @throws SQLException + */ + @Nullable + T getValue(ResultSet rs, int startIndex) throws SQLException; + + /** + * Set the object to the statement + * + * @param st statement + * @param startIndex column index in statement + * @param value value to be set + * @throws SQLException + */ + void setValue(PreparedStatement st, int startIndex, T value) throws SQLException; + +} \ No newline at end of file diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/types/URLType.java b/querydsl-sql/src/main/java/com/querydsl/sql/types/URLType.java similarity index 89% rename from querydsl-sql/src/main/java/com/mysema/query/sql/types/URLType.java rename to querydsl-sql/src/main/java/com/querydsl/sql/types/URLType.java index 832bf68465..e8caa90ad2 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/types/URLType.java +++ b/querydsl-sql/src/main/java/com/querydsl/sql/types/URLType.java @@ -1,5 +1,5 @@ /* - * Copyright 2011, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql.types; +package com.querydsl.sql.types; import java.net.URL; import java.sql.PreparedStatement; @@ -20,7 +20,7 @@ import java.sql.Types; /** - * URLType maps URL to URL on the JDBC level + * {@code URLType} maps URL to URL on the JDBC level * * @author tiwe * diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/types/UtilDateType.java b/querydsl-sql/src/main/java/com/querydsl/sql/types/UtilDateType.java similarity index 84% rename from querydsl-sql/src/main/java/com/mysema/query/sql/types/UtilDateType.java rename to querydsl-sql/src/main/java/com/querydsl/sql/types/UtilDateType.java index c91a56108e..5fa286742e 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/types/UtilDateType.java +++ b/querydsl-sql/src/main/java/com/querydsl/sql/types/UtilDateType.java @@ -1,5 +1,5 @@ /* - * Copyright 2011, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql.types; +package com.querydsl.sql.types; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -20,7 +20,7 @@ import java.util.Date; /** - * UtilDateType maps Date to Timestamp on the JDBC level + * {@code UtilDateType} maps Date to Timestamp on the JDBC level * * @author tiwe * @@ -37,7 +37,7 @@ public UtilDateType(int type) { @Override public String getLiteral(Date value) { - return dateTimeFormatter.print(value.getTime()); + return dateTimeFormatter.format(new java.sql.Timestamp(value.getTime()).toLocalDateTime()); } @Override diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/types/UtilUUIDType.java b/querydsl-sql/src/main/java/com/querydsl/sql/types/UtilUUIDType.java new file mode 100644 index 0000000000..3a2a7d3e68 --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/types/UtilUUIDType.java @@ -0,0 +1,73 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.types; + +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Types; +import java.util.UUID; + +/** + * {@code UtilUUIDType} maps UUID to String on the JDBC level + * + * @author tiwe + * + */ +public class UtilUUIDType extends AbstractType { + + private final boolean asString; + + public UtilUUIDType() { + this(Types.OTHER, true); + } + + public UtilUUIDType(boolean asString) { + this(Types.OTHER, asString); + } + + public UtilUUIDType(int type) { + this(type, true); + } + + public UtilUUIDType(int type, boolean asString) { + super(type); + this.asString = asString; + } + + @Override + public UUID getValue(ResultSet rs, int startIndex) throws SQLException { + if (asString) { + String str = rs.getString(startIndex); + return str != null ? UUID.fromString(str) : null; + } else { + return (UUID) rs.getObject(startIndex); + } + } + + @Override + public Class getReturnedClass() { + return UUID.class; + } + + @Override + public void setValue(PreparedStatement st, int startIndex, UUID value) throws SQLException { + if (asString) { + st.setString(startIndex, value.toString()); + } else { + st.setObject(startIndex, value); + } + + } +} \ No newline at end of file diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/types/XMLAsStringType.java b/querydsl-sql/src/main/java/com/querydsl/sql/types/XMLAsStringType.java new file mode 100644 index 0000000000..1dcaee019a --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/types/XMLAsStringType.java @@ -0,0 +1,54 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.types; + +import java.sql.*; + +/** + * {@code XMLAsStringType} maps String to SQLXML on the JDBC level + * + * @author tiwe + * + */ +public class XMLAsStringType extends AbstractType { + + public XMLAsStringType() { + super(Types.SQLXML); + } + + public XMLAsStringType(int type) { + super(type); + } + + @Override + public String getValue(ResultSet rs, int startIndex) throws SQLException { + SQLXML value = rs.getSQLXML(startIndex); + return value != null ? value.getString() : null; + } + + @Override + public Class getReturnedClass() { + return String.class; + } + + @Override + public void setValue(PreparedStatement st, int startIndex, String value) + throws SQLException { + SQLXML xml = st.getConnection().createSQLXML(); + xml.setString(value); + st.setSQLXML(startIndex, xml); + + } + +} diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/types/YesNoType.java b/querydsl-sql/src/main/java/com/querydsl/sql/types/YesNoType.java similarity index 83% rename from querydsl-sql/src/main/java/com/mysema/query/sql/types/YesNoType.java rename to querydsl-sql/src/main/java/com/querydsl/sql/types/YesNoType.java index c0c1c52f70..023fb76ea8 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/types/YesNoType.java +++ b/querydsl-sql/src/main/java/com/querydsl/sql/types/YesNoType.java @@ -1,5 +1,5 @@ /* - * Copyright 2013, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,17 +11,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql.types; +package com.querydsl.sql.types; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Types; -import javax.annotation.Nullable; +import org.jetbrains.annotations.Nullable; /** - * YesNoType maps Boolean to 'Y'/'N' on the JDBC level + * {@code YesNoType} maps Boolean to 'Y'/'N' on the JDBC level * * @author tiwe * @@ -50,7 +50,7 @@ public Boolean getValue(ResultSet rs, int startIndex) throws SQLException { @Override public void setValue(PreparedStatement st, int startIndex, Boolean value) throws SQLException { - st.setString(startIndex, value.booleanValue() ? "Y" : "N"); + st.setString(startIndex, value ? "Y" : "N"); } diff --git a/querydsl-sql/src/main/java/com/querydsl/sql/types/package-info.java b/querydsl-sql/src/main/java/com/querydsl/sql/types/package-info.java new file mode 100644 index 0000000000..9179d7c39f --- /dev/null +++ b/querydsl-sql/src/main/java/com/querydsl/sql/types/package-info.java @@ -0,0 +1,19 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ + + +/** + * Types for de/serialization to ResultSet and PreparedStatement + */ +package com.querydsl.sql.types; diff --git a/querydsl-sql/src/main/resources/keywords/cubrid b/querydsl-sql/src/main/resources/keywords/cubrid new file mode 100644 index 0000000000..0342d73c3e --- /dev/null +++ b/querydsl-sql/src/main/resources/keywords/cubrid @@ -0,0 +1,371 @@ +# source http://www.cubrid.org/manual/830/en/CUBRID%20Keywords +ABSOLUTE +ACTION +ADD +ADD_MONTHS +AFTER +ALIAS +ALL +ALLOCATE +ALTER +AND +ANY +ARE +AS +ASC +ASSERTION +ASYNC +AT +ATTACH +ATTRIBUTE +AVG +BEFORE +BETWEEN +BIGINT +BIT +BIT_LENGTH +BOTH +BREADTH +BY +CALL +CASCADE +CASCADED +CASE +CAST +CATALOG +CHANGE +CHAR +CHARACTER +CHECK +CLASS +CLASSES +CLOSE +CLUSTER +COALESCE +COLLATE +COLLATION +COLUMN +COMMIT +COMPLETION +CONNECT +CONNECTION +CONNECT_BY_ISCYCLE +CONNECT_BY_ISLEAF +CONNECT_BY_ROOT +CONSTRAINT +CONSTRAINTS +CONTINUE +CONVERT +CORRESPONDING +COUNT +CREATE +CROSS +CURRENT +CURRENT_DATE +CURRENT_DATETIME +CURRENT_TIME +CURRENT_TIMESTAMP +CURRENT_USER +CURSOR +CYCLE +DATA +DATABASE +DATA_TYPE +DATE +DATETIME +DAY +DAY_HOUR +DAY_MILLISECOND +DAY_MINUTE +DAY_SECOND +DEALLOCATE +DEC +DECIMAL +DECLARE +DEFAULT +DEFERRABLE +DEFERRED +DELETE +DEPTH +DESC +DESCRIBE +DESCRIPTOR +DIAGNOSTICS +DICTIONARY +DIFFERENCE +DISCONNECT +DISTINCT +DISTINCTROW +DIV +DO +DOMAIN +DOUBLE +DROP +DUPLICATE +EACH +ELSE +ELSEIF +END +EQUALS +ESCAPE +EVALUATE +EXCEPT +EXCEPTION +EXCLUDE +EXEC +EXECUTE +EXISTS +EXTERNAL +EXTRACT +FALSE +FETCH +FILE +FIRST +FLOAT +FOR +FOREIGN +FOUND +FROM +FULL +FUNCTION +GENERAL +GET +GLOBAL +GO +GOTO +GRANT +GROUP +HAVING +HOUR +HOUR_MILLISECOND +HOUR_MINUTE +HOUR_SECOND +IDENTITY +IF +IGNORE +IMMEDIATE +IN +INDEX +INDICATOR +INHERIT +INITIALLY +INNER +INOUT +INPUT +INSERT +INT +INTEGER +INTERSECT +INTERSECTION +INTERVAL +INTO +IS +ISOLATION +JOIN +KEY +LANGUAGE +LAST +LDB +LEADING +LEAVE +LEFT +LESS +LEVEL +LIKE +LIMIT +LIST +LOCAL +LOCALTIME +LOCALTIMESTAMP +LOCAL_TRANSACTION_ID +LOOP +LOWER +MATCH +MAX +METHOD +MILLISECOND +MIN +MINUTE +MINUTE_MILLISECOND +MINUTE_SECOND +MOD +MODIFY +MODULE +MONETARY +MONTH +MULTISET +MULTISET_OF +NA +NAMES +NATIONAL +NATURAL +NCHAR +NEXT +NO +NONE +NOT +NULL +NULLIF +NUMERIC +OBJECT +OCTET_LENGTH +OF +OFF +OID +ON +ONLY +OPEN +OPERATION +OPERATORS +OPTIMIZATION +OPTION +OR +ORDER +OTHERS +OUT +OUTER +OUTPUT +OVERLAPS +PARAMETERS +PARTIAL +PENDANT +POSITION +PRECISION +PREORDER +PREPARE +PRESERVE +PRIMARY +PRIOR +PRIVATE +PRIVILEGES +PROCEDURE +PROTECTED +PROXY +QUERY +READ +REAL +RECURSIVE +REF +REFERENCES +REFERENCING +REGISTER +RELATIVE +RENAME +REPLACE +RESIGNAL +RESTRICT +RETURN +RETURNS +REVOKE +RIGHT +ROLE +ROLLBACK +ROLLUP +ROUTINE +ROW +ROWNUM +ROWS +SAVEPOINT +SCHEMA +SCOPE +SCROLL +SEARCH +SECOND +SECOND_MILLISECOND +SECTION +SELECT +SENSITIVE +SEQUENCE +SEQUENCE_OF +SERIALIZABLE +SESSION +SESSION_USER +SET +SETEQ +SET_OF +SHARED +SIBLINGS +SIGNAL +SIMILAR +SIZE +SMALLINT +SOME +SQL +SQLCODE +SQLERROR +SQLEXCEPTION +SQLSTATE +SQLWARNING +STATISTICS +STRING +STRUCTURE +SUBCLASS +SUBSET +SUBSETEQ +SUBSTRING +SUM +SUPERCLASS +SUPERSET +SUPERSETEQ +SYSDATE +SYSDATETIME +SYSTEM_USER +SYSTIME +SYS_CONNECT_BY_PATH +SYS_DATE +SYS_DATETIME +SYS_TIME +SYS_TIMESTAMP +SYS_USER +TABLE +TEMPORARY +TEST +THEN +THERE +TIME +TIMESTAMP +TIMEZONE_HOUR +TIMEZONE_MINUTE +TO +TRAILING +TRANSACTION +TRANSLATE +TRANSLATION +TRIGGER +TRIM +TRUE +TRUNCATE +TYPE +UNDER +UNION +UNIQUE +UNKNOWN +UPDATE +UPPER +USAGE +USE +USER +USING +UTIME +VALUE +VALUES +VARCHAR +VARIABLE +VARYING +VCLASS +VIEW +VIRTUAL +VISIBLE +WAIT +WHEN +WHENEVER +WHERE +WHILE +WITH +WITHOUT +WORK +WRITE +XOR +YEAR +YEAR_MONTH +ZONE diff --git a/querydsl-sql/src/main/resources/keywords/db2 b/querydsl-sql/src/main/resources/keywords/db2 new file mode 100644 index 0000000000..d496f46dc4 --- /dev/null +++ b/querydsl-sql/src/main/resources/keywords/db2 @@ -0,0 +1,518 @@ +# source http://www-01.ibm.com/support/knowledgecenter/SSEPGG_10.1.0/com.ibm.db2.luw.sql.ref.doc/doc/r0001095.html +ABS +ACTIVATE +ADD +AFTER +ALIAS +ALL +ALLOCATE +ALLOW +ALTER +AND +ANY +ARE +ARRAY +AS +ASENSITIVE +ASSOCIATE +ASUTIME +ASYMMETRIC +AT +ATOMIC +ATTRIBUTES +AUDIT +AUTHORIZATION +AUX +AUXILIARY +AVG +BEFORE +BEGIN +BETWEEN +BIGINT +BINARY +BLOB +BOOLEAN +BOTH +BUFFERPOOL +BY +CACHE +CALL +CALLED +CAPTURE +CARDINALITY +CASCADED +CASE +CAST +CCSID +CEIL +CEILING +CHAR +CHARACTER +CHARACTER_LENGTH +CHAR_LENGTH +CHECK +CLOB +CLONE +CLOSE +CLUSTER +COALESCE +COLLATE +COLLECT +COLLECTION +COLLID +COLUMN +COMMENT +COMMIT +CONCAT +CONDITION +CONNECT +CONNECTION +CONSTRAINT +CONTAINS +CONTINUE +CONVERT +CORR +CORRESPONDING +COUNT +COUNT_BIG +COVAR_POP +COVAR_SAMP +CREATE +CROSS +CUBE +CUME_DIST +CURRENT +CURRENT_DATE +CURRENT_DEFAULT_TRANSFORM_GROUP +CURRENT_LC_CTYPE +CURRENT_PATH +CURRENT_ROLE +CURRENT_SCHEMA +CURRENT_SERVER +CURRENT_TIME +CURRENT_TIMESTAMP +CURRENT_TIMEZONE +CURRENT_TRANSFORM_GROUP_FOR_TYPE +CURRENT_USER +CURSOR +CYCLE +DATA +DATABASE +DATAPARTITIONNAME +DATAPARTITIONNUM +DATE +DAY +DAYS +DB2GENERAL +DB2GENRL +DB2SQL +DBINFO +DBPARTITIONNAME +DBPARTITIONNUM +DEALLOCATE +DEC +DECIMAL +DECLARE +DEFAULT +DEFAULTS +DEFINITION +DELETE +DENSERANK +DENSE_RANK +DEREF +DESCRIBE +DESCRIPTOR +DETERMINISTIC +DIAGNOSTICS +DISABLE +DISALLOW +DISCONNECT +DISTINCT +DO +DOCUMENT +DOUBLE +DROP +DSSIZE +DYNAMIC +EACH +EDITPROC +ELEMENT +ELSE +ELSEIF +ENABLE +ENCODING +ENCRYPTION +END +END-EXEC +ENDING +ERASE +ESCAPE +EVERY +EXCEPT +EXCEPTION +EXCLUDING +EXCLUSIVE +EXEC +EXECUTE +EXISTS +EXIT +EXP +EXPLAIN +EXTENDED +EXTERNAL +EXTRACT +FALSE +FENCED +FETCH +FIELDPROC +FILE +FILTER +FINAL +FLOAT +FLOOR +FOR +FOREIGN +FREE +FROM +FULL +FUNCTION +FUSION +GENERAL +GENERATED +GET +GLOBAL +GO +GOTO +GRANT +GRAPHIC +GROUP +GROUPING +HANDLER +HASH +HASHED_VALUE +HAVING +HINT +HOLD +HOUR +HOURS +IDENTITY +IF +IMMEDIATE +IN +INCLUDING +INCLUSIVE +INCREMENT +INDEX +INDICATOR +INDICATORS +INF +INFINITY +INHERIT +INNER +INOUT +INSENSITIVE +INSERT +INT +INTEGER +INTEGRITY +INTERSECT +INTERSECTION +INTERVAL +INTO +IS +ISOBID +ISOLATION +ITERATE +JAR +JAVA +JOIN +KEEP +KEY +LABEL +LANGUAGE +LARGE +LATERAL +LC_CTYPE +LEADING +LEAVE +LEFT +LIKE +LIMIT +LINKTYPE +LN +LOCAL +LOCALDATE +LOCALE +LOCALTIME +LOCALTIMESTAMP +LOCATOR +LOCATORS +LOCK +LOCKMAX +LOCKSIZE +LONG +LOOP +LOWER +MAINTAINED +MATCH +MATERIALIZED +MAX +MAXVALUE +MEMBER +MERGE +METHOD +MICROSECOND +MICROSECONDS +MIN +MINUTE +MINUTES +MINVALUE +MOD +MODE +MODIFIES +MODULE +MONTH +MONTHS +MULTISET +NAN +NATIONAL +NATURAL +NCHAR +NCLOB +NEW +NEW_TABLE +NEXTVAL +NO +NOCACHE +NOCYCLE +NODENAME +NODENUMBER +NOMAXVALUE +NOMINVALUE +NONE +NOORDER +NORMALIZE +NORMALIZED +NOT +NULL +NULLIF +NULLS +NUMERIC +NUMPARTS +OBID +OCTET_LENGTH +OF +OFFSET +OLD +OLD_TABLE +ON +ONLY +OPEN +OPTIMIZATION +OPTIMIZE +OPTION +OR +ORDER +OUT +OUTER +OVER +OVERLAPS +OVERLAY +OVERRIDING +PACKAGE +PADDED +PAGESIZE +PARAMETER +PART +PARTITION +PARTITIONED +PARTITIONING +PARTITIONS +PASSWORD +PATH +PERCENTILE_CONT +PERCENTILE_DISC +PERCENT_RANK +PIECESIZE +PLAN +POSITION +POWER +PRECISION +PREPARE +PREVVAL +PRIMARY +PRIQTY +PRIVILEGES +PROCEDURE +PROGRAM +PSID +PUBLIC +QUERY +QUERYNO +RANGE +RANK +READ +READS +REAL +RECOVERY +RECURSIVE +REF +REFERENCES +REFERENCING +REFRESH +REGR_AVGX +REGR_AVGY +REGR_COUNT +REGR_INTERCEPT +REGR_R2 +REGR_SLOPE +REGR_SXX +REGR_SXY +REGR_SYY +RELEASE +RENAME +REPEAT +RESET +RESIGNAL +RESTART +RESTRICT +RESULT +RESULT_SET_LOCATOR +RETURN +RETURNS +REVOKE +RIGHT +ROLE +ROLLBACK +ROLLUP +ROUND_CEILING +ROUND_DOWN +ROUND_FLOOR +ROUND_HALF_DOWN +ROUND_HALF_EVEN +ROUND_HALF_UP +ROUND_UP +ROUTINE +ROW +ROWNUMBER +ROWS +ROWSET +ROW_NUMBER +RRN +RUN +SAVEPOINT +SCHEMA +SCOPE +SCRATCHPAD +SCROLL +SEARCH +SECOND +SECONDS +SECQTY +SECURITY +SELECT +SENSITIVE +SEQUENCE +SESSION +SESSION_USER +SET +SIGNAL +SIMILAR +SIMPLE +SMALLINT +SNAN +SOME +SOURCE +SPECIFIC +SPECIFICTYPE +SQL +SQLEXCEPTION +SQLID +SQLSTATE +SQLWARNING +SQRT +STACKED +STANDARD +START +STARTING +STATEMENT +STATIC +STATMENT +STAY +STDDEV_POP +STDDEV_SAMP +STOGROUP +STORES +STYLE +SUBMULTISET +SUBSTRING +SUM +SUMMARY +SYMMETRIC +SYNONYM +SYSFUN +SYSIBM +SYSPROC +SYSTEM +SYSTEM_USER +TABLE +TABLESAMPLE +TABLESPACE +THEN +TIME +TIMESTAMP +TIMEZONE_HOUR +TIMEZONE_MINUTE +TO +TRAILING +TRANSACTION +TRANSLATE +TRANSLATION +TREAT +TRIGGER +TRIM +TRUE +TRUNCATE +TYPE +UESCAPE +UNDO +UNION +UNIQUE +UNKNOWN +UNNEST +UNTIL +UPDATE +UPPER +USAGE +USER +USING +VALIDPROC +VALUE +VALUES +VARCHAR +VARIABLE +VARIANT +VARYING +VAR_POP +VAR_SAMP +VCAT +VERSION +VIEW +VOLATILE +VOLUMES +WHEN +WHENEVER +WHERE +WHILE +WIDTH_BUCKET +WINDOW +WITH +WITHIN +WITHOUT +WLM +WRITE +XMLELEMENT +XMLEXISTS +XMLNAMESPACES +YEAR +YEARS diff --git a/querydsl-sql/src/main/resources/keywords/default b/querydsl-sql/src/main/resources/keywords/default new file mode 100644 index 0000000000..87b1f4287d --- /dev/null +++ b/querydsl-sql/src/main/resources/keywords/default @@ -0,0 +1,327 @@ +ABS +ALL +ALLOCATE +ALTER +AND +ANY +ARE +ARRAY +ARRAY_AGG +AS +ASENSITIVE +ASYMMETRIC +AT +ATOMIC +AUTHORIZATION +AVG +BEGIN +BETWEEN +BIGINT +BINARY +BLOB +BOOLEAN +BOTH +BY +CALL +CALLED +CARDINALITY +CASCADED +CASE +CAST +CEIL +CEILING +CHAR +CHARACTER +CHARACTER_LENGTH +CHAR_LENGTH +CHECK +CLOB +CLOSE +COALESCE +COLLATE +COLLECT +COLUMN +COMMIT +CONDITION +CONNECT +CONSTRAINT +CONVERT +CORR +CORRESPONDING +COUNT +COVAR_POP +COVAR_SAMP +CREATE +CROSS +CUBE +CUME_DIST +CURRENT +CURRENT_CATALOG +CURRENT_DATE +CURRENT_DEFAULT_TRANSFORM_GROUP +CURRENT_PATH +CURRENT_ROLE +CURRENT_SCHEMA +CURRENT_TIME +CURRENT_TIMESTAMP +CURRENT_TRANSFORM_GROUP_FOR_TYPE +CURRENT_USER +CURSOR +CYCLE +DATE +DAY +DEALLOCATE +DEC +DECIMAL +DECLARE +DEFAULT +DELETE +DENSE_RANK +DEREF +DESCRIBE +DETERMINISTIC +DISCONNECT +DISTINCT +DOUBLE +DROP +DYNAMIC +EACH +ELEMENT +ELSE +END +END-EXEC +ESCAPE +EVERY +EXCEPT +EXEC +EXECUTE +EXISTS +EXP +EXTERNAL +EXTRACT +FALSE +FETCH +FILTER +FIRST_VALUE +FLOAT +FLOOR +FOR +FOREIGN +FREE +FROM +FULL +FUNCTION +FUSION +GET +GLOBAL +GRANT +GROUP +GROUPING +HAVING +HOLD +HOUR +IDENTITY +IN +INDICATOR +INNER +INOUT +INSENSITIVE +INSERT +INT +INTEGER +INTERSECT +INTERSECTION +INTERVAL +INTO +IS +JOIN +LAG +LANGUAGE +LARGE +LAST_VALUE +LATERAL +LEAD +LEADING +LEFT +LIKE +LIKE_REGEX +LN +LOCAL +LOCALTIME +LOCALTIMESTAMP +LOWER +MATCH +MAX +MAX_CARDINALITY +MEMBER +MERGE +METHOD +MIN +MINUTE +MOD +MODIFIES +MODULE +MONTH +MULTISET +NATIONAL +NATURAL +NCHAR +NCLOB +NEW +NO +NONE +NORMALIZE +NOT +NTH_VALUE +NTILE +NULL +NULLIF +NUMERIC +OCCURRENCES_REGEX +OCTET_LENGTH +OF +OFFSET +OLD +ON +ONLY +OPEN +OR +ORDER +OUT +OUTER +OVER +OVERLAPS +OVERLAY +PARAMETER +PARTITION +PERCENTILE_CONT +PERCENTILE_DISC +PERCENT_RANK +POSITION +POSITION_REGEX +POWER +PRECISION +PREPARE +PRIMARY +PROCEDURE +RANGE +RANK +READS +REAL +RECURSIVE +REF +REFERENCES +REFERENCING +REGR_AVGX +REGR_AVGY +REGR_COUNT +REGR_INTERCEPT +REGR_R2 +REGR_SLOPE +REGR_SXX +REGR_SXY +REGR_SYY +RELEASE +RESULT +RETURN +RETURNS +REVOKE +RIGHT +ROLLBACK +ROLLUP +ROW +ROWS +ROW_NUMBER +SAVEPOINT +SCOPE +SCROLL +SEARCH +SECOND +SELECT +SENSITIVE +SESSION_USER +SET +SIMILAR +SMALLINT +SOME +SPECIFIC +SPECIFICTYPE +SQL +SQLEXCEPTION +SQLSTATE +SQLWARNING +SQRT +START +STATIC +STDDEV_POP +STDDEV_SAMP +SUBMULTISET +SUBSTRING +SUBSTRING_REGEX +SUM +SYMMETRIC +SYSTEM +SYSTEM_USER +TABLE +TABLESAMPLE +THEN +TIME +TIMESTAMP +TIMEZONE_HOUR +TIMEZONE_MINUTE +TO +TRAILING +TRANSLATE +TRANSLATE_REGEX +TRANSLATION +TREAT +TRIGGER +TRIM +TRIM_ARRAY +TRUE +TRUNCATE +UESCAPE +UNION +UNIQUE +UNKNOWN +UNNEST +UPDATE +UPPER +USER +USING +VALUE +VALUES +VARBINARY +VARCHAR +VARYING +VAR_POP +VAR_SAMP +WHEN +WHENEVER +WHERE +WIDTH_BUCKET +WINDOW +WITH +WITHIN +WITHOUT +XML +XMLAGG +XMLATTRIBUTES +XMLBINARY +XMLCAST +XMLCOMMENT +XMLCONCAT +XMLDOCUMENT +XMLELEMENT +XMLEXISTS +XMLFOREST +XMLITERATE +XMLNAMESPACES +XMLPARSE +XMLPI +XMLQUERY +XMLSERIALIZE +XMLTABLE +XMLTEXT +XMLVALIDATE +YEAR \ No newline at end of file diff --git a/querydsl-sql/src/main/resources/keywords/derby b/querydsl-sql/src/main/resources/keywords/derby new file mode 100644 index 0000000000..fac58c39d9 --- /dev/null +++ b/querydsl-sql/src/main/resources/keywords/derby @@ -0,0 +1,208 @@ +# source https://db.apache.org/derby/docs/10.1/ref/rrefkeywords29722.html +ADD +ALL +ALLOCATE +ALTER +AND +ANY +ARE +AS +ASC +ASSERTION +AT +AUTHORIZATION +AVG +BEGIN +BETWEEN +BIT +BOOLEAN +BOTH +BY +CALL +CASCADE +CASCADED +CASE +CAST +CHAR +CHARACTER +CHECK +CLOSE +COLLATE +COLLATION +COLUMN +COMMIT +CONNECT +CONNECTION +CONSTRAINT +CONSTRAINTS +CONTINUE +CONVERT +CORRESPONDING +COUNT +CREATE +CURRENT +CURRENT_DATE +CURRENT_TIME +CURRENT_TIMESTAMP +CURRENT_USER +CURSOR +DEALLOCATE +DEC +DECIMAL +DECLARE +DEFERRABLE +DEFERRED +DELETE +DESC +DESCRIBE +DIAGNOSTICS +DISCONNECT +DISTINCT +DOUBLE +DROP +ELSE +END +ENDEXEC +ESCAPE +EXCEPT +EXCEPTION +EXEC +EXECUTE +EXISTS +EXPLAIN +EXTERNAL +FALSE +FETCH +FIRST +FLOAT +FOR +FOREIGN +FOUND +FROM +FULL +FUNCTION +GET +GET_CURRENT_CONNECTION +GLOBAL +GO +GOTO +GRANT +GROUP +HAVING +HOUR +IDENTITY +IMMEDIATE +IN +INDICATOR +INITIALLY +INNER +INOUT +INPUT +INSENSITIVE +INSERT +INT +INTEGER +INTERSECT +INTO +IS +ISOLATION +JOIN +KEY +LAST +LEFT +LIKE +LONGINT +LOWER +LTRIM +MATCH +MAX +MIN +MINUTE +NATIONAL +NATURAL +NCHAR +NEXT +NO +NOT +NULL +NULLIF +NUMERIC +NVARCHAR +OF +ON +ONLY +OPEN +OPTION +OR +ORDER +OUT +OUTER +OUTPUT +OVERLAPS +PAD +PARTIAL +PREPARE +PRESERVE +PRIMARY +PRIOR +PRIVILEGES +PROCEDURE +PUBLIC +READ +REAL +REFERENCES +RELATIVE +RESTRICT +REVOKE +RIGHT +ROLLBACK +ROWS +RTRIM +SCHEMA +SCROLL +SECOND +SELECT +SESSION_USER +SET +SMALLINT +SOME +SPACE +SQL +SQLCODE +SQLERROR +SQLSTATE +SUBSTR +SUBSTRING +SUM +SYSTEM_USER +TABLE +TEMPORARY +TIMEZONE_HOUR +TIMEZONE_MINUTE +TO +TRAILING +TRANSACTION +TRANSLATE +TRANSLATION +TRUE +UNION +UNIQUE +UNKNOWN +UPDATE +UPPER +USER +USING +VALUES +VARCHAR +VARYING +VIEW +WHENEVER +WHERE +WITH +WORK +WRITE +XML +XMLEXISTS +XMLPARSE +XMLSERIALIZE +YEAR diff --git a/querydsl-sql/src/main/resources/keywords/firebird b/querydsl-sql/src/main/resources/keywords/firebird new file mode 100644 index 0000000000..4ad75e2dfa --- /dev/null +++ b/querydsl-sql/src/main/resources/keywords/firebird @@ -0,0 +1,168 @@ +# source http://www.firebirdsql.org/refdocs/langrefupd25-reskeywords-full-reswords.html +ADD +ADMIN +ALL +ALTER +AND +ANY +AS +AT +AVG +BEGIN +BETWEEN +BIGINT +BIT_LENGTH +BLOB +BOTH +BY +CASE +CAST +CHAR +CHAR_LENGTH +CHARACTER +CHARACTER_LENGTH +CHECK +CLOSE +COLLATE +COLUMN +COMMIT +CONNECT +CONSTRAINT +COUNT +CREATE +CROSS +CURRENT +CURRENT_CONNECTION +CURRENT_DATE +CURRENT_ROLE +CURRENT_TIME +CURRENT_TIMESTAMP +CURRENT_TRANSACTION +CURRENT_USER +CURSOR +DATE +DAY +DEC +DECIMAL +DECLARE +DEFAULT +DELETE +DISCONNECT +DISTINCT +DOUBLE +DROP +ELSE +END +ESCAPE +EXECUTE +EXISTS +EXTERNAL +EXTRACT +FETCH +FILTER +FLOAT +FOR +FOREIGN +FROM +FULL +FUNCTION +GDSCODE +GLOBAL +GRANT +GROUP +HAVING +HOUR +IN +INDEX +INNER +INSENSITIVE +INSERT +INT +INTEGER +INTO +IS +JOIN +LEADING +LEFT +LIKE +LONG +LOWER +MAX +MAXIMUM_SEGMENT +MERGE +MIN +MINUTE +MONTH +NATIONAL +NATURAL +NCHAR +NO +NOT +NULL +NUMERIC +OCTET_LENGTH +OF +ON +ONLY +OPEN +OR +ORDER +OUTER +PARAMETER +PLAN +POSITION +POST_EVENT +PRECISION +PRIMARY +PROCEDURE +RDB$DB_KEY +REAL +RECORD_VERSION +RECREATE +RECURSIVE +REFERENCES +RELEASE +RETURNING_VALUES +RETURNS +REVOKE +RIGHT +ROLLBACK +ROW_COUNT +ROWS +SAVEPOINT +SECOND +SELECT +SENSITIVE +SET +SIMILAR +SMALLINT +SOME +SQLCODE +SQLSTATE +START +SUM +TABLE +THEN +TIME +TIMESTAMP +TO +TRAILING +TRIGGER +TRIM +UNION +UNIQUE +UPDATE +UPPER +USER +USING +VALUE +VALUES +VARCHAR +VARIABLE +VARYING +VIEW +WHEN +WHERE +WHILE +WITH +YEAR \ No newline at end of file diff --git a/querydsl-sql/src/main/resources/keywords/h2 b/querydsl-sql/src/main/resources/keywords/h2 new file mode 100644 index 0000000000..3b45635404 --- /dev/null +++ b/querydsl-sql/src/main/resources/keywords/h2 @@ -0,0 +1,81 @@ +# source http://www.h2database.com/html/advanced.html +ALL +AND +ARRAY +AS +BETWEEN +BOTH +CASE +CHECK +CONSTRAINT +CROSS +CURRENT_CATALOG +CURRENT_DATE +CURRENT_SCHEMA +CURRENT_TIME +CURRENT_TIMESTAMP +CURRENT_USER +DISTINCT +EXCEPT +EXISTS +FALSE +FETCH +FILTER +FOR +FOREIGN +FROM +FULL +GROUP +GROUPS +HAVING +IF +ILIKE +IN +INNER +INTERSECT +INTERSECTS +INTERVAL +IS +JOIN +LEADING +LEFT +LIKE +LIMIT +LOCALTIME +LOCALTIMESTAMP +MINUS +NATURAL +NOT +NULL +OFFSET +ON +OR +ORDER +OVER +PARTITION +PRIMARY +QUALIFY +RANGE +REGEXP +RIGHT +ROW +_ROWID_ +ROWNUM +ROWS +SELECT +SYSDATE +SYSTIME +SYSTIMESTAMP +TABLE +TODAY +TOP +TRAILING +TRUE +UNION +UNIQUE +UNKNOWN +USING +VALUES +WHERE +WINDOW +WITH \ No newline at end of file diff --git a/querydsl-sql/src/main/resources/keywords/hsqldb b/querydsl-sql/src/main/resources/keywords/hsqldb new file mode 100644 index 0000000000..2b606a7736 --- /dev/null +++ b/querydsl-sql/src/main/resources/keywords/hsqldb @@ -0,0 +1,322 @@ +# source http://hsqldb.org/doc/guide/lists-app.html +ABS +ALL +ALLOCATE +ALTER +AND +ANY +ARE +ARRAY +AS +ASENSITIVE +ASYMMETRIC +AT +ATOMIC +AUTHORIZATION +AVG +BEGIN +BETWEEN +BIGINT +BINARY +BLOB +BOOLEAN +BOTH +BY +CALL +CALLED +CARDINALITY +CASCADED +CASE +CAST +CEIL +CEILING +CHAR +CHARACTER +CHARACTER_LENGTH +CHAR_LENGTH +CHECK +CLOB +CLOSE +COALESCE +COLLATE +COLLECT +COLUMN +COMMIT +COMPARABLE +CONDITION +CONNECT +CONSTRAINT +CONVERT +CORR +CORRESPONDING +COUNT +COVAR_POP +COVAR_SAMP +CREATE +CROSS +CUBE +CUME_DIST +CURRENT +CURRENT_CATALOG +CURRENT_DATE +CURRENT_DEFAULT_TRANSFORM_GROUP +CURRENT_PATH +CURRENT_ROLE +CURRENT_SCHEMA +CURRENT_TIME +CURRENT_TIMESTAMP +CURRENT_TRANSFORM_GROUP_FOR_TYPE +CURRENT_USER +CURSOR +CYCLE +DATE +DAY +DEALLOCATE +DEC +DECIMAL +DECLARE +DEFAULT +DELETE +DENSE_RANK +DEREF +DESCRIBE +DETERMINISTIC +DISCONNECT +DISTINCT +DO +DOUBLE +DROP +DYNAMIC +EACH +ELEMENT +ELSE +ELSEIF +END +END_EXEC +ESCAPE +EVERY +EXCEPT +EXEC +EXECUTE +EXISTS +EXIT +EXP +EXTERNAL +EXTRACT +FALSE +FETCH +FILTER +FIRST_VALUE +FLOAT +FLOOR +FOR +FOREIGN +FREE +FROM +FULL +FUNCTION +FUSION +GET +GLOBAL +GRANT +GROUP +GROUPING +HANDLER +HAVING +HOLD +HOUR +IDENTITY +IN +INDICATOR +INNER +INOUT +INSENSITIVE +INSERT +INT +INTEGER +INTERSECT +INTERSECTION +INTERVAL +INTO +IS +ITERATE +JOIN +LAG +LANGUAGE +LARGE +LAST_VALUE +LATERAL +LEAD +LEADING +LEAVE +LEFT +LIKE +LIKE_REGEX +LN +LOCAL +LOCALTIME +LOCALTIMESTAMP +LOOP +LOWER +MATCH +MAX +MAX_CARDINALITY +MEMBER +MERGE +METHOD +MIN +MINUTE +MOD +MODIFIES +MODULE +MONTH +MULTISET +NATIONAL +NATURAL +NCHAR +NCLOB +NEW +NO +NONE +NORMALIZE +NOT +NTH_VALUE +NTILE +NULL +NULLIF +NUMERIC +OCCURRENCES_REGEX +OCTET_LENGTH +OF +OFFSET +OLD +ON +ONLY +OPEN +OR +ORDER +OUT +OUTER +OVER +OVERLAPS +OVERLAY +PARAMETER +PARTITION +PERCENTILE_CONT +PERCENTILE_DISC +PERCENT_RANK +POSITION +POSITION_REGEX +POWER +PRECISION +PREPARE +PRIMARY +PROCEDURE +RANGE +RANK +READS +REAL +RECURSIVE +REF +REFERENCES +REFERENCING +REGR_AVGX +REGR_AVGY +REGR_COUNT +REGR_INTERCEPT +REGR_R2 +REGR_SLOPE +REGR_SXX +REGR_SXY +REGR_SYY +RELEASE +REPEAT +RESIGNAL +RESULT +RETURN +RETURNS +REVOKE +RIGHT +ROLLBACK +ROLLUP +ROW +ROWS +ROW_NUMBER +SAVEPOINT +SCOPE +SCROLL +SEARCH +SECOND +SELECT +SENSITIVE +SESSION_USER +SET +SIGNAL +SIMILAR +SMALLINT +SOME +SPECIFIC +SPECIFICTYPE +SQL +SQLEXCEPTION +SQLSTATE +SQLWARNING +SQRT +STACKED +START +STATIC +STDDEV_POP +STDDEV_SAMP +SUBMULTISET +SUBSTRING +SUBSTRING_REGEX +SUM +SYMMETRIC +SYSTEM +SYSTEM_USER +TABLE +TABLESAMPLE +THEN +TIME +TIMESTAMP +TIMEZONE_HOUR +TIMEZONE_MINUTE +TO +TRAILING +TRANSLATE +TRANSLATE_REGEX +TRANSLATION +TREAT +TRIGGER +TRIM +TRIM_ARRAY +TRUE +TRUNCATE +UESCAPE +UNDO +UNION +UNIQUE +UNKNOWN +UNNEST +UNTIL +UPDATE +UPPER +USER +USING +VALUE +VALUES +VARBINARY +VARCHAR +VARYING +VAR_POP +VAR_SAMP +WHEN +WHENEVER +WHERE +WHILE +WIDTH_BUCKET +WINDOW +WITH +WITHIN +WITHOUT +YEAR diff --git a/querydsl-sql/src/main/resources/keywords/mysql b/querydsl-sql/src/main/resources/keywords/mysql new file mode 100644 index 0000000000..eba58b00ff --- /dev/null +++ b/querydsl-sql/src/main/resources/keywords/mysql @@ -0,0 +1,227 @@ +# source https://dev.mysql.com/doc/refman/5.5/en/keywords.html +ACCESSIBLE +ADD +ALL +ALTER +ANALYZE +AND +AS +ASC +ASENSITIVE +BEFORE +BETWEEN +BIGINT +BINARY +BLOB +BOTH +BY +CALL +CASCADE +CASE +CHANGE +CHAR +CHARACTER +CHECK +COLLATE +COLUMN +CONDITION +CONSTRAINT +CONTINUE +CONVERT +CREATE +CROSS +CURRENT_DATE +CURRENT_TIME +CURRENT_TIMESTAMP +CURRENT_USER +CURSOR +DATABASE +DATABASES +DAY_HOUR +DAY_MICROSECOND +DAY_MINUTE +DAY_SECOND +DEC +DECIMAL +DECLARE +DEFAULT +DELAYED +DELETE +DESC +DESCRIBE +DETERMINISTIC +DISTINCT +DISTINCTROW +DIV +DOUBLE +DROP +DUAL +EACH +ELSE +ELSEIF +ENCLOSED +ESCAPED +EXISTS +EXIT +EXPLAIN +FALSE +FETCH +FLOAT +FLOAT4 +FLOAT8 +FOR +FORCE +FOREIGN +FROM +FULLTEXT +GRANT +GROUP +HAVING +HIGH_PRIORITY +HOUR_MICROSECOND +HOUR_MINUTE +HOUR_SECOND +IF +IGNORE +IN +INDEX +INFILE +INNER +INOUT +INSENSITIVE +INSERT +INT +INT1 +INT2 +INT3 +INT4 +INT8 +INTEGER +INTERVAL +INTO +IS +ITERATE +JOIN +KEY +KEYS +KILL +LEADING +LEAVE +LEFT +LIKE +LIMIT +LINEAR +LINES +LOAD +LOCALTIME +LOCALTIMESTAMP +LOCK +LONG +LONGBLOB +LONGTEXT +LOOP +LOW_PRIORITY +MASTER_SSL_VERIFY_SERVER_CERT +MATCH +MAXVALUE +MEDIUMBLOB +MEDIUMINT +MEDIUMTEXT +MIDDLEINT +MINUTE_MICROSECOND +MINUTE_SECOND +MOD +MODIFIES +NATURAL +NOT +NO_WRITE_TO_BINLOG +NULL +NUMERIC +ON +OPTIMIZE +OPTION +OPTIONALLY +OR +ORDER +OUT +OUTER +OUTFILE +PRECISION +PRIMARY +PROCEDURE +PURGE +RANGE +READ +READS +READ_WRITE +REAL +REFERENCES +REGEXP +RELEASE +RENAME +REPEAT +REPLACE +REQUIRE +RESIGNAL +RESTRICT +RETURN +REVOKE +RIGHT +RLIKE +SCHEMA +SCHEMAS +SECOND_MICROSECOND +SELECT +SENSITIVE +SEPARATOR +SET +SHOW +SIGNAL +SMALLINT +SPATIAL +SPECIFIC +SQL +SQLEXCEPTION +SQLSTATE +SQLWARNING +SQL_BIG_RESULT +SQL_CALC_FOUND_ROWS +SQL_SMALL_RESULT +SSL +STARTING +STRAIGHT_JOIN +TABLE +TERMINATED +THEN +TINYBLOB +TINYINT +TINYTEXT +TO +TRAILING +TRIGGER +TRUE +UNDO +UNION +UNIQUE +UNLOCK +UNSIGNED +UPDATE +USAGE +USE +USING +UTC_DATE +UTC_TIME +UTC_TIMESTAMP +VALUES +VARBINARY +VARCHAR +VARCHARACTER +VARYING +WHEN +WHERE +WHILE +WITH +WRITE +XOR +YEAR_MONTH +ZEROFILL diff --git a/querydsl-sql/src/main/resources/keywords/oracle b/querydsl-sql/src/main/resources/keywords/oracle new file mode 100644 index 0000000000..44c0209d83 --- /dev/null +++ b/querydsl-sql/src/main/resources/keywords/oracle @@ -0,0 +1,110 @@ +# source https://docs.oracle.com/cd/B19306_01/server.102/b14200/ap_keywd.htm +ACCESS +ADD +ALL +ALTER +AND +ANY +AS +ASC +AUDIT +BETWEEN +BY +CHAR +CHECK +CLUSTER +COLUMN +COMMENT +COMPRESS +CONNECT +CREATE +CURRENT +DATE +DECIMAL +DEFAULT +DELETE +DESC +DISTINCT +DROP +ELSE +EXCLUSIVE +EXISTS +FILE +FLOAT +FOR +FROM +GRANT +GROUP +HAVING +IDENTIFIED +IMMEDIATE +IN +INCREMENT +INDEX +INITIAL +INSERT +INTEGER +INTERSECT +INTO +IS +LEVEL +LIKE +LOCK +LONG +MAXEXTENTS +MINUS +MLSLABEL +MODE +MODIFY +NOAUDIT +NOCOMPRESS +NOT +NOWAIT +NULL +NUMBER +OF +OFFLINE +ON +ONLINE +OPTION +OR +ORDER +PCTFREE +PRIOR +PRIVILEGES +PUBLIC +RAW +RENAME +RESOURCE +REVOKE +ROW +ROWID +ROWNUM +ROWS +SELECT +SESSION +SET +SHARE +SIZE +SMALLINT +START +SUCCESSFUL +SYNONYM +SYSDATE +TABLE +THEN +TO +TRIGGER +UID +UNION +UNIQUE +UPDATE +USER +VALIDATE +VALUES +VARCHAR +VARCHAR2 +VIEW +WHENEVER +WHERE +WITH diff --git a/querydsl-sql/src/main/resources/keywords/postgresql b/querydsl-sql/src/main/resources/keywords/postgresql new file mode 100644 index 0000000000..dcb857d030 --- /dev/null +++ b/querydsl-sql/src/main/resources/keywords/postgresql @@ -0,0 +1,101 @@ +# source http://www.postgresql.org/docs/9.4/static/sql-keywords-appendix.html +ALL +ANALYSE +ANALYZE +AND +ANY +ARRAY +AS +ASC +ASYMMETRIC +AUTHORIZATION +BINARY +BOTH +CASE +CAST +CHECK +COLLATE +COLLATION +COLUMN +CONCURRENTLY +CONSTRAINT +CREATE +CROSS +CURRENT_CATALOG +CURRENT_DATE +CURRENT_ROLE +CURRENT_SCHEMA +CURRENT_TIME +CURRENT_TIMESTAMP +CURRENT_USER +DEFAULT +DEFERRABLE +DESC +DISTINCT +DO +ELSE +END +EXCEPT +FALSE +FETCH +FOR +FOREIGN +FREEZE +FROM +FULL +GRANT +GROUP +HAVING +ILIKE +IN +INITIALLY +INNER +INTERSECT +INTO +IS +ISNULL +JOIN +LATERAL +LEADING +LEFT +LIKE +LIMIT +LOCALTIME +LOCALTIMESTAMP +NATURAL +NOT +NOTNULL +NULL +OFFSET +ON +ONLY +OR +ORDER +OUTER +OVER +OVERLAPS +PLACING +PRIMARY +REFERENCES +RETURNING +RIGHT +SELECT +SESSION_USER +SIMILAR +SOME +SYMMETRIC +TABLE +THEN +TO +TRAILING +TRUE +UNION +UNIQUE +USER +USING +VARIADIC +VERBOSE +WHEN +WHERE +WINDOW +WITH diff --git a/querydsl-sql/src/main/resources/keywords/sqlite b/querydsl-sql/src/main/resources/keywords/sqlite new file mode 100644 index 0000000000..cf61d95af4 --- /dev/null +++ b/querydsl-sql/src/main/resources/keywords/sqlite @@ -0,0 +1,125 @@ +# source https://sqlite.org/lang_keywords.html +ABORT +ACTION +ADD +AFTER +ALL +ALTER +ANALYZE +AND +AS +ASC +ATTACH +AUTOINCREMENT +BEFORE +BEGIN +BETWEEN +BY +CASCADE +CASE +CAST +CHECK +COLLATE +COLUMN +COMMIT +CONFLICT +CONSTRAINT +CREATE +CROSS +CURRENT_DATE +CURRENT_TIME +CURRENT_TIMESTAMP +DATABASE +DEFAULT +DEFERRABLE +DEFERRED +DELETE +DESC +DETACH +DISTINCT +DROP +EACH +ELSE +END +ESCAPE +EXCEPT +EXCLUSIVE +EXISTS +EXPLAIN +FAIL +FOR +FOREIGN +FROM +FULL +GLOB +GROUP +HAVING +IF +IGNORE +IMMEDIATE +IN +INDEX +INDEXED +INITIALLY +INNER +INSERT +INSTEAD +INTERSECT +INTO +IS +ISNULL +JOIN +KEY +LEFT +LIKE +LIMIT +MATCH +NATURAL +NO +NOT +NOTNULL +NULL +OF +OFFSET +ON +OR +ORDER +OUTER +PLAN +PRAGMA +PRIMARY +QUERY +RAISE +RECURSIVE +REFERENCES +REGEXP +REINDEX +RELEASE +RENAME +REPLACE +RESTRICT +RIGHT +ROLLBACK +ROW +SAVEPOINT +SELECT +SET +TABLE +TEMP +TEMPORARY +THEN +TO +TRANSACTION +TRIGGER +UNION +UNIQUE +UPDATE +USING +VACUUM +VALUES +VIEW +VIRTUAL +WHEN +WHERE +WITH +WITHOUT diff --git a/querydsl-sql/src/main/resources/keywords/sqlserver2005 b/querydsl-sql/src/main/resources/keywords/sqlserver2005 new file mode 100644 index 0000000000..182a92266e --- /dev/null +++ b/querydsl-sql/src/main/resources/keywords/sqlserver2005 @@ -0,0 +1,180 @@ +# source https://msdn.microsoft.com/en-us/library/ms189822(v=sql.90).aspx +ADD +ALL +ALTER +AND +ANY +AS +ASC +AUTHORIZATION +BACKUP +BEGIN +BETWEEN +BREAK +BROWSE +BULK +BY +CASCADE +CASE +CHECK +CHECKPOINT +CLOSE +CLUSTERED +COALESCE +COLLATE +COLUMN +COMMIT +COMPUTE +CONSTRAINT +CONTAINS +CONTAINSTABLE +CONTINUE +CONVERT +CREATE +CROSS +CURRENT +CURRENT_DATE +CURRENT_TIME +CURRENT_TIMESTAMP +CURRENT_USER +CURSOR +DATABASE +DBCC +DEALLOCATE +DECLARE +DEFAULT +DELETE +DENY +DESC +DISK +DISTINCT +DISTRIBUTED +DOUBLE +DROP +DUMP +ELSE +END +ERRLVL +ESCAPE +EXCEPT +EXEC +EXECUTE +EXISTS +EXIT +EXTERNAL +FETCH +FILE +FILLFACTOR +FOR +FOREIGN +FREETEXT +FREETEXTTABLE +FROM +FULL +FUNCTION +GOTO +GRANT +GROUP +HAVING +HOLDLOCK +IDENTITY +IDENTITYCOL +IDENTITY_INSERT +IF +IN +INDEX +INNER +INSERT +INTERSECT +INTO +IS +JOIN +KEY +KILL +LEFT +LIKE +LINENO +LOAD +NATIONAL +NOCHECK +NONCLUSTERED +NOT +NULL +NULLIF +OF +OFF +OFFSETS +ON +OPEN +OPENDATASOURCE +OPENQUERY +OPENROWSET +OPENXML +OPTION +OR +ORDER +OUTER +OVER +PERCENT +PIVOT +PLAN +PRECISION +PRIMARY +PRINT +PROC +PROCEDURE +PUBLIC +RAISERROR +READ +READTEXT +RECONFIGURE +REFERENCES +REPLICATION +RESTORE +RESTRICT +RETURN +REVERT +REVOKE +RIGHT +ROLLBACK +ROWCOUNT +ROWGUIDCOL +RULE +SAVE +SCHEMA +SECURITYAUDIT +SELECT +SESSION_USER +SET +SETUSER +SHUTDOWN +SOME +STATISTICS +SYSTEM_USER +TABLE +TABLESAMPLE +TEXTSIZE +THEN +TO +TOP +TRAN +TRANSACTION +TRIGGER +TRUNCATE +TSEQUAL +UNION +UNIQUE +UNPIVOT +UPDATE +UPDATETEXT +USE +USER +VALUES +VARYING +VIEW +WAITFOR +WHEN +WHERE +WHILE +WITH +WRITETEXT diff --git a/querydsl-sql/src/main/resources/keywords/sqlserver2008 b/querydsl-sql/src/main/resources/keywords/sqlserver2008 new file mode 100644 index 0000000000..f85b5930b7 --- /dev/null +++ b/querydsl-sql/src/main/resources/keywords/sqlserver2008 @@ -0,0 +1,181 @@ +# source https://msdn.microsoft.com/en-us/library/ms189822(v=sql.100).aspx +ADD +ALL +ALTER +AND +ANY +AS +ASC +AUTHORIZATION +BACKUP +BEGIN +BETWEEN +BREAK +BROWSE +BULK +BY +CASCADE +CASE +CHECK +CHECKPOINT +CLOSE +CLUSTERED +COALESCE +COLLATE +COLUMN +COMMIT +COMPUTE +CONSTRAINT +CONTAINS +CONTAINSTABLE +CONTINUE +CONVERT +CREATE +CROSS +CURRENT +CURRENT_DATE +CURRENT_TIME +CURRENT_TIMESTAMP +CURRENT_USER +CURSOR +DATABASE +DBCC +DEALLOCATE +DECLARE +DEFAULT +DELETE +DENY +DESC +DISK +DISTINCT +DISTRIBUTED +DOUBLE +DROP +DUMP +ELSE +END +ERRLVL +ESCAPE +EXCEPT +EXEC +EXECUTE +EXISTS +EXIT +EXTERNAL +FETCH +FILE +FILLFACTOR +FOR +FOREIGN +FREETEXT +FREETEXTTABLE +FROM +FULL +FUNCTION +GOTO +GRANT +GROUP +HAVING +HOLDLOCK +IDENTITY +IDENTITYCOL +IDENTITY_INSERT +IF +IN +INDEX +INNER +INSERT +INTERSECT +INTO +IS +JOIN +KEY +KILL +LEFT +LIKE +LINENO +LOAD +MERGE +NATIONAL +NOCHECK +NONCLUSTERED +NOT +NULL +NULLIF +OF +OFF +OFFSETS +ON +OPEN +OPENDATASOURCE +OPENQUERY +OPENROWSET +OPENXML +OPTION +OR +ORDER +OUTER +OVER +PERCENT +PIVOT +PLAN +PRECISION +PRIMARY +PRINT +PROC +PROCEDURE +PUBLIC +RAISERROR +READ +READTEXT +RECONFIGURE +REFERENCES +REPLICATION +RESTORE +RESTRICT +RETURN +REVERT +REVOKE +RIGHT +ROLLBACK +ROWCOUNT +ROWGUIDCOL +RULE +SAVE +SCHEMA +SECURITYAUDIT +SELECT +SESSION_USER +SET +SETUSER +SHUTDOWN +SOME +STATISTICS +SYSTEM_USER +TABLE +TABLESAMPLE +TEXTSIZE +THEN +TO +TOP +TRAN +TRANSACTION +TRIGGER +TRUNCATE +TSEQUAL +UNION +UNIQUE +UNPIVOT +UPDATE +UPDATETEXT +USE +USER +VALUES +VARYING +VIEW +WAITFOR +WHEN +WHERE +WHILE +WITH +WRITETEXT diff --git a/querydsl-sql/src/main/resources/keywords/sqlserver2012 b/querydsl-sql/src/main/resources/keywords/sqlserver2012 new file mode 100644 index 0000000000..9e35e1dcac --- /dev/null +++ b/querydsl-sql/src/main/resources/keywords/sqlserver2012 @@ -0,0 +1,186 @@ +# source https://msdn.microsoft.com/en-us/library/ms189822(v=sql.110).aspx +ADD +ALL +ALTER +AND +ANY +AS +ASC +AUTHORIZATION +BACKUP +BEGIN +BETWEEN +BREAK +BROWSE +BULK +BY +CASCADE +CASE +CHECK +CHECKPOINT +CLOSE +CLUSTERED +COALESCE +COLLATE +COLUMN +COMMIT +COMPUTE +CONSTRAINT +CONTAINS +CONTAINSTABLE +CONTINUE +CONVERT +CREATE +CROSS +CURRENT +CURRENT_DATE +CURRENT_TIME +CURRENT_TIMESTAMP +CURRENT_USER +CURSOR +DATABASE +DBCC +DEALLOCATE +DECLARE +DEFAULT +DELETE +DENY +DESC +DISK +DISTINCT +DISTRIBUTED +DOUBLE +DROP +DUMP +ELSE +END +ERRLVL +ESCAPE +EXCEPT +EXEC +EXECUTE +EXISTS +EXIT +EXTERNAL +FETCH +FILE +FILLFACTOR +FOR +FOREIGN +FREETEXT +FREETEXTTABLE +FROM +FULL +FUNCTION +GOTO +GRANT +GROUP +HAVING +HOLDLOCK +IDENTITY +IDENTITYCOL +IDENTITY_INSERT +IF +IN +INDEX +INNER +INSERT +INTERSECT +INTO +IS +JOIN +KEY +KILL +LEFT +LIKE +LINENO +LOAD +MERGE +NATIONAL +NOCHECK +NONCLUSTERED +NOT +NULL +NULLIF +OF +OFF +OFFSETS +ON +OPEN +OPENDATASOURCE +OPENQUERY +OPENROWSET +OPENXML +OPTION +OR +ORDER +OUTER +OVER +PERCENT +PIVOT +PLAN +PRECISION +PRIMARY +PRINT +PROC +PROCEDURE +PUBLIC +RAISERROR +READ +READTEXT +RECONFIGURE +REFERENCES +REPLICATION +RESTORE +RESTRICT +RETURN +REVERT +REVOKE +RIGHT +ROLLBACK +ROWCOUNT +ROWGUIDCOL +RULE +SAVE +SCHEMA +SECURITYAUDIT +SELECT +SEMANTICKEYPHRASETABLE +SEMANTICSIMILARITYDETAILSTABLE +SEMANTICSIMILARITYTABLE +SESSION_USER +SET +SETUSER +SHUTDOWN +SOME +STATISTICS +SYSTEM_USER +TABLE +TABLESAMPLE +TEXTSIZE +THEN +TO +TOP +TRAN +TRANSACTION +TRIGGER +TRUNCATE +TRY_CONVERT +TSEQUAL +UNION +UNIQUE +UNPIVOT +UPDATE +UPDATETEXT +USE +USER +VALUES +VARYING +VIEW +WAITFOR +WHEN +WHERE +WHILE +WITH +WITHIN GROUP +WRITETEXT diff --git a/querydsl-sql/src/test/java/com/example/Price.java b/querydsl-sql/src/test/java/com/example/Price.java index af5b9f9a4b..010a816960 100644 --- a/querydsl-sql/src/test/java/com/example/Price.java +++ b/querydsl-sql/src/test/java/com/example/Price.java @@ -3,7 +3,7 @@ public class Price { private float price; - + private String currency; public float getPrice() { @@ -21,7 +21,7 @@ public String getCurrency() { public void setCurrency(String currency) { this.currency = currency; } - - + + } diff --git a/querydsl-sql/src/test/java/com/mysema/query/AbstractBaseTest.java b/querydsl-sql/src/test/java/com/mysema/query/AbstractBaseTest.java deleted file mode 100644 index a2f75f96a3..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/AbstractBaseTest.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query; - -import java.util.List; -import javax.annotation.Nullable; -import java.sql.Connection; -import java.util.List; - -import com.mysema.query.sql.*; -import com.mysema.query.sql.dml.SQLDeleteClause; -import com.mysema.query.sql.dml.SQLInsertClause; -import com.mysema.query.sql.dml.SQLMergeClause; -import com.mysema.query.sql.dml.SQLUpdateClause; -import com.mysema.query.sql.mysql.MySQLReplaceClause; -import com.mysema.query.sql.teradata.TeradataQuery; -import org.junit.Rule; -import org.junit.rules.MethodRule; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import static org.junit.Assert.assertEquals; - -public abstract class AbstractBaseTest { - - protected static final Logger logger = LoggerFactory.getLogger(AbstractBaseTest.class); - - protected final class TestQuery extends AbstractSQLQuery implements SQLCommonQuery { - - private TestQuery(Connection conn, Configuration configuration) { - super(conn, configuration); - } - - private TestQuery(Connection conn, Configuration configuration, QueryMetadata metadata) { - super(conn, configuration, metadata); - } - - @Override - protected SQLSerializer serialize(boolean countRow) { - SQLSerializer serializer = super.serialize(countRow); - String rv = serializer.toString(); - if (expectedQuery != null) { - assertEquals(expectedQuery, rv.replace('\n', ' ')); - expectedQuery = null; - } - logger.debug(rv); - return serializer; - } - - public TestQuery clone(Connection conn) { - TestQuery q = new TestQuery(conn, getConfiguration(), getMetadata().clone()); - q.union = union; - q.unionAll = unionAll; - return q; - } - } - - protected Connection connection = Connections.getConnection(); - - protected SQLTemplates templates = Connections.getTemplates(); - - protected Target target = Connections.getTarget(); - - protected Configuration configuration = new Configuration(templates); - - @Nullable - protected String expectedQuery; - - @Rule - public static MethodRule skipForQuotedRule = new SkipForQuotedRule(); - - @Rule - public static MethodRule targetRule = new TargetRule(); - - protected void add(List list, T arg, Target... exclusions) { - if (exclusions.length > 0) { - for (Target t : exclusions) { - if (t.equals(target)) { - return; - } - } - } - list.add(arg); - } - - protected SQLUpdateClause update(RelationalPath e) { - return new SQLUpdateClause(connection, configuration, e); - } - - protected SQLInsertClause insert(RelationalPath e) { - return new SQLInsertClause(connection, configuration, e); - } - - protected SQLInsertClause insert(RelationalPath e, AbstractSQLSubQuery sq) { - return new SQLInsertClause(connection, configuration, e, sq); - } - - protected SQLDeleteClause delete(RelationalPath e) { - return new SQLDeleteClause(connection, configuration, e); - } - - protected SQLMergeClause merge(RelationalPath e) { - return new SQLMergeClause(connection, configuration, e); - } - - protected ExtendedSQLQuery extQuery() { - return new ExtendedSQLQuery(connection, configuration); - } - - protected SQLInsertClause mysqlReplace(RelationalPath path) { - return new MySQLReplaceClause(connection, configuration, path); - } - - protected TestQuery query() { - return new TestQuery(connection, configuration); - } - - protected TeradataQuery teradataQuery() { - return new TeradataQuery(connection, configuration); - } - - protected TestQuery testQuery() { - return new TestQuery(connection, configuration, - new DefaultQueryMetadata().noValidate()); - } - - protected SQLSubQuery sq() { - return new SQLSubQuery(); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/BeanPopulationBase.java b/querydsl-sql/src/test/java/com/mysema/query/BeanPopulationBase.java deleted file mode 100644 index f5ed491b8c..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/BeanPopulationBase.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query; - -import static com.mysema.query.Target.CUBRID; -import static com.mysema.query.Target.DERBY; -import static com.mysema.query.Target.ORACLE; -import static com.mysema.query.Target.POSTGRES; -import static com.mysema.query.Target.SQLITE; -import static com.mysema.query.Target.SQLSERVER; -import static com.mysema.query.Target.TERADATA; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -import org.junit.After; -import org.junit.Test; - -import com.mysema.query.sql.dml.BeanMapper; -import com.mysema.query.sql.domain.Employee; -import com.mysema.query.sql.domain.QEmployee; -import com.mysema.testutil.ExcludeIn; - -@ExcludeIn({CUBRID, DERBY, ORACLE, SQLSERVER, POSTGRES, SQLITE, TERADATA}) -public class BeanPopulationBase extends AbstractBaseTest { - - private final QEmployee e = new QEmployee("e"); - - @After - public void tearDown() { - delete(e).where(e.firstname.eq("John")).execute(); - } - - @Test - public void CustomProjection() { - // Insert - Employee employee = new Employee(); - employee.setFirstname("John"); - Integer id = insert(e).populate(employee).executeWithKey(e.id); - employee.setId(id); - - // Update - employee.setLastname("S"); - assertEquals(1l, update(e).populate(employee).where(e.id.eq(employee.getId())).execute()); - - // Query - Employee smith = extQuery().from(e).where(e.lastname.eq("S")) - .limit(1) - .uniqueResult(Employee.class, e.lastname, e.firstname); - assertEquals("John", smith.getFirstname()); - assertEquals("S", smith.getLastname()); - - // Query with alias - smith = extQuery().from(e).where(e.lastname.eq("S")) - .limit(1) - .uniqueResult(Employee.class, e.lastname.as("lastname"), e.firstname.as("firstname")); - assertEquals("John", smith.getFirstname()); - assertEquals("S", smith.getLastname()); - - // Query into custom type - OtherEmployee other = extQuery().from(e).where(e.lastname.eq("S")) - .limit(1) - .uniqueResult(OtherEmployee.class, e.lastname, e.firstname); - assertEquals("John", other.getFirstname()); - assertEquals("S", other.getLastname()); - - // Delete (no changes needed) - assertEquals(1l, delete(e).where(e.id.eq(employee.getId())).execute()); - } - - @Test - public void Insert_Update_Query_and_Delete() { - // Insert - Employee employee = new Employee(); - employee.setFirstname("John"); - Integer id = insert(e).populate(employee).executeWithKey(e.id); - assertNotNull(id); - employee.setId(id); - - // Update - employee.setLastname("S"); - assertEquals(1l, update(e).populate(employee).where(e.id.eq(employee.getId())).execute()); - - // Query - Employee smith = query().from(e).where(e.lastname.eq("S")).limit(1).uniqueResult(e); - assertEquals("John", smith.getFirstname()); - - // Delete (no changes needed) - assertEquals(1l, delete(e).where(e.id.eq(employee.getId())).execute()); - } - - @Test - public void Populate_With_BeanMapper() { - Employee employee = new Employee(); - employee.setFirstname("John"); - insert(e).populate(employee, new BeanMapper()).execute(); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/ColumnMetadataTest.java b/querydsl-sql/src/test/java/com/mysema/query/ColumnMetadataTest.java deleted file mode 100644 index 49ba29eaac..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/ColumnMetadataTest.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.mysema.query; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -import java.sql.Types; - -import org.junit.Test; - -import com.mysema.query.sql.ColumnMetadata; -import com.mysema.query.sql.domain.QEmployee; - -public class ColumnMetadataTest { - - @Test - public void DefaultColumn() { - ColumnMetadata column = ColumnMetadata.named("Person"); - assertEquals("Person", column.getName()); - assertFalse(column.hasJdbcType()); - assertFalse(column.hasSize()); - assertTrue(column.isNullable()); - } - - @Test - public void FullyConfigured() { - ColumnMetadata column = ColumnMetadata.named("Person").withSize(10) - .notNull().ofType(Types.BIGINT); - assertEquals("Person", column.getName()); - assertTrue(column.hasJdbcType()); - assertEquals(Types.BIGINT, column.getJdbcType()); - assertTrue(column.hasSize()); - assertEquals(10, column.getSize()); - assertFalse(column.isNullable()); - } - - @Test - public void ExtractFromRelationalPath() { - ColumnMetadata column = ColumnMetadata.getColumnMetadata(QEmployee.employee.id); - assertEquals("ID", column.getName()); - } - - @Test - public void FallBackToDefaultWhenMissing() { - ColumnMetadata column = ColumnMetadata.getColumnMetadata(QEmployee.employee.salary); - assertEquals("SALARY", column.getName()); - } -} \ No newline at end of file diff --git a/querydsl-sql/src/test/java/com/mysema/query/Connections.java b/querydsl-sql/src/test/java/com/mysema/query/Connections.java deleted file mode 100644 index 19b0fc3162..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/Connections.java +++ /dev/null @@ -1,903 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query; - -import java.sql.*; -import java.util.Map; -import java.util.Properties; - -import com.google.common.collect.Maps; -import com.mysema.query.ddl.CreateTableClause; -import com.mysema.query.ddl.DropTableClause; -import com.mysema.query.sql.*; -import org.hsqldb.types.Types; - -/** - * @author tiwe - * - */ -public final class Connections { - - public static final int TEST_ROW_COUNT = 100; - - private static ThreadLocal connHolder = new ThreadLocal(); - - private static ThreadLocal targetHolder = new ThreadLocal(); - - private static ThreadLocal templatesHolder = new ThreadLocal(); - - // datetest - private static final String CREATE_TABLE_DATETEST = "create table DATE_TEST(DATE_TEST date)"; - - // survey - private static final String CREATE_TABLE_SURVEY = - "create table SURVEY(ID int auto_increment, NAME varchar(30), NAME2 varchar(30))"; - - // test - private static final String CREATE_TABLE_TEST = "create table TEST(NAME varchar(255))"; - - // timetest - private static final String CREATE_TABLE_TIMETEST = "create table TIME_TEST(TIME_TEST time)"; - - // employee - private static final String INSERT_INTO_EMPLOYEE = "insert into EMPLOYEE " + - "(ID, FIRSTNAME, LASTNAME, SALARY, DATEFIELD, TIMEFIELD, SUPERIOR_ID) " + - "values (?,?,?,?,?,?,?)"; - - private static final String INSERT_INTO_TEST_VALUES = "insert into TEST values(?)"; - - private static ThreadLocal stmtHolder = new ThreadLocal(); - - private static boolean derbyInited, sqlServerInited, h2Inited, hsqlInited, mysqlInited, cubridInited, oracleInited, postgresInited, sqliteInited, teradataInited; - - public static void close() throws SQLException{ - if (stmtHolder.get() != null) { - stmtHolder.get().close(); - } - if (connHolder.get() != null) { - connHolder.get().close(); - } - } - - public static Connection getConnection() { - return connHolder.get(); - } - - public static Target getTarget() { - return targetHolder.get(); - } - - public static SQLTemplates getTemplates() { - return templatesHolder.get(); - } - - public static void setTemplates(SQLTemplates templates) { - templatesHolder.set(templates); - } - - private static Connection getDerby() throws SQLException, ClassNotFoundException { - Class.forName("org.apache.derby.jdbc.EmbeddedDriver"); - String url = "jdbc:derby:target/demoDB;create=true"; - return DriverManager.getConnection(url, "", ""); - } - - private static Connection getHSQL() throws SQLException, ClassNotFoundException { - Class.forName("org.hsqldb.jdbcDriver"); - String url = "jdbc:hsqldb:target/tutorial"; - return DriverManager.getConnection(url, "sa", ""); - } - - private static Connection getH2() throws SQLException, ClassNotFoundException{ - Class.forName("org.h2.Driver"); - String url = "jdbc:h2:~/dbs/h2-test;LOCK_MODE=0"; - return DriverManager.getConnection(url, "sa", ""); - } - - private static Connection getMySQL() throws SQLException, ClassNotFoundException { - Class.forName("com.mysql.jdbc.Driver"); - String url = "jdbc:mysql://localhost:3306/querydsl"; // ?useLegacyDatetimeCode=false - return DriverManager.getConnection(url, "querydsl", "querydsl"); - } - - private static Connection getOracle() throws SQLException, ClassNotFoundException{ - Class.forName("oracle.jdbc.driver.OracleDriver"); - String url = "jdbc:oracle:thin:@localhost:1521:xe"; - return DriverManager.getConnection(url, "querydsl", "querydsl"); - } - - private static Connection getPostgres() throws ClassNotFoundException, SQLException{ - Class.forName("org.postgresql.Driver"); - String url = "jdbc:postgresql://localhost:5432/querydsl"; - return DriverManager.getConnection(url, "querydsl", "querydsl"); - } - - private static Connection getSQLServer() throws ClassNotFoundException, SQLException{ - Class.forName("net.sourceforge.jtds.jdbc.Driver"); - Properties props = new Properties(); - props.put("user", "querydsl"); - props.put("password", "querydsl"); - props.put("sendTimeAsDatetime", "false"); - String url = "jdbc:jtds:sqlserver://localhost:1433/querydsl"; -// return DriverManager.getConnection(url, "querydsl", "querydsl"); - return DriverManager.getConnection(url, props); - } - - private static Connection getCubrid() throws ClassNotFoundException, SQLException { - Class.forName("cubrid.jdbc.driver.CUBRIDDriver"); - String url = "jdbc:cubrid:localhost:30000:demodb:public::"; - return DriverManager.getConnection(url); - } - - private static Connection getSQLite() throws SQLException, ClassNotFoundException { - //System.setProperty("sqlite.purejava", "true"); - Class.forName("org.sqlite.JDBC"); - return DriverManager.getConnection("jdbc:sqlite:target/sample.db"); - } - - private static Connection getTeradata() throws SQLException, ClassNotFoundException { - Class.forName("com.teradata.jdbc.TeraDriver"); - return DriverManager.getConnection("jdbc:teradata://teradata/dbc", "querydsl", "querydsl"); - } - - private static CreateTableClause createTable(SQLTemplates templates, String table) { - return new CreateTableClause(connHolder.get(), templates, table); - } - - public static void dropTable(SQLTemplates templates, String table) throws SQLException{ - new DropTableClause(connHolder.get(), templates, table).execute(); - } - - public static void dropType(Statement stmt, String type) throws SQLException { - try { - stmt.execute("drop type " + type); - } catch (SQLException e) { - if (!e.getMessage().contains("does not exist")) { - throw e; - } - } - } - - public static Statement getStatement() { - return stmtHolder.get(); - } - - private static void createEmployeeTable(SQLTemplates templates) { - createTable(templates, "EMPLOYEE") - .column("ID", Integer.class).notNull() - .column("FIRSTNAME", String.class).size(50) - .column("LASTNAME", String.class).size(50) - .column("SALARY", Double.class) - .column("DATEFIELD", Date.class) - .column("TIMEFIELD", Time.class) - .column("SUPERIOR_ID", Integer.class) - .primaryKey("PK_EMPLOYEE", "ID") - .foreignKey("FK_SUPERIOR","SUPERIOR_ID").references("EMPLOYEE","ID") - .execute(); - } - - public static Map getSpatialData() { - Map m = Maps.newHashMap(); - // point - m.put(1, "POINT (2 2)"); - m.put(2, "POINT (8 7)"); - m.put(3, "POINT (1 9)"); - m.put(4, "POINT (9 2)"); - m.put(5, "POINT (4 4)"); - // linestring - m.put(6, "LINESTRING (30 10, 10 30)"); - m.put(7, "LINESTRING (30 10, 10 30, 40 40)"); - // polygon - m.put(8, "POLYGON ((30 10, 40 40, 20 40, 10 20, 30 10), (20 30, 35 35, 30 20, 20 30))"); - m.put(9, "POLYGON ((35 10, 45 45, 15 40, 10 20, 35 10), (20 30, 35 35, 30 20, 20 30))"); - // multipoint - m.put(11, "MULTIPOINT (10 40, 40 30)"); - m.put(11, "MULTIPOINT (10 40, 40 30, 20 20, 30 10)"); - // multilinestring - m.put(12, "MULTILINESTRING ((10 10, 20 20, 10 40), (40 40, 30 30, 40 20, 30 10))"); - m.put(13, "MULTILINESTRING ((10 10, 20 20, 10 40))"); - // multipolygon - m.put(14, "MULTIPOLYGON (((30 20, 45 40, 10 40, 30 20)), ((15 5, 40 10, 10 20, 5 10, 15 5)))"); - m.put(15, "MULTIPOLYGON (((40 40, 20 45, 45 30, 40 40)), " + - "((20 35, 10 30, 10 10, 30 5, 45 20, 20 35), " + - "(30 20, 20 15, 20 25, 30 20)))"); - - // XXX POLYHEDRALSURFACE not supported - - /* GEOMETRYCOLLECTION(POINT(4 6),LINESTRING(4 6,7 10)) - CIRCULARSTRING(1 5, 6 2, 7 3) - COMPOUNDCURVE(CIRCULARSTRING(0 0,1 1,1 0),(1 0,0 1)) - CURVEPOLYGON(CIRCULARSTRING(-2 0,-1 -1,0 0,1 -1,2 0,0 2,-2 0),(-1 0,0 0.5,1 0,0 1,-1 0)) - MULTICURVE((5 5,3 5,3 3,0 3),CIRCULARSTRING(0 0,2 1,2 2)) - TRIANGLE((0 0 0,0 1 0,1 1 0,0 0 0)) - TIN (((0 0 0, 0 0 1, 0 1 0, 0 0 0)), ((0 0 0, 0 1 0, 1 1 0, 0 0 0))) - */ - return m; - } - - public static void initCubrid() throws SQLException, ClassNotFoundException{ - targetHolder.set(Target.CUBRID); - //SQLTemplates templates = new MySQLTemplates(); - Connection c = getCubrid(); - connHolder.set(c); - Statement stmt = c.createStatement(); - stmtHolder.set(stmt); - - if (cubridInited) { - return; - } - - // survey - stmt.execute("drop table if exists SURVEY"); - stmt.execute("create table SURVEY(ID int auto_increment(16693,2), " + - "NAME varchar(30)," + - "NAME2 varchar(30)," + - "constraint suryey_pk primary key(ID))"); - stmt.execute("insert into SURVEY values (1,'Hello World','Hello');"); - - // test - stmt.execute("drop table if exists \"TEST\""); - stmt.execute("create table \"TEST\"(NAME varchar(255))"); - PreparedStatement pstmt = c.prepareStatement("insert into \"TEST\" values(?)"); - try{ - for (int i = 0; i < TEST_ROW_COUNT; i++) { - pstmt.setString(1, "name" + i); - pstmt.addBatch(); - } - pstmt.executeBatch(); - }finally{ - pstmt.close(); - } - - // employee - stmt.execute("drop table if exists EMPLOYEE"); - //createEmployeeTable(templates); - stmt.execute("create table EMPLOYEE ( " + - "ID INT PRIMARY KEY AUTO_INCREMENT, " + - "FIRSTNAME VARCHAR(50), " + - "LASTNAME VARCHAR(50), " + - "SALARY DECIMAL, " + - "DATEFIELD DATE, " + - "TIMEFIELD TIME, " + - "SUPERIOR_ID INT, " + - "CONSTRAINT FK_SUPERIOR FOREIGN KEY(SUPERIOR_ID) REFERENCES EMPLOYEE(ID) " + - ")"); - - addEmployees(INSERT_INTO_EMPLOYEE); - - // date_test and time_test - stmt.execute("drop table if exists TIME_TEST"); - stmt.execute("drop table if exists DATE_TEST"); - stmt.execute(CREATE_TABLE_TIMETEST); - stmt.execute(CREATE_TABLE_DATETEST); - cubridInited = true; - } - - public static void initDerby() throws SQLException, ClassNotFoundException { - targetHolder.set(Target.DERBY); - SQLTemplates templates = new DerbyTemplates(); - Connection c = getDerby(); - connHolder.set(c); - Statement stmt = c.createStatement(); - stmtHolder.set(stmt); - - if (derbyInited) { - return; - } - - // types - dropType(stmt, "price restrict"); - stmt.execute("create type price external name 'com.example.Price' language java"); - - // survey - dropTable(templates, "SURVEY"); - stmt.execute("create table SURVEY(" + - "ID int generated by default as identity(start with 1, increment by 1), " + - "NAME varchar(30)," + - "NAME2 varchar(30))"); - stmt.execute("insert into SURVEY values (1,'Hello World','Hello')"); - - // test - dropTable(templates, "TEST"); - stmt.execute(CREATE_TABLE_TEST); - stmt.execute("create index test_name on test(name)"); - PreparedStatement pstmt = c.prepareStatement(INSERT_INTO_TEST_VALUES); - try{ - for (int i = 0; i < TEST_ROW_COUNT; i++) { - pstmt.setString(1, "name" + i); - pstmt.addBatch(); - } - pstmt.executeBatch(); - }finally{ - pstmt.close(); - } - - // employee - dropTable(templates, "EMPLOYEE"); - - createEmployeeTable(templates); - - addEmployees(INSERT_INTO_EMPLOYEE); - - // date_test and time_test - dropTable(templates, "TIME_TEST"); - stmt.execute(CREATE_TABLE_TIMETEST); - - dropTable(templates, "DATE_TEST"); - stmt.execute(CREATE_TABLE_DATETEST); - derbyInited = true; - } - - - - public static void initH2() throws SQLException, ClassNotFoundException{ - targetHolder.set(Target.H2); - SQLTemplates templates = new H2Templates(); - Connection c = getH2(); - connHolder.set(c); - Statement stmt = c.createStatement(); - stmtHolder.set(stmt); - - if (h2Inited) { - return; - } - - stmt.execute("DROP ALIAS IF EXISTS InitGeoDB"); - stmt.execute("CREATE ALIAS InitGeoDB for \"geodb.GeoDB.InitGeoDB\""); - stmt.execute("CALL InitGeoDB()"); - - // shapes - dropTable(templates, "SHAPES"); - stmt.execute("create table SHAPES (ID int not null primary key, GEOMETRY blob)"); - for (Map.Entry entry : getSpatialData().entrySet()) { - stmt.execute("insert into SHAPES values(" + entry.getKey() - +", ST_GeomFromText('" + entry.getValue() + "', 4326))"); - } - - // qtest - stmt.execute("drop table QTEST if exists"); - stmt.execute("create table QTEST (ID int IDENTITY(1,1) NOT NULL, C1 int NULL)"); - - // survey - stmt.execute("drop table SURVEY if exists"); - stmt.execute(CREATE_TABLE_SURVEY); - stmt.execute("insert into SURVEY values (1, 'Hello World', 'Hello');"); - stmt.execute("alter table SURVEY alter column id int auto_increment"); - - // test - stmt.execute("drop table TEST if exists"); - stmt.execute(CREATE_TABLE_TEST); - PreparedStatement pstmt = c.prepareStatement(INSERT_INTO_TEST_VALUES); - try{ - for (int i = 0; i < TEST_ROW_COUNT; i++) { - pstmt.setString(1, "name" + i); - pstmt.addBatch(); - } - pstmt.executeBatch(); - }finally{ - pstmt.close(); - } - - // employee - stmt.execute("drop table EMPLOYEE if exists"); - createEmployeeTable(templates); - stmt.execute("alter table EMPLOYEE alter column id int auto_increment"); - addEmployees(INSERT_INTO_EMPLOYEE); - - - // date_test and time_test - stmt.execute("drop table TIME_TEST if exists"); - stmt.execute("drop table DATE_TEST if exists"); - stmt.execute(CREATE_TABLE_TIMETEST); - stmt.execute(CREATE_TABLE_DATETEST); - h2Inited = true; - } - - public static void initHSQL() throws SQLException, ClassNotFoundException{ - targetHolder.set(Target.HSQLDB); - SQLTemplates templates = new HSQLDBTemplates(); - Connection c = getHSQL(); - connHolder.set(c); - Statement stmt = c.createStatement(); - stmtHolder.set(stmt); - - if (hsqlInited) { - return; - } - - // dual - stmt.execute("drop table DUAL if exists"); - stmt.execute("create table DUAL ( DUMMY varchar(1) )"); - stmt.execute("insert into DUAL (DUMMY) values ('X')"); - - // survey - stmt.execute("drop table SURVEY if exists"); - //stmt.execute(CREATE_TABLE_SURVEY); - stmt.execute("create table SURVEY(" + - "ID int generated by default as identity, " + - "NAME varchar(30)," + - "NAME2 varchar(30))"); - stmt.execute("insert into SURVEY values (1, 'Hello World', 'Hello')"); - - // test - stmt.execute("drop table TEST if exists"); - stmt.execute(CREATE_TABLE_TEST); - PreparedStatement pstmt = c.prepareStatement(INSERT_INTO_TEST_VALUES); - try{ - for (int i = 0; i < TEST_ROW_COUNT; i++) { - pstmt.setString(1, "name" + i); - pstmt.addBatch(); - } - pstmt.executeBatch(); - }finally{ - pstmt.close(); - } - - // employee - stmt.execute("drop table EMPLOYEE if exists"); - createEmployeeTable(templates); - stmt.execute("alter table EMPLOYEE alter column id int generated by default as identity"); - addEmployees(INSERT_INTO_EMPLOYEE); - - // date_test and time_test - stmt.execute("drop table TIME_TEST if exists"); - stmt.execute("drop table DATE_TEST if exists"); - stmt.execute(CREATE_TABLE_TIMETEST); - stmt.execute(CREATE_TABLE_DATETEST); - hsqlInited = true; - } - - public static void initMySQL() throws SQLException, ClassNotFoundException{ - targetHolder.set(Target.MYSQL); - //SQLTemplates templates = new MySQLTemplates(); - Connection c = getMySQL(); - connHolder.set(c); - Statement stmt = c.createStatement(); - stmtHolder.set(stmt); - - if (mysqlInited) { - return; - } - - // shapes - stmt.execute("drop table if exists SHAPES"); - stmt.execute("create table SHAPES (ID int not null primary key, GEOMETRY geometry)"); - for (Map.Entry entry : getSpatialData().entrySet()) { - stmt.execute("insert into SHAPES values(" + entry.getKey() - +", GeomFromText('" + entry.getValue() + "'))"); - } - - // survey - stmt.execute("drop table if exists SURVEY"); - stmt.execute("create table SURVEY(ID int primary key auto_increment, " + - "NAME varchar(30)," + - "NAME2 varchar(30))"); - stmt.execute("insert into SURVEY values (1,'Hello World','Hello');"); - - // test - stmt.execute("drop table if exists TEST"); - stmt.execute(CREATE_TABLE_TEST); - PreparedStatement pstmt = c.prepareStatement(INSERT_INTO_TEST_VALUES); - try{ - for (int i = 0; i < TEST_ROW_COUNT; i++) { - pstmt.setString(1, "name" + i); - pstmt.addBatch(); - } - pstmt.executeBatch(); - }finally{ - pstmt.close(); - } - - // employee - stmt.execute("drop table if exists EMPLOYEE"); - //createEmployeeTable(templates); - stmt.execute("create table EMPLOYEE ( " + - "ID INT PRIMARY KEY AUTO_INCREMENT, " + - "FIRSTNAME VARCHAR(50), " + - "LASTNAME VARCHAR(50), " + - "SALARY DECIMAL, " + - "DATEFIELD DATE, " + - "TIMEFIELD TIME, " + - "SUPERIOR_ID INT, " + - "CONSTRAINT FK_SUPERIOR FOREIGN KEY(SUPERIOR_ID) REFERENCES EMPLOYEE(ID) " + - ")"); - - addEmployees(INSERT_INTO_EMPLOYEE); - - // date_test and time_test - stmt.execute("drop table if exists TIME_TEST"); - stmt.execute("drop table if exists DATE_TEST"); - stmt.execute(CREATE_TABLE_TIMETEST); - stmt.execute(CREATE_TABLE_DATETEST); - mysqlInited = true; - } - - public static void initOracle() throws SQLException, ClassNotFoundException{ - targetHolder.set(Target.ORACLE); - SQLTemplates templates = new OracleTemplates(); - Connection c = getOracle(); - connHolder.set(c); - Statement stmt = c.createStatement(); - stmtHolder.set(stmt); - - if (oracleInited) { - return; - } - - // types - stmt.execute("create or replace type ssn_t as object (ssn_type char(11))"); - - // survey - dropTable(templates, "SURVEY"); - stmt.execute("create table SURVEY (ID number(10,0), " + - "NAME varchar(30 char)," + - "NAME2 varchar(30 char))"); - - try { - stmt.execute("drop sequence survey_seq"); - } catch(SQLException e) { - if (!e.getMessage().contains("sequence does not exist")) { - throw e; - } - } - - stmt.execute("create sequence survey_seq"); - stmt.execute("create or replace trigger survey_trigger\n"+ - "before insert on survey\n"+ - "for each row\n" + - "when (new.id is null)\n"+ - "begin\n"+ - " select survey_seq.nextval into :new.id from dual;\n"+ - "end;\n"); - - stmt.execute("insert into SURVEY values (1,'Hello World','Hello')"); - - // test - dropTable(templates, "TEST"); - stmt.execute("create table TEST(name varchar(255))"); - String sql = "insert into TEST values(?)"; - PreparedStatement pstmt = c.prepareStatement(sql); - for (int i = 0; i < TEST_ROW_COUNT; i++) { - pstmt.setString(1, "name" + i); - pstmt.addBatch(); - } - pstmt.executeBatch(); - - // employee - dropTable(templates, "EMPLOYEE"); - stmt.execute("create table EMPLOYEE ( " + - "ID NUMBER(10,0), " + - "FIRSTNAME VARCHAR2(50 CHAR), " + - "LASTNAME VARCHAR2(50 CHAR), " + - "SALARY DOUBLE PRECISION, " + - "DATEFIELD DATE, " + - "TIMEFIELD TIMESTAMP, " + - "SUPERIOR_ID NUMBER(10,0), " + - "CONSTRAINT PK_EMPLOYEE PRIMARY KEY(ID), " + - "CONSTRAINT FK_SUPERIOR FOREIGN KEY(SUPERIOR_ID) REFERENCES EMPLOYEE(ID)" + - ")"); - - addEmployees(INSERT_INTO_EMPLOYEE); - - // date_test and time_test - dropTable(templates, "DATE_TEST"); - stmt.execute("create table date_test(date_test date)"); - oracleInited = true; - } - - public static void initPostgres() throws SQLException, ClassNotFoundException{ - targetHolder.set(Target.POSTGRES); - SQLTemplates templates = new PostgresTemplates(true); - // NOTE : unquoted identifiers are converted to lower case in Postgres - Connection c = getPostgres(); - connHolder.set(c); - Statement stmt = c.createStatement(); - stmtHolder.set(stmt); - - if (postgresInited) { - return; - } - - // shapes - dropTable(templates, "SHAPES"); -// stmt.execute("create table \"SHAPES\" (\"ID\" int not null primary key, \"GEOMETRY\" geography(POINT,4326))"); - stmt.execute("create table \"SHAPES\" (\"ID\" int not null primary key)"); - stmt.execute("select AddGeometryColumn('SHAPES', 'GEOMETRY', -1, 'GEOMETRY', 2)"); - for (Map.Entry entry : getSpatialData().entrySet()) { - stmt.execute("insert into \"SHAPES\" values(" + entry.getKey() - +", '" + entry.getValue() + "')"); - } - - // types - dropType(stmt, "u_country"); - stmt.execute("create type u_country as enum ('Brazil', 'England', 'Germany')"); - - dropType(stmt, "u_street_type"); - stmt.execute("create type u_street_type as (street VARCHAR(100), number VARCHAR(30))"); - - // arrays - dropTable(templates, "ARRAYTEST"); - stmt.execute("create table \"ARRAYTEST\" (\n" + - "\"ID\" bigint primary key,\n" + - "\"MYARRAY\" varchar(8)[])"); - - // survey - dropTable(templates, "SURVEY"); - try { - stmt.execute("drop sequence SURVEY_SEQ"); - } catch(SQLException e) { - if (!e.getMessage().contains("does not exist")) { - throw e; - } - } - stmt.execute("create sequence SURVEY_SEQ"); - stmt.execute("create table \"SURVEY\"(" + - "\"ID\" int DEFAULT NEXTVAL('SURVEY_SEQ'), " + - "\"NAME\" varchar(30), \"NAME2\" varchar(30))"); - stmt.execute("insert into \"SURVEY\" values (1, 'Hello World', 'Hello')"); - - // test - dropTable(templates, "TEST"); - stmt.execute(quote(CREATE_TABLE_TEST,"TEST","NAME")); - String sql = quote(INSERT_INTO_TEST_VALUES,"TEST"); - PreparedStatement pstmt = c.prepareStatement(sql); - try{ - for (int i = 0; i < TEST_ROW_COUNT; i++) { - pstmt.setString(1, "name" + i); - pstmt.addBatch(); - } - pstmt.executeBatch(); - }finally{ - pstmt.close(); - } - - // employee - // stmt.execute("drop table employee if exists"); - dropTable(templates, "EMPLOYEE"); - createEmployeeTable(templates); - addEmployees("insert into \"EMPLOYEE\" " + - "(\"ID\", \"FIRSTNAME\", \"LASTNAME\", \"SALARY\", \"DATEFIELD\", \"TIMEFIELD\", \"SUPERIOR_ID\") " + - "values (?,?,?,?,?,?,?)"); - - // date_test and time_test - dropTable(templates, "TIME_TEST"); - dropTable(templates, "DATE_TEST"); - stmt.execute(quote(CREATE_TABLE_TIMETEST, "TIME_TEST")); - stmt.execute(quote(CREATE_TABLE_DATETEST, "DATE_TEST")); - postgresInited = true; - } - - public static void initSQLite() throws SQLException, ClassNotFoundException{ - targetHolder.set(Target.SQLITE); -// SQLTemplates templates = new SQLiteTemplates(); - Connection c = getSQLite(); - connHolder.set(c); - Statement stmt = c.createStatement(); - stmtHolder.set(stmt); - - if (sqliteInited) { - return; - } - - // qtest - stmt.execute("drop table if exists QTEST"); - stmt.execute("create table QTEST (ID int IDENTITY(1,1) NOT NULL, C1 int NULL)"); - - // survey - stmt.execute("drop table if exists SURVEY"); - stmt.execute("create table SURVEY(ID int auto_increment, " + - "NAME varchar(30)," + - "NAME2 varchar(30)," + - "constraint suryey_pk primary key(ID))"); - stmt.execute("insert into SURVEY values (1,'Hello World','Hello');"); - - // test - stmt.execute("drop table if exists TEST"); - stmt.execute(CREATE_TABLE_TEST); - PreparedStatement pstmt = c.prepareStatement(INSERT_INTO_TEST_VALUES); - try{ - for (int i = 0; i < TEST_ROW_COUNT; i++) { - pstmt.setString(1, "name" + i); - pstmt.addBatch(); - } - pstmt.executeBatch(); - }finally{ - pstmt.close(); - } - - // employee - stmt.execute("drop table if exists EMPLOYEE"); - stmt.execute("create table EMPLOYEE ( " + - "ID INT AUTO_INCREMENT, " + - "FIRSTNAME VARCHAR(50), " + - "LASTNAME VARCHAR(50), " + - "SALARY DECIMAL, " + - "DATEFIELD DATE, " + - "TIMEFIELD TIME, " + - "SUPERIOR_ID INT, " + - "CONSTRAINT PK_EMPLOYEE PRIMARY KEY(ID),"+ - "CONSTRAINT FK_SUPERIOR FOREIGN KEY(SUPERIOR_ID) REFERENCES EMPLOYEE(ID) " + - ")"); - addEmployees(INSERT_INTO_EMPLOYEE); - - - // date_test and time_test - stmt.execute("drop table if exists TIME_TEST"); - stmt.execute("drop table if exists DATE_TEST"); - stmt.execute(CREATE_TABLE_TIMETEST); - stmt.execute(CREATE_TABLE_DATETEST); - sqliteInited = true; - } - - public static void initSQLServer() throws SQLException, ClassNotFoundException { - targetHolder.set(Target.SQLSERVER); - SQLTemplates templates = new SQLServerTemplates(); - Connection c = getSQLServer(); - connHolder.set(c); - Statement stmt = c.createStatement(); - stmtHolder.set(stmt); - - if (sqlServerInited) { - return; - } - - dropTable(templates, "SHAPES"); - stmt.execute("create table SHAPES (ID int not null primary key, GEOMETRY geometry)"); - for (Map.Entry entry : getSpatialData().entrySet()) { - stmt.execute("insert into SHAPES values(" + entry.getKey() - +", geometry::STGeomFromText('" + entry.getValue() + "', 0))"); - } - - // survey - dropTable(templates, "SURVEY"); - stmt.execute("create table SURVEY(ID int, NAME varchar(30), NAME2 varchar(30))"); - stmt.execute("insert into SURVEY values (1, 'Hello World', 'Hello')"); - - // test - dropTable(templates, "TEST"); - stmt.execute(CREATE_TABLE_TEST); - PreparedStatement pstmt = c.prepareStatement(INSERT_INTO_TEST_VALUES); - try{ - for (int i = 0; i < TEST_ROW_COUNT; i++) { - pstmt.setString(1, "name" + i); - pstmt.addBatch(); - } - pstmt.executeBatch(); - }finally{ - pstmt.close(); - } - - // employee - dropTable(templates, "EMPLOYEE"); - createEmployeeTable(templates); - addEmployees(INSERT_INTO_EMPLOYEE); - - // date_test and time_test - dropTable(templates, "TIME_TEST"); - dropTable(templates, "DATE_TEST"); - stmt.execute(CREATE_TABLE_TIMETEST); - stmt.execute(CREATE_TABLE_DATETEST); - sqlServerInited = true; - } - - public static void initTeradata() throws SQLException, ClassNotFoundException{ - targetHolder.set(Target.TERADATA); - SQLTemplates templates = new TeradataTemplates(); - Connection c = getTeradata(); - connHolder.set(c); - Statement stmt = c.createStatement(); - stmtHolder.set(stmt); - - if (teradataInited) { - return; - } - - String identity = "GENERATED ALWAYS AS IDENTITY(START WITH 1 INCREMENT BY 1)"; - - // shapes - dropTable(templates, "SHAPES"); - stmt.execute("create table SHAPES (ID int not null primary key, GEOMETRY ST_GEOMETRY)"); - for (Map.Entry entry : getSpatialData().entrySet()) { - stmt.execute("insert into SHAPES values(" + entry.getKey() - +", '" + entry.getValue() + "')"); - } - - // qtest - dropTable(templates, "QTEST"); - stmt.execute("create table QTEST (ID int " + identity + " NOT NULL, C1 int NULL)"); - - // survey - dropTable(templates, "SURVEY"); - stmt.execute("create table SURVEY(ID int " + identity + ", NAME varchar(30), NAME2 varchar(30))"); - stmt.execute("insert into SURVEY values (1, 'Hello World', 'Hello');"); - - // test - dropTable(templates, "TEST"); - stmt.execute(CREATE_TABLE_TEST); - PreparedStatement pstmt = c.prepareStatement(INSERT_INTO_TEST_VALUES); - try{ - for (int i = 0; i < TEST_ROW_COUNT; i++) { - pstmt.setString(1, "name" + i); - pstmt.addBatch(); - } - pstmt.executeBatch(); - }finally{ - pstmt.close(); - } - - // employee - dropTable(templates, "EMPLOYEE"); - stmt.execute("create table EMPLOYEE (\n" + - "ID INTEGER NOT NULL PRIMARY KEY, \n" + - "FIRSTNAME VARCHAR(100),\n" + - "LASTNAME VARCHAR(100),\n" + - "SALARY DOUBLE PRECISION,\n" + - "DATEFIELD DATE,\n" + - "TIMEFIELD TIME,\n" + - "SUPERIOR_ID INTEGER,\n" + - "CONSTRAINT FK_SUPERIOR FOREIGN KEY(SUPERIOR_ID) REFERENCES EMPLOYEE(ID))"); - addEmployees(INSERT_INTO_EMPLOYEE); - - // date_test and time_test - dropTable(templates, "TIME_TEST"); - dropTable(templates, "DATE_TEST"); - stmt.execute(CREATE_TABLE_TIMETEST); - stmt.execute(CREATE_TABLE_DATETEST); - teradataInited = true; - } - - static void addEmployee(String sql, int id, String firstName, String lastName, - double salary, int superiorId) throws SQLException { - PreparedStatement stmt = connHolder.get().prepareStatement(sql); - stmt.setInt(1, id); - stmt.setString(2, firstName); - stmt.setString(3,lastName); - stmt.setDouble(4, salary); - stmt.setDate(5, Constants.date); - stmt.setTime(6, Constants.time); - if (superiorId <= 0) { - stmt.setNull(7, Types.INTEGER); - } else { - stmt.setInt(7, superiorId); - } - stmt.execute(); - stmt.close(); - } - - private static void addEmployees(String sql) throws SQLException { - addEmployee(sql, 1, "Mike", "Smith", 160000, -1); - addEmployee(sql, 2, "Mary", "Smith", 140000, -1); - - // Employee under Mike - addEmployee(sql, 10, "Joe", "Divis", 50000, 1); - addEmployee(sql, 11, "Peter", "Mason", 45000, 1); - addEmployee(sql, 12, "Steve", "Johnson", 40000, 1); - addEmployee(sql, 13, "Jim", "Hood", 35000, 1); - - // Employee under Mike - addEmployee(sql, 20, "Jennifer", "Divis", 60000, 2); - addEmployee(sql, 21, "Helen", "Mason", 50000, 2); - addEmployee(sql, 22, "Daisy", "Johnson", 40000, 2); - addEmployee(sql, 23, "Barbara", "Hood", 30000, 2); - } - - private static String quote(String sql, String... identifiers) { - String rv = sql; - for (String id : identifiers) { - rv = rv.replace(id, "\"" + id + "\""); - } - return rv; - } - - private Connections() {} -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/ConnectionsTest.java b/querydsl-sql/src/test/java/com/mysema/query/ConnectionsTest.java deleted file mode 100644 index 78a8cfa6e9..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/ConnectionsTest.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.mysema.query; - -import static org.junit.Assert.assertNotNull; - -import org.geolatte.geom.codec.Wkt; -import org.junit.Test; - -public class ConnectionsTest { - - @Test - public void Valid_Wkt() { - for (String wkt : Connections.getSpatialData().values()) { - assertNotNull(Wkt.newWktDecoder(Wkt.Dialect.POSTGIS_EWKT_1).decode(wkt)); - } - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/Constants.java b/querydsl-sql/src/test/java/com/mysema/query/Constants.java deleted file mode 100644 index b447fcc055..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/Constants.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query; - -import java.util.Calendar; - -import com.mysema.query.sql.domain.QEmployee; -import com.mysema.query.sql.domain.QSurvey; - -public final class Constants { - - private Constants() {} - - public static final java.sql.Date date; - - public static final java.sql.Time time; - - public static final QEmployee employee = new QEmployee("e"); - - public static final QEmployee employee2 = new QEmployee("e2"); - - public static final QSurvey survey = new QSurvey("s"); - - public static final QSurvey survey2 = new QSurvey("s2"); - - static{ - Calendar cal = Calendar.getInstance(); - cal.clear(); - cal.set(Calendar.YEAR, 2000); - cal.set(Calendar.MONTH, 1); - cal.set(Calendar.DAY_OF_MONTH, 2); - date = new java.sql.Date(cal.getTimeInMillis()); - - cal = Calendar.getInstance(); - cal.set(1970, 0, 1, 3, 4); - cal.set(Calendar.SECOND, 30); - cal.set(Calendar.MILLISECOND, 0); - time = new java.sql.Time(cal.getTimeInMillis()); - } -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/DeleteBase.java b/querydsl-sql/src/test/java/com/mysema/query/DeleteBase.java deleted file mode 100644 index 23a86c6455..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/DeleteBase.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query; - -import static com.mysema.query.Constants.survey; -import static com.mysema.query.Target.CUBRID; -import static com.mysema.query.Target.H2; -import static com.mysema.query.Target.MYSQL; -import static com.mysema.query.Target.ORACLE; -import static com.mysema.query.Target.SQLSERVER; -import static org.junit.Assert.assertEquals; - -import java.sql.SQLException; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.mysema.query.sql.SQLSubQuery; -import com.mysema.query.sql.dml.SQLDeleteClause; -import com.mysema.query.sql.domain.QEmployee; -import com.mysema.query.sql.domain.QSurvey; -import com.mysema.query.types.expr.Param; -import com.mysema.testutil.ExcludeIn; -import com.mysema.testutil.IncludeIn; - -public class DeleteBase extends AbstractBaseTest{ - - private void reset() throws SQLException{ - delete(survey).where(survey.name.isNotNull()).execute(); - insert(survey).values(1, "Hello World", "Hello").execute(); - } - - @Before - public void setUp() throws SQLException{ - reset(); - } - - @After - public void tearDown() throws SQLException{ - reset(); - } - - @Test - public void Batch() throws SQLException{ - insert(survey).values(2, "A","B").execute(); - insert(survey).values(3, "B","C").execute(); - - SQLDeleteClause delete = delete(survey); - delete.where(survey.name.eq("A")).addBatch(); - delete.where(survey.name.eq("B")).addBatch(); - assertEquals(2, delete.execute()); - } - - @Test - @ExcludeIn(MYSQL) - public void Delete() throws SQLException{ - long count = query().from(survey).count(); - assertEquals(0, delete(survey).where(survey.name.eq("XXX")).execute()); - assertEquals(count, delete(survey).execute()); - } - - @Test - @IncludeIn({CUBRID, H2, MYSQL, ORACLE, SQLSERVER}) - public void Delete_Limit() { - insert(survey).values(2, "A","B").execute(); - insert(survey).values(3, "B","C").execute(); - insert(survey).values(4, "D","E").execute(); - - assertEquals(2, delete(survey).limit(2).execute()); - } - - @Test - public void Delete_with_SubQuery_exists() { - QSurvey survey1 = new QSurvey("s1"); - QEmployee employee = new QEmployee("e"); - SQLDeleteClause delete = delete(survey1); - delete.where(survey1.name.eq("XXX"), - sq().from(employee).where(survey1.id.eq(employee.id)).exists()); - delete.execute(); - } - - @Test - public void Delete_with_SubQuery_exists_Params() { - QSurvey survey1 = new QSurvey("s1"); - QEmployee employee = new QEmployee("e"); - - Param param = new Param(Integer.class, "param"); - SQLSubQuery sq = sq().from(employee).where(employee.id.eq(param)); - sq.set(param, -12478923); - - SQLDeleteClause delete = delete(survey1); - delete.where(survey1.name.eq("XXX"), sq.exists()); - delete.execute(); - } - - @Test - public void Delete_with_SubQuery_exists2() { - QSurvey survey1 = new QSurvey("s1"); - QEmployee employee = new QEmployee("e"); - SQLDeleteClause delete = delete(survey1); - delete.where(survey1.name.eq("XXX"), - sq().from(employee).where(survey1.name.eq(employee.lastname)).exists()); - delete.execute(); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/DependenciesTest.java b/querydsl-sql/src/test/java/com/mysema/query/DependenciesTest.java deleted file mode 100644 index 537c4f012b..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/DependenciesTest.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query; - -import static org.junit.Assert.assertFalse; - -import java.io.IOException; - -import jdepend.framework.JDepend; - -import org.junit.Ignore; -import org.junit.Test; - -public class DependenciesTest { - - @Test - @Ignore - public void test() throws IOException{ - JDepend jdepend = new JDepend(); - jdepend.addDirectory("target/classes/com/mysema/query/sql"); - jdepend.addDirectory("target/classes/com/mysema/query/sql/ddl"); - jdepend.addDirectory("target/classes/com/mysema/query/sql/dml"); - jdepend.addDirectory("target/classes/com/mysema/query/sql/mssql"); - jdepend.addDirectory("target/classes/com/mysema/query/sql/mysql"); - jdepend.addDirectory("target/classes/com/mysema/query/sql/oracle"); - jdepend.addDirectory("target/classes/com/mysema/query/sql/support"); - jdepend.addDirectory("target/classes/com/mysema/query/sql/types"); - - jdepend.analyze(); - assertFalse(jdepend.containsCycles()); - - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/ExtendedSQLQuery.java b/querydsl-sql/src/test/java/com/mysema/query/ExtendedSQLQuery.java deleted file mode 100644 index 7e3d96a4e9..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/ExtendedSQLQuery.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query; - -import java.sql.Connection; -import java.util.List; - -import com.mysema.commons.lang.CloseableIterator; -import com.mysema.query.sql.AbstractSQLQuery; -import com.mysema.query.sql.Configuration; -import com.mysema.query.sql.SQLTemplates; -import com.mysema.query.types.Expression; -import com.mysema.query.types.FactoryExpression; -import com.mysema.query.types.QBean; - -/** - * @author tiwe - * - */ -public class ExtendedSQLQuery extends AbstractSQLQuery { - - public ExtendedSQLQuery(SQLTemplates templates) { - super(null, new Configuration(templates), new DefaultQueryMetadata()); - } - - public ExtendedSQLQuery(Connection conn, SQLTemplates templates) { - super(conn, new Configuration(templates), new DefaultQueryMetadata()); - } - - public ExtendedSQLQuery(Connection conn, Configuration configuration) { - super(conn, configuration, new DefaultQueryMetadata()); - } - - public ExtendedSQLQuery(Connection conn, Configuration configuration, QueryMetadata metadata) { - super(conn, configuration, metadata); - } - - public CloseableIterator iterate(Class type, Expression... exprs) { - return iterate(createProjection(type, exprs)); - } - - public T uniqueResult(Class type, Expression... exprs) { - return uniqueResult(createProjection(type, exprs)); - } - - public List list(Class type, Expression... exprs) { - return list(createProjection(type, exprs)); - } - - public SearchResults listResults(Class type, Expression... exprs) { - return listResults(createProjection(type, exprs)); - } - - private FactoryExpression createProjection(Class type, Expression... exprs) { - return new QBean(type, exprs); - } - - @Override - public ExtendedSQLQuery clone(Connection connection) { - ExtendedSQLQuery query = new ExtendedSQLQuery(connection, getConfiguration(), getMetadata().clone()); - query.clone(this); - return query; - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/InsertBase.java b/querydsl-sql/src/test/java/com/mysema/query/InsertBase.java deleted file mode 100644 index ebca6ff4e9..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/InsertBase.java +++ /dev/null @@ -1,395 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query; - -import java.sql.ResultSet; -import java.sql.SQLException; - -import com.mysema.query.QueryFlag.Position; -import com.mysema.query.sql.SQLSubQuery; -import com.mysema.query.sql.dml.DefaultMapper; -import com.mysema.query.sql.dml.Mapper; -import com.mysema.query.sql.dml.SQLInsertClause; -import com.mysema.query.sql.domain.Employee; -import com.mysema.query.sql.domain.QDateTest; -import com.mysema.query.sql.domain.QEmployee; -import com.mysema.query.sql.domain.QSurvey; -import com.mysema.query.support.Expressions; -import com.mysema.query.types.Path; -import com.mysema.query.types.PathImpl; -import com.mysema.query.types.expr.Param; -import com.mysema.testutil.ExcludeIn; -import com.mysema.testutil.IncludeIn; -import org.joda.time.DateTime; -import org.joda.time.LocalDate; -import org.junit.After; -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; -import static com.mysema.query.Constants.survey; -import static com.mysema.query.Constants.survey2; -import static com.mysema.query.Target.*; -import static org.junit.Assert.*; - -public class InsertBase extends AbstractBaseTest { - - private void reset() throws SQLException{ - delete(survey).execute(); - insert(survey).values(1, "Hello World", "Hello").execute(); - - delete(QDateTest.qDateTest).execute(); - } - - @Before - public void setUp() throws SQLException{ - reset(); - } - - @After - public void tearDown() throws SQLException{ - reset(); - } - - @Test - @ExcludeIn(SQLITE) // https://bitbucket.org/xerial/sqlite-jdbc/issue/133/prepstmtsetdate-int-date-calendar-seems - public void Insert_Dates() { - QDateTest dateTest = QDateTest.qDateTest; - LocalDate localDate = new LocalDate(1978, 1, 2); - - Path localDateProperty = new PathImpl(LocalDate.class, "DATE_TEST"); - Path dateTimeProperty = new PathImpl(DateTime.class, "DATE_TEST"); - SQLInsertClause insert = insert(dateTest); - insert.set(localDateProperty, localDate); - insert.execute(); - - Tuple result = query().from(dateTest).singleResult( - dateTest.dateTest.year(), - dateTest.dateTest.month(), - dateTest.dateTest.dayOfMonth(), - dateTimeProperty); - assertEquals(Integer.valueOf(1978), result.get(0, Integer.class)); - assertEquals(Integer.valueOf(1), result.get(1, Integer.class)); - assertEquals(Integer.valueOf(2), result.get(2, Integer.class)); - - DateTime dateTime = result.get(dateTimeProperty); - if (target == CUBRID) { - // XXX Cubrid adds random milliseconds for some reason - dateTime = dateTime.withMillisOfSecond(0); - } - assertEquals(localDate.toDateTimeAtStartOfDay(), dateTime); - } - - @Test - public void Complex1() { - // related to #584795 - QSurvey survey = new QSurvey("survey"); - QEmployee emp1 = new QEmployee("emp1"); - QEmployee emp2 = new QEmployee("emp2"); - SQLInsertClause insert = insert(survey); - insert.columns(survey.id, survey.name); - insert.select(new SQLSubQuery().from(survey) - .innerJoin(emp1) - .on(survey.id.eq(emp1.id)) - .innerJoin(emp2) - .on(emp1.superiorId.eq(emp2.superiorId), emp1.firstname.eq(emp2.firstname)) - .list(survey.id, emp2.firstname)); - - insert.execute(); - } - - @Test - public void Insert_Alternative_Syntax() { - // with columns - assertEquals(1, insert(survey) - .set(survey.id, 3) - .set(survey.name, "Hello") - .execute()); - } - - @Test - public void Insert_Batch() { - SQLInsertClause insert = insert(survey) - .set(survey.id, 5) - .set(survey.name, "55") - .addBatch(); - - insert.set(survey.id, 6) - .set(survey.name, "66") - .addBatch(); - - assertEquals(2, insert.execute()); - - assertEquals(1l, query().from(survey).where(survey.name.eq("55")).count()); - assertEquals(1l, query().from(survey).where(survey.name.eq("66")).count()); - } - - @Test - public void Insert_Batch2() { - SQLInsertClause insert = insert(survey) - .set(survey.id, 5) - .set(survey.name, "55") - .addBatch(); - - insert.set(survey.id, 6) - .setNull(survey.name) - .addBatch(); - - assertEquals(2, insert.execute()); - } - - @Test - public void Insert_Null_With_Columns() { - assertEquals(1, insert(survey) - .columns(survey.id, survey.name) - .values(3, null).execute()); - } - - @Test - @ExcludeIn(DERBY) - public void Insert_Null_Without_Columns() { - assertEquals(1, insert(survey) - .values(4, null, null).execute()); - } - - @Test - @ExcludeIn({HSQLDB, DERBY, ORACLE}) - public void Insert_Without_Values() { - assertEquals(1, insert(survey).execute()); - } - - @Test - @ExcludeIn(ORACLE) - public void Insert_Nulls_In_Batch() { -// QFoo f= QFoo.foo; -// SQLInsertClause sic = new SQLInsertClause(c, new H2Templates(), f); -// sic.columns(f.c1,f.c2).values(null,null).addBatch(); -// sic.columns(f.c1,f.c2).values(null,1).addBatch(); -// sic.execute(); - SQLInsertClause sic = insert(survey); - sic.columns(survey.name, survey.name2).values(null, null).addBatch(); - sic.columns(survey.name, survey.name2).values(null, "X").addBatch(); - sic.execute(); - } - - @Test - @Ignore - @ExcludeIn({DERBY}) - public void Insert_Nulls_In_Batch2() { - Mapper mapper = DefaultMapper.WITH_NULL_BINDINGS; -// QFoo f= QFoo.foo; -// SQLInsertClause sic = new SQLInsertClause(c, new H2Templates(), f); -// Foo f1=new Foo(); -// sic.populate(f1).addBatch(); -// f1=new Foo(); -// f1.setC1(1); -// sic.populate(f1).addBatch(); -// sic.execute(); - QEmployee employee = QEmployee.employee; - SQLInsertClause sic = insert(employee); - Employee e = new Employee(); - sic.populate(e, mapper).addBatch(); - e = new Employee(); - e.setFirstname("X"); - sic.populate(e, mapper).addBatch(); - sic.execute(); - - } - - @Test - public void Insert_With_Columns() { - assertEquals(1, insert(survey) - .columns(survey.id, survey.name) - .values(3, "Hello").execute()); - } - - @Test - @ExcludeIn({CUBRID, SQLSERVER}) - public void Insert_With_Keys() throws SQLException{ - ResultSet rs = insert(survey).set(survey.name, "Hello World").executeWithKeys(); - assertTrue(rs.next()); - assertTrue(rs.getObject(1) != null); - rs.close(); - } - - @Test - @ExcludeIn({CUBRID, SQLSERVER}) - public void Insert_With_Keys_Projected() throws SQLException{ - assertNotNull(insert(survey).set(survey.name, "Hello you").executeWithKey(survey.id)); - } - - @Test - @ExcludeIn({CUBRID, SQLSERVER}) - public void Insert_With_Keys_Projected2() throws SQLException{ - Path idPath = new PathImpl(Object.class, "id"); - Object id = insert(survey).set(survey.name, "Hello you").executeWithKey(idPath); - assertNotNull(id); - } - - // http://sourceforge.net/tracker/index.php?func=detail&aid=3513432&group_id=280608&atid=2377440 - - @Test - public void Insert_With_Set() { - assertEquals(1, insert(survey) - .set(survey.id, 5) - .set(survey.name, (String)null) - .execute()); - } - - @Test - @IncludeIn(MYSQL) - @SkipForQuoted - public void Insert_with_Special_Options() { - SQLInsertClause clause = insert(survey) - .columns(survey.id, survey.name) - .values(3, "Hello"); - - clause.addFlag(Position.START_OVERRIDE, "insert ignore into "); - - assertEquals("insert ignore into SURVEY (ID, NAME) values (?, ?)", clause.toString()); - clause.execute(); - } - - @Test - public void Insert_With_SubQuery() { - int count = (int)query().from(survey).count(); - assertEquals(count, insert(survey) - .columns(survey.id, survey.name) - .select(sq().from(survey2).list(survey2.id.add(20), survey2.name)) - .execute()); - } - - @Test - @ExcludeIn({HSQLDB, CUBRID, DERBY}) - public void Insert_With_SubQuery2() { -// insert into modules(name) -// select 'MyModule' -// where not exists -// (select 1 from modules where modules.name = 'MyModule') - - assertEquals(1, insert(survey).set(survey.name, - sq().where(sq().from(survey2) - .where(survey2.name.eq("MyModule")).notExists()) - .unique(Expressions.constant("MyModule"))) - .execute()); - - assertEquals(1l , query().from(survey).where(survey.name.eq("MyModule")).count()); - } - - @Test - @ExcludeIn({HSQLDB, CUBRID, DERBY}) - public void Insert_With_SubQuery3() { -// insert into modules(name) -// select 'MyModule' -// where not exists -// (select 1 from modules where modules.name = 'MyModule') - - assertEquals(1, insert(survey).columns(survey.name).select( - sq().where(sq().from(survey2) - .where(survey2.name.eq("MyModule2")).notExists()) - .unique(Expressions.constant("MyModule2"))) - .execute()); - - assertEquals(1l , query().from(survey).where(survey.name.eq("MyModule2")).count()); - } - - @Test - public void Insert_With_SubQuery_Params() { - Param param = new Param(Integer.class, "param"); - SQLSubQuery sq = sq().from(survey2); - sq.set(param, 20); - - int count = (int)query().from(survey).count(); - assertEquals(count, insert(survey) - .columns(survey.id, survey.name) - .select(sq.list(survey2.id.add(param), survey2.name)) - .execute()); - } - - @Test - public void Insert_With_SubQuery_Via_Constructor() { - int count = (int)query().from(survey).count(); - SQLInsertClause insert = insert(survey, sq().from(survey2)); - insert.set(survey.id, survey2.id.add(20)); - insert.set(survey.name, survey2.name); - assertEquals(count, insert.execute()); - } - - @Test - public void Insert_With_SubQuery_Without_Columns() { - int count = (int)query().from(survey).count(); - assertEquals(count, insert(survey) - .select(sq().from(survey2).list(survey2.id.add(10), survey2.name, survey2.name2)) - .execute()); - - } - - @Test - public void Insert_Without_Columns() { - assertEquals(1, insert(survey).values(4, "Hello", "World").execute()); - - } - - @Test - public void InsertBatch_with_Subquery() { - SQLInsertClause insert = insert(survey) - .columns(survey.id, survey.name) - .select(sq().from(survey2).list(survey2.id.add(20), survey2.name)) - .addBatch(); - - insert(survey) - .columns(survey.id, survey.name) - .select(sq().from(survey2).list(survey2.id.add(40), survey2.name)) - .addBatch(); - - insert.execute(); -// assertEquals(1, insert.execute()); - } - - @Test - public void Like() { - insert(survey).values(11, "Hello World", "a\\b").execute(); - assertEquals(1l, query().from(survey).where(survey.name2.contains("a\\b")).count()); - } - - @Test - public void Like_with_Escape() { - SQLInsertClause insert = insert(survey); - insert.set(survey.id, 5).set(survey.name, "aaa").addBatch(); - insert.set(survey.id, 6).set(survey.name, "a_").addBatch(); - insert.set(survey.id, 7).set(survey.name, "a%").addBatch(); - assertEquals(3, insert.execute()); - - assertEquals(1l, query().from(survey).where(survey.name.like("a|%", '|')).count()); - assertEquals(1l, query().from(survey).where(survey.name.like("a|_", '|')).count()); - assertEquals(3l, query().from(survey).where(survey.name.like("a%")).count()); - assertEquals(2l, query().from(survey).where(survey.name.like("a_")).count()); - - assertEquals(1l, query().from(survey).where(survey.name.startsWith("a_")).count()); - assertEquals(1l, query().from(survey).where(survey.name.startsWith("a%")).count()); - } - - @Test - @IncludeIn(MYSQL) - @SkipForQuoted - public void Replace() { - SQLInsertClause clause = mysqlReplace(survey); - clause.columns(survey.id, survey.name) - .values(3, "Hello"); - - assertEquals("replace into SURVEY (ID, NAME) values (?, ?)", clause.toString()); - clause.execute(); - } - - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/LikeEscapeBase.java b/querydsl-sql/src/test/java/com/mysema/query/LikeEscapeBase.java deleted file mode 100644 index 8dd3e8f688..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/LikeEscapeBase.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query; - -import static com.mysema.query.Constants.survey; -import static org.junit.Assert.assertEquals; - -import java.sql.SQLException; - -import org.junit.After; -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; - -import com.mysema.query.sql.dml.SQLInsertClause; - -public class LikeEscapeBase extends AbstractBaseTest{ - - @Before - public void setUp() throws SQLException{ - delete(survey).execute(); - SQLInsertClause insert = insert(survey); - insert.set(survey.id, 5).set(survey.name, "aaa").addBatch(); - insert.set(survey.id, 6).set(survey.name, "a_").addBatch(); - insert.set(survey.id, 7).set(survey.name, "a%").addBatch(); - insert.execute(); - } - - @After - public void tearDown() throws SQLException{ - delete(survey).execute(); - insert(survey).values(1, "Hello World", "Hello").execute(); - } - - @Test - @Ignore - public void Like() { - assertEquals(1l, query().from(survey).where(survey.name.like("a!%")).count()); - assertEquals(1l, query().from(survey).where(survey.name.like("a!_")).count()); - assertEquals(3l, query().from(survey).where(survey.name.like("a%")).count()); - assertEquals(2l, query().from(survey).where(survey.name.like("a_")).count()); - - assertEquals(1l, query().from(survey).where(survey.name.startsWith("a_")).count()); - assertEquals(1l, query().from(survey).where(survey.name.startsWith("a%")).count()); - } - - @Test - public void Like_with_Escape() { - assertEquals(1l, query().from(survey).where(survey.name.like("a!%", '!')).count()); - assertEquals(1l, query().from(survey).where(survey.name.like("a!_", '!')).count()); - assertEquals(3l, query().from(survey).where(survey.name.like("a%", '!')).count()); - assertEquals(2l, query().from(survey).where(survey.name.like("a_", '!')).count()); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/ListSubQueryTest.java b/querydsl-sql/src/test/java/com/mysema/query/ListSubQueryTest.java deleted file mode 100644 index 3d1ea352ba..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/ListSubQueryTest.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.mysema.query; - -import static org.junit.Assert.assertEquals; - -import java.util.HashSet; -import java.util.Set; - -import org.junit.Test; - -import com.mysema.query.sql.SQLSubQuery; -import com.mysema.query.sql.domain.QEmployee; -import com.mysema.query.sql.domain.QSurvey; -import com.mysema.query.types.query.ListSubQuery; - -public class ListSubQueryTest { - - @Test - public void HashCode() { - QSurvey survey = QSurvey.survey; - QSurvey survey2 = new QSurvey("survey2"); - ListSubQuery query1 = new SQLSubQuery().from(survey).list(survey.all()); - ListSubQuery query2 = new SQLSubQuery().from(survey2).list(survey2.all()); - - - Set> queries = new HashSet>(); - queries.add(query1); - queries.add(query2); - assertEquals(2, queries.size()); - } - - @Test - public void HashCode2() { - QSurvey survey = new QSurvey("entity"); - QEmployee employee = new QEmployee("entity"); - ListSubQuery query1 = new SQLSubQuery().from(survey).list(survey.id); - ListSubQuery query2 = new SQLSubQuery().from(employee).list(employee.id); - - Set> queries = new HashSet>(); - queries.add(query1); - queries.add(query2); - assertEquals(1, queries.size()); - } -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/MergeBase.java b/querydsl-sql/src/test/java/com/mysema/query/MergeBase.java deleted file mode 100644 index b0d5491d91..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/MergeBase.java +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query; - -import static com.mysema.query.Constants.survey; -import static com.mysema.query.Constants.survey2; -import static com.mysema.query.Target.CUBRID; -import static com.mysema.query.Target.DERBY; -import static com.mysema.query.Target.H2; -import static com.mysema.query.Target.POSTGRES; -import static com.mysema.query.Target.SQLSERVER; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -import java.sql.ResultSet; -import java.sql.SQLException; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.mysema.query.sql.dml.SQLMergeClause; -import com.mysema.query.sql.domain.QSurvey; -import com.mysema.query.types.Path; -import com.mysema.query.types.PathImpl; -import com.mysema.testutil.ExcludeIn; -import com.mysema.testutil.IncludeIn; - -public class MergeBase extends AbstractBaseTest{ - - private void reset() throws SQLException{ - delete(survey).execute(); - insert(survey).values(1, "Hello World", "Hello").execute(); - } - - @Before - public void setUp() throws SQLException{ - reset(); - } - - @After - public void tearDown() throws SQLException{ - reset(); - } - - - @Test - @ExcludeIn({H2, CUBRID, SQLSERVER}) - public void Merge_With_Keys() throws SQLException{ - ResultSet rs = merge(survey).keys(survey.id) - .set(survey.id, 7) - .set(survey.name, "Hello World").executeWithKeys(); - assertTrue(rs.next()); - assertTrue(rs.getObject(1) != null); - rs.close(); - } - - @Test - @IncludeIn(H2) - public void Merge_with_Keys_and_SubQuery() { - assertEquals(1, insert(survey).set(survey.id, 6).set(survey.name, "H").execute()); - - // keys + subquery - QSurvey survey2 = new QSurvey("survey2"); - assertEquals(2, merge(survey).keys(survey.id).select( - sq().from(survey2).list(survey2.id.add(1), survey2.name, survey2.name2)).execute()); - } - - @Test - @IncludeIn(H2) - public void Merge_with_Keys_and_Values() { - // NOTE : doesn't work with composite merge implementation - // keys + values - assertEquals(1, merge(survey).keys(survey.id).values(5, "Hello World", "Hello").execute()); - } - - @Test - public void Merge_with_Keys_Columns_and_Values() { - // keys + columns + values - assertEquals(1, merge(survey).keys(survey.id) - .set(survey.id, 5) - .set(survey.name, "Hello World").execute()); - } - - @Test - public void Merge_with_Keys_Columns_and_Values_using_null() { - // keys + columns + values - assertEquals(1, merge(survey).keys(survey.id) - .set(survey.id, 5) - .set(survey.name, (String)null).execute()); - } - - @Test - @ExcludeIn({CUBRID, DERBY, POSTGRES, SQLSERVER}) - public void Merge_With_Keys_Null_Id() throws SQLException{ - ResultSet rs = merge(survey).keys(survey.id) - .setNull(survey.id) - .set(survey.name, "Hello World").executeWithKeys(); - assertTrue(rs.next()); - assertTrue(rs.getObject(1) != null); - rs.close(); - } - - @Test - @ExcludeIn({H2, CUBRID, SQLSERVER}) - public void Merge_With_Keys_Projected() throws SQLException{ - assertNotNull(merge(survey).keys(survey.id) - .set(survey.id, 8) - .set(survey.name, "Hello you").executeWithKey(survey.id)); - } - - @Test - @ExcludeIn({H2, CUBRID, SQLSERVER}) - public void Merge_With_Keys_Projected2() throws SQLException{ - Path idPath = new PathImpl(Object.class, "id"); - Object id = merge(survey).keys(survey.id) - .set(survey.id, 9) - .set(survey.name, "Hello you").executeWithKey(idPath); - assertNotNull(id); - } - - @Test - @IncludeIn(H2) - public void MergeBatch() { - SQLMergeClause merge = merge(survey) - .keys(survey.id) - .set(survey.id, 5) - .set(survey.name, "5") - .addBatch(); - - merge - .keys(survey.id) - .set(survey.id, 6) - .set(survey.name, "6") - .addBatch(); - - assertEquals(2, merge.execute()); - - assertEquals(1l, query().from(survey).where(survey.name.eq("5")).count()); - assertEquals(1l, query().from(survey).where(survey.name.eq("6")).count()); - } - - @Test - @IncludeIn(H2) - public void MergeBatch_with_subquery() { - SQLMergeClause merge = merge(survey) - .keys(survey.id) - .columns(survey.id, survey.name) - .select(sq().from(survey2).list(survey2.id.add(20), survey2.name)) - .addBatch(); - - merge(survey) - .keys(survey.id) - .columns(survey.id, survey.name) - .select(sq().from(survey2).list(survey2.id.add(40), survey2.name)) - .addBatch(); - - merge.execute(); -// assertEquals(1, insert.execute()); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/PrecedenceTest.java b/querydsl-sql/src/test/java/com/mysema/query/PrecedenceTest.java deleted file mode 100644 index 1b72697cc6..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/PrecedenceTest.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.mysema.query; - -import static org.junit.Assert.assertEquals; - -import org.junit.Test; - -import com.mysema.query.sql.Configuration; -import com.mysema.query.sql.SQLSerializer; -import com.mysema.query.types.expr.BooleanExpression; -import com.mysema.query.types.path.StringPath; - -public class PrecedenceTest { - - @Test - public void test() { - StringPath str1 = new StringPath("str1"); - StringPath str2 = new StringPath("str2"); - BooleanExpression pending = str1.eq("3").and(str2.eq("1")); - BooleanExpression notNew = str1.ne("1").and(str2.in("2", "3")); - BooleanExpression whereClause = str1.eq("a").and(pending.or(notNew)); - String str = new SQLSerializer(Configuration.DEFAULT).handle(whereClause).toString(); - assertEquals("str1 = ? and (str1 = ? and str2 = ? or str1 != ? and str2 in (?, ?))", str); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/Projection.java b/querydsl-sql/src/test/java/com/mysema/query/Projection.java deleted file mode 100644 index 8b6a4774ec..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/Projection.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query; - -import javax.annotation.Nullable; - -import com.mysema.query.types.Expression; - -public interface Projection { - - @Nullable - T get(Expression expr); - - @Nullable - T get(int index, Class type); - - @Nullable - Expression getExpr(Expression expr); - - @Nullable - Expression getExpr(int index, Class type); - - Object[] toArray(); - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/QBeanTest.java b/querydsl-sql/src/test/java/com/mysema/query/QBeanTest.java deleted file mode 100644 index 39198e1ff4..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/QBeanTest.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query; - -import com.mysema.query.sql.ColumnMetadata; -import com.mysema.query.sql.RelationalPathBase; -import com.mysema.query.types.PathMetadata; -import com.mysema.query.types.PathMetadataFactory; -import com.mysema.query.types.QBean; -import com.mysema.query.types.path.BeanPath; -import com.mysema.query.types.path.NumberPath; -import com.mysema.query.types.path.StringPath; -import org.junit.Test; -import static org.junit.Assert.assertEquals; - -public class QBeanTest { - -// @Table("PERSON") - public static class QPerson extends RelationalPathBase { - private static final long serialVersionUID = 609527362; - public static final QPerson person = new QPerson("PERSON"); - public final StringPath firstName = createString("firstName"); - public final NumberPath id = createNumber("id", Integer.class); - public final StringPath lastName = createString("lastName"); - - public QPerson(String variable) { - super(QPerson.class, PathMetadataFactory.forVariable(variable), "", "PERSON"); - addMetadata(); - } - - public QPerson(BeanPath entity) { - super(entity.getType(), entity.getMetadata(), "", "PERSON"); - addMetadata(); - } - - public QPerson(PathMetadata metadata) { - super(QPerson.class, metadata, "", "PERSON"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(firstName, ColumnMetadata.named("FIRST_NAME")); - addMetadata(lastName, ColumnMetadata.named("LAST_NAME")); - addMetadata(id, ColumnMetadata.named("ID")); - } - - } - - public static class Person { - private int id; - private String firstName; - private String lastName; - public int getId() { - return id; - } - public void setId(int id) { - this.id = id; - } - public String getFirstName() { - return firstName; - } - public void setFirstName(String firstName) { - this.firstName = firstName; - } - public String getLastName() { - return lastName; - } - public void setLastName(String lastName) { - this.lastName = lastName; - } - - } - - @Test - public void NewInstance() { - QPerson p = QPerson.person; - QBean projection = new QBean(Person.class, p.id, p.firstName.as("firstName"), p.lastName.as("lastName")); - - Person person = projection.newInstance(3, "John", "Doe"); - assertEquals(3, person.getId()); - assertEquals("John", person.getFirstName()); - assertEquals("Doe", person.getLastName()); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/QCompanies.java b/querydsl-sql/src/test/java/com/mysema/query/QCompanies.java deleted file mode 100644 index 97b804bbcf..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/QCompanies.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.mysema.query; - -import static com.mysema.query.types.PathMetadataFactory.forVariable; - -import javax.annotation.Generated; - -import com.mysema.query.sql.ColumnMetadata; -import com.mysema.query.types.Path; -import com.mysema.query.types.PathMetadata; -import com.mysema.query.types.path.NumberPath; -import com.mysema.query.types.path.StringPath; - - -/** - * QCompanies is a Querydsl query type for QCompanies - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class QCompanies extends com.mysema.query.sql.RelationalPathBase { - - private static final long serialVersionUID = 1808918375; - - public static final QCompanies companies = new QCompanies("COMPANIES"); - - public final NumberPath id = createNumber("id", Long.class); - - public final StringPath name = createString("name"); - - public final com.mysema.query.sql.PrimaryKey constraint5 = createPrimaryKey(id); - - public QCompanies(String variable) { - super(QCompanies.class, forVariable(variable), "PUBLIC", "COMPANIES"); - addMetadata(); - } - - public QCompanies(Path path) { - super(path.getType(), path.getMetadata(), "PUBLIC", "COMPANIES"); - addMetadata(); - } - - public QCompanies(PathMetadata metadata) { - super(QCompanies.class, metadata, "PUBLIC", "COMPANIES"); - addMetadata(); - } - - protected void addMetadata() { - addMetadata(id, ColumnMetadata.named("ID")); - addMetadata(name, ColumnMetadata.named("NAME")); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/QProjection.java b/querydsl-sql/src/test/java/com/mysema/query/QProjection.java deleted file mode 100644 index 30ba63390c..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/QProjection.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query; - -import java.util.Arrays; -import java.util.List; - -import com.mysema.query.types.Expression; -import com.mysema.query.types.ExpressionBase; -import com.mysema.query.types.FactoryExpression; -import com.mysema.query.types.Visitor; - -public class QProjection extends ExpressionBase implements FactoryExpression{ - - private static final long serialVersionUID = -7330905848558102164L; - - private final List> args; - - public QProjection(Expression... args) { - super(Projection.class); - this.args = Arrays.asList(args); - } - - @SuppressWarnings("unchecked") - @Override - public Projection newInstance(final Object... args) { - return new Projection() { - - @Override - public T get(int index, Class type) { - return (T) args[index]; - } - - @Override - public T get(Expression expr) { - int index = getArgs().indexOf(expr); - return index != -1 ? (T) args[index] : null; - } - - @Override - public Expression getExpr(Expression expr) { - T val = get(expr); - return val != null ? SimpleConstant.create(val) : null; - } - - @Override - public Expression getExpr(int index, Class type) { - T val = (T)args[index]; - return val != null ? SimpleConstant.create(val) : null; - } - - @Override - public Object[] toArray() { - return args; - } - - }; - } - - @Override - public List> getArgs() { - return args; - } - - @Override - public R accept(Visitor v, C context) { - return v.visit(this, context); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/QueryMutabilityTest.java b/querydsl-sql/src/test/java/com/mysema/query/QueryMutabilityTest.java deleted file mode 100644 index 13ad24ba85..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/QueryMutabilityTest.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query; - -import static org.junit.Assert.assertEquals; - -import java.io.IOException; -import java.lang.reflect.InvocationTargetException; -import java.sql.Connection; -import java.sql.SQLException; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.mysema.query.sql.DerbyTemplates; -import com.mysema.query.sql.SQLQuery; -import com.mysema.query.sql.domain.QSurvey; - -public class QueryMutabilityTest{ - - private static final QSurvey survey = new QSurvey("survey"); - - private Connection connection; - - @Before - public void setUp() throws Exception{ - Connections.initDerby(); - connection = Connections.getConnection(); - } - - @After - public void tearDown() throws SQLException{ - Connections.close(); - } - - @Test - public void test() throws IOException, SecurityException, - IllegalArgumentException, NoSuchMethodException, - IllegalAccessException, InvocationTargetException { - SQLQuery query = new SQLQuery(connection, new DerbyTemplates()); - query.from(survey); - new QueryMutability(query).test(survey.id, survey.name); - } - - @Test - public void Clone() { - SQLQuery query = new SQLQuery(new DerbyTemplates()).from(survey); - SQLQuery query2 = query.clone(connection); - assertEquals(query.getMetadata().getJoins(), query2.getMetadata().getJoins()); - assertEquals(query.getMetadata().getWhere(), query2.getMetadata().getWhere()); - query2.list(survey.id); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/QueryPerformanceTest.java b/querydsl-sql/src/test/java/com/mysema/query/QueryPerformanceTest.java deleted file mode 100644 index 56a5783c42..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/QueryPerformanceTest.java +++ /dev/null @@ -1,309 +0,0 @@ -package com.mysema.query; - -import static org.junit.Assert.assertNotNull; - -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; - -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.experimental.categories.Category; - -import com.mysema.commons.lang.CloseableIterator; -import com.mysema.query.sql.Configuration; -import com.mysema.query.sql.H2Templates; -import com.mysema.query.sql.SQLQuery; -import com.mysema.query.sql.SQLSerializer; -import com.mysema.query.sql.SQLTemplates; -import com.mysema.testutil.Benchmark; -import com.mysema.testutil.Performance; -import com.mysema.testutil.Runner; - -@Category(Performance.class) -public class QueryPerformanceTest { - - private static final String QUERY = "select COMPANIES.NAME\n" + - "from COMPANIES COMPANIES\n" + - "where COMPANIES.ID = ?"; - - private static final SQLTemplates templates = new H2Templates(); - - private static final Configuration conf = new Configuration(templates); - - private final Connection conn = Connections.getConnection(); - - @BeforeClass - public static void setUpClass() throws SQLException, ClassNotFoundException { - Connections.initH2(); - Connection conn = Connections.getConnection(); - Statement stmt = conn.createStatement(); - stmt.execute("create or replace table companies (id identity, name varchar(30) unique not null);"); - - PreparedStatement pstmt = conn.prepareStatement("insert into companies (name) values (?)"); - final int iterations = 1000000; - for (int i = 0; i < iterations; i++) { - pstmt.setString(1, String.valueOf(i)); - pstmt.execute(); - pstmt.clearParameters(); - } - pstmt.close(); - stmt.close(); - - conn.setAutoCommit(false); - } - - @AfterClass - public static void tearDownClass() throws SQLException { - Connection conn = Connections.getConnection(); - Statement stmt = conn.createStatement(); - stmt.execute("drop table companies"); - stmt.close(); - Connections.close(); - } - - - @Test - public void JDBC() throws Exception { - Runner.run("jdbc by id", new Benchmark() { - @Override - public void run(int times) throws Exception { - for (int i = 0; i < times; i++) { - PreparedStatement stmt = conn.prepareStatement(QUERY); - try { - stmt.setLong(1, i); - ResultSet rs = stmt.executeQuery(); - try { - while (rs.next()) { - rs.getString(1); - } - } finally { - rs.close(); - } - - } finally { - stmt.close(); - } - } - } - }); - } - - @Test - public void JDBC2() throws Exception { - Runner.run("jdbc by name", new Benchmark() { - @Override - public void run(int times) throws Exception { - for (int i = 0; i < times; i++) { - PreparedStatement stmt = conn.prepareStatement(QUERY); - try { - stmt.setString(1, String.valueOf(i)); - ResultSet rs = stmt.executeQuery(); - try { - while (rs.next()) { - rs.getString(1); - } - } finally { - rs.close(); - } - - } finally { - stmt.close(); - } - } - } - }); - } - - @Test - public void Querydsl1() throws Exception { - Runner.run("qdsl by id", new Benchmark() { - @Override - public void run(int times) throws Exception { - for (int i = 0; i < times; i++) { - QCompanies companies = QCompanies.companies; - SQLQuery query = new SQLQuery(conn, conf); - query.from(companies).where(companies.id.eq((long)i)) - .list(companies.name); - } - } - }); - } - - @Test - public void Querydsl12() throws Exception { - Runner.run("qdsl by id (iterated)", new Benchmark() { - @Override - public void run(int times) throws Exception { - for (int i = 0; i < times; i++) { - QCompanies companies = QCompanies.companies; - SQLQuery query = new SQLQuery(conn, conf); - CloseableIterator it = query.from(companies) - .where(companies.id.eq((long)i)).iterate(companies.name); - try { - while (it.hasNext()) { - it.next(); - } - } finally { - it.close(); - } - } - } - }); - } - - @Test - public void Querydsl13() throws Exception { - Runner.run("qdsl by id (result set access)", new Benchmark() { - @Override - public void run(int times) throws Exception { - for (int i = 0; i < times; i++) { - QCompanies companies = QCompanies.companies; - SQLQuery query = new SQLQuery(conn, conf); - ResultSet rs = query.from(companies) - .where(companies.id.eq((long)i)).getResults(companies.name); - try { - while (rs.next()) { - rs.getString(1); - } - } finally { - rs.close(); - } - } - } - }); - } - - @Test - public void Querydsl14() throws Exception { - Runner.run("qdsl by id (no validation)", new Benchmark() { - @Override - public void run(int times) throws Exception { - for (int i = 0; i < times; i++) { - QCompanies companies = QCompanies.companies; - SQLQuery query = new SQLQuery(conn, conf, new DefaultQueryMetadata().noValidate()); - query.from(companies).where(companies.id.eq((long)i)) - .list(companies.name); - } - } - }); - } - - @Test - public void Querydsl15() throws Exception { - Runner.run("qdsl by id (two cols)", new Benchmark() { - @Override - public void run(int times) throws Exception { - for (int i = 0; i < times; i++) { - QCompanies companies = QCompanies.companies; - SQLQuery query = new SQLQuery(conn, conf); - query.from(companies).where(companies.id.eq((long)i)) - .list(companies.id, companies.name); - } - } - }); - } - - @Test - public void Querydsl2() throws Exception { - Runner.run("qdsl by name", new Benchmark() { - @Override - public void run(int times) throws Exception { - for (int i = 0; i < times; i++) { - QCompanies companies = QCompanies.companies; - SQLQuery query = new SQLQuery(conn, conf); - query.from(companies).where(companies.name.eq(String.valueOf(i))) - .list(companies.name); - } - } - }); - } - - @Test - public void Querydsl22() throws Exception { - Runner.run("qdsl by name (iterated)", new Benchmark() { - @Override - public void run(int times) throws Exception { - for (int i = 0; i < times; i++) { - QCompanies companies = QCompanies.companies; - SQLQuery query = new SQLQuery(conn, conf); - CloseableIterator it = query.from(companies) - .where(companies.name.eq(String.valueOf(i))) - .iterate(companies.name); - try { - while (it.hasNext()) { - it.next(); - } - } finally { - it.close(); - } - } - } - }); - } - - @Test - public void Querydsl23() throws Exception { - Runner.run("qdsl by name (no validation)", new Benchmark() { - @Override - public void run(int times) throws Exception { - for (int i = 0; i < times; i++) { - QCompanies companies = QCompanies.companies; - SQLQuery query = new SQLQuery(conn, conf, new DefaultQueryMetadata().noValidate()); - query.from(companies) - .where(companies.name.eq(String.valueOf(i))) - .list(companies.name); - } - } - }); - } - - @Test - public void Serialization() throws Exception { - QCompanies companies = QCompanies.companies; - final QueryMetadata md = new DefaultQueryMetadata(); - md.addJoin(JoinType.DEFAULT, companies); - md.addWhere(companies.id.eq(1l)); - md.addProjection(companies.name); - - Runner.run("ser1", new Benchmark() { - @Override - public void run(int times) throws Exception { - for (int i = 0; i < times; i++) { - SQLSerializer serializer = new SQLSerializer(conf); - serializer.serialize(md, false); - serializer.getConstants(); - serializer.getConstantPaths(); - assertNotNull(serializer.toString()); - } - } - }); - } - - @Test - public void Serialization2() throws Exception { - QCompanies companies = QCompanies.companies; - final QueryMetadata md = new DefaultQueryMetadata(); - md.addJoin(JoinType.DEFAULT, companies); - md.addWhere(companies.id.eq(1l)); - md.addProjection(companies.name); - - Runner.run("ser2 (non normalized)", new Benchmark() { - @Override - public void run(int times) throws Exception { - for (int i = 0; i < times; i++) { - SQLSerializer serializer = new SQLSerializer(conf); - serializer.setNormalize(false); - serializer.serialize(md, false); - serializer.getConstants(); - serializer.getConstantPaths(); - assertNotNull(serializer.toString()); - } - } - }); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/SQLListenersTest.java b/querydsl-sql/src/test/java/com/mysema/query/SQLListenersTest.java deleted file mode 100644 index 2ff8c39cfc..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/SQLListenersTest.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.mysema.query; - -import static org.easymock.EasyMock.createMock; -import static org.easymock.EasyMock.replay; -import static org.easymock.EasyMock.verify; - -import org.junit.Test; - -import com.mysema.query.sql.SQLListener; -import com.mysema.query.sql.SQLListeners; - -public class SQLListenersTest { - - @Test - public void NotifyQuery() { - SQLListener listener = createMock(SQLListener.class); - SQLListeners listeners = new SQLListeners(); - listeners.add(listener); - - QueryMetadata md = new DefaultQueryMetadata(); - listener.notifyQuery(md); - replay(listener); - - listeners.notifyQuery(md); - verify(listener); - } - - @Test - public void NotifyQuery_Parent() { - SQLListener listener = createMock(SQLListener.class); - SQLListeners listeners = new SQLListeners(listener); - - QueryMetadata md = new DefaultQueryMetadata(); - listener.notifyQuery(md); - replay(listener); - - listeners.notifyQuery(md); - verify(listener); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/SelectBase.java b/querydsl-sql/src/test/java/com/mysema/query/SelectBase.java deleted file mode 100644 index 1b08628f01..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/SelectBase.java +++ /dev/null @@ -1,1523 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query; - -import java.io.*; -import java.math.BigDecimal; -import java.sql.Date; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.*; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.mysema.commons.lang.CloseableIterator; -import com.mysema.commons.lang.Pair; -import com.mysema.query.group.Group; -import com.mysema.query.group.GroupBy; -import com.mysema.query.sql.*; -import com.mysema.query.sql.domain.*; -import com.mysema.query.support.Expressions; -import com.mysema.query.types.*; -import com.mysema.query.types.expr.*; -import com.mysema.query.types.path.NumberPath; -import com.mysema.query.types.path.PathBuilder; -import com.mysema.query.types.path.StringPath; -import com.mysema.query.types.query.NumberSubQuery; -import com.mysema.query.types.template.NumberTemplate; -import com.mysema.testutil.ExcludeIn; -import com.mysema.testutil.IncludeIn; -import junit.framework.Assert; -import org.joda.time.DateTime; -import org.joda.time.LocalDate; -import org.joda.time.LocalDateTime; -import org.joda.time.LocalTime; -import org.junit.Ignore; -import org.junit.Test; -import static com.mysema.query.Constants.*; -import static com.mysema.query.Target.*; -import static org.junit.Assert.*; - -public class SelectBase extends AbstractBaseTest { - - private static final Expression[] NO_EXPRESSIONS = new Expression[0]; - - private final QueryExecution standardTest = new QueryExecution(Module.SQL, Connections.getTarget()) { - @Override - protected Pair[]> createQuery() { - return Pair.of( - (Projectable)testQuery().from(employee, employee2), - NO_EXPRESSIONS); - } - @Override - protected Pair[]> createQuery(Predicate filter) { - return Pair.of( - (Projectable)testQuery().from(employee, employee2).where(filter), - new Expression[]{employee.firstname}); - } - }; - - private T singleResult(Expression expr) { - return query().singleResult(expr); - } - - @Test - public void Aggregate_List() { - int min = 30000, avg = 65000, max = 160000; - // list - assertEquals(min, query().from(employee).list(employee.salary.min()).get(0).intValue()); - assertEquals(avg, query().from(employee).list(employee.salary.avg()).get(0).intValue()); - assertEquals(max, query().from(employee).list(employee.salary.max()).get(0).intValue()); - } - - @Test - public void Aggregate_UniqueResult() { - int min = 30000, avg = 65000, max = 160000; - // uniqueResult - assertEquals(min, query().from(employee).uniqueResult(employee.salary.min()).intValue()); - assertEquals(avg, query().from(employee).uniqueResult(employee.salary.avg()).intValue()); - assertEquals(max, query().from(employee).uniqueResult(employee.salary.max()).intValue()); - } - - @Test - @ExcludeIn({MYSQL, ORACLE}) - @SkipForQuoted - public void Alias_Quotes() { - expectedQuery = "select e.FIRSTNAME as \"First Name\" from EMPLOYEE e"; - query().from(employee).list(employee.firstname.as("First Name")); - } - - @Test - @IncludeIn(MYSQL) - @SkipForQuoted - public void Alias_Quotes_MySQL() { - expectedQuery = "select e.FIRSTNAME as `First Name` from EMPLOYEE e"; - query().from(employee).list(employee.firstname.as("First Name")); - } - - @Test - @IncludeIn(ORACLE) - @SkipForQuoted - public void Alias_Quotes_Oracle() { - expectedQuery = "select e.FIRSTNAME \"First Name\" from EMPLOYEE e"; - query().from(employee).list(employee.firstname.as("First Name")); - } - - @Test - public void All() { - for (Expression expr : survey.all()) { - Path path = (Path)expr; - assertEquals(survey, path.getMetadata().getParent()); - } - } - - @Test - public void Array_Projection() { - List results = query().from(employee).list( - new ArrayConstructorExpression(String[].class, employee.firstname)); - assertFalse(results.isEmpty()); - for (String[] result : results) { - assertNotNull(result[0]); - } - } - - @Test - public void Beans() { - QEmployee EMPLOYEE = new QEmployee("EMPLOYEE"); - List rows = query().from(employee, EMPLOYEE).list(new QBeans(employee, EMPLOYEE)); - assertFalse(rows.isEmpty()); - for (Beans row : rows) { - assertEquals(Employee.class, row.get(employee).getClass()); - assertEquals(Employee.class, row.get(EMPLOYEE).getClass()); - } - } - - @Test - @ExcludeIn({ORACLE, CUBRID, DERBY, SQLSERVER, SQLITE, TERADATA}) - public void Boolean_All() { - assertTrue(query().from(employee).uniqueResult(SQLExpressions.all(employee.firstname.isNotNull()))); - } - - @Test - @ExcludeIn({ORACLE, CUBRID, DERBY, SQLSERVER, SQLITE, TERADATA}) - public void Boolean_Any() { - assertTrue(query().from(employee).uniqueResult(SQLExpressions.any(employee.firstname.isNotNull()))); - } - - @Test - public void Casts() throws SQLException { - NumberExpression num = employee.id; - List> exprs = Lists.newArrayList(); - - add(exprs, num.byteValue(), MYSQL); - add(exprs, num.doubleValue()); - add(exprs, num.floatValue()); - add(exprs, num.intValue()); - add(exprs, num.longValue(), MYSQL); - add(exprs, num.shortValue(), MYSQL); - add(exprs, num.stringValue(), DERBY); - - for (Expression expr : exprs) { - for (Object o : query().from(employee).list(expr)) { - assertEquals(expr.getType(), o.getClass()); - } - } - } - - @Test - public void Coalesce() { - Coalesce c = new Coalesce(employee.firstname, employee.lastname).add("xxx"); - query().from(employee).where(c.getValue().eq("xxx")).list(employee.id); - } - - @Test - public void Compact_Join() { - // verbose - query().from(employee).innerJoin(employee2) - .on(employee.superiorId.eq(employee2.id)) - .list(employee.id, employee2.id); - - // compact - query().from(employee) - .innerJoin(employee.superiorIdKey, employee2) - .list(employee.id, employee2.id); - - } - - @Test - public void Complex_Boolean() { - BooleanExpression first = employee.firstname.eq("Mike").and(employee.lastname.eq("Smith")); - BooleanExpression second = employee.firstname.eq("Joe").and(employee.lastname.eq("Divis")); - assertEquals(2, query().from(employee).where(first.or(second)).count()); - - assertEquals(0, query().from(employee).where( - employee.firstname.eq("Mike"), - employee.lastname.eq("Smith").or(employee.firstname.eq("Joe")), - employee.lastname.eq("Divis") - ).count()); - } - - @Test - public void Complex_SubQuery() { - // alias for the salary - NumberPath sal = new NumberPath(BigDecimal.class, "sal"); - // alias for the subquery - PathBuilder sq = new PathBuilder(Object[].class, "sq"); - // query execution - query().from( - sq().from(employee) - .list(employee.salary.add(employee.salary).add(employee.salary).as(sal)).as(sq) - ).list(sq.get(sal).avg(), sq.get(sal).min(), sq.get(sal).max()); - } - - @Test - public void Constructor() throws Exception { - for (IdName idName : query().from(survey).list(new QIdName(survey.id, survey.name))) { - System.out.println("id and name : " + idName.getId() + ","+ idName.getName()); - } - } - - @Test - public void Constructor_Projection() { - // constructor projection - for (IdName idAndName : query().from(survey).list(new QIdName(survey.id, survey.name))) { - assertNotNull(idAndName); - assertNotNull(idAndName.getId()); - assertNotNull(idAndName.getName()); - } - } - - @Test - public void Constructor_Projection2() { - List projections =query().from(employee).list( - ConstructorExpression.create(SimpleProjection.class, - employee.firstname, employee.lastname)); - assertFalse(projections.isEmpty()); - for (SimpleProjection projection : projections) { - assertNotNull(projection); - } - } - - private double cot(double x) { - return Math.cos(x) / Math.sin(x); - } - - private double coth(double x) { - return Math.cosh(x) / Math.sinh(x); - } - - @Test - public void Count_With_PK() { - query().from(employee).count(); - } - - @Test - public void Count_Without_PK() { - query().from(QEmployeeNoPK.employee).count(); - } - - @Test - public void Count2() { - query().from(employee).singleResult(employee.count()); - } - - @Test - @SkipForQuoted - @ExcludeIn(ORACLE) - public void Count_All() { - expectedQuery = "select count(*) as rc from EMPLOYEE e"; - NumberPath rowCount = new NumberPath(Long.class, "rc"); - query().from(employee).uniqueResult(Wildcard.count.as(rowCount)); - } - - @Test - @SkipForQuoted - @IncludeIn(ORACLE) - public void Count_All_Oracle() { - expectedQuery = "select count(*) rc from EMPLOYEE e"; - NumberPath rowCount = new NumberPath(Long.class, "rc"); - query().from(employee).uniqueResult(Wildcard.count.as(rowCount)); - } - - @Test - public void Count_Distinct_With_PK() { - query().from(employee).distinct().count(); - } - - @Test - public void Count_Distinct_Without_PK() { - query().from(QEmployeeNoPK.employee).distinct().count(); - } - - @Test - public void Count_Distinct2() { - query().from(employee).singleResult(employee.countDistinct()); - } - - @Test - public void Custom_Projection() { - List tuples = query().from(employee).list( - new QProjection(employee.firstname, employee.lastname)); - assertFalse(tuples.isEmpty()); - for (Projection tuple : tuples) { - assertNotNull(tuple.get(employee.firstname)); - assertNotNull(tuple.get(employee.lastname)); - assertNotNull(tuple.getExpr(employee.firstname)); - assertNotNull(tuple.getExpr(employee.lastname)); - } - } - - @Test - @IncludeIn({H2, SQLSERVER, MYSQL, ORACLE, TERADATA}) // TODO fix postgres - public void Dates() { - long ts = ((long)Math.floor(System.currentTimeMillis() / 1000)) * 1000; - long tsDate = new org.joda.time.LocalDate(ts).toDateMidnight().getMillis(); - long tsTime = new org.joda.time.LocalTime(ts).getMillisOfDay(); - - List data = Lists.newArrayList(); - data.add(Constants.date); - data.add(Constants.time); - data.add(new java.util.Date(ts)); - data.add(new java.util.Date(tsDate)); - data.add(new java.util.Date(tsTime)); - data.add(new java.sql.Timestamp(ts)); - data.add(new java.sql.Timestamp(tsDate)); - data.add(new java.sql.Date(110, 0, 1)); - data.add(new java.sql.Date(tsDate)); - data.add(new java.sql.Time(0, 0, 0)); - data.add(new java.sql.Time(12, 30, 0)); - data.add(new java.sql.Time(23, 59, 59)); - //data.add(new java.sql.Time(tsTime)); - data.add(new DateTime(ts)); - data.add(new DateTime(tsDate)); - data.add(new DateTime(tsTime)); - data.add(new LocalDateTime(ts)); - data.add(new LocalDateTime(tsDate)); - data.add(new LocalDateTime(2014, 3, 30, 2, 0)); - data.add(new LocalDate(2010, 1, 1)); - data.add(new LocalDate(ts)); - data.add(new LocalDate(tsDate)); - data.add(new LocalTime(0, 0, 0)); - data.add(new LocalTime(12, 30, 0)); - data.add(new LocalTime(23, 59, 59)); - data.add(new LocalTime(ts)); - data.add(new LocalTime(tsTime)); - - Map failures = Maps.newIdentityHashMap(); - for (Object dt : data) { - Object dt2 = query().singleResult(new ConstantImpl(dt)); - if (!dt.equals(dt2)) { - failures.put(dt, dt2); - } - } - if (!failures.isEmpty()) { - for (Map.Entry entry : failures.entrySet()) { - System.out.println(entry.getKey().getClass().getName() - + ": " + entry.getKey() + " != " + entry.getValue()); - } - Assert.fail("Failed with " + failures); - } - } - - @Test - @ExcludeIn({SQLITE}) - public void Date_Add() { - TestQuery query = query().from(employee); - Date date1 = query.singleResult(employee.datefield); - Date date2 = query.singleResult(SQLExpressions.addYears(employee.datefield, 1)); - Date date3 = query.singleResult(SQLExpressions.addMonths(employee.datefield, 1)); - Date date4 = query.singleResult(SQLExpressions.addDays(employee.datefield, 1)); - - assertTrue(date2.getTime() > date1.getTime()); - assertTrue(date3.getTime() > date1.getTime()); - assertTrue(date4.getTime() > date1.getTime()); - } - - @Test - @ExcludeIn({SQLITE}) - public void Date_Add_Timestamp() { - List> exprs = Lists.newArrayList(); - DateTimeExpression dt = Expressions.currentTimestamp(); - - add(exprs, SQLExpressions.addYears(dt, 1)); - add(exprs, SQLExpressions.addMonths(dt, 1)); - add(exprs, SQLExpressions.addDays(dt, 1)); - add(exprs, SQLExpressions.addHours(dt, 1)); - add(exprs, SQLExpressions.addMinutes(dt, 1)); - add(exprs, SQLExpressions.addSeconds(dt, 1)); - - for (Expression expr : exprs) { - assertNotNull(query().singleResult(expr)); - } - } - - @Test - @ExcludeIn({CUBRID, SQLITE, TERADATA}) - public void Date_Diff() { - QEmployee employee2 = new QEmployee("employee2"); - TestQuery query = query().from(employee, employee2); - - List dps = Lists.newArrayList(); - add(dps, DatePart.year); - add(dps, DatePart.month); - add(dps, DatePart.week); - add(dps, DatePart.day); - add(dps, DatePart.hour, HSQLDB); - add(dps, DatePart.minute, HSQLDB); - add(dps, DatePart.second, HSQLDB); - - Date date = new Date(0); - for (DatePart dp : dps) { - query.singleResult(SQLExpressions.datediff(dp, employee.datefield, employee2.datefield)); - query.singleResult(SQLExpressions.datediff(dp, employee.datefield, date)); - query.singleResult(SQLExpressions.datediff(dp, date, employee.datefield)); - } - } - - @Test - @ExcludeIn({CUBRID, DERBY, HSQLDB, SQLITE, TERADATA}) - public void Date_Diff2() { - TestQuery query = query().from(employee).orderBy(employee.id.asc()); - int offset = TimeZone.getDefault().getOffset(0); - Date date = new java.sql.Date(-offset); - - int years = query.singleResult(SQLExpressions.datediff(DatePart.year, date, employee.datefield)); - int months = query.singleResult(SQLExpressions.datediff(DatePart.month, date, employee.datefield)); - // weeks - int days = query.singleResult(SQLExpressions.datediff(DatePart.day, date, employee.datefield)); - int hours = query.singleResult(SQLExpressions.datediff(DatePart.hour, date, employee.datefield)); - int minutes = query.singleResult(SQLExpressions.datediff(DatePart.minute, date, employee.datefield)); - int seconds = query.singleResult(SQLExpressions.datediff(DatePart.second, date, employee.datefield)); - - assertEquals(949449600, seconds); - assertEquals(15824160, minutes); - assertEquals(263736, hours); - assertEquals(10989, days); - assertEquals(361, months); - assertEquals(30, years); - } - - @Test - @ExcludeIn({CUBRID, DERBY, H2, HSQLDB, MYSQL, SQLITE, SQLSERVER, TERADATA}) // FIXME - public void Date_Trunc() { - DateTimeExpression expr = DateTimeExpression.currentTimestamp(); - - List dps = Lists.newArrayList(); - add(dps, DatePart.year); - add(dps, DatePart.month); - add(dps, DatePart.week); - add(dps, DatePart.day); - add(dps, DatePart.hour); - add(dps, DatePart.minute); - add(dps, DatePart.second); - - for (DatePart dp : dps) { - query().singleResult(SQLExpressions.datetrunc(dp, expr)); - } - } - - @Test - public void DateTime() { - TestQuery query = query().from(employee).orderBy(employee.id.asc()); - assertEquals(Integer.valueOf(2), query.singleResult(employee.datefield.dayOfMonth())); - assertEquals(Integer.valueOf(2), query.singleResult(employee.datefield.month())); - assertEquals(Integer.valueOf(2000), query.singleResult(employee.datefield.year())); - assertEquals(Integer.valueOf(200002), query.singleResult(employee.datefield.yearMonth())); - } - - @Test - @ExcludeIn(CUBRID) - public void DateTime_To_Date() { - query().singleResult(SQLExpressions.date(DateTimeExpression.currentTimestamp())); - } - - private double degrees(double x) { - return x * 180.0 / Math.PI; - } - - @Test - public void Distinct_Count() { - long count1 = query().from(employee).distinct().count(); - long count2 = query().from(employee).distinct().count(); - assertEquals(count1, count2); - } - - @Test - public void Distinct_List() { - List lengths1 = query().from(employee).distinct().list(employee.firstname.length()); - List lengths2 = query().from(employee).distinct().list(employee.firstname.length()); - assertEquals(lengths1, lengths2); - } - - @Test - public void Exists() { - assertTrue(query().from(employee).where(employee.firstname.eq("Barbara")).exists()); - } - - @Test - public void FactoryExpression_In_GroupBy() { - Expression empBean = Projections.bean(Employee.class, employee.id, employee.superiorId); - assertFalse(query().from(employee).groupBy(empBean).list(empBean).isEmpty()); - } - - @Test - @ExcludeIn({H2, SQLITE, DERBY, CUBRID, MYSQL}) - public void Full_Join() throws SQLException { - query().from(employee).fullJoin(employee2) - .on(employee.superiorIdKey.on(employee2)) - .list(employee.id, employee2.id); - } - - @Test - public void GetResultSet() throws IOException, SQLException{ - ResultSet results = query().from(survey).getResults(survey.id, survey.name); - while(results.next()) { - System.out.println(results.getInt(1) +","+results.getString(2)); - } - results.close(); - } - - @Test - public void GroupBy_Superior() { - TestQuery qry = query() - .from(employee) - .innerJoin(employee._superiorIdKey, employee2); - - QTuple subordinates = new QTuple(employee2.id, employee2.firstname, employee2.lastname); - - Map results = qry.transform( - GroupBy.groupBy(employee.id).as(employee.firstname, employee.lastname, - GroupBy.map(employee2.id, subordinates))); - - assertEquals(2, results.size()); - - // Mike Smith - Group group = results.get(1); - assertEquals("Mike", group.getOne(employee.firstname)); - assertEquals("Smith", group.getOne(employee.lastname)); - - Map emps = group.getMap(employee2.id, subordinates); - assertEquals(4, emps.size()); - assertEquals("Steve", emps.get(12).get(employee2.firstname)); - - // Mary Smith - group = results.get(2); - assertEquals("Mary", group.getOne(employee.firstname)); - assertEquals("Smith", group.getOne(employee.lastname)); - - emps = group.getMap(employee2.id, subordinates); - assertEquals(4, emps.size()); - assertEquals("Mason", emps.get(21).get(employee2.lastname)); - } - - @Test - public void GroupBy_YearMonth() { - query().from(employee) - .groupBy(employee.datefield.yearMonth()) - .orderBy(employee.datefield.yearMonth().asc()) - .list(employee.id.count()); - } - - @SuppressWarnings("unchecked") - @Test(expected=IllegalArgumentException.class) - public void IllegalUnion() throws SQLException { - SubQueryExpression sq1 = sq().from(employee).unique(employee.id.max()); - SubQueryExpression sq2 = sq().from(employee).unique(employee.id.max()); - query().from(employee).union(sq1, sq2).list(); - } - - @Test - public void In() { - query().from(employee).where(employee.id.in(Arrays.asList(1,2))).list(employee); - } - - @Test - public void Inner_Join() throws SQLException { - query().from(employee).innerJoin(employee2) - .on(employee.superiorIdKey.on(employee2)) - .list(employee.id, employee2.id); - } - - @Test - public void Inner_Join_2Conditions() { - query().from(employee).innerJoin(employee2) - .on(employee.superiorIdKey.on(employee2)) - .on(employee2.firstname.isNotNull()) - .list(employee.id, employee2.id); - } - - @Test - public void Join() throws Exception { - for (String name : query().from(survey, survey2) - .where(survey.id.eq(survey2.id)).list(survey.name)) { - System.out.println(name); - } - } - - @Test - public void Joins() throws SQLException { - for (Tuple row : query().from(employee).innerJoin(employee2) - .on(employee.superiorId.eq(employee2.superiorId)) - .where(employee2.id.eq(10)) - .list(employee.id, employee2.id)) { - System.out.println(row.get(employee.id) + ", " + row.get(employee2.id)); - } - } - - @Test - public void Left_Join() throws SQLException { - query().from(employee).leftJoin(employee2) - .on(employee.superiorIdKey.on(employee2)) - .list(employee.id, employee2.id); - } - - @Test - public void Like() { - query().from(employee).where(employee.firstname.like("\\")).count(); - query().from(employee).where(employee.firstname.like("\\\\")).count(); - } - - @Test - public void Like_Escape() { - List strs = ImmutableList.of("%a", "a%", "%a%", "_a", "a_", "_a_", "[C-P]arsen"); - - for (String str : strs) { - assertTrue(str, query() - .from(employee) - .where(Expressions.stringTemplate("'" + str + "'").contains(str)).count() > 0); - } - } - - @Test - @ExcludeIn(DERBY) - public void Like_Number() { - assertEquals(5, query().from(employee) - .where(employee.id.like("1%")).count()); - } - - @Test - public void Limit() throws SQLException { - query().from(employee) - .orderBy(employee.firstname.asc()) - .limit(4).list(employee.id); - } - - @Test - public void Limit_and_Offset() throws SQLException { - assertEquals(Arrays.asList(20, 13, 10, 2), - query().from(employee) - .orderBy(employee.firstname.asc()) - .limit(4).offset(3) - .list(employee.id)); - } - - @Test - public void Limit_and_Offset_and_Order() { - List names2 = Arrays.asList("Helen","Jennifer","Jim","Joe"); - assertEquals(names2, query().from(employee) - .orderBy(employee.firstname.asc()) - .limit(4).offset(2) - .list(employee.firstname)); - } - - @Test - @IncludeIn(DERBY) - public void Limit_and_Offset_In_Derby() throws SQLException { - expectedQuery = "select e.ID from EMPLOYEE e offset 3 rows fetch next 4 rows only"; - query().from(employee).limit(4).offset(3).list(employee.id); - - // limit - expectedQuery = "select e.ID from EMPLOYEE e fetch first 4 rows only"; - query().from(employee).limit(4).list(employee.id); - - // offset - expectedQuery = "select e.ID from EMPLOYEE e offset 3 rows"; - query().from(employee).offset(3).list(employee.id); - - } - - @Test - @IncludeIn(ORACLE) - @SkipForQuoted - public void Limit_and_Offset_In_Oracle() throws SQLException { - if (configuration.getUseLiterals()) return; - - // limit - expectedQuery = "select * from ( select e.ID from EMPLOYEE e ) where rownum <= ?"; - query().from(employee).limit(4).list(employee.id); - - // offset - expectedQuery = "select * from ( select a.*, rownum rn from ( select e.ID from EMPLOYEE e ) a) where rn > ?"; - query().from(employee).offset(3).list(employee.id); - - // limit offset - expectedQuery = "select * from ( select a.*, rownum rn from ( select e.ID from EMPLOYEE e ) a) where rn > 3 and rownum <= 4"; - query().from(employee).limit(4).offset(3).list(employee.id); - } - - @Test - @ExcludeIn({ORACLE, DERBY, SQLSERVER, CUBRID, TERADATA}) - @SkipForQuoted - public void Limit_and_Offset2() throws SQLException { - // limit - expectedQuery = "select e.ID from EMPLOYEE e limit ?"; - query().from(employee).limit(4).list(employee.id); - - // limit offset - expectedQuery = "select e.ID from EMPLOYEE e limit ? offset ?"; - query().from(employee).limit(4).offset(3).list(employee.id); - - } - - @Test - public void Limit_and_Order() { - List names1 = Arrays.asList("Barbara","Daisy","Helen","Jennifer"); - assertEquals(names1, query().from(employee) - .orderBy(employee.firstname.asc()) - .limit(4) - .list(employee.firstname)); - } - - @Test - public void ListResults() { - SearchResults results = query().from(employee) - .limit(10).offset(1).orderBy(employee.id.asc()) - .listResults(employee.id); - assertEquals(10, results.getTotal()); - } - - @Test - public void ListResults2() { - SearchResults results = query().from(employee) - .limit(2).offset(10).orderBy(employee.id.asc()) - .listResults(employee.id); - assertEquals(10, results.getTotal()); - } - - @Test - public void ListResults_FactoryExpression() { - SearchResults results = query().from(employee) - .limit(10).offset(1).orderBy(employee.id.asc()) - .listResults(employee); - assertEquals(10, results.getTotal()); - } - - private double log(double x, int y) { - return Math.log(x) / Math.log(y); - } - - @Test - @ExcludeIn({SQLITE, SQLSERVER, DERBY}) - public void LPad() { - assertEquals(" ab", singleResult(StringExpressions.lpad(ConstantImpl.create("ab"), 4))); - assertEquals("!!ab", singleResult(StringExpressions.lpad(ConstantImpl.create("ab"), 4, '!'))); - } - - - @Test - public void Map() { - Map idToName = query().from(employee).map(employee.id.as("id"), employee.firstname); - for (Map.Entry entry : idToName.entrySet()) { - assertNotNull(entry.getKey()); - assertNotNull(entry.getValue()); - } - } - - @Test - @SuppressWarnings("serial") - public void MappingProjection() { - List> pairs = query().from(employee) - .list(new MappingProjection>(Pair.class, - employee.firstname, employee.lastname) { - @Override - protected Pair map(Tuple row) { - return Pair.of(row.get(employee.firstname), row.get(employee.lastname)); - } - }); - - for (Pair pair : pairs) { - assertNotNull(pair.getFirst()); - assertNotNull(pair.getSecond()); - } - } - - @Test - @ExcludeIn(SQLSERVER) // FIXME - public void Math() { - Expression expr = Expressions.numberTemplate(Double.class, "0.5"); - - assertEquals(Math.acos(0.5), singleResult(MathExpressions.acos(expr)), 0.001); - assertEquals(Math.asin(0.5), singleResult(MathExpressions.asin(expr)), 0.001); - assertEquals(Math.atan(0.5), singleResult(MathExpressions.atan(expr)), 0.001); - assertEquals(Math.cos(0.5), singleResult(MathExpressions.cos(expr)), 0.001); - assertEquals(Math.cosh(0.5), singleResult(MathExpressions.cosh(expr)), 0.001); - assertEquals(cot(0.5), singleResult(MathExpressions.cot(expr)), 0.001); - assertEquals(coth(0.5), singleResult(MathExpressions.coth(expr)), 0.001); - assertEquals(degrees(0.5), singleResult(MathExpressions.degrees(expr)), 0.001); - assertEquals(Math.exp(0.5), singleResult(MathExpressions.exp(expr)), 0.001); - assertEquals(Math.log(0.5), singleResult(MathExpressions.ln(expr)), 0.001); - assertEquals(log(0.5, 10), singleResult(MathExpressions.log(expr, 10)), 0.001); - assertEquals(0.25, singleResult(MathExpressions.power(expr, 2)), 0.001); - assertEquals(radians(0.5), singleResult(MathExpressions.radians(expr)), 0.001); - assertEquals(Integer.valueOf(1), - singleResult(MathExpressions.sign(expr))); - assertEquals(Math.sin(0.5), singleResult(MathExpressions.sin(expr)), 0.001); - assertEquals(Math.sinh(0.5), singleResult(MathExpressions.sinh(expr)), 0.001); - assertEquals(Math.tan(0.5), singleResult(MathExpressions.tan(expr)), 0.001); - assertEquals(Math.tanh(0.5), singleResult(MathExpressions.tanh(expr)), 0.001); - } - - @Test - public void Nested_Tuple_Projection() { - Concatenation concat = new Concatenation(employee.firstname, employee.lastname); - List tuples = query().from(employee) - .list(new QTuple(employee.firstname, employee.lastname, concat)); - assertFalse(tuples.isEmpty()); - for (Tuple tuple : tuples) { - String firstName = tuple.get(employee.firstname); - String lastName = tuple.get(employee.lastname); - assertEquals(firstName + lastName, tuple.get(concat)); - } - } - - - @Test - public void No_From() { - assertNotNull(query().singleResult(DateExpression.currentDate())); - } - - @Test - public void NotExists() { - assertTrue(query().from(employee).where(employee.firstname.eq("Barb")).notExists()); - } - - @Test - public void Nullif() { - query().from(employee).list(employee.firstname.nullif(employee.lastname)); - } - - @Test - public void Nullif_Constant() { - query().from(employee).list(employee.firstname.nullif("xxx")); - } - - @Test - public void Offset_Only() { - query().from(employee) - .orderBy(employee.firstname.asc()) - .offset(3).list(employee.id); - } - - @Test - public void Operation_in_Constant_list() { - query().from(survey).where(survey.name.charAt(0).in(Arrays.asList('a'))).count(); - query().from(survey).where(survey.name.charAt(0).in(Arrays.asList('a','b'))).count(); - query().from(survey).where(survey.name.charAt(0).in(Arrays.asList('a','b','c'))).count(); - } - - @Test - @ExcludeIn(CUBRID) - public void Order_NullsFirst() { - query().from(survey) - .orderBy(survey.name.asc().nullsFirst()) - .list(survey.name); - } - - @Test - @ExcludeIn(CUBRID) - public void Order_NullsLast() { - query().from(survey) - .orderBy(survey.name.asc().nullsLast()) - .list(survey.name); - } - - @Test - public void Params() { - Param name = new Param(String.class,"name"); - assertEquals("Mike",query() - .from(employee).where(employee.firstname.eq(name)) - .set(name, "Mike") - .uniqueResult(employee.firstname)); - } - - @Test - public void Params_anon() { - Param name = new Param(String.class); - assertEquals("Mike",query() - .from(employee).where(employee.firstname.eq(name)) - .set(name, "Mike") - .uniqueResult(employee.firstname)); - } - - @Test(expected=ParamNotSetException.class) - public void Params_not_set() { - Param name = new Param(String.class,"name"); - assertEquals("Mike",query() - .from(employee).where(employee.firstname.eq(name)) - .uniqueResult(employee.firstname)); - } - - @Test - @ExcludeIn({DERBY, HSQLDB, ORACLE, SQLSERVER}) - @SkipForQuoted - public void Path_Alias() { - expectedQuery = "select e.LASTNAME, sum(e.SALARY) as salarySum " + - "from EMPLOYEE e " + - "group by e.LASTNAME having salarySum > ?"; - - NumberExpression salarySum = employee.salary.sum().as("salarySum"); - query().from(employee) - .groupBy(employee.lastname) - .having(salarySum.gt(10000)) - .list(employee.lastname, salarySum); - } - - @Test - public void Path_in_Constant_list() { - query().from(survey).where(survey.name.in(Arrays.asList("a"))).count(); - query().from(survey).where(survey.name.in(Arrays.asList("a","b"))).count(); - query().from(survey).where(survey.name.in(Arrays.asList("a","b","c"))).count(); - } - - @Test - public void Precedence() { - StringPath fn = employee.firstname; - StringPath ln = employee.lastname; - Predicate where = fn.eq("Mike").and(ln.eq("Smith")).or(fn.eq("Joe").and(ln.eq("Divis"))); - assertEquals(2l, query().from(employee).where(where).count()); - } - - @Test - public void Precedence2() { - StringPath fn = employee.firstname; - StringPath ln = employee.lastname; - Predicate where = fn.eq("Mike").and(ln.eq("Smith").or(fn.eq("Joe")).and(ln.eq("Divis"))); - assertEquals(0l, query().from(employee).where(where).count()); - } - - @Test - public void Projection() throws IOException{ - CloseableIterator results = query().from(survey).iterate(survey.all()); - assertTrue(results.hasNext()); - while (results.hasNext()) { - assertEquals(3, results.next().size()); - } - results.close(); - } - - @Test - public void Projection_and_TwoColumns() { - // projection and two columns - for (Tuple row : query().from(survey) - .list(new QIdName(survey.id, survey.name), survey.id, survey.name)) { - assertEquals(3, row.size()); - assertEquals(IdName.class, row.get(0, Object.class).getClass()); - assertEquals(Integer.class, row.get(1, Object.class).getClass()); - assertEquals(String.class, row.get(2, Object.class).getClass()); - } - } - - @Test - public void Projection2() throws IOException{ - // TODO : add assertions - CloseableIterator results = query().from(survey).iterate(survey.id, survey.name); - assertTrue(results.hasNext()); - while (results.hasNext()) { - assertEquals(2, results.next().size()); - } - results.close(); - } - - @Test - public void Projection3() throws IOException{ - CloseableIterator names = query().from(survey).iterate(survey.name); - assertTrue(names.hasNext()); - while (names.hasNext()) { - System.out.println(names.next()); - } - names.close(); - } - - @Test - public void QBeanUsage() { - PathBuilder sq = new PathBuilder(Object[].class, "sq"); - List surveys = - query().from( - sq().from(survey).list(survey.all()).as("sq")) - .list(new QBean(Survey.class, Collections.singletonMap("name", sq.get(survey.name)))); - assertFalse(surveys.isEmpty()); - - } - - @Test - public void Query_with_Constant() throws Exception { - for (Tuple row : query().from(survey) - .where(survey.id.eq(1)) - .list(survey.id, survey.name)) { - System.out.println(row.get(survey.id) + ", " + row.get(survey.name)); - } - } - - @Test - public void Query1() throws Exception { - for (String s : query().from(survey).list(survey.name)) { - System.out.println(s); - } - } - - @Test - public void Query2() throws Exception { - for (Tuple row : query().from(survey).list(survey.id, survey.name)) { - System.out.println(row.get(survey.id) + ", " + row.get(survey.name)); - } - } - - private double radians(double x) { - return x * Math.PI / 180.0; - } - - @Test - public void Random() { - query().uniqueResult(MathExpressions.random()); - } - - @Test - @ExcludeIn({ORACLE, POSTGRES, SQLITE, TERADATA}) - public void Random2() { - query().uniqueResult(MathExpressions.random(10)); - } - - @Test - public void RelationalPath_Projection() { - List results = query().from(employee, employee2).where(employee.id.eq(employee2.id)) - .list(employee, employee2); - assertFalse(results.isEmpty()); - for (Tuple row : results) { - Employee e1 = row.get(employee); - Employee e2 = row.get(employee2); - assertEquals(e1.getId(), e2.getId()); - } - } - - @Test - @ExcludeIn(SQLITE) - public void Right_Join() throws SQLException { - query().from(employee).rightJoin(employee2) - .on(employee.superiorIdKey.on(employee2)) - .list(employee.id, employee2.id); - } - - @Test - @ExcludeIn({DERBY, SQLSERVER}) - public void Round() { - Expression expr = Expressions.numberTemplate(Double.class, "1.32"); - - assertEquals(Double.valueOf(1.0), singleResult(MathExpressions.round(expr))); - assertEquals(Double.valueOf(1.3), singleResult(MathExpressions.round(expr, 1))); - } - - @Test - @ExcludeIn({SQLITE, SQLSERVER, DERBY}) - public void Rpad() { - assertEquals("ab ", singleResult(StringExpressions.rpad(ConstantImpl.create("ab"), 4))); - assertEquals("ab!!", singleResult(StringExpressions.rpad(ConstantImpl.create("ab"), 4,'!'))); - } - - @Test - @Ignore - @ExcludeIn({ORACLE, DERBY, SQLSERVER}) - public void Select_BooleanExpr() throws SQLException { - // TODO : FIXME - System.out.println(query().from(survey).list(survey.id.eq(0))); - } - - @Test - @Ignore - @ExcludeIn({ORACLE, DERBY, SQLSERVER}) - public void Select_BooleanExpr2() throws SQLException { - // TODO : FIXME - System.out.println(query().from(survey).list(survey.id.gt(0))); - } - - @Test - public void Select_Concat() throws SQLException { - System.out.println(query().from(survey).list(survey.name.append("Hello World"))); - } - - @Test - @ExcludeIn({SQLITE, SQLSERVER, CUBRID, TERADATA}) - public void Select_For_Update() { - query().from(survey).forUpdate().list(survey.id); - } - - @Test - @ExcludeIn({SQLITE, SQLSERVER, CUBRID, TERADATA}) - public void Select_For_Update_UniqueResult() { - query().from(survey).forUpdate().uniqueResult(survey.id); - } - - @Test - @SkipForQuoted - public void Serialization() { - TestQuery query = query(); - query.from(survey); - assertEquals("from SURVEY s", query.toString()); - query.from(survey2); - assertEquals("from SURVEY s, SURVEY s2", query.toString()); - } - - @Test - public void Serialization2() throws Exception { - List rows = query().from(survey).list(survey.id, survey.name); - serialize(rows); - } - - private void serialize(Object obj) throws IOException, ClassNotFoundException{ - ByteArrayOutputStream bytesOut = new ByteArrayOutputStream(); - ObjectOutputStream out = new ObjectOutputStream(bytesOut); - out.writeObject(obj); - out.close(); - bytesOut.close(); - - ByteArrayInputStream bytesIn = new ByteArrayInputStream(bytesOut.toByteArray()); - ObjectInputStream in = new ObjectInputStream(bytesIn); - List rows = (List) in.readObject(); - for (Tuple row : rows) { - row.hashCode(); - } - } - - @Test - public void Single() { - assertNotNull(query().from(survey).singleResult(survey.name)); - } - - @Test - public void Single_Array() { - assertNotNull(query().from(survey).singleResult(new Expression[]{survey.name})); - } - - @Test - public void Single_Column() { - // single column - for (String s : query().from(survey).list(survey.name)) { - assertNotNull(s); - } - } - - @Test - public void Single_Column_via_Object_type() { - for (Object s : query().from(survey) - .list(new PathImpl(Object.class, survey.name.getMetadata()))) { - assertEquals(String.class, s.getClass()); - } - } - - @Test - public void SpecialChars() { - query().from(survey).where(survey.name.in("\n", "\r", "\\", "\'", "\"")).exists(); - } - - @Test - public void StandardTest() { - standardTest.runBooleanTests(employee.firstname.isNull(), employee2.lastname.isNotNull()); - // datetime - standardTest.runDateTests(employee.datefield, employee2.datefield, date); - - // numeric - standardTest.runNumericCasts(employee.id, employee2.id, 1); - standardTest.runNumericTests(employee.id, employee2.id, 1); - // BigDecimal - standardTest.runNumericTests(employee.salary, employee2.salary, new BigDecimal("30000.00")); - - standardTest.runStringTests(employee.firstname, employee2.firstname, "Jennifer"); - Target target = Connections.getTarget(); - if (target != SQLITE && target != SQLSERVER) { - // jTDS driver does not support TIME SQL data type - standardTest.runTimeTests(employee.timefield, employee2.timefield, time); - } - - standardTest.report(); - } - - @Test - @ExcludeIn(SQLITE) - public void String() { - StringExpression str = Expressions.stringTemplate("' abcd '"); - - assertEquals("abcd ", singleResult(StringExpressions.ltrim(str))); - assertEquals(Integer.valueOf(3), singleResult(str.locate("a"))); - assertEquals(Integer.valueOf(0), singleResult(str.locate("a", 4))); - assertEquals(Integer.valueOf(4), singleResult(str.locate("b", 2))); - assertEquals(" abcd", singleResult(StringExpressions.rtrim(str))); - } - - @Test - @ExcludeIn({POSTGRES, SQLITE}) - public void String_IndexOf() { - StringExpression str = Expressions.stringTemplate("' abcd '"); - - assertEquals(Integer.valueOf(2), singleResult(str.indexOf("a"))); - assertEquals(Integer.valueOf(-1), singleResult(str.indexOf("a", 4))); - assertEquals(Integer.valueOf(3), singleResult(str.indexOf("b", 2))); - } - - @Test - public void StringFunctions2() throws SQLException { - for (BooleanExpression where : Arrays. asList( - employee.firstname.startsWith("a"), - employee.firstname.startsWithIgnoreCase("a"), - employee.firstname.endsWith("a"), - employee.firstname.endsWithIgnoreCase("a"))) { - query().from(employee).where(where).list(employee.firstname); - } - } - - @Test - @ExcludeIn(SQLITE) - public void String_Left() { - assertEquals("John", query().from(employee).where(employee.lastname.eq("Johnson")) - .singleResult(SQLExpressions.left(employee.lastname, 4))); - } - - @Test - @ExcludeIn({DERBY, SQLITE}) - public void String_Right() { - assertEquals("son", query().from(employee).where(employee.lastname.eq("Johnson")) - .singleResult(SQLExpressions.right(employee.lastname, 3))); - } - - @Test - @ExcludeIn({DERBY, SQLITE}) - public void String_Left_Right() { - assertEquals("hn", query().from(employee).where(employee.lastname.eq("Johnson")) - .singleResult(SQLExpressions.right(SQLExpressions.left(employee.lastname, 4), 2))); - } - - @Test - @ExcludeIn({DERBY, SQLITE}) - public void String_Right_Left() { - assertEquals("ns", query().from(employee).where(employee.lastname.eq("Johnson")) - .singleResult(SQLExpressions.left(SQLExpressions.right(employee.lastname, 4), 2))); - } - - @Test - @ExcludeIn(DERBY) - public void Substring() { - //SELECT * FROM account where SUBSTRING(name, -x, 1) = SUBSTRING(name, -y, 1) - query().from(employee) - .where(employee.firstname.substring(-3, 1).eq(employee.firstname.substring(-2, 1))) - .list(employee.id); - } - - @Test - public void Syntax_For_Employee() throws SQLException { - query().from(employee).groupBy(employee.superiorId) - .orderBy(employee.superiorId.asc()) - .list(employee.salary.avg(),employee.id.max()); - - query().from(employee).groupBy(employee.superiorId) - .having(employee.id.max().gt(5)) - .orderBy(employee.superiorId.asc()) - .list(employee.salary.avg(), employee.id.max()); - - query().from(employee).groupBy(employee.superiorId) - .having(employee.superiorId.isNotNull()) - .orderBy(employee.superiorId.asc()) - .list(employee.salary.avg(),employee.id.max()); - } - - @Test - public void TemplateExpression() { - NumberExpression one = NumberTemplate.create(Integer.class, "1"); - query().from(survey).list(one.as("col1")); - } - - @Test - public void Transform_GroupBy() { - QEmployee employee = new QEmployee("employee"); - QEmployee employee2 = new QEmployee("employee2"); - Map> results = query().from(employee, employee2) - .transform(GroupBy.groupBy(employee.id).as(GroupBy.map(employee2.id, employee2))); - - int count = (int) query().from(employee).count(); - assertEquals(count, results.size()); - for (Map.Entry> entry : results.entrySet()) { - Map employees = entry.getValue(); - assertEquals(count, employees.size()); - } - - } - - @Test - public void Tuple_Projection() { - List tuples = query().from(employee) - .list(new QTuple(employee.firstname, employee.lastname)); - assertFalse(tuples.isEmpty()); - for (Tuple tuple : tuples) { - assertNotNull(tuple.get(employee.firstname)); - assertNotNull(tuple.get(employee.lastname)); - } - } - - @Test - @ExcludeIn(DERBY) - public void Tuple2() { - query().from(employee) - .list(Expressions.as(ConstantImpl.create("1"),"code"), - employee.id); - } - - @Test - public void TwoColumns() { - // two columns - for (Tuple row : query().from(survey).list(survey.id, survey.name)) { - assertEquals(2, row.size()); - assertEquals(Integer.class, row.get(0, Object.class).getClass()); - assertEquals(String.class, row.get(1, Object.class).getClass()); - } - } - - @Test - public void TwoColumns_and_Projection() { - // two columns and projection - for (Tuple row : query().from(survey) - .list(survey.id, survey.name, new QIdName(survey.id, survey.name))) { - assertEquals(3, row.size()); - assertEquals(Integer.class, row.get(0, Object.class).getClass()); - assertEquals(String.class, row.get(1, Object.class).getClass()); - assertEquals(IdName.class, row.get(2, Object.class).getClass()); - } - } - - @Test - public void Unique_Constructor_Projection() { - IdName idAndName = query().from(survey).limit(1).uniqueResult(new QIdName(survey.id, survey.name)); - assertNotNull(idAndName); - assertNotNull(idAndName.getId()); - assertNotNull(idAndName.getName()); - } - - @Test - public void Unique_Single() { - String s = query().from(survey).limit(1).uniqueResult(survey.name); - assertNotNull(s); - } - - @Test - public void Unique_Wildcard() { - // unique wildcard - Tuple row = query().from(survey).limit(1).uniqueResult(survey.all()); - assertNotNull(row); - assertEquals(3, row.size()); - assertNotNull(row.get(0, Object.class)); - assertNotNull(row.get(0, Object.class) +" is not null", row.get(1, Object.class)); - } - - @Test(expected=NonUniqueResultException.class) - public void UniqueResultContract() { - query().from(employee).uniqueResult(employee.all()); - } - - @Test - public void Various() throws SQLException { - for (String s : query().from(survey).list(survey.name.lower())) { - assertEquals(s, s.toLowerCase()); - } - - for (String s : query().from(survey).list(survey.name.append("abc"))) { - assertTrue(s.endsWith("abc")); - } - - System.out.println(query().from(survey).list(survey.id.sqrt())); - } - - @Test - public void Where_Exists() throws SQLException { - NumberSubQuery sq1 = sq().from(employee).unique(employee.id.max()); - query().from(employee).where(sq1.exists()).count(); - } - - @Test - public void Where_Exists_Not() throws SQLException { - NumberSubQuery sq1 = sq().from(employee).unique(employee.id.max()); - query().from(employee).where(sq1.exists().not()).count(); - } - - @Test - @IncludeIn({HSQLDB, ORACLE, POSTGRES}) - public void With() { - query().with(employee2, sq().from(employee) - .where(employee.firstname.eq("Tom")) - .list(Wildcard.all)) - .from(employee, employee2) - .list(employee.id, employee2.id); - } - - @Test - @IncludeIn({HSQLDB, ORACLE, POSTGRES}) - public void With2() { - QEmployee employee3 = new QEmployee("e3"); - query().with(employee2, sq().from(employee) - .where(employee.firstname.eq("Tom")) - .list(Wildcard.all)) - .with(employee2, sq().from(employee) - .where(employee.firstname.eq("Tom")) - .list(Wildcard.all)) - .from(employee, employee2, employee3) - .list(employee.id, employee2.id, employee3.id); - } - - @Test - @IncludeIn({HSQLDB, ORACLE, POSTGRES}) - public void With3() { - query().with(employee2, employee2.all()).as( - sq().from(employee) - .where(employee.firstname.eq("Tom")) - .list(Wildcard.all)) - .from(employee, employee2) - .list(employee.id, employee2.id); - } - - @Test - @IncludeIn({ORACLE, POSTGRES}) - public void With_Recursive() { - query().withRecursive(employee2, sq().from(employee) - .where(employee.firstname.eq("Tom")) - .list(Wildcard.all)) - .from(employee, employee2) - .list(employee.id, employee2.id); - } - - - @Test - @IncludeIn({ORACLE, POSTGRES}) - public void With_Recursive2() { - query().withRecursive(employee2, employee2.all()).as( - sq().from(employee) - .where(employee.firstname.eq("Tom")) - .list(Wildcard.all)) - .from(employee, employee2) - .list(employee.id, employee2.id); - } - - @Test - public void Wildcard() { - // wildcard - for (Tuple row : query().from(survey).list(survey.all())) { - assertNotNull(row); - assertEquals(3, row.size()); - assertNotNull(row.get(0, Object.class)); - assertNotNull(row.get(0, Object.class) + " is not null", row.get(1, Object.class)); - } - } - - @Test - @SkipForQuoted - public void Wildcard_All() { - expectedQuery = "select * from EMPLOYEE e"; - query().from(employee).list(Wildcard.all); - } - - @Test - public void Wildcard_All2() { - query().from(new RelationalPathBase(Object.class, "employee", "public", "EMPLOYEE")) - .list(Wildcard.all); - } - - @Test - public void Wildcard_and_QTuple() { - // wildcard and QTuple - for (Tuple tuple : query().from(survey).list(new QTuple(survey.all()))) { - assertNotNull(tuple.get(survey.id)); - assertNotNull(tuple.get(survey.name)); - } - } - - @Test - @IncludeIn(ORACLE) - public void WithinGroup() { - List> exprs = new ArrayList>(); - NumberPath path = survey.id; - - // two args - add(exprs, SQLExpressions.cumeDist(2, 3)); - add(exprs, SQLExpressions.denseRank(4, 5)); - add(exprs, SQLExpressions.listagg(path, ",")); - add(exprs, SQLExpressions.percentRank(6, 7)); - add(exprs, SQLExpressions.rank(8, 9)); - - for (WithinGroup wg : exprs) { - query().from(survey).list(wg.withinGroup().orderBy(survey.id, survey.id)); - } - - // one arg - exprs.clear(); - add(exprs, SQLExpressions.percentileCont(0.1)); - add(exprs, SQLExpressions.percentileDisc(0.9)); - - for (WithinGroup wg : exprs) { - query().from(survey).list(wg.withinGroup().orderBy(survey.id)); - } - } - - @Test - @ExcludeIn({DERBY, H2}) - public void YearWeek() { - TestQuery query = query().from(employee).orderBy(employee.id.asc()); - assertEquals(Integer.valueOf(200005), query.singleResult(employee.datefield.yearWeek())); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/SelectMySQLBase.java b/querydsl-sql/src/test/java/com/mysema/query/SelectMySQLBase.java deleted file mode 100644 index 967bd839ed..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/SelectMySQLBase.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.mysema.query; - -import static com.mysema.query.Constants.survey; -import static com.mysema.query.Target.MYSQL; - -import org.junit.Test; - -import com.mysema.query.sql.mysql.MySQLQuery; -import com.mysema.testutil.IncludeIn; - - -public class SelectMySQLBase extends AbstractBaseTest { - - protected MySQLQuery mysqlQuery() { - return new MySQLQuery(connection, configuration); - } - - @Test - @IncludeIn(MYSQL) - public void MySQL_Extensions() { - mysqlQuery().from(survey).bigResult().list(survey.id); - mysqlQuery().from(survey).bufferResult().list(survey.id); - mysqlQuery().from(survey).cache().list(survey.id); - mysqlQuery().from(survey).calcFoundRows().list(survey.id); - mysqlQuery().from(survey).noCache().list(survey.id); - - mysqlQuery().from(survey).highPriority().list(survey.id); - mysqlQuery().from(survey).lockInShareMode().list(survey.id); - mysqlQuery().from(survey).smallResult().list(survey.id); - mysqlQuery().from(survey).straightJoin().list(survey.id); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/SelectOracleBase.java b/querydsl-sql/src/test/java/com/mysema/query/SelectOracleBase.java deleted file mode 100644 index 42fde08d0c..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/SelectOracleBase.java +++ /dev/null @@ -1,146 +0,0 @@ -package com.mysema.query; - -import java.sql.SQLException; - -import com.mysema.query.sql.SQLExpressions; -import com.mysema.query.sql.SQLSerializer; -import com.mysema.query.sql.domain.QEmployee; -import com.mysema.query.sql.oracle.OracleQuery; -import com.mysema.testutil.IncludeIn; -import junit.framework.Assert; -import org.junit.Ignore; -import org.junit.Test; -import static com.mysema.query.Constants.employee; -import static com.mysema.query.Target.ORACLE; -import static com.mysema.query.sql.oracle.OracleGrammar.level; - -public class SelectOracleBase extends AbstractBaseTest { - - protected OracleQuery oracleQuery() { - return new OracleQuery(connection, configuration) { - @Override - protected SQLSerializer serialize(boolean forCountRow) { - SQLSerializer serializer = super.serialize(forCountRow); - String rv = serializer.toString(); - if (expectedQuery != null) { - Assert.assertEquals(expectedQuery, rv.replace('\n', ' ')); - expectedQuery = null; - } - logger.debug(rv); - return serializer; - } - }; - } - - @Test - @Ignore - public void ConnectBy() throws SQLException { - // TODO : come up with a legal case - oracleQuery().from(employee) - .where(level.eq(-1)) - .connectBy(level.lt(1000)) - .list(employee.id); - } - - @Test - @IncludeIn(ORACLE) - @SkipForQuoted - public void ConnectByPrior() throws SQLException { - expectedQuery = "select e.ID, e.LASTNAME, e.SUPERIOR_ID " + - "from EMPLOYEE e " + - "connect by prior e.ID = e.SUPERIOR_ID"; - oracleQuery().from(employee) - .connectByPrior(employee.id.eq(employee.superiorId)) - .list(employee.id, employee.lastname, employee.superiorId); - } - - @Test - @IncludeIn(ORACLE) - @SkipForQuoted - public void ConnectByPrior2() throws SQLException { - if (configuration.getUseLiterals()) return; - - expectedQuery = - "select e.ID, e.LASTNAME, e.SUPERIOR_ID " + - "from EMPLOYEE e " + - "start with e.ID = ? " + - "connect by prior e.ID = e.SUPERIOR_ID"; - oracleQuery().from(employee) - .startWith(employee.id.eq(1)) - .connectByPrior(employee.id.eq(employee.superiorId)) - .list(employee.id, employee.lastname, employee.superiorId); - } - - @Test - @IncludeIn(ORACLE) - @SkipForQuoted - public void ConnectByPrior3() throws SQLException { - if (configuration.getUseLiterals()) return; - - expectedQuery = - "select e.ID, e.LASTNAME, e.SUPERIOR_ID " + - "from EMPLOYEE e " + - "start with e.ID = ? " + - "connect by prior e.ID = e.SUPERIOR_ID " + - "order siblings by e.LASTNAME"; - oracleQuery().from(employee) - .startWith(employee.id.eq(1)) - .connectByPrior(employee.id.eq(employee.superiorId)) - .orderSiblingsBy(employee.lastname) - .list(employee.id, employee.lastname, employee.superiorId); - } - - @Test - @IncludeIn(ORACLE) - @SkipForQuoted - public void ConnectByPrior4() throws SQLException { - if (configuration.getUseLiterals()) return; - - expectedQuery = - "select e.ID, e.LASTNAME, e.SUPERIOR_ID " + - "from EMPLOYEE e " + - "connect by nocycle prior e.ID = e.SUPERIOR_ID"; - oracleQuery().from(employee) - .connectByNocyclePrior(employee.id.eq(employee.superiorId)) - .list(employee.id, employee.lastname, employee.superiorId); - } - - @Test - @IncludeIn(ORACLE) - @SkipForQuoted - public void SumOver() throws SQLException{ -// SQL> select deptno, -// 2 ename, -// 3 sal, -// 4 sum(sal) over (partition by deptno -// 5 order by sal,ename) CumDeptTot, -// 6 sum(sal) over (partition by deptno) SalByDept, -// 7 sum(sal) over (order by deptno, sal) CumTot, -// 8 sum(sal) over () TotSal -// 9 from emp -// 10 order by deptno, sal; - expectedQuery = "select e.LASTNAME, e.SALARY, " + - "sum(e.SALARY) over (partition by e.SUPERIOR_ID order by e.LASTNAME, e.SALARY), " + - "sum(e.SALARY) over (order by e.SUPERIOR_ID, e.SALARY), " + - "sum(e.SALARY) over () from EMPLOYEE e order by e.SALARY asc, e.SUPERIOR_ID asc"; - - oracleQuery().from(employee) - .orderBy(employee.salary.asc(), employee.superiorId.asc()) - .list( - employee.lastname, - employee.salary, - SQLExpressions.sum(employee.salary).over().partitionBy(employee.superiorId).orderBy(employee.lastname, employee.salary), - SQLExpressions.sum(employee.salary).over().orderBy(employee.superiorId, employee.salary), - SQLExpressions.sum(employee.salary).over()); - - // shorter version - QEmployee e = employee; - oracleQuery().from(e) - .orderBy(e.salary.asc(), e.superiorId.asc()) - .list(e.lastname, e.salary, - SQLExpressions.sum(e.salary).over().partitionBy(e.superiorId).orderBy(e.lastname, e.salary), - SQLExpressions.sum(e.salary).over().orderBy(e.superiorId, e.salary), - SQLExpressions.sum(e.salary).over()); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/SelectTeradataBase.java b/querydsl-sql/src/test/java/com/mysema/query/SelectTeradataBase.java deleted file mode 100644 index c4cb09a643..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/SelectTeradataBase.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.mysema.query; - -import static com.mysema.query.Constants.survey; -import static com.mysema.query.Target.TERADATA; - -import org.junit.Test; - -import com.mysema.query.sql.teradata.SetQueryBandClause; -import com.mysema.testutil.IncludeIn; - -public class SelectTeradataBase extends AbstractBaseTest { - - - protected SetQueryBandClause setQueryBand() { - return new SetQueryBandClause(connection, configuration); - } - - @Test - @IncludeIn(TERADATA) - public void SetQueryBand_ForSession() { - setQueryBand().set("a", "bb").forSession().execute(); - query().from(survey).list(survey.id); - } - - @Test - @IncludeIn(TERADATA) - public void SetQueryBand_ForTransaction() { - setQueryBand().set("a", "bb").forTransaction().execute(); - query().from(survey).list(survey.id); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/SelectUseLiteralsBase.java b/querydsl-sql/src/test/java/com/mysema/query/SelectUseLiteralsBase.java deleted file mode 100644 index bd6bb5e1d2..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/SelectUseLiteralsBase.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2013, Mysema Ltd - * - * 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. - */ -package com.mysema.query; - -public class SelectUseLiteralsBase extends SelectBase { - - public SelectUseLiteralsBase() { - configuration.setUseLiterals(true); - } - - @Override - public void Limit_and_Offset2() { - // not supported - } - - @Override - public void Path_Alias() { - // not supported - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/SelectWindowFunctionsBase.java b/querydsl-sql/src/test/java/com/mysema/query/SelectWindowFunctionsBase.java deleted file mode 100644 index 6974ad71cf..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/SelectWindowFunctionsBase.java +++ /dev/null @@ -1,228 +0,0 @@ -package com.mysema.query; - -import static com.mysema.query.Constants.employee; -import static com.mysema.query.Constants.employee2; -import static com.mysema.query.Constants.survey; -import static com.mysema.query.Target.ORACLE; -import static com.mysema.query.Target.SQLSERVER; -import static com.mysema.query.Target.TERADATA; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import org.junit.Test; - -import com.mysema.query.sql.SQLExpressions; -import com.mysema.query.sql.WindowOver; -import com.mysema.query.types.Expression; -import com.mysema.query.types.expr.Wildcard; -import com.mysema.query.types.path.NumberPath; -import com.mysema.query.types.path.SimplePath; -import com.mysema.query.types.query.ListSubQuery; -import com.mysema.query.types.query.SimpleSubQuery; -import com.mysema.testutil.ExcludeIn; -import com.mysema.testutil.IncludeIn; - -public class SelectWindowFunctionsBase extends AbstractBaseTest { - - @Test - @ExcludeIn(SQLSERVER) // FIXME - public void WindowFunctions() { - NumberPath path = survey.id; - NumberPath path2 = survey.id; - - List> exprs = new ArrayList>(); - add(exprs, SQLExpressions.avg(path)); - add(exprs, SQLExpressions.count(path)); - add(exprs, SQLExpressions.corr(path, path2)); - add(exprs, SQLExpressions.covarPop(path, path2)); - add(exprs, SQLExpressions.covarSamp(path, path2)); - add(exprs, SQLExpressions.cumeDist(), TERADATA); - add(exprs, SQLExpressions.denseRank(), TERADATA); - add(exprs, SQLExpressions.firstValue(path), TERADATA); - add(exprs, SQLExpressions.lag(path), TERADATA); - add(exprs, SQLExpressions.lastValue(path), TERADATA); - add(exprs, SQLExpressions.lead(path), TERADATA); - add(exprs, SQLExpressions.max(path)); - add(exprs, SQLExpressions.min(path)); - add(exprs, SQLExpressions.nthValue(path, 2), TERADATA); - add(exprs, SQLExpressions.ntile(3), TERADATA); - add(exprs, SQLExpressions.percentRank()); - add(exprs, SQLExpressions.rank()); - add(exprs, SQLExpressions.rowNumber()); - add(exprs, SQLExpressions.stddev(path), TERADATA); - add(exprs, SQLExpressions.stddevPop(path), TERADATA); - add(exprs, SQLExpressions.stddevSamp(path), TERADATA); - add(exprs, SQLExpressions.sum(path)); - add(exprs, SQLExpressions.variance(path), TERADATA); - add(exprs, SQLExpressions.varPop(path), TERADATA); - add(exprs, SQLExpressions.varSamp(path), TERADATA); - - for (WindowOver wo : exprs) { - query().from(survey).list(wo.over().partitionBy(survey.name).orderBy(survey.id)); - } - } - - @Test - public void WindowFunctions_Manual_Paging() { - Expression rowNumber = SQLExpressions.rowNumber().over().orderBy(employee.lastname.asc()).as("rn"); - Expression all = Wildcard.all; - - // simple - System.out.println("#1"); - for (Tuple row : query().from(employee).list(employee.firstname, employee.lastname, rowNumber)) { - System.out.println(row); - } - System.out.println(); - - // with subquery, generic alias - System.out.println("#2"); - ListSubQuery sub = sq().from(employee).list(employee.firstname, employee.lastname, rowNumber); - SimplePath subAlias = new SimplePath(Tuple.class, "s"); - for (Object[] row : query().from(sub.as(subAlias)).list(all)) { - System.out.println(Arrays.asList(row)); - } - System.out.println(); - - // with subquery, only row number - System.out.println("#3"); - SimpleSubQuery sub2 = sq().from(employee).unique(rowNumber); - SimplePath subAlias2 = new SimplePath(Long.class, "s"); - for (Object[] row : query().from(sub2.as(subAlias2)).list(all)) { - System.out.println(Arrays.asList(row)); - } - System.out.println(); - - // with subquery, specific alias - System.out.println("#4"); - ListSubQuery sub3 = sq().from(employee).list(employee.firstname, employee.lastname, rowNumber); - for (Tuple row : query().from(sub3.as(employee2)).list(employee2.firstname, employee2.lastname)) { - System.out.println(Arrays.asList(row)); - } - } - - @Test - @IncludeIn(ORACLE) - public void WindowFunctions_Keep() { - List> exprs = new ArrayList>(); - NumberPath path = survey.id; - - add(exprs, SQLExpressions.avg(path)); - add(exprs, SQLExpressions.count(path)); - add(exprs, SQLExpressions.max(path)); - add(exprs, SQLExpressions.min(path)); - add(exprs, SQLExpressions.stddev(path)); - add(exprs, SQLExpressions.variance(path)); - - for (WindowOver wo : exprs) { - query().from(survey).list(wo.keepFirst().orderBy(survey.id)); - } - } - - @Test - @ExcludeIn(SQLSERVER) - public void WindowFunctions_Regr() { - List> exprs = new ArrayList>(); - NumberPath path = survey.id; - NumberPath path2 = survey.id; - - add(exprs, SQLExpressions.regrSlope(path, path2), SQLSERVER); - add(exprs, SQLExpressions.regrIntercept(path, path2)); - add(exprs, SQLExpressions.regrCount(path, path2)); - add(exprs, SQLExpressions.regrR2(path, path2)); - add(exprs, SQLExpressions.regrAvgx(path, path2)); - add(exprs, SQLExpressions.regrSxx(path, path2)); - add(exprs, SQLExpressions.regrSyy(path, path2)); - add(exprs, SQLExpressions.regrSxy(path, path2)); - - for (WindowOver wo : exprs) { - query().from(survey).list(wo.over().partitionBy(survey.name).orderBy(survey.id)); - } - } - - @Test - @IncludeIn(ORACLE) - public void WindowFunctions_Oracle() { - List> exprs = new ArrayList>(); - NumberPath path = survey.id; - add(exprs, SQLExpressions.countDistinct(path)); - add(exprs, SQLExpressions.ratioToReport(path)); - add(exprs, SQLExpressions.stddevDistinct(path)); - - for (WindowOver wo : exprs) { - query().from(survey).list(wo.over().partitionBy(survey.name)); - } - } - - @Test - public void WindowFunctions_Over() { - //SELECT Shipment_id,Ship_date, SUM(Qty) OVER () AS Total_Qty - //FROM TestDB.Shipment - - query().from(employee).list( - employee.id, - SQLExpressions.sum(employee.salary).over()); - } - - @Test - public void WindowFunctions_PartitionBy() { - //SELECT Shipment_id,Ship_date,Ship_Type, - //SUM(Qty) OVER (PARTITION BY Ship_Type ) AS Total_Qty - //FROM TestDB.Shipment - - query().from(employee).list( - employee.id, - employee.superiorId, - SQLExpressions.sum(employee.salary).over() - .partitionBy(employee.superiorId)); - } - - @Test - @ExcludeIn(SQLSERVER) - public void WindowFunctions_OrderBy() { - //SELECT Shipment_id,Ship_date,Ship_Type, - //SUM(Qty) OVER (PARTITION BY Ship_Type ORDER BY Ship_Dt ) AS Total_Qty - //FROM TestDB.Shipment - - query().from(employee).list( - employee.id, - SQLExpressions.sum(employee.salary).over() - .partitionBy(employee.superiorId) - .orderBy(employee.datefield)); - } - - @Test - @ExcludeIn(SQLSERVER) - public void WindowFunctions_UnboundedRows() { - //SELECT Shipment_id,Ship_date,Ship_Type, - //SUM(Qty) OVER (PARTITION BY Ship_Type ORDER BY Ship_Dt - //ROWS BETWEEN UNBOUNDED PRECEDING - //AND CURRENT ROW) AS Total_Qty - //FROM TestDB.Shipment - - query().from(employee).list( - employee.id, - SQLExpressions.sum(employee.salary).over() - .partitionBy(employee.superiorId) - .orderBy(employee.datefield) - .rows().between().unboundedPreceding().currentRow()); - } - - @Test - @IncludeIn({TERADATA}) - public void WindowFunctions_Qualify() { - //SELECT Shipment_id,Ship_date,Ship_Type, - //Rank() OVER (PARTITION BY Ship_Type ORDER BY Ship_Dt ) AS rnk - //FROM TestDB.Shipment - //QUALIFY (Rank() OVER (PARTITION BY Ship_Type ORDER BY Ship_Dt )) =1 - - teradataQuery().from(employee) - .qualify(SQLExpressions.rank().over() - .partitionBy(employee.superiorId) - .orderBy(employee.datefield).eq(1l)) - .list(employee.id,SQLExpressions.sum(employee.salary).over()); - - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/SkipForQuotedRule.java b/querydsl-sql/src/test/java/com/mysema/query/SkipForQuotedRule.java deleted file mode 100644 index c8392c9bb1..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/SkipForQuotedRule.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.mysema.query; - -import org.junit.rules.MethodRule; -import org.junit.runners.model.FrameworkMethod; -import org.junit.runners.model.Statement; - -import com.mysema.query.sql.SQLTemplates; -import com.mysema.testutil.EmptyStatement; - -public class SkipForQuotedRule implements MethodRule { - - @Override - public Statement apply(Statement base, FrameworkMethod method, Object target) { - SQLTemplates templates = Connections.getTemplates(); - if (templates.isUseQuotes() || templates.isPrintSchema()) { - boolean run = method.getMethod().getAnnotation(SkipForQuoted.class) == null; - return run ? base : EmptyStatement.DEFAULT; - } else { - return base; - } - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/SpatialBase.java b/querydsl-sql/src/test/java/com/mysema/query/SpatialBase.java deleted file mode 100644 index 5661a14f05..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/SpatialBase.java +++ /dev/null @@ -1,419 +0,0 @@ -package com.mysema.query; - -import java.util.List; - -import com.google.common.collect.Lists; -import com.mysema.query.spatial.PointExpression; -import com.mysema.query.spatial.path.*; -import com.mysema.query.sql.spatial.QShapes; -import com.mysema.query.sql.spatial.QSpatialRefSys; -import com.mysema.query.sql.spatial.Shapes; -import com.mysema.query.types.ConstantImpl; -import com.mysema.query.types.Expression; -import com.mysema.testutil.ExcludeIn; -import com.mysema.testutil.IncludeIn; -import org.geolatte.geom.*; -import org.geolatte.geom.codec.Wkt; -import org.junit.Test; -import static com.mysema.query.Target.*; -import static org.junit.Assert.*; - -public class SpatialBase extends AbstractBaseTest { - - private static final QShapes shapes = QShapes.shapes; - - // point 1-5 - // linestring 6-7 - // polygon 8-9 - // multipoint 10-11 - // multilinestring 12-13 - // multipolygon 14-15 - - private TestQuery withPoints() { - return query().from(shapes).where(shapes.id.between(1, 5)); - } - - private TestQuery withLineStrings() { - return query().from(shapes).where(shapes.id.between(6, 7)); - } - - private TestQuery withPolygons() { - return query().from(shapes).where(shapes.id.between(8, 9)); - } - - private TestQuery withMultipoints() { - return query().from(shapes).where(shapes.id.between(10, 11)); - } - - private TestQuery withMultiLineStrings() { - return query().from(shapes).where(shapes.id.between(12, 13)); - } - - private TestQuery withMultiPolygons() { - return query().from(shapes).where(shapes.id.between(14, 15)); - } - - @Test - @IncludeIn(POSTGRES) - public void SpatialRefSys() { - QSpatialRefSys spatialRefSys = QSpatialRefSys.spatialRefSys; - query().from(spatialRefSys).list(spatialRefSys); - } - - private String normalize(String s) { - String normalized = s.replace(" ", "").replace("ST_", "").replace("_", ""); - normalized = normalized.substring(normalized.indexOf(';') + 1); - return normalized.toUpperCase(); - } - - @Test // FIXME, maybe use enum as the type ?!? - @ExcludeIn(H2) - public void GeometryType() { - List results = query().from(shapes).list(shapes.geometry, shapes.geometry.geometryType()); - assertFalse(results.isEmpty()); - for (Tuple row : results) { - assertEquals( - normalize(row.get(shapes.geometry).getGeometryType().name()), - normalize(row.get(shapes.geometry.geometryType()))); - } - } - - @Test - public void AsText() { - List results = query().from(shapes).list(shapes.geometry, shapes.geometry.asText()); - assertFalse(results.isEmpty()); - for (Tuple row : results) { - if (!(row.get(shapes.geometry) instanceof MultiPoint)) { - assertEquals( - normalize(row.get(shapes.geometry).asText()), - normalize(row.get(shapes.geometry.asText()))); - } - } - } - - @Test - @ExcludeIn(H2) - public void Point_X_Y() { - PointPath point = shapes.geometry.asPoint(); - List results = withPoints().list(point, point.x(), point.y()); - assertFalse(results.isEmpty()); - for (Tuple row : results) { - assertEquals(Double.valueOf(row.get(point).getX()), row.get(point.x())); - assertEquals(Double.valueOf(row.get(point).getY()), row.get(point.y())); - } - } - - @Test - @ExcludeIn(MYSQL) - public void Point_Distance() { - QShapes shapes1 = QShapes.shapes; - QShapes shapes2 = new QShapes("shapes2"); - for (Tuple tuple : query().from(shapes1, shapes2) - .where(shapes1.id.loe(5), shapes2.id.loe(5)) - .list(shapes1.geometry.asPoint(), - shapes2.geometry.asPoint(), - shapes1.geometry.distance(shapes2.geometry))) { - Point point1 = tuple.get(shapes1.geometry.asPoint()); - Point point2 = tuple.get(shapes2.geometry.asPoint()); - Double distance = tuple.get(shapes1.geometry.distance(shapes2.geometry)); - assertEquals(point1.distance(point2), distance.doubleValue(), 0.0001); - } - } - - @Test - public void Point_Instances() { - List results = withPoints().list(shapes); - assertEquals(5, results.size()); - for (Shapes row : results) { - assertNotNull(row.getId()); - assertNotNull(row.getGeometry()); - assertTrue(row.getGeometry() instanceof Point); - } - } - - @Test - public void LineString_Instances() { - List results = withLineStrings().list(shapes.geometry); - assertFalse(results.isEmpty()); - for (Geometry row : results) { - assertNotNull(row); - assertTrue(row instanceof LineString); - } - } - - @Test - public void Polygon_Instances() { - List results = withPolygons().list(shapes.geometry); - assertFalse(results.isEmpty()); - for (Geometry row : results) { - assertNotNull(row); - assertTrue(row instanceof Polygon); - } - } - - @Test - public void MultiPoint_Instances() { - List results = withMultipoints().list(shapes.geometry); - assertFalse(results.isEmpty()); - for (Geometry row : results) { - assertNotNull(row); - assertTrue(row instanceof MultiPoint); - } - } - - @Test - public void MultiLineString_Instances() { - List results = withMultiLineStrings().list(shapes.geometry); - assertFalse(results.isEmpty()); - for (Geometry row : results) { - assertNotNull(row); - assertTrue(row instanceof MultiLineString); - } - } - - @Test - public void MultiPolygon_Instances() { - List results = withMultiPolygons().list(shapes.geometry); - assertFalse(results.isEmpty()); - for (Geometry row : results) { - assertNotNull(row); - assertTrue(row instanceof MultiPolygon); - } - } - - @Test - public void Point_Methods() { - PointPath point = shapes.geometry.asPoint(); - - List> expressions = Lists.newArrayList(); - add(expressions, point.asBinary(), H2); - add(expressions, point.asText()); - add(expressions, point.boundary(), MYSQL); - add(expressions, point.convexHull(), MYSQL); - add(expressions, point.dimension()); - add(expressions, point.envelope(), H2); - add(expressions, point.geometryType(), H2); - add(expressions, point.isEmpty()); - add(expressions, point.isSimple()); - add(expressions, point.m(), MYSQL, TERADATA, H2); - add(expressions, point.srid()); - // TODO add emulations - add(expressions, point.transform(26986), MYSQL, POSTGRES, SQLSERVER, TERADATA, H2); - // point specific - add(expressions, point.x(), H2); - add(expressions, point.y(), H2); - add(expressions, point.z(), MYSQL, TERADATA, H2); - - for (Expression expr : expressions) { - boolean logged = false; - for (Object row : withPoints().list(expr)) { - if (row == null && !logged) { - System.err.println(expr.toString()); - logged = true; - } - } - } - } - - private List> createExpressions(PointExpression point1, Expression point2) { - List> expressions = Lists.newArrayList(); - add(expressions, point1.contains(point2)); - add(expressions, point1.crosses(point2)); - add(expressions, point1.difference(point2), MYSQL); - add(expressions, point1.disjoint(point2)); - add(expressions, point1.distance(point2), MYSQL); - add(expressions, point1.distanceSphere(point2), H2, MYSQL, SQLSERVER); - add(expressions, point1.distanceSpheroid(point2), H2, MYSQL, POSTGRES, SQLSERVER); - add(expressions, point1.eq(point2)); - add(expressions, point1.intersection(point2), MYSQL); - add(expressions, point1.intersects(point2)); - add(expressions, point1.overlaps(point2)); - add(expressions, point1.symDifference(point2), MYSQL); - add(expressions, point1.touches(point2)); - add(expressions, point1.union(point2), MYSQL); - add(expressions, point1.within(point2)); - return expressions; - } - - @Test - public void Point_Methods2() { - QShapes shapes1 = QShapes.shapes; - QShapes shapes2 = new QShapes("shapes2"); - - List> expressions = Lists.newArrayList(); - expressions.addAll(createExpressions(shapes1.geometry.asPoint(), shapes2.geometry.asPoint())); - expressions.addAll(createExpressions(shapes1.geometry.asPoint(), ConstantImpl.create((Point)Wkt.fromWkt("Point(2 2)")))); - - for (Expression expr : expressions) { - boolean logged = false; - for (Object row : query().from(shapes1, shapes2) - .where(shapes1.id.loe(5), shapes2.id.loe(5)).list(expr)) { - if (row == null && !logged) { - System.err.println(expr.toString()); - logged = true; - } - } - } - } - - @Test - public void LineString_Methods() { - LineStringPath lineString = shapes.geometry.asLineString(); - - List> expressions = Lists.newArrayList(); - add(expressions, lineString.asBinary(), H2); - add(expressions, lineString.asText()); - add(expressions, lineString.boundary(), MYSQL); - add(expressions, lineString.convexHull(), MYSQL); - add(expressions, lineString.dimension()); - add(expressions, lineString.envelope(), H2); - add(expressions, lineString.geometryType(), H2); - add(expressions, lineString.isEmpty()); - add(expressions, lineString.isSimple()); - // curve specific - add(expressions, lineString.length(), H2); - add(expressions, lineString.startPoint(), H2); - add(expressions, lineString.endPoint(), H2); - add(expressions, lineString.isClosed(), H2); - add(expressions, lineString.isRing(), H2, MYSQL); - // linestring specific - add(expressions, lineString.numPoints(), H2); - add(expressions, lineString.pointN(1), H2); - - for (Expression expr : expressions) { - boolean logged = false; - for (Object row : withLineStrings().list(expr)) { - if (row == null && !logged) { - System.err.println(expr.toString()); - logged = true; - } - } - } - } - - @Test - public void Polygon_Methods() { - PolygonPath polygon = shapes.geometry.asPolygon(); - - List> expressions = Lists.newArrayList(); - add(expressions, polygon.asBinary(), H2); - add(expressions, polygon.asText()); - add(expressions, polygon.boundary(), MYSQL); - add(expressions, polygon.convexHull(), MYSQL); - add(expressions, polygon.dimension()); - add(expressions, polygon.envelope(), H2); - add(expressions, polygon.geometryType(), H2); - add(expressions, polygon.isEmpty()); - add(expressions, polygon.isSimple()); - // surface specific - add(expressions, polygon.area()); - add(expressions, polygon.centroid()); - add(expressions, polygon.pointOnSurface(), H2, MYSQL); - // polygon specific - add(expressions, polygon.exteriorRing(), H2); - add(expressions, polygon.numInteriorRing(), H2); - add(expressions, polygon.interiorRingN(1), H2); - - for (Expression expr : expressions) { - boolean logged = false; - for (Object row : withPolygons().list(expr)) { - if (row == null && !logged) { - System.err.println(expr.toString()); - logged = true; - } - } - } - } - - @Test - public void MultiPoint_Methods() { - MultiPointPath multipoint = shapes.geometry.asMultiPoint(); - - List> expressions = Lists.newArrayList(); - add(expressions, multipoint.asBinary(), H2); - add(expressions, multipoint.asText()); - add(expressions, multipoint.boundary(), MYSQL); - add(expressions, multipoint.convexHull(), MYSQL); - add(expressions, multipoint.dimension()); - add(expressions, multipoint.envelope(), H2); - add(expressions, multipoint.geometryType(), H2); - add(expressions, multipoint.isEmpty()); - add(expressions, multipoint.isSimple()); - // multipoint specific - add(expressions, multipoint.numGeometries(), H2); - add(expressions, multipoint.geometryN(1), H2); - - for (Expression expr : expressions) { - boolean logged = false; - for (Object row : withMultipoints().list(expr)) { - if (row == null && !logged) { - System.err.println(expr.toString()); - logged = true; - } - } - } - } - - @Test - public void MultiLineString_Methods() { - MultiLineStringPath multilinestring = shapes.geometry.asMultiLineString(); - - List> expressions = Lists.newArrayList(); - add(expressions, multilinestring.asBinary(), H2); - add(expressions, multilinestring.asText()); - add(expressions, multilinestring.boundary(), MYSQL); - add(expressions, multilinestring.convexHull(), MYSQL); - add(expressions, multilinestring.dimension()); - add(expressions, multilinestring.envelope(), H2); - add(expressions, multilinestring.geometryType(), H2); - add(expressions, multilinestring.isEmpty()); - add(expressions, multilinestring.isSimple()); - // multicurve specific - add(expressions, multilinestring.isClosed(), H2); - add(expressions, multilinestring.length(), H2); - // multilinestring specific - add(expressions, multilinestring.numGeometries(), H2); - add(expressions, multilinestring.geometryN(1), H2); - - for (Expression expr : expressions) { - boolean logged = false; - for (Object row : withMultiLineStrings().list(expr)) { - if (row == null && !logged) { - System.err.println(expr.toString()); - logged = true; - } - } - } - } - - @Test - public void MultiPolygon_Methods() { - MultiPolygonPath multipolygon = shapes.geometry.asMultiPolygon(); - - List> expressions = Lists.newArrayList(); - add(expressions, multipolygon.asBinary(), H2); - add(expressions, multipolygon.asText()); - add(expressions, multipolygon.boundary(), MYSQL); - add(expressions, multipolygon.convexHull(), MYSQL); - add(expressions, multipolygon.dimension()); - add(expressions, multipolygon.envelope(), H2); - add(expressions, multipolygon.geometryType(), H2); - add(expressions, multipolygon.isEmpty()); - add(expressions, multipolygon.isSimple()); - // multipolygon specific - add(expressions, multipolygon.numGeometries(), H2); - add(expressions, multipolygon.geometryN(1), H2); - - for (Expression expr : expressions) { - boolean logged = false; - for (Object row : withMultiPolygons().list(expr)) { - if (row == null && !logged) { - System.err.println(expr.toString()); - logged = true; - } - } - } - } - - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/StoredProcedures.java b/querydsl-sql/src/test/java/com/mysema/query/StoredProcedures.java deleted file mode 100644 index 89da2878fb..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/StoredProcedures.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query; - -import java.sql.Connection; -import java.sql.DatabaseMetaData; -import java.sql.DriverManager; -import java.sql.ResultSet; -import java.sql.SQLException; - -public class StoredProcedures { - - public static void main(String[] args) throws ClassNotFoundException, SQLException { - Class.forName("org.apache.derby.jdbc.EmbeddedDriver"); - String url = "jdbc:derby:target/procedure_test;create=true"; - Connection connection = DriverManager.getConnection(url, "", ""); - - try { - DatabaseMetaData md = connection.getMetaData(); - ResultSet procedures = md.getProcedures(null, null, null); - try { - while (procedures.next()) { - String cat = procedures.getString(1); - String schema = procedures.getString(2); - String name = procedures.getString(3); - String remarks = procedures.getString(7); - String type = procedures.getString(8); - String specificName = procedures.getString(9); - System.out.println(name + "\n" + remarks + "\n" + type + "\n" + specificName); - - ResultSet procedureColumns = md.getProcedureColumns(cat, schema, name, null); - try { - while (procedureColumns.next()) { - String columnName = procedureColumns.getString(4); - int columnType = procedureColumns.getInt(5); - int dataType = procedureColumns.getInt(6); - String typeName = procedureColumns.getString(7); - short nullable = procedureColumns.getShort(12); - System.out.println(" " + columnName + " " + columnType + " " + dataType + " " + typeName + " " + nullable); - } - System.out.println(); - } finally { - procedureColumns.close(); - } - } - } finally { - procedures.close(); - } - } finally { - connection.close(); - } - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/SubqueriesBase.java b/querydsl-sql/src/test/java/com/mysema/query/SubqueriesBase.java deleted file mode 100644 index 58d000b4f3..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/SubqueriesBase.java +++ /dev/null @@ -1,175 +0,0 @@ -package com.mysema.query; - -import static com.mysema.query.Constants.employee; -import static com.mysema.query.Constants.employee2; -import static com.mysema.query.Constants.survey; -import static com.mysema.query.Constants.survey2; -import static com.mysema.query.Target.CUBRID; -import static com.mysema.query.Target.DERBY; -import static com.mysema.query.Target.H2; -import static com.mysema.query.Target.HSQLDB; -import static com.mysema.query.Target.MYSQL; -import static com.mysema.query.Target.POSTGRES; -import static com.mysema.query.Target.SQLITE; -import static com.mysema.query.Target.SQLSERVER; -import static com.mysema.query.Target.TERADATA; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; - -import java.math.BigDecimal; -import java.sql.SQLException; -import java.util.List; - -import org.junit.Test; - -import com.google.common.collect.ImmutableList; -import com.mysema.query.sql.Configuration; -import com.mysema.query.sql.ForeignKey; -import com.mysema.query.sql.SQLSerializer; -import com.mysema.query.sql.SQLSubQuery; -import com.mysema.query.sql.domain.Employee; -import com.mysema.query.sql.domain.QEmployee; -import com.mysema.query.support.Expressions; -import com.mysema.query.types.expr.Param; -import com.mysema.query.types.expr.Wildcard; -import com.mysema.query.types.path.NumberPath; -import com.mysema.query.types.path.PathBuilder; -import com.mysema.query.types.query.ListSubQuery; -import com.mysema.testutil.ExcludeIn; - -public class SubqueriesBase extends AbstractBaseTest { - - @Test - @ExcludeIn({CUBRID, DERBY, H2, HSQLDB, SQLITE, SQLSERVER}) - public void Keys() { - QEmployee employee2 = new QEmployee("employee2"); - ForeignKey nameKey1 = new ForeignKey(employee, - ImmutableList.of(employee.firstname, employee.lastname), - ImmutableList.of("a", "b")); - ForeignKey nameKey2 = new ForeignKey(employee, - ImmutableList.of(employee.firstname, employee.lastname), - ImmutableList.of("a", "b")); - - query().from(employee) - .where(nameKey1.in(sq().from(employee2).list(nameKey2))) - .list(employee.id); - } - - @Test - @ExcludeIn({CUBRID, DERBY, H2, HSQLDB, SQLITE, SQLSERVER}) - public void List_In_Query() { - QEmployee employee2 = new QEmployee("employee2"); - query().from(employee) - .where(Expressions.list(employee.id, employee.lastname) - .in(sq().from(employee2).list(employee2.id, employee2.lastname))) - .list(employee.id); - } - - @Test - @SkipForQuoted - public void SubQueries() throws SQLException { - // subquery in where block - expectedQuery = "select e.ID from EMPLOYEE e " - + "where e.ID = (select max(e.ID) " - + "from EMPLOYEE e)"; - List list = query().from(employee) - .where(employee.id.eq(sq().from(employee).unique(employee.id.max()))) - .list(employee.id); - assertFalse(list.isEmpty()); - } - - @Test - public void SubQuery_Alias() { - query().from(sq().from(employee).list(employee.all()).as(employee2)).list(employee2.all()); - } - - @Test - @ExcludeIn(SQLITE) - public void SubQuery_All() { - query().from(employee).where(employee.id.gtAll( - sq().from(employee2).list(employee2.id))).count(); - } - - @Test - @ExcludeIn(SQLITE) - public void SubQuery_Any() { - query().from(employee).where(employee.id.gtAny( - sq().from(employee2).list(employee2.id))).count(); - } - - @Test - public void SubQuery_InnerJoin() { - ListSubQuery sq = sq().from(employee2).list(employee2.id); - QEmployee sqEmp = new QEmployee("sq"); - query().from(employee).innerJoin(sq, sqEmp).on(sqEmp.id.eq(employee.id)).list(employee.id); - - } - - @Test - public void SubQuery_LeftJoin() { - ListSubQuery sq = sq().from(employee2).list(employee2.id); - QEmployee sqEmp = new QEmployee("sq"); - query().from(employee).leftJoin(sq, sqEmp).on(sqEmp.id.eq(employee.id)).list(employee.id); - - } - - @Test - @ExcludeIn({MYSQL, POSTGRES, DERBY, SQLSERVER, TERADATA}) - public void SubQuery_Params() { - Param aParam = new Param(String.class, "param"); - SQLSubQuery subQuery = new SQLSubQuery().from(employee).where(employee.firstname.eq(aParam)); - subQuery.set(aParam, "Mike"); - - assertEquals(1, query().from(subQuery.list(Wildcard.all)).count()); - } - - @Test - @ExcludeIn(SQLITE) - public void SubQuery_RightJoin() { - ListSubQuery sq = sq().from(employee2).list(employee2.id); - QEmployee sqEmp = new QEmployee("sq"); - query().from(employee).rightJoin(sq, sqEmp).on(sqEmp.id.eq(employee.id)).list(employee.id); - } - - @Test - public void SubQuery_with_Alias() { - List ids1 = query().from(employee).list(employee.id); - List ids2 = query().from(sq().from(employee).list(employee.id), employee).list(employee.id); - assertEquals(ids1, ids2); - } - - @Test - public void SubQuery_with_Alias2() { - List ids1 = query().from(employee).list(employee.id); - List ids2 = query().from(sq().from(employee).list(employee.id).as(employee)).list(employee.id); - assertEquals(ids1, ids2); - } - - @Test - public void SubQuerySerialization() { - SQLSubQuery query = sq(); - query.from(survey); - assertEquals("from SURVEY s", query.toString()); - - query.from(survey2); - assertEquals("from SURVEY s, SURVEY s2", query.toString()); - } - - @Test - public void SubQuerySerialization2() { - NumberPath sal = new NumberPath(BigDecimal.class, "sal"); - PathBuilder sq = new PathBuilder(Object[].class, "sq"); - SQLSerializer serializer = new SQLSerializer(Configuration.DEFAULT); - - serializer.handle( - sq() - .from(employee) - .list(employee.salary.add(employee.salary).add(employee.salary).as(sal)) - .as(sq)); - assertEquals( - "(select (e.SALARY + e.SALARY + e.SALARY) as sal\nfrom EMPLOYEE e) as sq", - serializer.toString()); - } - - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/Survey.java b/querydsl-sql/src/test/java/com/mysema/query/Survey.java deleted file mode 100644 index 97cd63f54f..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/Survey.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.mysema.query; - -import com.mysema.query.sql.Column; - -public class Survey { - - @Column("NAME") - private String name; - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - -} \ No newline at end of file diff --git a/querydsl-sql/src/test/java/com/mysema/query/TargetRule.java b/querydsl-sql/src/test/java/com/mysema/query/TargetRule.java deleted file mode 100644 index 1ea84ba02a..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/TargetRule.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.mysema.query; - -import java.lang.reflect.Method; -import java.util.Arrays; - -import org.junit.rules.MethodRule; -import org.junit.runners.model.FrameworkMethod; -import org.junit.runners.model.Statement; - -import com.mysema.testutil.EmptyStatement; -import com.mysema.testutil.ExcludeIn; -import com.mysema.testutil.IncludeIn; - -public class TargetRule implements MethodRule { - - @Override - public Statement apply(Statement base, FrameworkMethod method, Object obj) { - Target target = Connections.getTarget(); - boolean run = target == null || isExecuted(method.getMethod(), target); - return run ? base : EmptyStatement.DEFAULT; - } - - private boolean isExecuted(Method method, Target target) { - ExcludeIn ex = method.getAnnotation(ExcludeIn.class); - if (ex == null) { - ex = method.getDeclaringClass().getAnnotation(ExcludeIn.class); - } - // excluded in given targets - if (ex != null && Arrays.asList(ex.value()).contains(target)) { - return false; - } - // included only in given targets - IncludeIn in = method.getAnnotation(IncludeIn.class); - if (in == null) { - in = method.getDeclaringClass().getAnnotation(IncludeIn.class); - } - if (in != null && !Arrays.asList(in.value()).contains(target)) { - return false; - } - return true; - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/TypesBase.java b/querydsl-sql/src/test/java/com/mysema/query/TypesBase.java deleted file mode 100644 index 4493821ef7..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/TypesBase.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.mysema.query; - -import static com.mysema.query.Target.CUBRID; -import static com.mysema.query.Target.POSTGRES; -import static com.mysema.query.Target.TERADATA; - -import java.sql.Connection; -import java.sql.DatabaseMetaData; -import java.sql.ResultSet; -import java.sql.SQLException; - -import org.junit.Test; - -import com.mysema.testutil.ExcludeIn; - -public class TypesBase extends AbstractBaseTest { - - @Test - @ExcludeIn({CUBRID, POSTGRES, TERADATA}) - public void DumpTypes() throws SQLException { - Connection conn = Connections.getConnection(); - DatabaseMetaData md = conn.getMetaData(); - - // types - ResultSet rs = md.getUDTs(null, null, null, null); - try { - while (rs.next()) { - // cat, schema, name, classname, datatype, remarks, base_type - String cat = rs.getString(1); - String schema = rs.getString(2); - String name = rs.getString(3); - String classname = rs.getString(4); - String datatype = rs.getString(5); - String remarks = rs.getString(6); - String base_type = rs.getString(7); - System.out.println(name + " " + classname + " " + datatype + " " + - remarks + " " + base_type); - - // attributes - ResultSet rs2 = md.getAttributes(cat, schema, name, null); - try { - while (rs2.next()) { - // cat, schema, name, attr_name, data_type, attr_type_name, attr_size - // decimal_digits, num_prec_radix, nullable, remarks, attr_def, sql_data_type, ordinal_position - // ... - String _cat = rs2.getString(1); - String _schema = rs2.getString(2); - String _name = rs2.getString(3); - String _attr_name = rs2.getString(4); - String _data_type = rs2.getString(5); - String _attr_type_name = rs2.getString(6); - String _attr_size = rs2.getString(7); - - System.out.println(" " + _attr_name + " " + _data_type + " " + _attr_type_name + " " + _attr_size); - } - } finally { - rs2.close(); - } - } - } finally { - rs.close(); - } - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/UnionBase.java b/querydsl-sql/src/test/java/com/mysema/query/UnionBase.java deleted file mode 100644 index 47f897bae7..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/UnionBase.java +++ /dev/null @@ -1,215 +0,0 @@ -package com.mysema.query; - -import static com.mysema.query.Constants.employee; -import static com.mysema.query.Target.CUBRID; -import static com.mysema.query.Target.DERBY; -import static com.mysema.query.Target.MYSQL; -import static com.mysema.query.Target.TERADATA; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -import java.io.IOException; -import java.sql.SQLException; -import java.util.Arrays; -import java.util.List; - -import org.junit.Test; - -import com.mysema.commons.lang.CloseableIterator; -import com.mysema.query.sql.domain.Employee; -import com.mysema.query.sql.domain.QEmployee; -import com.mysema.query.types.Expression; -import com.mysema.query.types.Projections; -import com.mysema.query.types.SubQueryExpression; -import com.mysema.query.types.query.ListSubQuery; -import com.mysema.query.types.query.SimpleSubQuery; -import com.mysema.query.types.template.NumberTemplate; -import com.mysema.testutil.ExcludeIn; - -public class UnionBase extends AbstractBaseTest { - - @Test - @ExcludeIn({MYSQL, TERADATA}) - public void In_Union() { - assertTrue(query().from(employee) - .where(employee.id.in( - sq().union(sq().unique(NumberTemplate.ONE), - sq().unique(NumberTemplate.TWO)))) - .exists()); - } - - @Test - @SuppressWarnings("unchecked") - public void Union() throws SQLException { - SubQueryExpression sq1 = sq().from(employee).unique(employee.id.max()); - SubQueryExpression sq2 = sq().from(employee).unique(employee.id.min()); - List list = query().union(sq1, sq2).list(); - assertFalse(list.isEmpty()); - } - - @Test - @SuppressWarnings("unchecked") - public void Union_All() { - SubQueryExpression sq1 = sq().from(employee).unique(employee.id.max()); - SubQueryExpression sq2 = sq().from(employee).unique(employee.id.min()); - List list = query().unionAll(sq1, sq2).list(); - assertFalse(list.isEmpty()); - } - - @SuppressWarnings("unchecked") - @Test - public void Union_Multiple_Columns() throws SQLException { - SubQueryExpression sq1 = sq().from(employee).unique(employee.firstname, employee.lastname); - SubQueryExpression sq2 = sq().from(employee).unique(employee.lastname, employee.firstname); - List list = query().union(sq1, sq2).list(); - assertFalse(list.isEmpty()); - for (Tuple row : list) { - assertNotNull(row.get(0, Object.class)); - assertNotNull(row.get(1, Object.class)); - } - } - - @Test - @SuppressWarnings("unchecked") - public void Union_Empty_Result() throws SQLException { - SubQueryExpression sq1 = sq().from(employee).where(employee.firstname.eq("XXX")).unique(employee.id); - SubQueryExpression sq2 = sq().from(employee).where(employee.firstname.eq("YYY")).unique(employee.id); - List list = query().union(sq1, sq2).list(); - assertTrue(list.isEmpty()); - } - - @Test - @SuppressWarnings("unchecked") - public void Union2() throws SQLException { - List list = query().union( - sq().from(employee).unique(employee.id.max()), - sq().from(employee).unique(employee.id.min())).list(); - assertFalse(list.isEmpty()); - - } - - @Test - @SuppressWarnings("unchecked") - public void Union3() throws SQLException { - SimpleSubQuery sq3 = sq().from(employee).unique(new Expression[]{employee.id.max()}); - SimpleSubQuery sq4 = sq().from(employee).unique(new Expression[]{employee.id.min()}); - List list2 = query().union(sq3, sq4).list(); - assertFalse(list2.isEmpty()); - } - - @Test - @ExcludeIn({DERBY}) - public void Union4() { - SimpleSubQuery sq1 = sq().from(employee).unique(employee.id, employee.firstname); - SimpleSubQuery sq2 = sq().from(employee).unique(employee.id, employee.firstname); - query().union(employee, sq1, sq2).list(employee.id.count()); - } - - // FIXME for CUBRID - // Teradata: The ORDER BY clause must contain only integer constants. - @Test - @ExcludeIn({DERBY, CUBRID, TERADATA}) - public void Union5() { - /* (select e.ID, e.FIRSTNAME, superior.ID as sup_id, superior.FIRSTNAME as sup_name - * from EMPLOYEE e join EMPLOYEE superior on e.SUPERIOR_ID = superior.ID) - * union - * (select e.ID, e.FIRSTNAME, null, null from EMPLOYEE e) - * order by ID asc - */ - QEmployee superior = new QEmployee("superior"); - ListSubQuery sq1 = sq().from(employee) - .join(employee.superiorIdKey, superior) - .list(employee.id, employee.firstname, superior.id.as("sup_id"), superior.firstname.as("sup_name")); - ListSubQuery sq2 = sq().from(employee) - .list(employee.id, employee.firstname, null, null); - List results = query().union(sq1, sq2).orderBy(employee.id.asc()).list(); - for (Tuple result : results) { - System.err.println(Arrays.asList(result)); - } - } - - @Test - @ExcludeIn(TERADATA) // The ORDER BY clause must contain only integer constants. - @SuppressWarnings("unchecked") - public void Union_With_Order() throws SQLException { - SubQueryExpression sq1 = sq().from(employee).unique(employee.id); - SubQueryExpression sq2 = sq().from(employee).unique(employee.id); - List list = query().union(sq1, sq2).orderBy(employee.id.asc()).list(); - assertFalse(list.isEmpty()); - } - - @SuppressWarnings("unchecked") - @Test - public void Union_Multi_Column_Projection_List() throws IOException{ - SubQueryExpression sq1 = sq().from(employee).unique(employee.id.max(), employee.id.max().subtract(1)); - SubQueryExpression sq2 = sq().from(employee).unique(employee.id.min(), employee.id.min().subtract(1)); - - List list = query().union(sq1, sq2).list(); - assertEquals(2, list.size()); - assertTrue(list.get(0) != null); - assertTrue(list.get(1) != null); - } - - @SuppressWarnings("unchecked") - @Test - public void Union_Multi_Column_Projection_Iterate() throws IOException{ - SubQueryExpression sq1 = sq().from(employee).unique(employee.id.max(), employee.id.max().subtract(1)); - SubQueryExpression sq2 = sq().from(employee).unique(employee.id.min(), employee.id.min().subtract(1)); - - CloseableIterator iterator = query().union(sq1,sq2).iterate(); - try{ - assertTrue(iterator.hasNext()); - assertTrue(iterator.next() != null); - assertTrue(iterator.next() != null); - assertFalse(iterator.hasNext()); - }finally{ - iterator.close(); - } - } - - @SuppressWarnings("unchecked") - @Test - public void Union_Single_Column_Projections_List() throws IOException{ - SubQueryExpression sq1 = sq().from(employee).unique(employee.id.max()); - SubQueryExpression sq2 = sq().from(employee).unique(employee.id.min()); - - List list = query().union(sq1, sq2).list(); - assertEquals(2, list.size()); - assertTrue(list.get(0) != null); - assertTrue(list.get(1) != null); - } - - @SuppressWarnings("unchecked") - @Test - public void Union_Single_Column_Projections_Iterate() throws IOException{ - SubQueryExpression sq1 = sq().from(employee).unique(employee.id.max()); - SubQueryExpression sq2 = sq().from(employee).unique(employee.id.min()); - - CloseableIterator iterator = query().union(sq1,sq2).iterate(); - try{ - assertTrue(iterator.hasNext()); - assertTrue(iterator.next() != null); - assertTrue(iterator.next() != null); - assertFalse(iterator.hasNext()); - }finally{ - iterator.close(); - } - } - - @SuppressWarnings("unchecked") - @Test - public void Union_FactoryExpression() { - ListSubQuery sq1 = sq().from(employee) - .list(Projections.constructor(Employee.class, employee.id)); - ListSubQuery sq2 = sq().from(employee) - .list(Projections.constructor(Employee.class, employee.id)); - List employees = query().union(sq1, sq2).list(); - for (Employee employee : employees) { - assertNotNull(employee); - } - } - - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/UpdateBase.java b/querydsl-sql/src/test/java/com/mysema/query/UpdateBase.java deleted file mode 100644 index 57b3dbda83..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/UpdateBase.java +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query; - -import static com.mysema.query.Constants.survey; -import static com.mysema.query.Target.CUBRID; -import static com.mysema.query.Target.H2; -import static com.mysema.query.Target.MYSQL; -import static com.mysema.query.Target.ORACLE; -import static com.mysema.query.Target.SQLSERVER; -import static org.junit.Assert.assertEquals; - -import java.sql.SQLException; -import java.util.Collections; -import java.util.List; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.mysema.query.sql.SQLSubQuery; -import com.mysema.query.sql.dml.SQLUpdateClause; -import com.mysema.query.sql.domain.QEmployee; -import com.mysema.query.sql.domain.QSurvey; -import com.mysema.query.types.Path; -import com.mysema.query.types.expr.Param; -import com.mysema.testutil.IncludeIn; - -public class UpdateBase extends AbstractBaseTest { - - protected void reset() throws SQLException{ - delete(survey).execute(); - insert(survey).values(1, "Hello World", "Hello").execute(); - } - - @Before - public void setUp() throws SQLException{ - reset(); - } - - @After - public void tearDown() throws SQLException{ - reset(); - } - - @Test - public void Update() throws SQLException{ - - // original state - long count = query().from(survey).count(); - assertEquals(0, query().from(survey).where(survey.name.eq("S")).count()); - - // update call with 0 update count - assertEquals(0, update(survey).where(survey.name.eq("XXX")).set(survey.name, "S").execute()); - assertEquals(0, query().from(survey).where(survey.name.eq("S")).count()); - - // update call with full update count - assertEquals(count, update(survey).set(survey.name, "S").execute()); - assertEquals(count, query().from(survey).where(survey.name.eq("S")).count()); - - } - - @Test - @IncludeIn({CUBRID, H2, MYSQL, ORACLE, SQLSERVER}) - public void Update_Limit() { - insert(survey).values(2, "A","B").execute(); - insert(survey).values(3, "B","C").execute(); - - assertEquals(2, update(survey).set(survey.name, "S").limit(2).execute()); - } - - @Test - public void Update2() throws SQLException{ - List> paths = Collections.>singletonList(survey.name); - List values = Collections.singletonList("S"); - - // original state - long count = query().from(survey).count(); - assertEquals(0, query().from(survey).where(survey.name.eq("S")).count()); - - // update call with 0 update count - assertEquals(0, update(survey).where(survey.name.eq("XXX")).set(paths, values).execute()); - assertEquals(0, query().from(survey).where(survey.name.eq("S")).count()); - - // update call with full update count - assertEquals(count, update(survey).set(paths, values).execute()); - assertEquals(count, query().from(survey).where(survey.name.eq("S")).count()); - - } - - @Test - public void Update3() { - update(survey).set(survey.name, survey.name.append("X")).execute(); - } - - @Test - public void SetNull() { - List> paths = Collections.>singletonList(survey.name); - List values = Collections.singletonList(null); - long count = query().from(survey).count(); - assertEquals(count, update(survey).set(paths, values).execute()); - } - - @Test - public void SetNull2() { - long count = query().from(survey).count(); - assertEquals(count, update(survey).set(survey.name, (String)null).execute()); - } - - @Test - public void Batch() throws SQLException{ - insert(survey).values(2, "A","B").execute(); - insert(survey).values(3, "B","C").execute(); - - SQLUpdateClause update = update(survey); - update.set(survey.name, "AA").where(survey.name.eq("A")).addBatch(); - update.set(survey.name, "BB").where(survey.name.eq("B")).addBatch(); - assertEquals(2, update.execute()); - } - - @Test - public void Update_with_SubQuery_exists() { - QSurvey survey1 = new QSurvey("s1"); - QEmployee employee = new QEmployee("e"); - SQLUpdateClause update = update(survey1); - update.set(survey1.name, "AA"); - update.where(new SQLSubQuery().from(employee).where(survey1.id.eq(employee.id)).exists()); - update.execute(); - } - - @Test - public void Update_with_SubQuery_exists_Params() { - QSurvey survey1 = new QSurvey("s1"); - QEmployee employee = new QEmployee("e"); - - Param param = new Param(Integer.class, "param"); - SQLSubQuery sq = sq().from(employee).where(employee.id.eq(param)); - sq.set(param, -12478923); - - SQLUpdateClause update = update(survey1); - update.set(survey1.name, "AA"); - update.where(sq.exists()); - update.execute(); - } - - @Test - public void Update_with_SubQuery_exists2() { - QSurvey survey1 = new QSurvey("s1"); - QEmployee employee = new QEmployee("e"); - SQLUpdateClause update = update(survey1); - update.set(survey1.name, "AA"); - update.where(new SQLSubQuery().from(employee).where(survey1.name.eq(employee.lastname)).exists()); - update.execute(); - } - - @Test - public void Update_with_SubQuery_notExists() { - QSurvey survey1 = new QSurvey("s1"); - QEmployee employee = new QEmployee("e"); - SQLUpdateClause update = update(survey1); - update.set(survey1.name, "AA"); - update.where(sq().from(employee).where(survey1.id.eq(employee.id)).notExists()); - update.execute(); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/ddl/ColumnData.java b/querydsl-sql/src/test/java/com/mysema/query/ddl/ColumnData.java deleted file mode 100644 index 3f1eaddc14..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/ddl/ColumnData.java +++ /dev/null @@ -1,61 +0,0 @@ -/* -* Copyright (c) 2010 Mysema Ltd. -* All rights reserved. -* -*/ -package com.mysema.query.ddl; - -/** -* @author tiwe -* -*/ -public class ColumnData { - - private final String name; - - private final String type; - - private boolean nullAllowed = true; - - private boolean autoIncrement; - - private Integer size; - - public ColumnData(String name, String type) { - this.name = name; - this.type = type; - } - - public String getName() { - return name; - } - - public String getType() { - return type; - } - - public boolean isNullAllowed() { - return nullAllowed; - } - - public void setNullAllowed(boolean nullAllowed) { - this.nullAllowed = nullAllowed; - } - - public void setSize(Integer size) { - this.size = size; - } - - public Integer getSize() { - return size; - } - - public boolean isAutoIncrement() { - return autoIncrement; - } - - public void setAutoIncrement(boolean autoIncrement) { - this.autoIncrement = autoIncrement; - } - -} \ No newline at end of file diff --git a/querydsl-sql/src/test/java/com/mysema/query/ddl/CreateTableClause.java b/querydsl-sql/src/test/java/com/mysema/query/ddl/CreateTableClause.java deleted file mode 100644 index 1a7844b9f2..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/ddl/CreateTableClause.java +++ /dev/null @@ -1,222 +0,0 @@ -/* - * Copyright (c) 2010 Mysema Ltd. - * All rights reserved. - * - */ -package com.mysema.query.ddl; - -import java.sql.Connection; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.ArrayList; -import java.util.List; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.common.base.Joiner; -import com.mysema.query.QueryException; -import com.mysema.query.sql.SQLTemplates; - -/** - * CreateTableClause defines a CREATE TABLE clause - * - * @author tiwe - * - */ -public class CreateTableClause { - - private static final Logger logger = LoggerFactory.getLogger(CreateTableClause.class); - - private static final Joiner COMMA_JOINER = Joiner.on(", "); - - private final Connection connection; - - private final SQLTemplates templates; - - private final String table; - - private final List columns = new ArrayList(); - - private final List indexes = new ArrayList(); - - private PrimaryKeyData primaryKey; - - private final List foreignKeys = new ArrayList(); - - public CreateTableClause(Connection conn, SQLTemplates templates, String table) { - this.connection = conn; - this.templates = templates; - this.table = templates.quoteIdentifier(table); - } - - /** - * Add a new column definition - * - * @param name - * @param type - * @return - */ - public CreateTableClause column(String name, Class type) { - columns.add(new ColumnData(templates.quoteIdentifier(name), templates.getTypeForClass(type))); - return this; - } - - private ColumnData lastColumn() { - return columns.get(columns.size()-1); - } - - /** - * Set the last added column to not null - * - * @return - */ - public CreateTableClause notNull() { - lastColumn().setNullAllowed(false); - return this; - } - - /** - * Set the size of the last column's type - * - * @param size - * @return - */ - public CreateTableClause size(int size) { - lastColumn().setSize(size); - return this; - } - - /** - * Set the last column to auto increment - * - * @return - */ - public CreateTableClause autoIncrement() { - lastColumn().setAutoIncrement(true); - return this; - } - - /** - * Set the primary key - * - * @param name - * @param columns - * @return - */ - public CreateTableClause primaryKey(String name, String... columns) { - for (int i = 0; i < columns.length; i++) { - columns[i] = templates.quoteIdentifier(columns[i]); - } - primaryKey = new PrimaryKeyData(templates.quoteIdentifier(name), columns); - return this; - } - - /** - * Add an index - * - * @param name - * @param columns - * @return - */ - public CreateTableClause index(String name, String... columns) { - indexes.add(new IndexData(name, columns)); - return this; - } - - /** - * Set the last added index to unique - * - * @return - */ - public CreateTableClause unique() { - indexes.get(indexes.size()-1).setUnique(true); - return this; - } - - /** - * Add a foreign key - * - * @param name - * @param columns - * @return - */ - public ForeignKeyBuilder foreignKey(String name, String... columns) { - return new ForeignKeyBuilder(this, templates, foreignKeys, templates.quoteIdentifier(name), columns); - } - - /** - * Execute the clause - */ - @SuppressWarnings("SQL_NONCONSTANT_STRING_PASSED_TO_EXECUTE") - public void execute() { - StringBuilder builder = new StringBuilder(); - builder.append(templates.getCreateTable() + table + " (\n"); - List lines = new ArrayList(columns.size() + foreignKeys.size() + 1); - // columns - for (ColumnData column : columns) { - StringBuilder line = new StringBuilder(); - line.append(column.getName() + " " + column.getType().toUpperCase()); - if (column.getSize() != null) { - line.append("(" + column.getSize() + ")"); - } - if (!column.isNullAllowed()) { - line.append(templates.getNotNull().toUpperCase()); - } - if (column.isAutoIncrement()) { - line.append(templates.getAutoIncrement().toUpperCase()); - } - lines.add(line.toString()); - } - - // primary key - if (primaryKey != null) { - StringBuilder line = new StringBuilder(); - line.append("CONSTRAINT " + primaryKey.getName()+ " "); - line.append("PRIMARY KEY(" + COMMA_JOINER.join(primaryKey.getColumns()) +")"); - lines.add(line.toString()); - } - - // foreign keys - for (ForeignKeyData foreignKey : foreignKeys) { - StringBuilder line = new StringBuilder(); - line.append("CONSTRAINT " + foreignKey.getName()+ " "); - line.append("FOREIGN KEY(" + COMMA_JOINER.join(foreignKey.getForeignColumns())+ ") "); - line.append("REFERENCES " + foreignKey.getTable() + "(" + COMMA_JOINER.join(foreignKey.getParentColumns())+ ")"); - lines.add(line.toString()); - } - builder.append(" " + Joiner.on(",\n ").join(lines)); - builder.append("\n)\n"); - logger.info(builder.toString()); - - Statement stmt = null; - try{ - stmt = connection.createStatement(); - stmt.execute(builder.toString()); - - // indexes - for (IndexData index : indexes) { - String indexColumns = COMMA_JOINER.join(index.getColumns()); - String prefix = templates.getCreateIndex(); - if (index.isUnique()) { - prefix = templates.getCreateUniqueIndex(); - } - String sql = prefix + index.getName() + templates.getOn() + table + "(" + indexColumns+ ")"; - logger.info(sql); - stmt.execute(sql); - } - } catch (SQLException e) { - System.err.println(builder.toString()); - throw new QueryException(e.getMessage(), e); - }finally{ - if (stmt != null) { - try { - stmt.close(); - } catch (SQLException e) { - throw new QueryException(e); - } - } - } - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/ddl/DropTableClause.java b/querydsl-sql/src/test/java/com/mysema/query/ddl/DropTableClause.java deleted file mode 100644 index e7f8d1c348..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/ddl/DropTableClause.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2010 Mysema Ltd. - * All rights reserved. - * - */ -package com.mysema.query.ddl; - -import java.sql.Connection; -import java.sql.SQLException; -import java.sql.Statement; - -import com.mysema.query.QueryException; -import com.mysema.query.sql.SQLTemplates; - -/** - * DropTableClause defines a DROP TABLE clause - * - * @author tiwe - * - */ -public class DropTableClause { - - private final Connection connection; - - private final String table; - - public DropTableClause(Connection conn, SQLTemplates templates, String table) { - this.connection = conn; - this.table = templates.quoteIdentifier(table); - } - - @SuppressWarnings("SQL_NONCONSTANT_STRING_PASSED_TO_EXECUTE") - public void execute() { - Statement stmt = null; - try{ - stmt = connection.createStatement(); - stmt.execute("DROP TABLE " + table); - } catch (SQLException e) { - // do not rethrow - }finally{ - if (stmt != null) { - try { - stmt.close(); - } catch (SQLException e) { - throw new QueryException(e); - } - } - } - } - -} - \ No newline at end of file diff --git a/querydsl-sql/src/test/java/com/mysema/query/ddl/ForeignKeyData.java b/querydsl-sql/src/test/java/com/mysema/query/ddl/ForeignKeyData.java deleted file mode 100644 index f7f6ca0217..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/ddl/ForeignKeyData.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2010 Mysema Ltd. - * All rights reserved. - * - */ -package com.mysema.query.ddl; - -import java.util.ArrayList; -import java.util.List; - -/** - * @author tiwe - * - */ -public class ForeignKeyData implements KeyData { - - private final String name; - - private final String table; - - private final List foreignColumns = new ArrayList(); - - private final List parentColumns = new ArrayList(); - - public ForeignKeyData(String name, String parentTable) { - this.name = name; - this.table = parentTable; - } - - public void add(String foreignColumn, String parentColumn) { - foreignColumns.add(foreignColumn); - parentColumns.add(parentColumn); - } - - public String getName() { - return name; - } - - public String getTable() { - return table; - } - - public List getForeignColumns() { - return foreignColumns; - } - - public List getParentColumns() { - return parentColumns; - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/ddl/IndexData.java b/querydsl-sql/src/test/java/com/mysema/query/ddl/IndexData.java deleted file mode 100644 index 92b47c7055..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/ddl/IndexData.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2010 Mysema Ltd. - * All rights reserved. - * - */ -package com.mysema.query.ddl; - -/** - * @author tiwe - * - */ -public class IndexData { - - private final String name; - - private final String[] columns; - - private boolean unique; - - public IndexData(String name, String[] columns) { - this.name = name; - this.columns = columns.clone(); - } - - public String getName() { - return name; - } - - public String[] getColumns() { - return columns.clone(); - } - - public boolean isUnique() { - return unique; - } - - public void setUnique(boolean unique) { - this.unique = unique; - } - - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/ddl/KeyData.java b/querydsl-sql/src/test/java/com/mysema/query/ddl/KeyData.java deleted file mode 100644 index 81f122c95e..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/ddl/KeyData.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * - */ -package com.mysema.query.ddl; - -import java.util.List; - -/** - * Common interface for ForeignKeyData and InverseForeignKeyData - * - * @author tiwe - * - */ -public interface KeyData { - - String getName(); - - String getTable(); - - List getForeignColumns(); - - List getParentColumns(); - -} \ No newline at end of file diff --git a/querydsl-sql/src/test/java/com/mysema/query/ddl/PrimaryKeyData.java b/querydsl-sql/src/test/java/com/mysema/query/ddl/PrimaryKeyData.java deleted file mode 100644 index 7037c53538..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/ddl/PrimaryKeyData.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2010 Mysema Ltd. - * All rights reserved. - * - */ -package com.mysema.query.ddl; - -import java.util.ArrayList; -import java.util.List; - -/** - * @author tiwe - * - */ -public class PrimaryKeyData { - - private final String name; - - private final List columns = new ArrayList(); - - public PrimaryKeyData(String name) { - this.name = name; - } - - public PrimaryKeyData(String name, String[] c) { - this.name = name; - for (String column : c) { - columns.add(column); - } - } - - public void add(String column) { - columns.add(column); - } - - public String getName() { - return name; - } - - public List getColumns() { - return columns; - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/AbstractSQLTemplatesTest.java b/querydsl-sql/src/test/java/com/mysema/query/sql/AbstractSQLTemplatesTest.java deleted file mode 100644 index bccd32e821..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/AbstractSQLTemplatesTest.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import static org.junit.Assert.assertEquals; - -import org.junit.Before; -import org.junit.Test; - -import com.mysema.query.sql.domain.QSurvey; -import com.mysema.query.types.Path; -import com.mysema.query.types.expr.NumberExpression; -import com.mysema.query.types.path.SimplePath; -import com.mysema.query.types.template.NumberTemplate; - -public abstract class AbstractSQLTemplatesTest { - - protected static final QSurvey survey1 = new QSurvey("survey1"); - - protected static final QSurvey survey2 = new QSurvey("survey2"); - - private SQLTemplates templates; - - protected SQLQuery query; - - protected abstract SQLTemplates createTemplates(); - - @Before - public void setUp() { - templates = createTemplates(); - templates.newLineToSingleSpace(); - query = new SQLQuery(templates); - } - - @Test - public void NoFrom() { - query.getMetadata().addProjection(NumberTemplate.ONE); - if (templates.getDummyTable() == null) { - assertEquals("select 1", query.toString()); - } else { - assertEquals("select 1 from dual", query.toString()); - } - } - - @SuppressWarnings("unchecked") - @Test - public void Union() { - NumberExpression one = NumberTemplate.ONE; - NumberExpression two = NumberTemplate.TWO; - NumberExpression three = NumberTemplate.THREE; - Path col1 = new SimplePath(Integer.class,"col1"); - Union union = query.union( - sq().unique(one.as(col1)), - sq().unique(two), - sq().unique(three)); - - if (templates.getDummyTable() == null) { - assertEquals( - "(select 1 as col1)\n" + - "union\n" + - "(select 2)\n" + - "union\n" + - "(select 3)", union.toString()); - } else { - assertEquals( - "(select 1 as col1 from dual)\n" + - "union\n" + - "(select 2 from dual)\n" + - "union\n" + - "(select 3 from dual)", union.toString()); - } - } - - @Test - public void InnerJoin() { - query.from(survey1).innerJoin(survey2); - assertEquals("from SURVEY survey1 inner join SURVEY survey2", query.toString()); - } - - protected SQLSubQuery sq() { - return new SQLSubQuery(); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/ConfigurationTest.java b/querydsl-sql/src/test/java/com/mysema/query/sql/ConfigurationTest.java deleted file mode 100644 index ed220e5051..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/ConfigurationTest.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import java.io.InputStream; -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.sql.Types; - -import com.mysema.query.alias.Gender; -import com.mysema.query.sql.domain.QSurvey; -import com.mysema.query.sql.types.*; -import org.easymock.EasyMock; -import org.junit.Test; -import static org.junit.Assert.assertEquals; - -public class ConfigurationTest { - - @Test - public void Various() { - Configuration configuration = new Configuration(new H2Templates()); -// configuration.setJavaType(Types.DATE, java.util.Date.class); - configuration.register(new UtilDateType()); - configuration.register("person", "secureId", new EncryptedString()); - configuration.register("person", "gender", new EnumByNameType(Gender.class)); - configuration.register(new StringType()); - assertEquals(Gender.class, configuration.getJavaType(java.sql.Types.VARCHAR, null, 0,0,"person", "gender")); - } - - @Test - public void Custom_Type() { - Configuration configuration = new Configuration(new H2Templates()); -// configuration.setJavaType(Types.BLOB, InputStream.class); - configuration.register(new InputStreamType()); - assertEquals(InputStream.class, configuration.getJavaType(Types.BLOB, null, 0,0,"", "")); - } - - @Test - public void Set_Null() throws SQLException { - Configuration configuration = new Configuration(new H2Templates()); -// configuration.register(new UntypedNullType()); - configuration.register("SURVEY", "NAME", new EncryptedString()); - PreparedStatement stmt = EasyMock.createNiceMock(PreparedStatement.class); - configuration.set(stmt, QSurvey.survey.name, 0, Null.DEFAULT); - } - - @Test - public void Get_Schema() { - Configuration configuration = new Configuration(new H2Templates()); - configuration.registerSchemaOverride("public", "pub"); - configuration.registerTableOverride("employee", "emp"); - configuration.registerTableOverride("public", "employee", "employees"); - - assertEquals("pub", configuration.getOverride(new SchemaAndTable("public", "")).getSchema()); - assertEquals("emp", configuration.getOverride(new SchemaAndTable("", "employee")).getTable()); - assertEquals("employees", configuration.getOverride(new SchemaAndTable("public", "employee")).getTable()); -// assertEquals("pub", configuration.getSchema("public")); -// assertEquals("emp", configuration.getTable("", "employee")); -// assertEquals("employees", configuration.getTable("public", "employee")); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/DateArithmeticTest.java b/querydsl-sql/src/test/java/com/mysema/query/sql/DateArithmeticTest.java deleted file mode 100644 index 22c65fa3e8..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/DateArithmeticTest.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.mysema.query.sql; - -import java.util.Date; -import java.util.List; - -import org.junit.Test; - -import com.google.common.collect.Lists; -import com.mysema.query.types.Expression; -import com.mysema.query.types.path.DateTimePath; - -public class DateArithmeticTest { - - private String serialize(Expression expr, SQLTemplates templates) { - SQLSerializer serializer = new SQLSerializer(new Configuration(templates)); - serializer.handle(expr); - return serializer.toString(); - } - - @Test - public void test() { - List list = Lists.newArrayList(); - list.add(new CUBRIDTemplates()); - list.add(new DerbyTemplates()); - list.add(new H2Templates()); - list.add(new HSQLDBTemplates()); - list.add(new MySQLTemplates()); - list.add(new OracleTemplates()); - list.add(new PostgresTemplates()); - list.add(new SQLiteTemplates()); - list.add(new SQLServerTemplates()); - list.add(new SQLServer2005Templates()); - list.add(new SQLServer2012Templates()); - list.add(new TeradataTemplates()); - - List> exprs = Lists.newArrayList(); - DateTimePath path = new DateTimePath(Date.class, "date"); - exprs.add(SQLExpressions.addYears(path, 2)); - exprs.add(SQLExpressions.addMonths(path, 2)); - exprs.add(SQLExpressions.addDays(path, 2)); - exprs.add(SQLExpressions.addHours(path, 2)); - exprs.add(SQLExpressions.addMinutes(path, 2)); - exprs.add(SQLExpressions.addSeconds(path, 2)); - - for (SQLTemplates templates : list) { - System.out.println(templates.getClass().getSimpleName()); - for (Expression expr : exprs) { - System.err.println(serialize(expr, templates)); - } - System.out.println(); - - } - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/DerbyTemplatesTest.java b/querydsl-sql/src/test/java/com/mysema/query/sql/DerbyTemplatesTest.java deleted file mode 100644 index a86045707e..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/DerbyTemplatesTest.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import static org.junit.Assert.assertEquals; - -import org.junit.Test; - -import com.mysema.query.types.ConstantImpl; -import com.mysema.query.types.Operation; -import com.mysema.query.types.OperationImpl; - -public class DerbyTemplatesTest { - - @Test - public void NextVal() { - Operation nextval = OperationImpl.create(String.class, SQLOps.NEXTVAL, ConstantImpl.create("myseq")); - assertEquals("next value for myseq", new SQLSerializer(new Configuration(new DerbyTemplates())).handle(nextval).toString()); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/EncryptedString.java b/querydsl-sql/src/test/java/com/mysema/query/sql/EncryptedString.java deleted file mode 100644 index a4f42d9ff7..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/EncryptedString.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import com.mysema.query.sql.types.StringType; - -public class EncryptedString extends StringType{ - -} \ No newline at end of file diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/H2TemplatesTest.java b/querydsl-sql/src/test/java/com/mysema/query/sql/H2TemplatesTest.java deleted file mode 100644 index 3c74b970c0..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/H2TemplatesTest.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import static org.junit.Assert.*; - -import org.junit.Test; - -public class H2TemplatesTest extends AbstractSQLTemplatesTest{ - - @Override - protected SQLTemplates createTemplates() { - return new H2Templates(); - } - - @Test - public void Builder() { - SQLTemplates templates = H2Templates.builder().quote() - .newLineToSingleSpace() - .build(); - - assertNotNull(templates); - } -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/JavaTypeMappingTest.java b/querydsl-sql/src/test/java/com/mysema/query/sql/JavaTypeMappingTest.java deleted file mode 100644 index bed6949e4c..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/JavaTypeMappingTest.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -import java.io.FileInputStream; -import java.io.InputStream; - -import org.junit.Test; - -import com.mysema.query.sql.types.BlobType; -import com.mysema.query.sql.types.BooleanType; -import com.mysema.query.sql.types.ByteType; -import com.mysema.query.sql.types.CharacterType; -import com.mysema.query.sql.types.DoubleType; -import com.mysema.query.sql.types.FloatType; -import com.mysema.query.sql.types.InputStreamType; -import com.mysema.query.sql.types.IntegerType; -import com.mysema.query.sql.types.LongType; -import com.mysema.query.sql.types.ObjectType; -import com.mysema.query.sql.types.ShortType; - -public class JavaTypeMappingTest { - - private JavaTypeMapping typeMapping = new JavaTypeMapping(); - - @Test - public void GetType_With_Subtypes() { - typeMapping.register(new InputStreamType()); - assertNotNull(typeMapping.getType(InputStream.class)); - assertNotNull(typeMapping.getType(FileInputStream.class)); - } - - @Test - public void GetType_With_Interfaces() { - assertEquals(BlobType.class, typeMapping.getType(DummyBlob.class).getClass()); - } - - @Test - public void GetType_for_Object() { - assertEquals(ObjectType.class, typeMapping.getType(Object.class).getClass()); - } - - @Test - public void GetType_For_Primitive() { - assertEquals(ByteType.class, typeMapping.getType(byte.class).getClass()); - assertEquals(ShortType.class, typeMapping.getType(short.class).getClass()); - assertEquals(IntegerType.class, typeMapping.getType(int.class).getClass()); - assertEquals(LongType.class, typeMapping.getType(long.class).getClass()); - assertEquals(FloatType.class, typeMapping.getType(float.class).getClass()); - assertEquals(DoubleType.class, typeMapping.getType(double.class).getClass()); - assertEquals(BooleanType.class, typeMapping.getType(boolean.class).getClass()); - assertEquals(CharacterType.class, typeMapping.getType(char.class).getClass()); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/JoinFlagsTest.java b/querydsl-sql/src/test/java/com/mysema/query/sql/JoinFlagsTest.java deleted file mode 100644 index 177e596683..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/JoinFlagsTest.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import static org.junit.Assert.assertEquals; - -import java.sql.Connection; - -import org.easymock.EasyMock; -import org.junit.Before; -import org.junit.Test; - -import com.mysema.query.JoinFlag; -import com.mysema.query.sql.domain.QSurvey; - -public class JoinFlagsTest { - - private Connection connection = EasyMock.createMock(Connection.class); - - private QSurvey s1, s2, s3, s4, s5, s6; - - private SQLQuery query; - - @Before - public void setUp() { - s1 = new QSurvey("s"); - s2 = new QSurvey("s2"); - s3 = new QSurvey("s3"); - s4 = new QSurvey("s4"); - s5 = new QSurvey("s5"); - s6 = new QSurvey("s6"); - query = new SQLQuery(connection,SQLTemplates.DEFAULT); - query.from(s1); - } - - @Test - public void JoinFlag_BeforeCondition() { - query.innerJoin(s2).on(s1.eq(s2)); - query.addJoinFlag(" a ", JoinFlag.Position.BEFORE_CONDITION); - - assertEquals("from SURVEY s\n" + - "inner join SURVEY s2 a \n" + - "on s = ?", query.toString()); - } - - @Test - public void JoinFlags_BeforeTarget() { - query.innerJoin(s3).on(s1.eq(s3)); - query.addJoinFlag(" b ", JoinFlag.Position.BEFORE_TARGET); - - assertEquals("from SURVEY s\n" + - "inner join b SURVEY s3\n" + - "on s = ?", query.toString()); - } - - @Test - public void JoinFlags_End() { - query.innerJoin(s4).on(s1.eq(s4)); - query.addJoinFlag(" c ", JoinFlag.Position.END); - - assertEquals("from SURVEY s\n" + - "inner join SURVEY s4\n" + - "on s = ? c", query.toString()); - } - - @Test - public void JoinFlags_Override() { - query.innerJoin(s5).on(s1.eq(s5)); - query.addJoinFlag(" d ", JoinFlag.Position.OVERRIDE); - - assertEquals("from SURVEY s d SURVEY s5\n" + - "on s = ?", query.toString()); - } - - @Test - public void JoinFlags_Start() { - query.innerJoin(s6).on(s1.eq(s6)); - query.addJoinFlag(" e ", JoinFlag.Position.START); - - assertEquals("from SURVEY s e \n" + - "inner join SURVEY s6\n" + - "on s = ?", query.toString()); - } - - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/JoinUsageTest.java b/querydsl-sql/src/test/java/com/mysema/query/sql/JoinUsageTest.java deleted file mode 100644 index 5a85cea6e1..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/JoinUsageTest.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import org.junit.Test; - -import com.mysema.query.DefaultQueryMetadata; -import com.mysema.query.sql.domain.QSurvey; - -public class JoinUsageTest { - - @Test(expected=IllegalStateException.class) - public void Join_Already_Declared() { - QSurvey survey = QSurvey.survey; - SQLSubQuery subQuery = new SQLSubQuery(new DefaultQueryMetadata()); - subQuery.from(survey).fullJoin(survey); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/MySQLTemplatesTest.java b/querydsl-sql/src/test/java/com/mysema/query/sql/MySQLTemplatesTest.java deleted file mode 100644 index 47d0ddaca2..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/MySQLTemplatesTest.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import static org.junit.Assert.assertEquals; - -import org.junit.Test; - - - -public class MySQLTemplatesTest extends AbstractSQLTemplatesTest { - - @Override - protected SQLTemplates createTemplates() { - return new MySQLTemplates(); - } - - @Test - public void test() { - SQLTemplates templates = MySQLTemplates.builder() - .printSchema() - .build(); - Configuration conf = new Configuration(templates); - System.out.println(new SQLQuery(conf).from(survey1).toString()); - } - - @Test - public void Order_NullsFirst() { - query.from(survey1).orderBy(survey1.name.asc().nullsFirst()); - assertEquals("from SURVEY survey1 order by (case when survey1.NAME is null then 0 else 1 end), survey1.NAME asc", query.toString()); - } - - @Test - public void Order_NullsLast() { - query.from(survey1).orderBy(survey1.name.asc().nullsLast()); - assertEquals("from SURVEY survey1 order by (case when survey1.NAME is null then 1 else 0 end), survey1.NAME asc", query.toString()); - } - - - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/OracleTemplatesTest.java b/querydsl-sql/src/test/java/com/mysema/query/sql/OracleTemplatesTest.java deleted file mode 100644 index 338b1015ce..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/OracleTemplatesTest.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import static org.junit.Assert.assertEquals; - -import org.junit.Test; - -import com.mysema.query.QueryFlag; -import com.mysema.query.types.ConstantImpl; -import com.mysema.query.types.Operation; -import com.mysema.query.types.OperationImpl; -import com.mysema.query.types.expr.SimpleExpression; -import com.mysema.query.types.path.NumberPath; -import com.mysema.query.types.template.SimpleTemplate; - - - -public class OracleTemplatesTest extends AbstractSQLTemplatesTest{ - - @Override - protected SQLTemplates createTemplates() { - return new OracleTemplates(); - } - - @Override - @SuppressWarnings("unchecked") - @Test - public void Union() { - SimpleExpression one = SimpleTemplate.create(Integer.class,"1"); - SimpleExpression two = SimpleTemplate.create(Integer.class,"2"); - SimpleExpression three = SimpleTemplate.create(Integer.class,"3"); - NumberPath col1 = new NumberPath(Integer.class,"col1"); - Union union = query.union( - sq().unique(one.as(col1)), - sq().unique(two), - sq().unique(three)); - assertEquals( - "(select 1 col1 from dual)\n" + - "union\n" + - "(select 2 from dual)\n" + - "union\n" + - "(select 3 from dual)", union.toString()); - } - - @Test - public void Modifiers() { - query.from(survey1).limit(5).offset(3); - query.getMetadata().addProjection(survey1.id); - assertEquals("select * from ( " + - "select a.*, rownum rn from ( " + - "select survey1.ID from SURVEY survey1 ) " + - "a) " + - "where rn > 3 and rownum <= 5", query.toString()); - } - - @Test - public void Modifiers2() { - query.from(survey1).limit(5).offset(3); - query.getMetadata().addProjection(survey1.id); - query.getMetadata().addFlag(new QueryFlag(QueryFlag.Position.AFTER_PROJECTION, ", count(*) over() ")); - - assertEquals("select * from ( " + - "select a.*, rownum rn from ( " + - "select survey1.ID, count(*) over() from SURVEY survey1 ) " + - "a) " + - "where rn > 3 and rownum <= 5", query.toString()); - } - - @Test - public void NextVal() { - Operation nextval = OperationImpl.create(String.class, SQLOps.NEXTVAL, ConstantImpl.create("myseq")); - assertEquals("myseq.nextval", new SQLSerializer(new Configuration(new OracleTemplates())).handle(nextval).toString()); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/PaginationTest.java b/querydsl-sql/src/test/java/com/mysema/query/sql/PaginationTest.java deleted file mode 100644 index 933e957b53..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/PaginationTest.java +++ /dev/null @@ -1,70 +0,0 @@ -package com.mysema.query.sql; - -import java.util.List; - -import org.junit.Test; - -import com.google.common.collect.Lists; -import com.mysema.query.QueryMetadata; -import com.mysema.query.QueryModifiers; -import com.mysema.query.sql.domain.QEmployee; -import com.mysema.query.support.QueryMixin; - -public class PaginationTest { - - private String serialize(QueryMetadata metadata, SQLTemplates templates) { - SQLSerializer serializer = new SQLSerializer(new Configuration(templates)); - serializer.serialize(metadata, false); - return serializer.toString(); - } - - @Test - public void test() { - List list = Lists.newArrayList(); - list.add(new CUBRIDTemplates()); - list.add(new DerbyTemplates()); - list.add(new H2Templates()); - list.add(new HSQLDBTemplates()); - list.add(new MySQLTemplates()); - list.add(new OracleTemplates()); // inner query - list.add(new PostgresTemplates()); - list.add(new SQLiteTemplates()); - list.add(new SQLServerTemplates()); - list.add(new SQLServer2005Templates()); // inner query - list.add(new SQLServer2012Templates()); - list.add(new TeradataTemplates()); // qualify - - for (SQLTemplates templates : list) { - QEmployee employee = QEmployee.employee; - QueryMixin query = new QueryMixin(); - query.from(employee); - query.orderBy(employee.firstname.asc()); - query.addProjection(employee.id); - - System.out.println(templates.getClass().getSimpleName()); - System.out.println(); - - // limit - query.restrict(QueryModifiers.limit(10l)); - System.out.println("* limit"); - System.out.println(serialize(query.getMetadata(), templates)); - System.out.println(); - - if (!templates.getClass().equals(SQLServerTemplates.class)) { - // offset - query.restrict(QueryModifiers.offset(10l)); - System.out.println("* offset"); - System.out.println(serialize(query.getMetadata(), templates)); - System.out.println(); - - // limit and offset - query.restrict(new QueryModifiers(10l, 10l)); - System.out.println("* limit and offset"); - System.out.println(serialize(query.getMetadata(), templates)); - System.out.println(); - } - - } - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/PerformanceTest.java b/querydsl-sql/src/test/java/com/mysema/query/sql/PerformanceTest.java deleted file mode 100644 index b1f9c737cd..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/PerformanceTest.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.mysema.query.sql; - -import static org.junit.Assert.assertNotNull; - -import org.junit.Before; -import org.junit.Test; -import org.junit.experimental.categories.Category; - -import com.mysema.query.DefaultQueryMetadata; -import com.mysema.query.JoinType; -import com.mysema.query.QueryMetadata; -import com.mysema.query.sql.domain.QSurvey; -import com.mysema.testutil.Performance; - -@Category(Performance.class) -public class PerformanceTest { - - private QueryMetadata md; - - private SQLTemplates templates; - - private Configuration configuration; - - int iterations; - - @Before - public void setUp() { - QSurvey survey = QSurvey.survey; - md = new DefaultQueryMetadata(); - md.addJoin(JoinType.DEFAULT, survey); - md.addWhere(survey.id.eq(10)); - md.addProjection(survey.name); - - templates = new H2Templates(); - configuration = new Configuration(templates); - - iterations = 1000000; - } - - @Test - public void NonNormalized() { - long start = System.currentTimeMillis(); - for (int i = 0; i < iterations; i++) { - SQLSerializer serializer = new SQLSerializer(configuration); - serializer.setNormalize(false); - serializer.serialize(md, false); - serializer.getConstants(); - serializer.getConstantPaths(); - assertNotNull(serializer.toString()); - } - System.err.println("non-normalized " + (System.currentTimeMillis() - start)); - } - - @Test - public void Default() { - long start = System.currentTimeMillis(); - for (int i = 0; i < iterations; i++) { - SQLSerializer serializer = new SQLSerializer(configuration); - serializer.serialize(md, false); - serializer.getConstants(); - serializer.getConstantPaths(); - assertNotNull(serializer.toString()); - } - System.err.println("default " + (System.currentTimeMillis() - start)); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/PostgresTemplatesTest.java b/querydsl-sql/src/test/java/com/mysema/query/sql/PostgresTemplatesTest.java deleted file mode 100644 index 521a64489a..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/PostgresTemplatesTest.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import static org.junit.Assert.assertEquals; - -import org.junit.Test; - -import com.mysema.query.types.Path; -import com.mysema.query.types.expr.NumberExpression; -import com.mysema.query.types.path.SimplePath; -import com.mysema.query.types.template.NumberTemplate; - - -public class PostgresTemplatesTest extends AbstractSQLTemplatesTest{ - - @Override - protected SQLTemplates createTemplates() { - return new PostgresTemplates(); - } - - @Test - public void NoFrom() { - query.getMetadata().addProjection(NumberTemplate.ONE); - assertEquals("select 1", query.toString()); - } - - @SuppressWarnings("unchecked") - @Test - public void Union() { - NumberExpression one = NumberTemplate.ONE; - NumberExpression two = NumberTemplate.TWO; - NumberExpression three = NumberTemplate.THREE; - Path col1 = new SimplePath(Integer.class,"col1"); - Union union = query.union( - sq().unique(one.as(col1)), - sq().unique(two), - sq().unique(three)); - assertEquals( - "(select 1 as col1)\n" + - "union\n" + - "(select 2)\n" + - "union\n" + - "(select 3)", union.toString()); - } - - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/QBeanTest.java b/querydsl-sql/src/test/java/com/mysema/query/sql/QBeanTest.java deleted file mode 100644 index 340956d639..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/QBeanTest.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import static org.junit.Assert.assertEquals; - -import org.junit.Test; - -import com.mysema.query.sql.domain.Employee; -import com.mysema.query.sql.domain.QEmployee; -import com.mysema.query.types.FactoryExpression; -import com.mysema.query.types.QBean; - -public class QBeanTest { - - private final QEmployee e = new QEmployee("e"); - - @Test - public void Direct_to_Managed_type() { - FactoryExpression expr = new QBean(Employee.class, e.superiorId); - Employee e = expr.newInstance(3); - assertEquals(Integer.valueOf(3), e.getSuperiorId()); - } - - @Test - public void Direct_to_Custom_type() { - FactoryExpression expr = new QBean(Employee.class, e.firstname, e.lastname); - Employee e = expr.newInstance("John","Smith"); - assertEquals("John", e.getFirstname()); - assertEquals("Smith", e.getLastname()); - } - - @Test - public void Alias_to_Managed_type() { - FactoryExpression expr = new QBean(Employee.class, e.superiorId.as("id")); - Employee e = expr.newInstance(3); - assertEquals(3, e.getId().intValue()); - } - - @Test - public void Alias_to_Custom_type() { - FactoryExpression expr = new QBean(Employee.class, e.firstname.as("lastname"), e.lastname.as("firstname")); - Employee e = expr.newInstance("John","Smith"); - assertEquals("Smith", e.getFirstname()); - assertEquals("John", e.getLastname()); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/QPerson.java b/querydsl-sql/src/test/java/com/mysema/query/sql/QPerson.java deleted file mode 100644 index dc5b363cce..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/QPerson.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import com.mysema.query.types.PathMetadata; -import com.mysema.query.types.PathMetadataFactory; -import com.mysema.query.types.path.BeanPath; -import com.mysema.query.types.path.EnumPath; -import com.mysema.query.types.path.NumberPath; -import com.mysema.query.types.path.StringPath; - -//@Table("PERSON") -public class QPerson extends RelationalPathBase { - - private static final long serialVersionUID = 475064746; - - public static final QPerson person = new QPerson("PERSON"); - - public final StringPath firstname = createString("firstname"); - - public final EnumPath gender = createEnum("gender", com.mysema.query.alias.Gender.class); - - public final NumberPath id = createNumber("id", Integer.class); - - public final StringPath securedid = createString("securedid"); - - public final PrimaryKey sysIdx118 = createPrimaryKey(id); - - public QPerson(String variable) { - super(QPerson.class, PathMetadataFactory.forVariable(variable), null, "PERSON"); - addMetadata(); - } - - public QPerson(BeanPath entity) { - super(entity.getType(), entity.getMetadata(), "", "PERSON"); - addMetadata(); - } - - public QPerson(PathMetadata metadata) { - super(QPerson.class, metadata, "", "PERSON"); - addMetadata(); - } - - protected void addMetadata() { - addMetadata(id, ColumnMetadata.named("ID")); - addMetadata(firstname, ColumnMetadata.named("FIRSTNAME")); - addMetadata(securedid, ColumnMetadata.named("SECUREDID")); - addMetadata(gender, ColumnMetadata.named("GENDER")); - } - -} \ No newline at end of file diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/RelationalFunctionCallTest.java b/querydsl-sql/src/test/java/com/mysema/query/sql/RelationalFunctionCallTest.java deleted file mode 100644 index 02a3231eef..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/RelationalFunctionCallTest.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import static org.junit.Assert.assertEquals; - -import org.junit.Test; - -import com.mysema.query.sql.domain.QSurvey; -import com.mysema.query.types.ConstantImpl; -import com.mysema.query.types.Expression; -import com.mysema.query.types.path.PathBuilder; -import com.mysema.query.types.path.StringPath; - -public class RelationalFunctionCallTest { - - private static Expression[] serializeCollection(String... tokens) { - Expression[] rv = new Expression[tokens.length]; - for (int i = 0; i < tokens.length; i++) { - rv[i] = ConstantImpl.create(tokens[i]); - } - return rv; - } - - private static class TokenizeFunction extends RelationalFunctionCall { - final PathBuilder alias; - final StringPath token; - - public TokenizeFunction(String alias, String... tokens) { - super(String.class, "tokenize", serializeCollection(tokens)); - this.alias = new PathBuilder(String.class, alias); - this.token = new StringPath(this.alias, "token"); - } - - } - - @Test - public void Validation() { - QSurvey survey = QSurvey.survey; - TokenizeFunction func = new TokenizeFunction("func", "a", "b"); - SQLSubQuery sub = new SQLSubQuery().from(func.as(func.alias)).where(survey.name.like(func.token)); - System.out.println(sub); - - } - - @Test - public void NoArgs() { - RelationalFunctionCall functionCall = RelationalFunctionCall.create(String.class, "getElements"); - assertEquals("getElements()", functionCall.getTemplate().toString()); - } - - @Test - public void TwoArgs() { - StringPath str = new StringPath("str"); - RelationalFunctionCall functionCall = RelationalFunctionCall.create(String.class, "getElements", "a", str); - assertEquals("getElements({0}, {1})", functionCall.getTemplate().toString()); - assertEquals("a", functionCall.getArg(0)); - assertEquals(str, functionCall.getArg(1)); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/RelationalPathExtractorTest.java b/querydsl-sql/src/test/java/com/mysema/query/sql/RelationalPathExtractorTest.java deleted file mode 100644 index 03b95f4bd5..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/RelationalPathExtractorTest.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.mysema.query.sql; - -import static com.mysema.query.Constants.employee; -import static com.mysema.query.sql.RelationalPathExtractor.extract; -import static org.junit.Assert.assertEquals; - -import org.junit.Test; - -import com.google.common.collect.ImmutableSet; -import com.mysema.query.sql.domain.QEmployee; -import com.mysema.query.support.Expressions; - -public class RelationalPathExtractorTest { - - private SQLQuery query() { - return new SQLQuery(SQLTemplates.DEFAULT); - } - - private SQLSubQuery sq() { - return new SQLSubQuery(); - } - - @Test - public void SimpleQuery() { - QEmployee employee2 = new QEmployee("employee2"); - SQLQuery query = query().from(employee, employee2); - - assertEquals(ImmutableSet.of(employee, employee2), extract(query.getMetadata())); - } - - @Test - public void Joins() { - QEmployee employee2 = new QEmployee("employee2"); - SQLQuery query = query().from(employee) - .innerJoin(employee2).on(employee.superiorId.eq(employee2.id)); - - assertEquals(ImmutableSet.of(employee, employee2), extract(query.getMetadata())); - } - - @Test - public void SubQuery() { - SQLQuery query = query().from(employee) - .where(employee.id.eq(sq().from(employee).unique(employee.id.max()))); - assertEquals(ImmutableSet.of(employee), extract(query.getMetadata())); - } - - @Test - public void SubQuery2() { - QEmployee employee2 = new QEmployee("employee2"); - SQLQuery query = query().from(employee) - .where(Expressions.list(employee.id, employee.lastname) - .in(sq().from(employee2).list(employee2.id, employee2.lastname))); - - assertEquals(ImmutableSet.of(employee, employee2), extract(query.getMetadata())); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/RelationalPathTest.java b/querydsl-sql/src/test/java/com/mysema/query/sql/RelationalPathTest.java deleted file mode 100644 index fdb6db5dbe..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/RelationalPathTest.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.mysema.query.sql; - -import static org.junit.Assert.assertEquals; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.util.Arrays; - -import org.junit.Test; - -import com.mysema.query.sql.domain.QSurvey; -import com.mysema.query.types.QTuple; - -public class RelationalPathTest { - - @Test - public void Path() throws ClassNotFoundException, IOException { - QSurvey survey = QSurvey.survey; - QSurvey survey2 = (QSurvey) serialize(survey); - assertEquals(Arrays.asList(survey.all()), Arrays.asList(survey2.all())); - assertEquals(survey.getMetadata(), survey2.getMetadata()); - assertEquals(survey.getMetadata(survey.id), survey2.getMetadata(survey.id)); - } - - @Test - public void In_Tuple() throws ClassNotFoundException, IOException { - //(survey.id, survey.name) - QSurvey survey = QSurvey.survey; - QTuple tuple = new QTuple(survey.id, survey.name); - serialize(tuple); - serialize(tuple.newInstance(1, "a")); - } - - private Object serialize(Object obj) throws IOException, ClassNotFoundException{ - ByteArrayOutputStream bytesOut = new ByteArrayOutputStream(); - ObjectOutputStream out = new ObjectOutputStream(bytesOut); - out.writeObject(obj); - out.close(); - - ByteArrayInputStream bytesIn = new ByteArrayInputStream(bytesOut.toByteArray()); - ObjectInputStream in = new ObjectInputStream(bytesIn); - return in.readObject(); - } -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/SQLBindingsTest.java b/querydsl-sql/src/test/java/com/mysema/query/sql/SQLBindingsTest.java deleted file mode 100644 index 043cde4f14..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/SQLBindingsTest.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.mysema.query.sql; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import java.util.Arrays; - -import org.junit.Test; - -import com.mysema.query.sql.domain.QSurvey; -import com.mysema.query.types.expr.Param; - -public class SQLBindingsTest { - - private QSurvey survey = QSurvey.survey; - - private SQLQuery query = new SQLQuery(SQLTemplates.DEFAULT); - - @Test - public void Empty() { - SQLBindings bindings = query.getSQL(); - assertEquals("\nfrom dual", bindings.getSQL()); - assertTrue(bindings.getBindings().isEmpty()); - } - - @Test - public void SingleArg() { - query.from(survey).where(survey.name.eq("Bob")); - SQLBindings bindings = query.getSQL(survey.id); - assertEquals("select SURVEY.ID\nfrom SURVEY SURVEY\nwhere SURVEY.NAME = ?", bindings.getSQL()); - assertEquals(Arrays.asList("Bob"), bindings.getBindings()); - } - - @Test - public void TwoArgs() { - query.from(survey).where(survey.name.eq("Bob"), survey.name2.eq("A")); - SQLBindings bindings = query.getSQL(survey.id); - assertEquals("select SURVEY.ID\nfrom SURVEY SURVEY\nwhere SURVEY.NAME = ? and SURVEY.NAME2 = ?", bindings.getSQL()); - assertEquals(Arrays.asList("Bob", "A"), bindings.getBindings()); - } - - @Test - public void Params() { - Param name = new Param(String.class, "name"); - query.from(survey).where(survey.name.eq(name), survey.name2.eq("A")); - query.set(name, "Bob"); - SQLBindings bindings = query.getSQL(survey.id); - assertEquals("select SURVEY.ID\nfrom SURVEY SURVEY\nwhere SURVEY.NAME = ? and SURVEY.NAME2 = ?", bindings.getSQL()); - assertEquals(Arrays.asList("Bob", "A"), bindings.getBindings()); - } -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/SQLQueryFactoryTest.java b/querydsl-sql/src/test/java/com/mysema/query/sql/SQLQueryFactoryTest.java deleted file mode 100644 index 40ed22b0ea..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/SQLQueryFactoryTest.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import static org.junit.Assert.assertNotNull; - -import java.sql.Connection; - -import javax.inject.Provider; - -import org.easymock.EasyMock; -import org.junit.Before; -import org.junit.Test; - -import com.mysema.query.sql.domain.QSurvey; - -public class SQLQueryFactoryTest { - - private SQLQueryFactoryImpl queryFactory; - - @Before - public void setUp() { - Provider provider = new Provider() { - @Override - public Connection get() { - return EasyMock.createNiceMock(Connection.class); - } - }; - queryFactory = new SQLQueryFactoryImpl(SQLTemplates.DEFAULT, provider); - } - - @Test - public void Query() { - assertNotNull(queryFactory.query()); - } - - @Test - public void SubQuery() { - assertNotNull(queryFactory.subQuery()); - } - - @Test - public void SubQuery_From() { - assertNotNull(queryFactory.subQuery(QSurvey.survey)); - } - - @Test - public void From() { - assertNotNull(queryFactory.from(QSurvey.survey)); - } - - @Test - public void Delete() { - assertNotNull(queryFactory.delete(QSurvey.survey)); - } - - @Test - public void Insert() { - assertNotNull(queryFactory.insert(QSurvey.survey)); - } - - @Test - public void Update() { - assertNotNull(queryFactory.update(QSurvey.survey)); - } - - @Test - public void Merge() { - assertNotNull(queryFactory.merge(QSurvey.survey)); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/SQLSerializerTest.java b/querydsl-sql/src/test/java/com/mysema/query/sql/SQLSerializerTest.java deleted file mode 100644 index 39321078ea..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/SQLSerializerTest.java +++ /dev/null @@ -1,327 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.TimeZone; - -import com.mysema.query.BooleanBuilder; -import com.mysema.query.QueryMetadata; -import com.mysema.query.Survey; -import com.mysema.query.Tuple; -import com.mysema.query.sql.domain.QEmployee; -import com.mysema.query.sql.domain.QEmployeeNoPK; -import com.mysema.query.sql.domain.QSurvey; -import com.mysema.query.support.Expressions; -import com.mysema.query.types.Expression; -import com.mysema.query.types.Path; -import com.mysema.query.types.SubQueryExpression; -import com.mysema.query.types.expr.Wildcard; -import com.mysema.query.types.path.NumberPath; -import com.mysema.query.types.path.PathBuilder; -import com.mysema.query.types.path.StringPath; -import org.junit.Test; -import static org.junit.Assert.assertEquals; - -public class SQLSerializerTest { - - private static final QEmployee employee = QEmployee.employee; - - private static final QSurvey survey = QSurvey.survey; - - @Test - public void Count() { - SQLSerializer serializer = new SQLSerializer(Configuration.DEFAULT); - serializer.handle(employee.id.count().add(employee.id.countDistinct())); - assertEquals("count(EMPLOYEE.ID) + count(distinct EMPLOYEE.ID)", serializer.toString()); - } - - @Test - public void CountDistinct() { - SQLSerializer serializer = new SQLSerializer(Configuration.DEFAULT); - SQLSubQuery query = new SQLSubQuery(); - query.from(QEmployeeNoPK.employee); - query.distinct(); - serializer.serializeForQuery(query.getMetadata(), true); - assertEquals("select count(*)\n" + - "from (select distinct EMPLOYEE.ID, EMPLOYEE.FIRSTNAME, EMPLOYEE.LASTNAME, EMPLOYEE.SALARY, " + - "EMPLOYEE.DATEFIELD, EMPLOYEE.TIMEFIELD, EMPLOYEE.SUPERIOR_ID\n" + - "from EMPLOYEE EMPLOYEE) internal", serializer.toString()); - } - - @Test - public void CountDistinct_PostgreSQL() { - Configuration postgres = new Configuration(new PostgresTemplates()); - SQLSerializer serializer = new SQLSerializer(postgres); - SQLSubQuery query = new SQLSubQuery(); - query.from(QEmployeeNoPK.employee); - query.distinct(); - serializer.serializeForQuery(query.getMetadata(), true); - assertEquals("select count(" + - "distinct (EMPLOYEE.ID, EMPLOYEE.FIRSTNAME, EMPLOYEE.LASTNAME, EMPLOYEE.SALARY, " + - "EMPLOYEE.DATEFIELD, EMPLOYEE.TIMEFIELD, EMPLOYEE.SUPERIOR_ID))\n" + - "from EMPLOYEE EMPLOYEE", serializer.toString()); - } - - @Test - public void DynamicQuery() { - Path userPath = Expressions.path(Object.class, "user"); - NumberPath idPath = Expressions.numberPath(Long.class, userPath, "id"); - StringPath usernamePath = Expressions.stringPath(userPath, "username"); - Expression sq = new SQLSubQuery() - .from(userPath).where(idPath.eq(1l)) - .list(idPath, usernamePath); - - SQLSerializer serializer = new SQLSerializer(Configuration.DEFAULT); - serializer.handle(sq); - assertEquals("(select user.id, user.username\n" + - "from user\n" + - "where user.id = ?)", serializer.toString()); - } - - @Test - public void DynamicQuery2() { - PathBuilder userPath = new PathBuilder(Object.class, "user"); - NumberPath idPath = userPath.getNumber("id", Long.class); - StringPath usernamePath = userPath.getString("username"); - Expression sq = new SQLSubQuery() - .from(userPath).where(idPath.eq(1l)) - .list(idPath, usernamePath); - - SQLSerializer serializer = new SQLSerializer(Configuration.DEFAULT); - serializer.handle(sq); - assertEquals("(select user.id, user.username\n" + - "from user\n" + - "where user.id = ?)", serializer.toString()); - } - - @Test - public void Some() { - //select some((e.FIRSTNAME is not null)) from EMPLOYEE - SQLSerializer serializer = new SQLSerializer(Configuration.DEFAULT); - serializer.handle(SQLExpressions.any(employee.firstname.isNotNull())); - assertEquals("some(EMPLOYEE.FIRSTNAME is not null)", serializer.toString()); - } - - @Test - public void StartsWith() { - SQLSerializer serializer = new SQLSerializer(Configuration.DEFAULT); - QSurvey s1 = new QSurvey("s1"); - serializer.handle(s1.name.startsWith("X")); - assertEquals("s1.NAME like ? escape '\\'", serializer.toString()); - assertEquals(Arrays.asList("X%"), serializer.getConstants()); - } - - @Test - public void From_Function() { - SQLQuery query = query(); - query.from(Expressions.template(Survey.class, "functionCall()")).join(survey); - query.where(survey.name.isNotNull()); - assertEquals("from functionCall()\njoin SURVEY SURVEY\nwhere SURVEY.NAME is not null", query.toString()); - } - - @Test - public void Join_To_Function_With_Alias() { - SQLQuery query = query(); - query.from(survey).join(RelationalFunctionCall.create(Survey.class, "functionCall"), Expressions.path(Survey.class, "fc")); - query.where(survey.name.isNotNull()); - assertEquals("from SURVEY SURVEY\njoin functionCall() as fc\nwhere SURVEY.NAME is not null", query.toString()); - } - - @Test - public void Join_To_Function_In_Derby() { - SQLQuery query = new SQLQuery(new DerbyTemplates()); - query.from(survey).join(RelationalFunctionCall.create(Survey.class, "functionCall"), Expressions.path(Survey.class, "fc")); - query.where(survey.name.isNotNull()); - assertEquals("from SURVEY SURVEY\njoin table(functionCall()) as fc\nwhere SURVEY.NAME is not null", query.toString()); - } - - @Test - public void Like() { - Expression expr = Expressions.stringTemplate("'%a%'").contains("%a%"); - SQLSerializer serializer = new SQLSerializer(Configuration.DEFAULT); - serializer.handle(expr); - assertEquals("'%a%' like ? escape '\\'", serializer.toString()); - } - - @Test - public void Override() { - Configuration conf = new Configuration(new DerbyTemplates()); - conf.registerTableOverride("SURVEY", "surveys"); - - SQLQuery query = new SQLQuery(conf); - query.from(survey); - assertEquals("from surveys SURVEY", query.toString()); - } - - @Test - public void ColumnOverrides() { - Configuration conf = new Configuration(new DerbyTemplates()); - conf.registerColumnOverride("SURVEY", "NAME", "LABEL"); - - SQLQuery query = new SQLQuery(conf); - query.from(survey).where(survey.name.isNull()); - assertEquals("from SURVEY SURVEY\n" + - "where SURVEY.LABEL is null", query.toString()); - } - - @Test - public void ColumnOverrides2() { - Configuration conf = new Configuration(new DerbyTemplates()); - conf.registerColumnOverride("PUBLIC", "SURVEY", "NAME", "LABEL"); - - SQLQuery query = new SQLQuery(conf); - query.from(survey).where(survey.name.isNull()); - assertEquals("from SURVEY SURVEY\n" + - "where SURVEY.LABEL is null", query.toString()); - } - - @Test - public void Complex_SubQuery() { - // create sub queries - List> sq = new ArrayList>(); - String[] strs = new String[]{"a","b","c"}; - for(String str : strs) { - Expression alias = Expressions.cases().when(survey.name.eq(str)).then(true).otherwise(false); - sq.add(sq().from(survey).distinct().unique(survey.name, alias)); - } - - // master query - PathBuilder subAlias = new PathBuilder(Tuple.class, "sub"); - SubQueryExpression master = sq() - .from(sq().union(sq).as(subAlias)) - .groupBy(subAlias.get("prop1")) - .list(subAlias.get("prop2")); - - SQLSerializer serializer = new SQLSerializer(Configuration.DEFAULT); - serializer.serialize(master.getMetadata(), false); - System.err.println(serializer); - } - - private SQLQuery query() { - return new SQLQuery(Configuration.DEFAULT); - } - - private SQLSubQuery sq() { - return new SQLSubQuery(); - } - - @Test - public void Boolean() { - QSurvey s = new QSurvey("s"); - BooleanBuilder bb1 = new BooleanBuilder(); - bb1.and(s.name.eq(s.name)); - - BooleanBuilder bb2 = new BooleanBuilder(); - bb2.or(s.name.eq(s.name)); - bb2.or(s.name.eq(s.name)); - - String str = new SQLSerializer(Configuration.DEFAULT).handle(bb1.and(bb2)).toString(); - assertEquals("s.NAME = s.NAME and (s.NAME = s.NAME or s.NAME = s.NAME)", str); - } - - @Test - public void List_In_Query() { - Expression expr = Expressions.list(survey.id, survey.name).in(sq().from(survey).list(survey.id, survey.name)); - - String str = new SQLSerializer(Configuration.DEFAULT).handle(expr).toString(); - assertEquals("(SURVEY.ID, SURVEY.NAME) in (select SURVEY.ID, SURVEY.NAME\nfrom SURVEY SURVEY)", str); - } - - @Test - public void WithRecursive() { - /*with sub (id, firstname, superior_id) as ( - select id, firstname, superior_id from employee where firstname like 'Mike' - union all - select employee.id, employee.firstname, employee.superior_id from sub, employee - where employee.superior_id = sub.id) - select * from sub;*/ - - QEmployee e = QEmployee.employee; - PathBuilder sub = new PathBuilder(Tuple.class, "sub"); - SQLQuery query = new SQLQuery(SQLTemplates.DEFAULT); - query.withRecursive(sub, - sq().unionAll( - sq().from(e).where(e.firstname.eq("Mike")) - .list(e.id, e.firstname, e.superiorId), - sq().from(e, sub).where(e.superiorId.eq(sub.get(e.id))) - .list(e.id, e.firstname, e.superiorId))) - .from(sub); - - QueryMetadata md = query.getMetadata(); - md.addProjection(Wildcard.all); - SQLSerializer serializer = new SQLSerializer(Configuration.DEFAULT); - serializer.serialize(md, false); - assertEquals("with recursive sub as ((select EMPLOYEE.ID, EMPLOYEE.FIRSTNAME, EMPLOYEE.SUPERIOR_ID\n" + - "from EMPLOYEE EMPLOYEE\n" + - "where EMPLOYEE.FIRSTNAME = ?)\n" + - "union all\n" + - "(select EMPLOYEE.ID, EMPLOYEE.FIRSTNAME, EMPLOYEE.SUPERIOR_ID\n" + - "from EMPLOYEE EMPLOYEE, sub\n" + - "where EMPLOYEE.SUPERIOR_ID = sub.ID))\n" + - "select *\n" + - "from sub", serializer.toString()); - - } - - @Test - public void WithRecursive2() { - /*with sub (id, firstname, superior_id) as ( - select id, firstname, superior_id from employee where firstname like 'Mike' - union all - select employee.id, employee.firstname, employee.superior_id from sub, employee - where employee.superior_id = sub.id) - select * from sub;*/ - - QEmployee e = QEmployee.employee; - PathBuilder sub = new PathBuilder(Tuple.class, "sub"); - SQLQuery query = new SQLQuery(SQLTemplates.DEFAULT); - query.withRecursive(sub, sub.get(e.id), sub.get(e.firstname), sub.get(e.superiorId)).as( - sq().unionAll( - sq().from(e).where(e.firstname.eq("Mike")) - .list(e.id, e.firstname, e.superiorId), - sq().from(e, sub).where(e.superiorId.eq(sub.get(e.id))) - .list(e.id, e.firstname, e.superiorId))) - .from(sub); - - QueryMetadata md = query.getMetadata(); - md.addProjection(Wildcard.all); - SQLSerializer serializer = new SQLSerializer(Configuration.DEFAULT); - serializer.serialize(md, false); - assertEquals("with recursive sub (ID, FIRSTNAME, SUPERIOR_ID) as ((select EMPLOYEE.ID, EMPLOYEE.FIRSTNAME, EMPLOYEE.SUPERIOR_ID\n" + - "from EMPLOYEE EMPLOYEE\n" + - "where EMPLOYEE.FIRSTNAME = ?)\n" + - "union all\n" + - "(select EMPLOYEE.ID, EMPLOYEE.FIRSTNAME, EMPLOYEE.SUPERIOR_ID\n" + - "from EMPLOYEE EMPLOYEE, sub\n" + - "where EMPLOYEE.SUPERIOR_ID = sub.ID))\n" + - "select *\n" + - "from sub", serializer.toString()); - - } - - @Test - public void UseLiterals() { - SQLSerializer serializer = new SQLSerializer(Configuration.DEFAULT); - serializer.setUseLiterals(true); - - int offset = TimeZone.getDefault().getRawOffset(); - Expression expr = SQLExpressions.datediff(DatePart.year, employee.datefield, new java.sql.Date(-offset)); - serializer.handle(expr); - assertEquals("datediff('year',EMPLOYEE.DATEFIELD,(date '1970-01-01'))", serializer.toString()); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/SQLServer2005TemplatesTest.java b/querydsl-sql/src/test/java/com/mysema/query/sql/SQLServer2005TemplatesTest.java deleted file mode 100644 index 6a8e653c57..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/SQLServer2005TemplatesTest.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import static org.junit.Assert.assertEquals; - -import org.junit.Test; - -import com.mysema.query.types.ConstantImpl; -import com.mysema.query.types.Operation; -import com.mysema.query.types.OperationImpl; -import com.mysema.query.types.Path; -import com.mysema.query.types.expr.NumberExpression; -import com.mysema.query.types.path.SimplePath; -import com.mysema.query.types.template.NumberTemplate; - - -public class SQLServer2005TemplatesTest extends AbstractSQLTemplatesTest{ - - @Override - @Test - public void NoFrom() { - query.getMetadata().addProjection(NumberTemplate.ONE); - assertEquals("select 1", query.toString()); - } - - @Override - protected SQLTemplates createTemplates() { - return new SQLServer2005Templates(); - } - - @SuppressWarnings("unchecked") - @Test - @Override - public void Union() { - NumberExpression one = NumberTemplate.ONE; - NumberExpression two = NumberTemplate.TWO; - NumberExpression three = NumberTemplate.THREE; - Path col1 = new SimplePath(Integer.class,"col1"); - Union union = query.union( - sq().unique(one.as(col1)), - sq().unique(two), - sq().unique(three)); - assertEquals( - "(select 1 as col1)\n" + - "union\n" + - "(select 2)\n" + - "union\n" + - "(select 3)", union.toString()); - } - - @Test - public void Limit() { - query.from(survey1).limit(5); - query.getMetadata().addProjection(survey1.id); - assertEquals("select top (?) survey1.ID from SURVEY survey1", query.toString()); - } - - @Test - public void Modifiers() { - query.from(survey1).limit(5).offset(3); - query.getMetadata().addProjection(survey1.id); - assertEquals("select * from (" + - " select survey1.ID, row_number() over () as rn from SURVEY survey1) a " + - "where rn > ? and rn <= ? order by rn", query.toString()); - } - - @Test - public void NextVal() { - Operation nextval = OperationImpl.create(String.class, SQLOps.NEXTVAL, ConstantImpl.create("myseq")); - assertEquals("myseq.nextval", new SQLSerializer(new Configuration(new SQLServerTemplates())).handle(nextval).toString()); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/SQLServer2012TemplatesTest.java b/querydsl-sql/src/test/java/com/mysema/query/sql/SQLServer2012TemplatesTest.java deleted file mode 100644 index dc3bc203c6..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/SQLServer2012TemplatesTest.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import static org.junit.Assert.assertEquals; - -import org.junit.Test; - -import com.mysema.query.types.ConstantImpl; -import com.mysema.query.types.Operation; -import com.mysema.query.types.OperationImpl; -import com.mysema.query.types.Path; -import com.mysema.query.types.expr.NumberExpression; -import com.mysema.query.types.path.SimplePath; -import com.mysema.query.types.template.NumberTemplate; - - -public class SQLServer2012TemplatesTest extends AbstractSQLTemplatesTest { - - @Override - @Test - public void NoFrom() { - query.getMetadata().addProjection(NumberTemplate.ONE); - assertEquals("select 1", query.toString()); - } - - @Override - protected SQLTemplates createTemplates() { - return new SQLServer2012Templates(); - } - - @SuppressWarnings("unchecked") - @Test - @Override - public void Union() { - NumberExpression one = NumberTemplate.ONE; - NumberExpression two = NumberTemplate.TWO; - NumberExpression three = NumberTemplate.THREE; - Path col1 = new SimplePath(Integer.class,"col1"); - Union union = query.union( - sq().unique(one.as(col1)), - sq().unique(two), - sq().unique(three)); - assertEquals( - "(select 1 as col1)\n" + - "union\n" + - "(select 2)\n" + - "union\n" + - "(select 3)", union.toString()); - } - - @Test - public void Limit() { - query.from(survey1).limit(5); - query.getMetadata().addProjection(survey1.id); - assertEquals("select survey1.ID from SURVEY survey1 offset ? rows fetch next ? rows only", query.toString()); - } - - @Test - public void Modifiers() { - query.from(survey1).limit(5).offset(3); - query.getMetadata().addProjection(survey1.id); - assertEquals("select survey1.ID from SURVEY survey1 offset ? rows fetch next ? rows only", query.toString()); - } - - @Test - public void NextVal() { - Operation nextval = OperationImpl.create(String.class, SQLOps.NEXTVAL, ConstantImpl.create("myseq")); - assertEquals("myseq.nextval", new SQLSerializer(new Configuration(new SQLServerTemplates())).handle(nextval).toString()); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/SQLServerTemplatesTest.java b/querydsl-sql/src/test/java/com/mysema/query/sql/SQLServerTemplatesTest.java deleted file mode 100644 index 1d549705de..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/SQLServerTemplatesTest.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import static org.junit.Assert.assertEquals; - -import org.junit.Test; - -import com.mysema.query.types.ConstantImpl; -import com.mysema.query.types.Operation; -import com.mysema.query.types.OperationImpl; -import com.mysema.query.types.Path; -import com.mysema.query.types.expr.NumberExpression; -import com.mysema.query.types.path.SimplePath; -import com.mysema.query.types.template.NumberTemplate; - - -public class SQLServerTemplatesTest extends AbstractSQLTemplatesTest{ - - @Override - @Test - public void NoFrom() { - query.getMetadata().addProjection(NumberTemplate.ONE); - assertEquals("select 1", query.toString()); - } - - @Override - protected SQLTemplates createTemplates() { - return new SQLServerTemplates(); - } - - @SuppressWarnings("unchecked") - @Test - @Override - public void Union() { - NumberExpression one = NumberTemplate.ONE; - NumberExpression two = NumberTemplate.TWO; - NumberExpression three = NumberTemplate.THREE; - Path col1 = new SimplePath(Integer.class,"col1"); - Union union = query.union( - sq().unique(one.as(col1)), - sq().unique(two), - sq().unique(three)); - assertEquals( - "(select 1 as col1)\n" + - "union\n" + - "(select 2)\n" + - "union\n" + - "(select 3)", union.toString()); - } - - @Test - public void Limit() { - query.from(survey1).limit(5); - query.getMetadata().addProjection(survey1.id); - assertEquals("select top 5 survey1.ID from SURVEY survey1", query.toString()); - } - - @Test - public void NextVal() { - Operation nextval = OperationImpl.create(String.class, SQLOps.NEXTVAL, ConstantImpl.create("myseq")); - assertEquals("myseq.nextval", new SQLSerializer(new Configuration(new SQLServerTemplates())).handle(nextval).toString()); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/SQLSubQueryTest.java b/querydsl-sql/src/test/java/com/mysema/query/sql/SQLSubQueryTest.java deleted file mode 100644 index 552e398161..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/SQLSubQueryTest.java +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import java.util.List; - -import com.mysema.query.DefaultQueryMetadata; -import com.mysema.query.sql.domain.QEmployee; -import com.mysema.query.sql.domain.QSurvey; -import com.mysema.query.types.*; -import com.mysema.query.types.expr.BooleanOperation; -import com.mysema.query.types.expr.Wildcard; -import com.mysema.query.types.path.NumberPath; -import com.mysema.query.types.query.ListSubQuery; -import com.mysema.query.types.query.NumberSubQuery; -import org.junit.Test; -import static org.junit.Assert.assertEquals; - -public class SQLSubQueryTest { - - private static final QEmployee employee = QEmployee.employee; - - @Test - public void UnknownOperator() { - Operator op = new OperatorImpl(SQLSubQueryTest.class.getName(), "unknownfn"); - SQLSubQuery query = new SQLSubQuery(); - query.from(employee) - .where(BooleanOperation.create(op, employee.id)); - - assertEquals("from EMPLOYEE EMPLOYEE\nwhere com.mysema.query.sql.SQLSubQueryTest#unknownfn(EMPLOYEE.ID)", query.toString()); - } - - @Test - public void Multiple_Projections() { - SQLSubQuery query = new SQLSubQuery(); - query.from(employee); - assertEquals(1, query.list(employee).getMetadata().getProjection().size()); - assertEquals(1, query.list(employee).getMetadata().getProjection().size()); - } - - @Test - public void List() { - SQLSubQuery query = new SQLSubQuery(); - query.from(employee); - ListSubQuery subQuery = query.list(employee.id, "XXX", employee.firstname); - List> exprs = subQuery.getMetadata().getProjection(); - assertEquals(employee.id, exprs.get(0)); - assertEquals(ConstantImpl.create("XXX") , exprs.get(1)); - assertEquals(employee.firstname, exprs.get(2)); - } - - @Test - public void List_Entity() { - QEmployee employee2 = new QEmployee("employee2"); - SQLSubQuery query = new SQLSubQuery(); - Expression expr = query.from(employee) - .innerJoin(employee.superiorIdKey, employee2) - .list(employee, employee2.id); - - SQLSerializer serializer = new SQLSerializer(new Configuration(SQLTemplates.DEFAULT)); - serializer.handle(expr); - - assertEquals("(select EMPLOYEE.ID, EMPLOYEE.SUPERIOR_ID, EMPLOYEE.TIMEFIELD, EMPLOYEE.LASTNAME, EMPLOYEE.DATEFIELD, EMPLOYEE.SALARY, EMPLOYEE.FIRSTNAME, employee2.ID\n" + - "from EMPLOYEE EMPLOYEE\n" + - "inner join EMPLOYEE employee2\n" + - "on EMPLOYEE.SUPERIOR_ID = employee2.ID)", serializer.toString()); - } - - @Test - public void In() { - ListSubQuery ints = new SQLSubQuery().from(employee).list(employee.id); - QEmployee.employee.id.in(ints); - } - - @Test - public void In_Union() { - ListSubQuery ints1 = new SQLSubQuery().from(employee).list(employee.id); - ListSubQuery ints2 = new SQLSubQuery().from(employee).list(employee.id); - QEmployee.employee.id.in(new SQLSubQuery().union(ints1, ints2)); - } - - @Test - public void In_Union2() { - NumberSubQuery ints1 = new SQLSubQuery().from(employee).unique(employee.id); - NumberSubQuery ints2 = new SQLSubQuery().from(employee).unique(employee.id); - QEmployee.employee.id.in(new SQLSubQuery().union(ints1, ints2)); - } - - @Test - public void Unique() { - SQLSubQuery query = new SQLSubQuery(); - query.from(employee); - SubQueryExpression subQuery = query.unique(employee.id, "XXX", employee.firstname); - List> exprs = subQuery.getMetadata().getProjection(); - assertEquals(employee.id, exprs.get(0)); - assertEquals(ConstantImpl.create("XXX") , exprs.get(1)); - assertEquals(employee.firstname, exprs.get(2)); - } - - @Test - public void Complex() { - // related to #584795 - QSurvey survey = new QSurvey("survey"); - QEmployee emp1 = new QEmployee("emp1"); - QEmployee emp2 = new QEmployee("emp2"); - SubQueryExpression subQuery = new SQLSubQuery().from(survey) - .innerJoin(emp1) - .on(survey.id.eq(emp1.id)) - .innerJoin(emp2) - .on(emp1.superiorId.eq(emp2.superiorId), emp1.firstname.eq(emp2.firstname)) - .list(survey.id, emp2.firstname); - - assertEquals(3, subQuery.getMetadata().getJoins().size()); - } - - @Test - public void Validate() { - NumberPath operatorTotalPermits = new NumberPath(Long.class, "operator_total_permits"); - QSurvey survey = new QSurvey("survey"); - - // select survey.name, count(*) as operator_total_permits - // from survey - // where survey.name >= "A" - // group by survey.name - // order by operator_total_permits asc - // limit 10 - - Expression e = new SQLSubQuery().from(survey) - .where(survey.name.goe("A")) - .groupBy(survey.name) - .orderBy(operatorTotalPermits.asc()) - .limit(10) - .list(survey.name, Wildcard.count.as(operatorTotalPermits)) - .as("top"); - - new SQLQuery(null, SQLTemplates.DEFAULT).from(e); - } - - @Test - public void Union() { - ListSubQuery q1 = new ListSubQuery(Object.class, new DefaultQueryMetadata()); - ListSubQuery q2 = new ListSubQuery(Object.class, new DefaultQueryMetadata()); - new SQLSubQuery().union(q1, q2); - new SQLSubQuery().union(q1); - } - - @Test - public void Union_With() { - QSurvey survey1 = new QSurvey("survey1"); - QSurvey survey2 = new QSurvey("survey2"); - QSurvey survey3 = new QSurvey("survey3"); - - SQLQuery query = new SQLQuery(SQLTemplates.DEFAULT); - query.with(survey1, new SQLSubQuery().from(survey1).list(survey1.all())); - query.union( - new SQLSubQuery().from(survey2).list(survey2.all()), - new SQLSubQuery().from(survey3).list(survey3.all())); - - assertEquals("with survey1 as (select survey1.NAME, survey1.NAME2, survey1.ID\n" + - "from SURVEY survey1)\n" + - "(select survey2.NAME, survey2.NAME2, survey2.ID\n" + - "from SURVEY survey2)\n" + - "union\n" + - "(select survey3.NAME, survey3.NAME2, survey3.ID\n" + - "from SURVEY survey3)", query.toString()); - - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/SQLTemplatesTest.java b/querydsl-sql/src/test/java/com/mysema/query/sql/SQLTemplatesTest.java deleted file mode 100644 index 98e51a5b0a..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/SQLTemplatesTest.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import com.mysema.query.support.Expressions; -import com.mysema.query.types.*; -import com.mysema.query.types.path.NumberPath; -import com.mysema.query.types.template.SimpleTemplate; -import org.joda.time.DateTime; -import org.joda.time.LocalDate; -import org.joda.time.LocalTime; -import org.junit.Test; - -import java.sql.Date; -import java.sql.Time; -import java.sql.Timestamp; -import java.util.regex.Pattern; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -public class SQLTemplatesTest { - - private static final String DATETIME = "\\(timestamp '\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}'\\)"; - private static final String TIME = "\\(time '\\d{2}:\\d{2}:\\d{2}'\\)"; - private static final String DATE = "\\(date '\\d{4}-\\d{2}-\\d{2}'\\)"; - - private static void assertMatches(String regex, String str) { - assertTrue(str, str.matches(regex)); - } - - @Test - public void test() { - Template template = TemplateFactory.DEFAULT.create("fetch first {0s} rows only"); - assertTrue(template.getElements().get(1) instanceof Template.AsString); - - SQLSerializer serializer = new SQLSerializer(new Configuration(new DerbyTemplates())); - serializer.handle(SimpleTemplate.create(Object.class, template, ConstantImpl.create(5))); - assertEquals("fetch first 5 rows only", serializer.toString()); - } - - @Test - public void AsLiteral() { - SQLTemplates templates = SQLTemplates.DEFAULT; - Configuration conf = new Configuration(templates); - assertMatches(DATE, conf.asLiteral(new Date(0))); - assertMatches(TIME, conf.asLiteral(new Time(0))); - assertMatches(DATETIME, conf.asLiteral(new Timestamp(0))); - } - - @Test - public void AsLiteral_JodaTime() { - SQLTemplates templates = SQLTemplates.DEFAULT; - Configuration conf = new Configuration(templates); - assertMatches(DATE, conf.asLiteral(new LocalDate(0))); - assertMatches(TIME, conf.asLiteral(new LocalTime(0))); - assertMatches(DATETIME, conf.asLiteral(new DateTime(0))); - } - - @Test - public void Quote() { - Pattern pattern = Pattern.compile("[a-zA-Z0-9_\\-]+"); - assertTrue(pattern.matcher("a1").matches()); - assertTrue(pattern.matcher("a").matches()); - } - - @Test - public void Quoting_Performance() { - // 385 -> 63 - SQLTemplates templates = new H2Templates(); - long start = System.currentTimeMillis(); - int iterations = 1000000; - for (int i = 0; i < iterations; i++) { - templates.quoteIdentifier("companies"); - } - System.err.println(System.currentTimeMillis() - start); - } - - @Test - public void NextVal() { - Operation nextval = OperationImpl.create(String.class, SQLOps.NEXTVAL, ConstantImpl.create("myseq")); - assertEquals("nextval('myseq')", new SQLSerializer(new Configuration(SQLTemplates.DEFAULT)).handle(nextval).toString()); - // Derby OK - // H2 OK - // HSQLDB OK - // MSSQL OK - // MySQL - // Oracle OK - // Postgres OK - - } - - @Test - public void Numeric_Operations() { - NumberPath intPath = Expressions.numberPath(Integer.class, "intPath"); - NumberPath intPath2 = Expressions.numberPath(Integer.class, "intPath2"); - SQLSerializer serializer = new SQLSerializer(new Configuration(SQLTemplates.DEFAULT)); - serializer.handle(intPath.subtract(intPath2.add(2))); - assertEquals("intPath - (intPath2 + ?)", serializer.toString()); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/SerializationTest.java b/querydsl-sql/src/test/java/com/mysema/query/sql/SerializationTest.java deleted file mode 100644 index 364d836e88..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/SerializationTest.java +++ /dev/null @@ -1,227 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import static org.junit.Assert.assertEquals; - -import java.sql.Connection; - -import org.easymock.EasyMock; -import org.junit.Test; - -import com.mysema.query.Survey; -import com.mysema.query.sql.dml.SQLDeleteClause; -import com.mysema.query.sql.dml.SQLInsertClause; -import com.mysema.query.sql.dml.SQLUpdateClause; -import com.mysema.query.sql.domain.QEmployee; -import com.mysema.query.sql.domain.QSurvey; -import com.mysema.query.types.Path; -import com.mysema.query.types.SubQueryExpression; -import com.mysema.query.types.path.PathBuilder; - -public class SerializationTest { - - private static final QSurvey survey = QSurvey.survey; - - private final Connection connection = EasyMock.createMock(Connection.class); - - @Test - public void InnerJoin() { - SQLQuery query = new SQLQuery(connection,SQLTemplates.DEFAULT); - query.from(new QSurvey("s1")).innerJoin(new QSurvey("s2")); - assertEquals("from SURVEY s1\ninner join SURVEY s2", query.toString()); - } - - @Test - public void LeftJoin() { - SQLQuery query = new SQLQuery(connection,SQLTemplates.DEFAULT); - query.from(new QSurvey("s1")).leftJoin(new QSurvey("s2")); - assertEquals("from SURVEY s1\nleft join SURVEY s2", query.toString()); - } - - @Test - public void RightJoin() { - SQLQuery query = new SQLQuery(connection,SQLTemplates.DEFAULT); - query.from(new QSurvey("s1")).rightJoin(new QSurvey("s2")); - assertEquals("from SURVEY s1\nright join SURVEY s2", query.toString()); - } - - @Test - public void FullJoin() { - SQLQuery query = new SQLQuery(connection,SQLTemplates.DEFAULT); - query.from(new QSurvey("s1")).fullJoin(new QSurvey("s2")); - assertEquals("from SURVEY s1\nfull join SURVEY s2", query.toString()); - } - - @Test - public void Update() { - SQLUpdateClause updateClause = new SQLUpdateClause(connection,SQLTemplates.DEFAULT,survey); - updateClause.set(survey.id, 1); - updateClause.set(survey.name, (String)null); - assertEquals("update SURVEY\nset ID = ?, NAME = ?", updateClause.toString()); - } - - @Test - public void Update_Where() { - SQLUpdateClause updateClause = new SQLUpdateClause(connection,SQLTemplates.DEFAULT,survey); - updateClause.set(survey.id, 1); - updateClause.set(survey.name, (String)null); - updateClause.where(survey.name.eq("XXX")); - assertEquals("update SURVEY\nset ID = ?, NAME = ?\nwhere SURVEY.NAME = ?", updateClause.toString()); - } - - @Test - public void Insert() { - SQLInsertClause insertClause = new SQLInsertClause(connection,SQLTemplates.DEFAULT,survey); - insertClause.set(survey.id, 1); - insertClause.set(survey.name, (String)null); - assertEquals("insert into SURVEY (ID, NAME)\nvalues (?, ?)", insertClause.toString()); - } - - @Test - public void Delete_with_SubQuery_exists() { - QSurvey survey1 = new QSurvey("s1"); - QEmployee employee = new QEmployee("e"); - SQLDeleteClause delete = new SQLDeleteClause(connection, SQLTemplates.DEFAULT,survey1); - delete.where(survey1.name.eq("XXX"), new SQLSubQuery().from(employee).where(survey1.id.eq(employee.id)).exists()); - assertEquals("delete from SURVEY\n" + - "where SURVEY.NAME = ? and exists (select 1\n" + - "from EMPLOYEE e\n" + - "where SURVEY.ID = e.ID)", delete.toString()); - } - - @Test - public void Nextval() { - SubQueryExpression sq = new SQLSubQuery().from(QSurvey.survey).list(SQLExpressions.nextval("myseq")); - SQLSerializer serializer = new SQLSerializer(Configuration.DEFAULT); - serializer.serialize(sq.getMetadata(), false); - assertEquals("select nextval('myseq')\nfrom SURVEY SURVEY", serializer.toString()); - } - - @Test - public void FunctionCall() { - RelationalFunctionCall func = RelationalFunctionCall.create(String.class, "TableValuedFunction", "parameter"); - PathBuilder funcAlias = new PathBuilder(String.class, "tokFunc"); - SQLSubQuery sq = new SQLSubQuery(); - SubQueryExpression expr = sq.from(survey) - .join(func, funcAlias).on(survey.name.like(funcAlias.getString("prop")).not()) - .list(survey.name); - - SQLSerializer serializer = new SQLSerializer(new Configuration(new SQLServerTemplates())); - serializer.serialize(expr.getMetadata(), false); - assertEquals("select SURVEY.NAME\n" + - "from SURVEY SURVEY\n" + - "join TableValuedFunction(?) as tokFunc\n" + - "on not SURVEY.NAME like tokFunc.prop escape '\\'", serializer.toString()); - - } - - @Test - public void FunctionCall2() { - RelationalFunctionCall func = RelationalFunctionCall.create(String.class, "TableValuedFunction", "parameter"); - PathBuilder funcAlias = new PathBuilder(String.class, "tokFunc"); - SQLQuery q = new SQLQuery(new SQLServerTemplates()); - q.from(survey) - .join(func, funcAlias).on(survey.name.like(funcAlias.getString("prop")).not()); - - assertEquals("from SURVEY SURVEY\n" + - "join TableValuedFunction(?) as tokFunc\n" + - "on not SURVEY.NAME like tokFunc.prop escape '\\'", q.toString()); - } - - @Test - public void Union() { - SQLQuery q = new SQLQuery(SQLTemplates.DEFAULT); - q.union(new SQLSubQuery().from(survey).list(survey.all()), - new SQLSubQuery().from(survey).list(survey.all())); - - assertEquals("(select SURVEY.NAME, SURVEY.NAME2, SURVEY.ID\n" + - "from SURVEY SURVEY)\n" + - "union\n" + - "(select SURVEY.NAME, SURVEY.NAME2, SURVEY.ID\n" + - "from SURVEY SURVEY)", q.toString()); - - } - - @Test - public void Union_GroupBy() { - SQLQuery q = new SQLQuery(SQLTemplates.DEFAULT); - q.union(new SQLSubQuery().from(survey).list(survey.all()), - new SQLSubQuery().from(survey).list(survey.all())) - .groupBy(survey.id); - - assertEquals("(select SURVEY.NAME, SURVEY.NAME2, SURVEY.ID\n" + - "from SURVEY SURVEY)\n" + - "union\n" + - "(select SURVEY.NAME, SURVEY.NAME2, SURVEY.ID\n" + - "from SURVEY SURVEY)\n"+ - "group by SURVEY.ID", q.toString()); - - } - - @Test - public void Union2() { - SQLQuery q = new SQLQuery(SQLTemplates.DEFAULT); - q.union(survey, - new SQLSubQuery().from(survey).list(survey.all()), - new SQLSubQuery().from(survey).list(survey.all())); - - assertEquals("from ((select SURVEY.NAME, SURVEY.NAME2, SURVEY.ID\n"+ - "from SURVEY SURVEY)\n" + - "union\n" + - "(select SURVEY.NAME, SURVEY.NAME2, SURVEY.ID\n" + - "from SURVEY SURVEY)) as SURVEY", q.toString()); - - } - - @Test - public void With() { - QSurvey survey2 = new QSurvey("survey2"); - SQLQuery q = new SQLQuery(SQLTemplates.DEFAULT); - q.with(survey, survey.id, survey.name).as( - new SQLSubQuery().from(survey2).list(survey2.id, survey2.name)); - - assertEquals("with SURVEY (ID, NAME) as (select survey2.ID, survey2.NAME\n" + - "from SURVEY survey2)\n\n" + - "from dual", q.toString()); - } - - @Test - public void With_Tuple() { - PathBuilder survey = new PathBuilder(Survey.class, "SURVEY"); - QSurvey survey2 = new QSurvey("survey2"); - SQLQuery q = new SQLQuery(SQLTemplates.DEFAULT); - q.with(survey, survey.get(survey2.id), survey.get(survey2.name)).as( - new SQLSubQuery().from(survey2).list(survey2.id, survey2.name)); - - assertEquals("with SURVEY (ID, NAME) as (select survey2.ID, survey2.NAME\n" + - "from SURVEY survey2)\n\n" + - "from dual", q.toString()); - } - - @Test - public void With_SingleColumn() { - QSurvey survey2 = new QSurvey("survey2"); - SQLQuery q = new SQLQuery(SQLTemplates.DEFAULT); - q.with(survey, new Path[]{ survey.id }).as( - new SQLSubQuery().from(survey2).list(survey2.id)); - - assertEquals("with SURVEY (ID) as (select survey2.ID\n" + - "from SURVEY survey2)\n\n" + - "from dual", q.toString()); - } - - - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/TemplateTest.java b/querydsl-sql/src/test/java/com/mysema/query/sql/TemplateTest.java deleted file mode 100644 index be680c7604..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/TemplateTest.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import static org.junit.Assert.assertEquals; - -import java.util.Date; - -import org.junit.Test; - -import com.mysema.query.types.ConstantImpl; -import com.mysema.query.types.Expression; -import com.mysema.query.types.expr.DateExpression; -import com.mysema.query.types.expr.StringExpression; -import com.mysema.query.types.path.DatePath; -import com.mysema.query.types.path.StringPath; -import com.mysema.query.types.template.DateTemplate; -import com.mysema.query.types.template.StringTemplate; - -public class TemplateTest { - - @Test - public void ToDate() { - StringExpression str = new StringPath("str"); - assertEquals("to_date(str,'DD-MON-YYYY')", to_date(str, "DD-MON-YYYY").toString()); - } - - @Test - public void ToChar() { - DateExpression date = new DatePath(Date.class,"date"); - assertEquals("to_char(date,'DD-MON-YYYY')", to_char(date, "DD-MON-YYYY").toString()); - } - - private DateExpression to_date(Expression expr, String pattern) { - return DateTemplate.create(Date.class, "to_date({0},'{1s}')", expr, ConstantImpl.create(pattern)); - } - - private StringExpression to_char(Expression expr, String pattern) { - return StringTemplate.create("to_char({0},'{1s}')", expr, ConstantImpl.create(pattern)); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/TemplatesTest.java b/querydsl-sql/src/test/java/com/mysema/query/sql/TemplatesTest.java deleted file mode 100644 index 53c77bfef5..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/TemplatesTest.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import org.junit.Test; - -public class TemplatesTest { - - @Test - public void test() { - new DerbyTemplates(); - new H2Templates(); - new HSQLDBTemplates(); - new MySQLTemplates(); - new OracleTemplates(); - new PostgresTemplates(); - new SQLTemplates("\"",'\\',false); - new SQLServerTemplates(); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/TeradataTemplatesTest.java b/querydsl-sql/src/test/java/com/mysema/query/sql/TeradataTemplatesTest.java deleted file mode 100644 index e6bc3cae49..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/TeradataTemplatesTest.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.mysema.query.sql; - -import static org.junit.Assert.assertEquals; - -import org.junit.Test; - -public class TeradataTemplatesTest extends AbstractSQLTemplatesTest { - - @Override - protected SQLTemplates createTemplates() { - return new TeradataTemplates(); - } - - @Test - public void Limit() { - query.from(survey1).limit(5); - assertEquals("from SURVEY survey1 " + - "qualify row_number() over (order by 1) <= ?", query.toString()); - } - - @Test - public void Offset() { - query.from(survey1).offset(5); - assertEquals("from SURVEY survey1 " + - "qualify row_number() over (order by 1) > ?", query.toString()); - } - - @Test - public void Limit_Offset() { - query.from(survey1).limit(5).offset(10); - assertEquals("from SURVEY survey1 " + - "qualify row_number() over (order by 1) between ? and ?", query.toString()); - } - - @Test - public void OrderBy_Limit() { - query.from(survey1).orderBy(survey1.name.asc()).limit(5); - assertEquals("from SURVEY survey1 " + - "order by survey1.NAME asc " + - "qualify row_number() over (order by survey1.NAME asc) <= ?", query.toString()); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/UnionSubQueryTest.java b/querydsl-sql/src/test/java/com/mysema/query/sql/UnionSubQueryTest.java deleted file mode 100644 index 07db2a5556..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/UnionSubQueryTest.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql; - -import static org.junit.Assert.assertEquals; - -import org.junit.Test; - -import com.mysema.query.types.Expression; -import com.mysema.query.types.path.NumberPath; -import com.mysema.query.types.path.SimplePath; - -public class UnionSubQueryTest { - - private SQLTemplates templates = H2Templates.builder().newLineToSingleSpace().build(); - - private SQLSerializer serializer = new SQLSerializer(new Configuration(templates)); - - @Test - public void In_Union() { - SimplePath one = new SimplePath(Integer.class,"1"); - SimplePath two = new SimplePath(Integer.class,"2"); - NumberPath intPath = new NumberPath(Integer.class, "intPath"); - - Expression expr = intPath.in(sq().union( - sq().unique(one), - sq().unique(two))); - - serializer.handle(expr); - assertEquals( - "intPath in ((select 1 from dual)\n" + - "union\n" + - "(select 2 from dual))", serializer.toString()); - } - - @Test - public void Union_SubQuery() { - SimplePath one = new SimplePath(Integer.class,"1"); - SimplePath two = new SimplePath(Integer.class,"2"); - SimplePath three = new SimplePath(Integer.class,"3"); - SimplePath col1 = new SimplePath(Integer.class,"col1"); - Expression union = sq().union( - sq().unique(one.as(col1)), - sq().unique(two), - sq().unique(three)); - - serializer.handle(union); - assertEquals( - "(select 1 as col1 from dual)\n" + - "union\n" + - "(select 2 from dual)\n" + - "union\n" + - "(select 3 from dual)", serializer.toString()); - } - - @Test - public void UnionAll_SubQuery() { - SimplePath one = new SimplePath(Integer.class,"1"); - SimplePath two = new SimplePath(Integer.class,"2"); - SimplePath three = new SimplePath(Integer.class,"3"); - SimplePath col1 = new SimplePath(Integer.class,"col1"); - Expression union = sq().unionAll( - sq().unique(one.as(col1)), - sq().unique(two), - sq().unique(three)); - - serializer.handle(union); - assertEquals( - "(select 1 as col1 from dual)\n" + - "union all\n" + - "(select 2 from dual)\n" + - "union all\n" + - "(select 3 from dual)", serializer.toString()); - } - - - protected SQLSubQuery sq() { - return new SQLSubQuery(); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/WindowFunctionTest.java b/querydsl-sql/src/test/java/com/mysema/query/sql/WindowFunctionTest.java deleted file mode 100644 index 20a3a124e7..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/WindowFunctionTest.java +++ /dev/null @@ -1,147 +0,0 @@ -package com.mysema.query.sql; - -import static org.junit.Assert.assertEquals; - -import org.junit.Test; - -import com.mysema.query.support.Expressions; -import com.mysema.query.types.Expression; -import com.mysema.query.types.path.NumberPath; - -public class WindowFunctionTest { - - private static String toString(Expression e) { - return new SQLSerializer(Configuration.DEFAULT).handle(e).toString(); - } - - @Test - public void Complex() { - NumberPath path = Expressions.numberPath(Long.class, "path"); - NumberPath path2 = Expressions.numberPath(Long.class, "path2"); - Expression wf = SQLExpressions.sum(path).over().partitionBy(path2).orderBy(path); - assertEquals("sum(path) over (partition by path2 order by path)", toString(wf)); - } - - @Test - public void All() { - NumberPath path = Expressions.numberPath(Long.class, "path"); - NumberPath path2 = Expressions.numberPath(Long.class, "path2"); - assertEquals("avg(path)", toString(SQLExpressions.avg(path))); - assertEquals("count(path)", toString(SQLExpressions.count(path))); - assertEquals("corr(path,path2)", toString(SQLExpressions.corr(path, path2))); - assertEquals("covar_pop(path,path2)", toString(SQLExpressions.covarPop(path, path2))); - assertEquals("covar_samp(path,path2)", toString(SQLExpressions.covarSamp(path, path2))); - assertEquals("cume_dist()", toString(SQLExpressions.cumeDist())); - assertEquals("dense_rank()", toString(SQLExpressions.denseRank())); - assertEquals("first_value(path)", toString(SQLExpressions.firstValue(path))); - assertEquals("lag(path)", toString(SQLExpressions.lag(path))); - assertEquals("last_value(path)", toString(SQLExpressions.lastValue(path))); - assertEquals("lead(path)", toString(SQLExpressions.lead(path))); - assertEquals("max(path)", toString(SQLExpressions.max(path))); - assertEquals("min(path)", toString(SQLExpressions.min(path))); - assertEquals("nth_value(path, ?)", toString(SQLExpressions.nthValue(path, 3))); - assertEquals("ntile(?)", toString(SQLExpressions.ntile(4))); - assertEquals("percent_rank()", toString(SQLExpressions.percentRank())); - assertEquals("rank()", toString(SQLExpressions.rank())); - assertEquals("ratio_to_report(path)", toString(SQLExpressions.ratioToReport(path))); - assertEquals("row_number()", toString(SQLExpressions.rowNumber())); - assertEquals("stddev(path)", toString(SQLExpressions.stddev(path))); - assertEquals("stddev(distinct path)", toString(SQLExpressions.stddevDistinct(path))); - assertEquals("stddev_pop(path)", toString(SQLExpressions.stddevPop(path))); - assertEquals("stddev_samp(path)", toString(SQLExpressions.stddevSamp(path))); - assertEquals("sum(path)", toString(SQLExpressions.sum(path))); - assertEquals("variance(path)", toString(SQLExpressions.variance(path))); - assertEquals("var_pop(path)", toString(SQLExpressions.varPop(path))); - assertEquals("var_samp(path)", toString(SQLExpressions.varSamp(path))); - - // TODO FIRST - // TODO LAST - // TODO NTH_VALUE ... FROM (FIRST|LAST) (RESPECT|IGNORE) NULLS - } - - @Test - public void Regr() { - NumberPath path = Expressions.numberPath(Long.class, "path"); - NumberPath path2 = Expressions.numberPath(Long.class, "path2"); - assertEquals("regr_slope(path, path2)", toString(SQLExpressions.regrSlope(path, path2))); - assertEquals("regr_intercept(path, path2)", toString(SQLExpressions.regrIntercept(path, path2))); - assertEquals("regr_count(path, path2)", toString(SQLExpressions.regrCount(path, path2))); - assertEquals("regr_r2(path, path2)", toString(SQLExpressions.regrR2(path, path2))); - assertEquals("regr_avgx(path, path2)", toString(SQLExpressions.regrAvgx(path, path2))); - assertEquals("regr_avgy(path, path2)", toString(SQLExpressions.regrAvgy(path, path2))); - assertEquals("regr_sxx(path, path2)", toString(SQLExpressions.regrSxx(path, path2))); - assertEquals("regr_syy(path, path2)", toString(SQLExpressions.regrSyy(path, path2))); - assertEquals("regr_sxy(path, path2)", toString(SQLExpressions.regrSxy(path, path2))); - } - - @Test - public void Rows_Between() { - NumberPath path = Expressions.numberPath(Long.class, "path"); - NumberPath intPath = Expressions.numberPath(Integer.class, "intPath"); - WindowFunction wf = SQLExpressions.sum(path).over().orderBy(path); - - assertEquals("sum(path) over (order by path rows between current row and unbounded following)", - toString(wf.rows().between().currentRow().unboundedFollowing())); - assertEquals("sum(path) over (order by path rows between preceding intPath and following intPath)", - toString(wf.rows().between().preceding(intPath).following(intPath))); - assertEquals("sum(path) over (order by path rows between preceding ? and following ?)", - toString(wf.rows().between().preceding(1).following(3))); - } - - @Test - public void Rows_UnboundedPreceding() { - NumberPath path = Expressions.numberPath(Long.class, "path"); - WindowFunction wf = SQLExpressions.sum(path).over().orderBy(path); - - assertEquals("sum(path) over (order by path rows unbounded preceding)", - toString(wf.rows().unboundedPreceding())); - } - - @Test - public void Rows_CurrentRow() { - NumberPath path = Expressions.numberPath(Long.class, "path"); - WindowFunction wf = SQLExpressions.sum(path).over().orderBy(path); - - assertEquals("sum(path) over (order by path rows current row)", - toString(wf.rows().currentRow())); - } - - @Test - public void Rows_PrecedingRow() { - NumberPath path = Expressions.numberPath(Long.class, "path"); - NumberPath intPath = Expressions.numberPath(Integer.class, "intPath"); - WindowFunction wf = SQLExpressions.sum(path).over().orderBy(path); - - assertEquals("sum(path) over (order by path rows preceding intPath)", - toString(wf.rows().preceding(intPath))); - assertEquals("sum(path) over (order by path rows preceding ?)", - toString(wf.rows().preceding(3))); - } - - @Test - public void Keep_First() { - //MIN(salary) KEEP (DENSE_RANK FIRST ORDER BY commission_pct) OVER (PARTITION BY department_id) - NumberPath path = Expressions.numberPath(Long.class, "path"); - NumberPath path2 = Expressions.numberPath(Long.class, "path2"); - NumberPath path3 = Expressions.numberPath(Long.class, "path3"); - assertEquals( - "min(path) keep (dense_rank first order by path2)", - toString(SQLExpressions.min(path).keepFirst().orderBy(path2))); - assertEquals( - "min(path) keep (dense_rank first order by path2) over (partition by path3)", - toString(SQLExpressions.min(path).keepFirst().orderBy(path2).over().partitionBy(path3))); - } - - @Test - public void Keep_Last() { - //MIN(salary) KEEP (DENSE_RANK FIRST ORDER BY commission_pct) OVER (PARTITION BY department_id) - NumberPath path = Expressions.numberPath(Long.class, "path"); - NumberPath path2 = Expressions.numberPath(Long.class, "path2"); - NumberPath path3 = Expressions.numberPath(Long.class, "path3"); - assertEquals( - "min(path) keep (dense_rank last order by path2) over (partition by path3)", - toString(SQLExpressions.min(path).keepLast().orderBy(path2).over().partitionBy(path3))); - } - - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/WithinGroupTest.java b/querydsl-sql/src/test/java/com/mysema/query/sql/WithinGroupTest.java deleted file mode 100644 index bf4451134e..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/WithinGroupTest.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.mysema.query.sql; - -import static org.junit.Assert.assertEquals; - -import org.junit.Test; - -import com.mysema.query.support.Expressions; -import com.mysema.query.types.Expression; -import com.mysema.query.types.path.NumberPath; - -public class WithinGroupTest { - - private static String toString(Expression e) { - return new SQLSerializer(Configuration.DEFAULT).handle(e).toString(); - } - - @Test - public void All() { - NumberPath path = Expressions.numberPath(Long.class, "path"); - NumberPath path2 = Expressions.numberPath(Long.class, "path2"); - - assertEquals("cume_dist(path)", toString(SQLExpressions.cumeDist(path))); - assertEquals("cume_dist(path, path2)", toString(SQLExpressions.cumeDist(path, path2))); - assertEquals("dense_rank(path, path2)", toString(SQLExpressions.denseRank(path, path2))); - assertEquals("listagg(path,',')", toString(SQLExpressions.listagg(path, ","))); - assertEquals("percent_rank(path, path2)", toString(SQLExpressions.percentRank(path, path2))); - assertEquals("percentile_cont(path)", toString(SQLExpressions.percentileCont(path))); - assertEquals("percentile_disc(path)", toString(SQLExpressions.percentileDisc(path))); - assertEquals("rank(path, path2)", toString(SQLExpressions.rank(path, path2))); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/dml/DefaultMapperTest.java b/querydsl-sql/src/test/java/com/mysema/query/sql/dml/DefaultMapperTest.java deleted file mode 100644 index bd84d0af63..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/dml/DefaultMapperTest.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.mysema.query.sql.dml; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import java.util.Map; - -import org.junit.Test; - -import com.mysema.query.sql.domain.QEmployee; -import com.mysema.query.types.Path; - -public class DefaultMapperTest extends AbstractMapperTest { - - private static final QEmployee emp = QEmployee.employee; - - @Test - public void Extract() { - Map, Object> values = DefaultMapper.DEFAULT.createMap(emp, employee); - assertEquals(employee.getDatefield(), values.get(emp.datefield)); - assertEquals(employee.getFirstname(), values.get(emp.firstname)); - assertEquals(employee.getLastname(), values.get(emp.lastname)); - assertEquals(employee.getSalary(), values.get(emp.salary)); - assertEquals(employee.getSuperiorId(), values.get(emp.superiorId)); - assertEquals(employee.getTimefield(), values.get(emp.timefield)); - } - - @Test - public void Extract2() { - Map, Object> values = DefaultMapper.DEFAULT.createMap(emp, new EmployeeX()); - assertTrue(values.isEmpty()); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/dml/SQLDeleteClauseTest.java b/querydsl-sql/src/test/java/com/mysema/query/sql/dml/SQLDeleteClauseTest.java deleted file mode 100644 index fa0b1e1a54..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/dml/SQLDeleteClauseTest.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.mysema.query.sql.dml; - -import com.google.common.collect.ImmutableList; -import com.mysema.query.sql.KeyAccessorsTest.QEmployee; -import com.mysema.query.sql.SQLBindings; -import com.mysema.query.sql.SQLTemplates; -import org.junit.Test; -import static org.junit.Assert.assertEquals; - -public class SQLDeleteClauseTest { - - @Test(expected=IllegalArgumentException.class) - public void Error() { - QEmployee emp1 = new QEmployee("emp1"); - QEmployee emp2 = new QEmployee("emp2"); - SQLDeleteClause delete = new SQLDeleteClause(null, SQLTemplates.DEFAULT, emp1); - delete.where(emp2.id.eq(1)); - } - - @Test - public void GetSQL() { - QEmployee emp1 = new QEmployee("emp1"); - SQLDeleteClause delete = new SQLDeleteClause(null, SQLTemplates.DEFAULT, emp1); - delete.where(emp1.id.eq(1)); - - SQLBindings sql = delete.getSQL().get(0); - assertEquals("delete from EMPLOYEE\nwhere EMPLOYEE.ID = ?", sql.getSQL()); - assertEquals(ImmutableList.of(1), sql.getBindings()); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/dml/SQLInsertClauseTest.java b/querydsl-sql/src/test/java/com/mysema/query/sql/dml/SQLInsertClauseTest.java deleted file mode 100644 index 0c99b71b8b..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/dml/SQLInsertClauseTest.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.mysema.query.sql.dml; - -import com.google.common.collect.ImmutableList; -import com.mysema.query.sql.KeyAccessorsTest.QEmployee; -import com.mysema.query.sql.SQLBindings; -import com.mysema.query.sql.SQLTemplates; -import org.junit.Test; -import static org.junit.Assert.assertEquals; - -public class SQLInsertClauseTest { - - @Test - public void GetSQL() { - QEmployee emp1 = new QEmployee("emp1"); - SQLInsertClause insert = new SQLInsertClause(null, SQLTemplates.DEFAULT, emp1); - insert.set(emp1.id, 1); - - SQLBindings sql = insert.getSQL().get(0); - assertEquals("insert into EMPLOYEE (ID)\nvalues (?)", sql.getSQL()); - assertEquals(ImmutableList.of(1), sql.getBindings()); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/dml/SQLUpdateClauseTest.java b/querydsl-sql/src/test/java/com/mysema/query/sql/dml/SQLUpdateClauseTest.java deleted file mode 100644 index a1b8f338d6..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/dml/SQLUpdateClauseTest.java +++ /dev/null @@ -1,74 +0,0 @@ -package com.mysema.query.sql.dml; - -import com.google.common.collect.ImmutableList; -import com.mysema.query.sql.KeyAccessorsTest.QEmployee; -import com.mysema.query.sql.SQLBindings; -import com.mysema.query.sql.SQLSubQuery; -import com.mysema.query.sql.SQLTemplates; -import org.junit.Test; -import static org.junit.Assert.assertEquals; - -public class SQLUpdateClauseTest { - - @Test - public void GetSQL() { - QEmployee emp1 = new QEmployee("emp1"); - SQLUpdateClause update = new SQLUpdateClause(null, SQLTemplates.DEFAULT, emp1); - update.set(emp1.id, 1); - - SQLBindings sql = update.getSQL().get(0); - assertEquals("update EMPLOYEE\nset ID = ?", sql.getSQL()); - assertEquals(ImmutableList.of(1), sql.getBindings()); - } - - @Test - public void Intertable() { - QEmployee emp1 = new QEmployee("emp1"); - QEmployee emp2 = new QEmployee("emp2"); - SQLUpdateClause update = new SQLUpdateClause(null, SQLTemplates.DEFAULT, emp1); - update.set(emp1.id, 1) - .where(emp1.id.eq(new SQLSubQuery().from(emp2) - .where(emp2.superiorId.isNotNull()) - .unique(emp2.id))); - - SQLBindings sql = update.getSQL().get(0); - assertEquals("update EMPLOYEE\n" + - "set ID = ?\n" + - "where EMPLOYEE.ID = (select emp2.ID\n" + - "from EMPLOYEE emp2\n" + - "where emp2.SUPERIOR_ID is not null)", sql.getSQL()); - } - - @Test - public void Intertable2() { - QEmployee emp1 = new QEmployee("emp1"); - QEmployee emp2 = new QEmployee("emp2"); - SQLUpdateClause update = new SQLUpdateClause(null, SQLTemplates.DEFAULT, emp1); - update.set(emp1.id, new SQLSubQuery().from(emp2) - .where(emp2.superiorId.isNotNull()) - .unique(emp2.id)); - - SQLBindings sql = update.getSQL().get(0); - assertEquals("update EMPLOYEE\n" + - "set ID = (select emp2.ID\n" + - "from EMPLOYEE emp2\n" + - "where emp2.SUPERIOR_ID is not null)", sql.getSQL()); - } - - @Test - public void Intertable3() { - QEmployee emp1 = new QEmployee("emp1"); - QEmployee emp2 = new QEmployee("emp2"); - SQLUpdateClause update = new SQLUpdateClause(null, SQLTemplates.DEFAULT, emp1); - update.set(emp1.superiorId, new SQLSubQuery().from(emp2) - .where(emp2.id.eq(emp1.id)) - .unique(emp2.id)); - - SQLBindings sql = update.getSQL().get(0); - assertEquals("update EMPLOYEE\n" + - "set SUPERIOR_ID = (select emp2.ID\n" + - "from EMPLOYEE emp2\n" + - "where emp2.ID = EMPLOYEE.ID)", sql.getSQL()); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/domain/Employee.java b/querydsl-sql/src/test/java/com/mysema/query/sql/domain/Employee.java deleted file mode 100644 index 6d1d3d0541..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/domain/Employee.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql.domain; - -import java.math.BigDecimal; -import java.sql.Date; -import java.sql.Time; - -//@Schema("PUBLIC") -//@Table("EMPLOYEE") -public class Employee { - - //@Column("ID") - private Integer id; - - //@Column("FIRSTNAME") - private String firstname; - - //@Column("LASTNAME") - private String lastname; - - //@Column("SALARY") - private BigDecimal salary; - - //@Column("DATEFIELD") - private Date datefield; - - //@Column("TIMEFIELD") - private Time timefield; - - //@Column("SUPERIOR_ID") - private Integer superiorId; - - public Employee() {} - - public Employee(int id) { - this.id = id; - } - - public Integer getId() { - return id; - } - - public void setId(Integer id) { - this.id = id; - } - - public String getFirstname() { - return firstname; - } - - public void setFirstname(String firstname) { - this.firstname = firstname; - } - - public String getLastname() { - return lastname; - } - - public void setLastname(String lastname) { - this.lastname = lastname; - } - - public BigDecimal getSalary() { - return salary; - } - - public void setSalary(BigDecimal salary) { - this.salary = salary; - } - - public Date getDatefield() { - return new Date(datefield.getTime()); - } - - public void setDatefield(Date datefield) { - this.datefield = new Date(datefield.getTime()); - } - - public Time getTimefield() { - return timefield; - } - - public void setTimefield(Time timefield) { - this.timefield = timefield; - } - - public Integer getSuperiorId() { - return superiorId; - } - - public void setSuperiorId(Integer superiorId) { - this.superiorId = superiorId; - } - - - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/domain/QDateTest.java b/querydsl-sql/src/test/java/com/mysema/query/sql/domain/QDateTest.java deleted file mode 100644 index c87832d2f0..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/domain/QDateTest.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.mysema.query.sql.domain; - -import com.mysema.query.sql.ColumnMetadata; -import com.mysema.query.sql.RelationalPathBase; -import com.mysema.query.types.PathMetadata; -import com.mysema.query.types.PathMetadataFactory; -import com.mysema.query.types.path.DatePath; - -import java.sql.Date; - -public class QDateTest extends RelationalPathBase { - - private static final long serialVersionUID = 1394463749655231079L; - - public static final QDateTest qDateTest = new QDateTest("DATE_TEST"); - - public final DatePath dateTest = createDate("dateTest", java.sql.Date.class); - - public QDateTest(String path) { - super(QDateTest.class, PathMetadataFactory.forVariable(path), "PUBLIC", "DATE_TEST"); - addMetadata(); - } - - public QDateTest(PathMetadata metadata) { - super(QDateTest.class, metadata, "PUBLIC", "DATE_TEST"); - addMetadata(); - } - - protected void addMetadata() { - addMetadata(dateTest, ColumnMetadata.named("DATE_TEST")); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/domain/QEmployee.java b/querydsl-sql/src/test/java/com/mysema/query/sql/domain/QEmployee.java deleted file mode 100644 index f95a42ffd1..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/domain/QEmployee.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql.domain; - -import java.math.BigDecimal; - -import com.mysema.query.sql.ColumnMetadata; -import com.mysema.query.sql.ForeignKey; -import com.mysema.query.sql.PrimaryKey; -import com.mysema.query.sql.RelationalPathBase; -import com.mysema.query.types.PathMetadata; -import com.mysema.query.types.PathMetadataFactory; -import com.mysema.query.types.path.DatePath; -import com.mysema.query.types.path.NumberPath; -import com.mysema.query.types.path.StringPath; -import com.mysema.query.types.path.TimePath; - -//@Schema("PUBLIC") -//@Table("EMPLOYEE") -public class QEmployee extends RelationalPathBase { - - private static final long serialVersionUID = 1394463749655231079L; - - public static final QEmployee employee = new QEmployee("EMPLOYEE"); - - public final NumberPath id = createNumber("id", Integer.class); - - public final StringPath firstname = createString("firstname"); - - public final StringPath lastname = createString("lastname"); - - public final NumberPath salary = createNumber("salary", BigDecimal.class); - - public final DatePath datefield = createDate("datefield", java.sql.Date.class); - - public final TimePath timefield = createTime("timefield", java.sql.Time.class); - - public final NumberPath superiorId = createNumber("superiorId", Integer.class); - - public final PrimaryKey idKey = createPrimaryKey(id); - - public final ForeignKey superiorIdKey = createForeignKey(superiorId, "ID"); - - public final ForeignKey _superiorIdKey = createInvForeignKey(id, "SUPERIOR_ID"); - - public QEmployee(String path) { - super(Employee.class, PathMetadataFactory.forVariable(path), "PUBLIC", "EMPLOYEE"); - addMetadata(); - } - - public QEmployee(PathMetadata metadata) { - super(Employee.class, metadata, "PUBLIC", "EMPLOYEE"); - addMetadata(); - } - - protected void addMetadata() { - addMetadata(id, ColumnMetadata.named("ID")); - addMetadata(firstname, ColumnMetadata.named("FIRSTNAME")); - addMetadata(lastname, ColumnMetadata.named("LASTNAME")); - addMetadata(salary, ColumnMetadata.named("SALARY")); - addMetadata(datefield, ColumnMetadata.named("DATEFIELD")); - addMetadata(timefield, ColumnMetadata.named("TIMEFIELD")); - addMetadata(superiorId, ColumnMetadata.named("SUPERIOR_ID")); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/domain/QIdName.java b/querydsl-sql/src/test/java/com/mysema/query/sql/domain/QIdName.java deleted file mode 100644 index 461940ec67..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/domain/QIdName.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql.domain; - -import com.mysema.query.types.ConstructorExpression; -import com.mysema.query.types.Expression; - -public class QIdName extends ConstructorExpression { - - private static final long serialVersionUID = 5770565824515003611L; - - public QIdName(Expression id, Expression name) { - super(IdName.class, new Class[]{int.class, String.class}, id, name); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/domain/QSurvey.java b/querydsl-sql/src/test/java/com/mysema/query/sql/domain/QSurvey.java deleted file mode 100644 index f6291f70eb..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/domain/QSurvey.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql.domain; - -import com.mysema.query.sql.ColumnMetadata; -import com.mysema.query.sql.PrimaryKey; -import com.mysema.query.sql.RelationalPathBase; -import com.mysema.query.types.PathMetadata; -import com.mysema.query.types.PathMetadataFactory; -import com.mysema.query.types.path.NumberPath; -import com.mysema.query.types.path.StringPath; - -//@Schema("PUBLIC") -//@Table("SURVEY") -public class QSurvey extends RelationalPathBase{ - - private static final long serialVersionUID = -7427577079709192842L; - - public static final QSurvey survey = new QSurvey("SURVEY"); - - public final StringPath name = createString("name"); - - public final StringPath name2 = createString("name2"); - - public final NumberPath id = createNumber("id", Integer.class); - - public final PrimaryKey idKey = createPrimaryKey(id); - - public QSurvey(String path) { - super(QSurvey.class, PathMetadataFactory.forVariable(path), "PUBLIC", "SURVEY"); - addMetadata(); - } - - public QSurvey(PathMetadata metadata) { - super(QSurvey.class, metadata, "PUBLIC", "SURVEY"); - addMetadata(); - } - - protected void addMetadata() { - addMetadata(name, ColumnMetadata.named("NAME")); - addMetadata(name2, ColumnMetadata.named("NAME2")); - addMetadata(id, ColumnMetadata.named("ID")); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/domain/QTest_.java b/querydsl-sql/src/test/java/com/mysema/query/sql/domain/QTest_.java deleted file mode 100644 index dd88b0770d..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/domain/QTest_.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql.domain; - -import com.mysema.query.types.PathMetadata; -import com.mysema.query.types.PathMetadataFactory; -import com.mysema.query.types.path.EntityPathBase; -import com.mysema.query.types.path.StringPath; - -//@Table("TEST") -public class QTest_ extends EntityPathBase { - - private static final long serialVersionUID = -8421112749591552595L; - - public final StringPath name = createString("NAME"); - - public QTest_(String path) { - super(Object.class, PathMetadataFactory.forVariable(path)); - } - - public QTest_(PathMetadata metadata) { - super(Object.class, metadata); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/h2/H2QueryTest.java b/querydsl-sql/src/test/java/com/mysema/query/sql/h2/H2QueryTest.java deleted file mode 100644 index 6c8b72e344..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/h2/H2QueryTest.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.mysema.query.sql.h2; - -import org.junit.Before; -import org.junit.Test; - -import com.mysema.query.sql.H2Templates; -import com.mysema.query.sql.SQLQuery; -import com.mysema.query.sql.domain.QSurvey; - -public class H2QueryTest { - - private SQLQuery query; - - private QSurvey survey = new QSurvey("survey"); - - @Before - public void setUp() { - query = new SQLQuery(null, new H2Templates() {{ - newLineToSingleSpace(); - }}); - } - - @Test - public void Syntax() { -// SELECT TOP? [DISTINCT | All]? selectExpression -// FROM tableExpression+ - query.from(survey); -// WHERE expression+ - query.where(survey.name.isNotNull()); -// GROUP BY expression+ - query.groupBy(survey.name); -// HAVING expression - query.having(survey.name.lt("")); -// [ -// UNION ALL? select ORDER BY order -// MINUS -// EXCEPT -// INTERSECT -// ] -// LIMIT expression - query.limit(2); -// OFFSET expression - query.offset(3); -// SAMPLE_SIZE rowCountInt - // TODO -// FOR UPDATE - query.forUpdate(); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/hsqldb/HsqldbQueryTest.java b/querydsl-sql/src/test/java/com/mysema/query/sql/hsqldb/HsqldbQueryTest.java deleted file mode 100644 index df329d1635..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/hsqldb/HsqldbQueryTest.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.mysema.query.sql.hsqldb; - -import org.junit.Before; -import org.junit.Test; - -import com.mysema.query.sql.H2Templates; -import com.mysema.query.sql.SQLQuery; -import com.mysema.query.sql.domain.QSurvey; - -public class HsqldbQueryTest { - - private SQLQuery query; - - private QSurvey survey = new QSurvey("survey"); - - @Before - public void setUp() { - query = new SQLQuery(null, new H2Templates() {{ - newLineToSingleSpace(); - }}); - } - - @Test - public void Syntax() { -// SELECT [{LIMIT | TOP }[2]][ALL | DISTINCT] -// { selectExpression | table.* | * } [, ...] -// [INTO [CACHED | TEMP | TEXT][2] newTable] -// FROM tableList - query.from(survey); -// [WHERE Expression] - query.where(survey.id.isNotNull()); -// [GROUP BY Expression [, ...]] - query.groupBy(survey.name); -// [HAVING Expression] - query.having(survey.id.isNotNull()); -// [{ UNION [ALL | DISTINCT] | {MINUS [DISTINCT] | EXCEPT [DISTINCT] } | - // TODO MINUS - // TODO EXCEPT -// INTERSECT [DISTINCT] } selectStatement] - // TODO INTERSECT -// [ORDER BY orderExpression [, ...]] - query.orderBy(survey.name.asc()); -// [LIMIT [OFFSET ]]; - query.limit(4); - query.offset(4); - - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/mssql/SQLServerQueryTest.java b/querydsl-sql/src/test/java/com/mysema/query/sql/mssql/SQLServerQueryTest.java deleted file mode 100644 index 3da89598e7..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/mssql/SQLServerQueryTest.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql.mssql; - -import static org.junit.Assert.assertEquals; - -import org.junit.Test; - -import com.mysema.query.sql.SQLServerTemplates; -import com.mysema.query.sql.domain.QSurvey; - -public class SQLServerQueryTest { - - private static final QSurvey survey = QSurvey.survey; - - @Test - public void TableHints_Single() { - SQLServerQuery query = new SQLServerQuery(null, new SQLServerTemplates()); - query.from(survey).tableHints(SQLServerTableHints.NOWAIT).where(survey.name.isNull()); - assertEquals("from SURVEY SURVEY with (NOWAIT)\nwhere SURVEY.NAME is null", query.toString()); - } - - @Test - public void TableHints_Multiple() { - SQLServerQuery query = new SQLServerQuery(null, new SQLServerTemplates()); - query.from(survey).tableHints(SQLServerTableHints.NOWAIT, SQLServerTableHints.NOLOCK).where(survey.name.isNull()); - assertEquals("from SURVEY SURVEY with (NOWAIT, NOLOCK)\nwhere SURVEY.NAME is null", query.toString()); - } - - @Test - public void TableHints_Multiple2() { - QSurvey survey2 = new QSurvey("survey2"); - SQLServerQuery query = new SQLServerQuery(null, new SQLServerTemplates()); - query.from(survey).tableHints(SQLServerTableHints.NOWAIT) - .from(survey2).tableHints(SQLServerTableHints.NOLOCK) - .where(survey.name.isNull()); - assertEquals("from SURVEY SURVEY with (NOWAIT), SURVEY survey2 with (NOLOCK)\nwhere SURVEY.NAME is null", query.toString()); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/mssql/SQLServerSubQueryTest.java b/querydsl-sql/src/test/java/com/mysema/query/sql/mssql/SQLServerSubQueryTest.java deleted file mode 100644 index 8c27c85b6f..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/mssql/SQLServerSubQueryTest.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql.mssql; - -import static org.junit.Assert.assertEquals; - -import org.junit.Test; - -import com.mysema.query.sql.domain.QSurvey; - -public class SQLServerSubQueryTest { - - private static final QSurvey survey = QSurvey.survey; - - @Test - public void TableHints_Single() { - SQLServerSubQuery query = new SQLServerSubQuery(); - query.from(survey).tableHints(SQLServerTableHints.NOWAIT).where(survey.name.isNull()); - assertEquals("from SURVEY SURVEY with (NOWAIT)\nwhere SURVEY.NAME is null", query.toString()); - } - - @Test - public void TableHints_Multiple() { - SQLServerSubQuery query = new SQLServerSubQuery(); - query.from(survey).tableHints(SQLServerTableHints.NOWAIT, SQLServerTableHints.NOLOCK).where(survey.name.isNull()); - assertEquals("from SURVEY SURVEY with (NOWAIT, NOLOCK)\nwhere SURVEY.NAME is null", query.toString()); - } - - @Test - public void TableHints_Multiple2() { - QSurvey survey2 = new QSurvey("survey2"); - SQLServerSubQuery query = new SQLServerSubQuery(); - query.from(survey).tableHints(SQLServerTableHints.NOWAIT) - .from(survey2).tableHints(SQLServerTableHints.NOLOCK) - .where(survey.name.isNull()); - assertEquals("from SURVEY SURVEY with (NOWAIT), SURVEY survey2 with (NOLOCK)\nwhere SURVEY.NAME is null", query.toString()); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/mssql/WindowFunctionTest.java b/querydsl-sql/src/test/java/com/mysema/query/sql/mssql/WindowFunctionTest.java deleted file mode 100644 index e0716f4d38..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/mssql/WindowFunctionTest.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql.mssql; - -import static com.mysema.query.Constants.employee; -import static com.mysema.query.sql.SQLExpressions.rowNumber; -import static org.junit.Assert.assertEquals; - -import org.junit.Test; - -import com.mysema.query.sql.Configuration; -import com.mysema.query.sql.SQLSerializer; -import com.mysema.query.sql.WindowFunction; -import com.mysema.query.types.Expression; - -public class WindowFunctionTest { - - private static String toString(Expression e) { - return new SQLSerializer(Configuration.DEFAULT).handle(e).toString(); - } - -// ROW_NUMBER() OVER (ORDER BY OrderDate) AS 'RowNumber' - -// ROW_NUMBER() OVER (PARTITION BY PostalCode ORDER BY SalesYTD DESC) - - @Test - public void Mutable() { - WindowFunction rn = rowNumber().over().orderBy(employee.firstname); - assertEquals("row_number() over (order by e.FIRSTNAME)", toString(rn)); - assertEquals("row_number() over (order by e.FIRSTNAME, e.LASTNAME)", toString(rn.orderBy(employee.lastname))); - } - - @Test - public void OrderBy() { - assertEquals("row_number() over (order by e.FIRSTNAME)", - toString(rowNumber().over().orderBy(employee.firstname.asc()))); - - assertEquals("row_number() over (order by e.FIRSTNAME)", - toString(rowNumber().over().orderBy(employee.firstname))); - - assertEquals("row_number() over (order by e.FIRSTNAME) as rn", - toString(rowNumber().over().orderBy(employee.firstname.asc()).as("rn"))); - - assertEquals("row_number() over (order by e.FIRSTNAME desc)", - toString(rowNumber().over().orderBy(employee.firstname.desc()))); - } - - @Test - public void PartitionBy() { - assertEquals("row_number() over (partition by e.LASTNAME order by e.FIRSTNAME)", - toString(rowNumber().over().partitionBy(employee.lastname).orderBy(employee.firstname.asc()))); - - assertEquals("row_number() over (partition by e.LASTNAME, e.FIRSTNAME order by e.FIRSTNAME)", - toString(rowNumber().over().partitionBy(employee.lastname, employee.firstname).orderBy(employee.firstname.asc()))); - } - - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/mysql/MySQLQueryFactoryTest.java b/querydsl-sql/src/test/java/com/mysema/query/sql/mysql/MySQLQueryFactoryTest.java deleted file mode 100644 index b23d0a0c99..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/mysql/MySQLQueryFactoryTest.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql.mysql; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -import java.sql.Connection; - -import javax.inject.Provider; - -import org.easymock.EasyMock; -import org.junit.Before; -import org.junit.Test; - -import com.mysema.query.sql.SQLTemplates; -import com.mysema.query.sql.dml.SQLInsertClause; -import com.mysema.query.sql.domain.QSurvey; - -public class MySQLQueryFactoryTest { - - private MySQLQueryFactory queryFactory; - - @Before - public void setUp() { - Provider provider = new Provider() { - @Override - public Connection get() { - return EasyMock.createNiceMock(Connection.class); - } - }; - queryFactory = new MySQLQueryFactory(SQLTemplates.DEFAULT, provider); - } - - @Test - public void Query() { - assertNotNull(queryFactory.query()); - } - - @Test - public void SubQuery() { - assertNotNull(queryFactory.subQuery()); - } - - @Test - public void SubQuery_From() { - assertNotNull(queryFactory.subQuery(QSurvey.survey)); - } - - @Test - public void From() { - assertNotNull(queryFactory.from(QSurvey.survey)); - } - - @Test - public void Delete() { - assertNotNull(queryFactory.delete(QSurvey.survey)); - } - - @Test - public void Insert() { - assertNotNull(queryFactory.insert(QSurvey.survey)); - } - - @Test - public void InsertIgnore() { - SQLInsertClause clause = queryFactory.insertIgnore(QSurvey.survey); - assertEquals("insert ignore into SURVEY\nvalues ()", clause.toString()); - } - - @Test - public void InsertOnDuplicateKeyUpdate() { - SQLInsertClause clause = queryFactory.insertOnDuplicateKeyUpdate(QSurvey.survey, "c = c+1"); - assertEquals("insert into SURVEY\nvalues () on duplicate key update c = c+1", clause.toString()); - } - - @Test - public void InsertOnDuplicateKeyUpdate2() { - SQLInsertClause clause = queryFactory.insertOnDuplicateKeyUpdate(QSurvey.survey, QSurvey.survey.id.eq(2)); - assertEquals("insert into SURVEY\nvalues () on duplicate key update SURVEY.ID = ?", clause.toString()); - } - - @Test - public void Replace() { - assertNotNull(queryFactory.replace(QSurvey.survey)); - } - - @Test - public void Update() { - assertNotNull(queryFactory.update(QSurvey.survey)); - } - - @Test - public void Merge() { - assertNotNull(queryFactory.merge(QSurvey.survey)); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/oracle/OracleQueryFactoryTest.java b/querydsl-sql/src/test/java/com/mysema/query/sql/oracle/OracleQueryFactoryTest.java deleted file mode 100644 index a6ba299b35..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/oracle/OracleQueryFactoryTest.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql.oracle; - -import static org.junit.Assert.assertNotNull; - -import java.sql.Connection; - -import javax.inject.Provider; - -import org.easymock.EasyMock; -import org.junit.Before; -import org.junit.Test; - -import com.mysema.query.sql.SQLTemplates; -import com.mysema.query.sql.domain.QSurvey; - -public class OracleQueryFactoryTest { - - private OracleQueryFactory queryFactory; - - @Before - public void setUp() { - Provider provider = new Provider() { - @Override - public Connection get() { - return EasyMock.createNiceMock(Connection.class); - } - }; - queryFactory = new OracleQueryFactory(SQLTemplates.DEFAULT, provider); - } - - @Test - public void Query() { - assertNotNull(queryFactory.query()); - } - - @Test - public void SubQuery() { - assertNotNull(queryFactory.subQuery()); - } - - @Test - public void SubQuery_From() { - assertNotNull(queryFactory.subQuery(QSurvey.survey)); - } - - @Test - public void From() { - assertNotNull(queryFactory.from(QSurvey.survey)); - } - - @Test - public void Delete() { - assertNotNull(queryFactory.delete(QSurvey.survey)); - } - - @Test - public void Insert() { - assertNotNull(queryFactory.insert(QSurvey.survey)); - } - - @Test - public void Update() { - assertNotNull(queryFactory.update(QSurvey.survey)); - } - - @Test - public void Merge() { - assertNotNull(queryFactory.merge(QSurvey.survey)); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/postgres/PostgresQueryFactoryTest.java b/querydsl-sql/src/test/java/com/mysema/query/sql/postgres/PostgresQueryFactoryTest.java deleted file mode 100644 index 1413952022..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/postgres/PostgresQueryFactoryTest.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql.postgres; - -import static org.junit.Assert.assertNotNull; - -import java.sql.Connection; - -import javax.inject.Provider; - -import org.easymock.EasyMock; -import org.junit.Before; -import org.junit.Test; - -import com.mysema.query.sql.SQLTemplates; -import com.mysema.query.sql.domain.QSurvey; - -public class PostgresQueryFactoryTest { - - private PostgresQueryFactory queryFactory; - - @Before - public void setUp() { - Provider provider = new Provider() { - @Override - public Connection get() { - return EasyMock.createNiceMock(Connection.class); - } - }; - queryFactory = new PostgresQueryFactory(SQLTemplates.DEFAULT, provider); - } - - @Test - public void Query() { - assertNotNull(queryFactory.query()); - } - - @Test - public void SubQuery() { - assertNotNull(queryFactory.subQuery()); - } - - @Test - public void SubQuery_From() { - assertNotNull(queryFactory.subQuery(QSurvey.survey)); - } - - @Test - public void From() { - assertNotNull(queryFactory.from(QSurvey.survey)); - } - - @Test - public void Delete() { - assertNotNull(queryFactory.delete(QSurvey.survey)); - } - - @Test - public void Insert() { - assertNotNull(queryFactory.insert(QSurvey.survey)); - } - - @Test - public void Update() { - assertNotNull(queryFactory.update(QSurvey.survey)); - } - - @Test - public void Merge() { - assertNotNull(queryFactory.merge(QSurvey.survey)); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/postgres/PostgresQueryTest.java b/querydsl-sql/src/test/java/com/mysema/query/sql/postgres/PostgresQueryTest.java deleted file mode 100644 index b2df7024a2..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/postgres/PostgresQueryTest.java +++ /dev/null @@ -1,94 +0,0 @@ -package com.mysema.query.sql.postgres; - -import static org.junit.Assert.assertEquals; - -import org.junit.Before; -import org.junit.Test; - -import com.mysema.query.sql.PostgresTemplates; -import com.mysema.query.sql.domain.QSurvey; - -public class PostgresQueryTest { - - private PostgresQuery query; - - private QSurvey survey = new QSurvey("survey"); - - @Before - public void setUp() { - query = new PostgresQuery(null, new PostgresTemplates() {{ - newLineToSingleSpace(); - }}); - } - - @Test - public void Syntax() { -// [ WITH [ RECURSIVE ] with_query [, ...] ] -// SELECT [ ALL | DISTINCT [ ON ( expression [, ...] ) ] ] -// * | expression [ [ AS ] output_name ] [, ...] -// [ FROM from_item [, ...] ] - query.from(survey); -// [ WHERE condition ] - query.where(survey.name.isNull()); -// [ GROUP BY expression [, ...] ] - query.groupBy(survey.name); -// [ HAVING condition [, ...] ] - query.having(survey.id.isNotNull()); -// [ WINDOW window_name AS ( window_definition ) [, ...] ] - // TODO -// [ { UNION | INTERSECT | EXCEPT } [ ALL ] select ] - // TODO INTERSECT - // TODO EXCEPT -// [ ORDER BY expression [ ASC | DESC | USING operator ] [ NULLS { FIRST | LAST } ] [, ...] ] - query.orderBy(survey.name.asc()); -// [ LIMIT { count | ALL } ] - query.limit(4); -// [ OFFSET start [ ROW | ROWS ] ] - query.offset(4); -// [ FETCH { FIRST | NEXT } [ count ] { ROW | ROWS } ONLY ] -// [ FOR { UPDATE | SHARE } [ OF table_name [, ...] ] [ NOWAIT ] [...] ] - query.forUpdate(); - query.forShare(); - query.noWait(); - - query.forUpdate().of(survey); - -// where from_item can be one of: -// -// [ ONLY ] table_name [ * ] [ [ AS ] alias [ ( column_alias [, ...] ) ] ] -// ( select ) [ AS ] alias [ ( column_alias [, ...] ) ] -// with_query_name [ [ AS ] alias [ ( column_alias [, ...] ) ] ] -// function_name ( [ argument [, ...] ] ) [ AS ] alias [ ( column_alias [, ...] | column_definition [, ...] ) ] -// function_name ( [ argument [, ...] ] ) AS ( column_definition [, ...] ) -// from_item [ NATURAL ] join_type from_item [ ON join_condition | USING ( join_column [, ...] ) ] -// -// and with_query is: -// -// with_query_name [ ( column_name [, ...] ) ] AS ( select ) -// -// TABLE { [ ONLY ] table_name [ * ] | with_query_name } - } - - @Test - public void ForShare() { - query.from(survey).forShare(); - assertEquals("from SURVEY survey for share", toString(query)); - } - - @Test - public void ForUpDate_NoWait() { - query.from(survey).forUpdate().noWait(); - assertEquals("from SURVEY survey for update nowait", toString(query)); - } - - @Test - public void ForUpdate_Of() { - query.from(survey).forUpdate().of(survey); - assertEquals("from SURVEY survey for update of SURVEY", toString(query)); - } - - private String toString(PostgresQuery query) { - return query.toString().replace('\n', ' '); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/postgres/PostgresTypesTest.java b/querydsl-sql/src/test/java/com/mysema/query/sql/postgres/PostgresTypesTest.java deleted file mode 100644 index 93c1535bc1..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/postgres/PostgresTypesTest.java +++ /dev/null @@ -1,81 +0,0 @@ -package com.mysema.query.sql.postgres; - -import java.lang.reflect.Field; -import java.sql.DatabaseMetaData; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.HashMap; -import java.util.Map; - -import com.mysema.testutil.ExternalDB; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.mysema.query.Connections; -import com.mysema.query.sql.JDBCTypeMapping; -import com.mysema.query.sql.PostgresTemplates; -import com.mysema.query.sql.SQLTemplates; -import org.junit.experimental.categories.Category; - -@Category(ExternalDB.class) -public class PostgresTypesTest { - - @Before - public void setUp() throws SQLException, ClassNotFoundException { - Connections.initPostgres(); - } - - @After - public void tearDown() throws SQLException { - Connections.close(); - } - - @Test - public void test() throws SQLException, IllegalArgumentException, IllegalAccessException { - SQLTemplates templates = new PostgresTemplates(); - Connections.dropTable(templates, "type_tests"); - Statement stmt = Connections.getStatement(); - stmt.execute("create table type_tests (" + - "_numeric_1 numeric(1), " + - "_numeric_2 numeric(2), " + - "_numeric_3 numeric(3), " + - "_numeric_4 numeric(3), " + - "_smallint smallint, " + - "_integer integer, " + - "_bigint bigint, " + - "_decimal decimal, " + - "_numeric numeric, " + - "_real real, " + - "_double_precision double precision, " + - "_serial serial, " + - "_bigserial bigserial)"); - - Map types = new HashMap(); - for (Field field : java.sql.Types.class.getFields()) { - types.put((Integer)field.get(null), field.getName()); - } - - JDBCTypeMapping jdbcTypeMapping = new JDBCTypeMapping(); - - DatabaseMetaData metadata = Connections.getConnection().getMetaData(); - ResultSet rs = metadata.getColumns(null, null, "type_tests", null); - try { - while (rs.next()) { - System.out.println(rs.getString("COLUMN_NAME")); - System.out.println(types.get(rs.getInt("DATA_TYPE"))); - System.out.println(rs.getInt("COLUMN_SIZE")); - System.out.println(rs.getInt("DECIMAL_DIGITS")); - System.out.println(jdbcTypeMapping.get( - rs.getInt("DATA_TYPE"), - rs.getInt("COLUMN_SIZE"), - rs.getInt("DECIMAL_DIGITS"))); - System.out.println(); - } - } finally { - rs.close(); - } - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/spatial/AbstractConverterTest.java b/querydsl-sql/src/test/java/com/mysema/query/sql/spatial/AbstractConverterTest.java deleted file mode 100644 index ffbb121057..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/spatial/AbstractConverterTest.java +++ /dev/null @@ -1,90 +0,0 @@ -package com.mysema.query.sql.spatial; - -import java.util.List; - -import org.geolatte.geom.Geometry; -import org.geolatte.geom.GeometryCollection; -import org.geolatte.geom.LineString; -import org.geolatte.geom.MultiLineString; -import org.geolatte.geom.MultiPoint; -import org.geolatte.geom.MultiPolygon; -import org.geolatte.geom.Point; -import org.geolatte.geom.PointSequence; -import org.geolatte.geom.PointSequenceBuilder; -import org.geolatte.geom.PointSequenceBuilders; -import org.geolatte.geom.Points; -import org.geolatte.geom.Polygon; -import org.geolatte.geom.codec.Wkt; -import org.geolatte.geom.crs.CrsId; - -import com.google.common.collect.Lists; -import com.mysema.query.Connections; - -public abstract class AbstractConverterTest { - - protected PointSequence createSequence(Point... points) { - PointSequenceBuilder builder = PointSequenceBuilders.fixedSized(points.length, points[0].getDimensionalFlag()); - for (Point point : points) { - builder.add(point); - } - return builder.toPointSequence(); - } - - protected List getGeometries() { - CrsId crs = CrsId.valueOf(1); - List data = Lists.newArrayList(); - // points -// data.add(Points.createEmpty()); - data.add(Points.create(1, 2)); - data.add(Points.create(1, 2, crs)); - data.add(Points.create3D(1, 2, 3)); - data.add(Points.create3D(1, 2, 3, crs)); - data.add(Points.createMeasured(1, 2, 3)); - data.add(Points.createMeasured(1, 2, 3, crs)); - - // linestring - data.add(LineString.createEmpty()); - for (int i = 0; i < 6; i++) { - data.add(new LineString(createSequence((Point)data.get(i)), crs)); - } - - // polgyon - // TODO - - // multipoint - data.add(MultiPoint.createEmpty()); - for (int i = 0; i < 6; i++) { - data.add(new MultiPoint(new Point[]{(Point)data.get(i)})); - } - - // multilinestring - int size = data.size(); - data.add(MultiLineString.createEmpty()); - for (int i = 0; i < size; i++) { - if (data.get(i) instanceof LineString) { - data.add(new MultiLineString(new LineString[]{(LineString)data.get(i)})); - } - } - - // multipolygon - data.add(MultiPolygon.createEmpty()); - for (int i = 0; i < size; i++) { - if (data.get(i) instanceof Polygon) { - data.add(new MultiPolygon(new Polygon[]{(Polygon)data.get(i)})); - } - } - - // collection - size = data.size(); - for (int i = 0; i < size; i++) { - data.add(new GeometryCollection(new Geometry[]{data.get(i)})); - } - - for (String wkt : Connections.getSpatialData().values()) { - data.add(Wkt.fromWkt(wkt)); - } - - return data; - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/spatial/JGeometryConverterTest.java b/querydsl-sql/src/test/java/com/mysema/query/sql/spatial/JGeometryConverterTest.java deleted file mode 100644 index bfa3e92210..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/spatial/JGeometryConverterTest.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.mysema.query.sql.spatial; - -import static org.junit.Assert.assertEquals; - -import java.util.List; - -import oracle.spatial.geometry.JGeometry; - -import org.geolatte.geom.Geometry; -import org.geolatte.geom.GeometryCollection; -import org.geolatte.geom.MultiLineString; -import org.geolatte.geom.MultiPolygon; -import org.geolatte.geom.Polygon; -import org.geolatte.geom.codec.Wkt; -import org.junit.Test; - -public class JGeometryConverterTest extends AbstractConverterTest { - - @Test - public void RoundTrip() { - List geometries = getGeometries(); - for (Geometry geometry : geometries) { - if (geometry instanceof MultiPolygon) continue; - if (geometry instanceof GeometryCollection) continue; - System.err.println(Wkt.toWkt(geometry)); - JGeometry converted = JGeometryConverter.convert(geometry); - Geometry back = JGeometryConverter.convert(converted); - assertEquals(geometry, back); - } - } - - @Test - public void Polygon() { - Polygon polygon = (org.geolatte.geom.Polygon) Wkt.fromWkt("POLYGON (" + - "(30 10, 40 40, 20 40, 10 20, 30 10), " + - "(20 30, 35 35, 30 20, 20 30))"); - JGeometry geo = JGeometryConverter.convert(polygon); - - double[] extRing = new double[]{30, 10, 40, 40, 20, 40, 10, 20, 30, 10}; - double[] intRing = new double[]{20, 30, 35, 35, 30, 20, 20, 30}; - JGeometry geo2 = JGeometry.createLinearPolygon(new Object[]{extRing, intRing}, - polygon.getCoordinateDimension(), polygon.getSRID()); - assertEquals(geo2, geo); - } - - @Test - public void MultiLineString() { - MultiLineString multiLineString = (org.geolatte.geom.MultiLineString) Wkt.fromWkt("MULTILINESTRING (" + - "(30 10, 40 40, 20 40, 10 20, 30 10), " + - "(20 30, 35 35, 30 20, 20 30))"); - JGeometry geo = JGeometryConverter.convert(multiLineString); - - double[] line1 = new double[]{30, 10, 40, 40, 20, 40, 10, 20, 30, 10}; - double[] line2 = new double[]{20, 30, 35, 35, 30, 20, 20, 30}; - JGeometry geo2 = JGeometry.createLinearMultiLineString(new Object[]{line1, line2}, - multiLineString.getCoordinateDimension(), multiLineString.getSRID()); -// System.err.println(Arrays.toString(geo.getElemInfo())); -// System.err.println(Arrays.toString(geo.getOrdinatesArray())); -// System.err.println(Arrays.toString(geo2.getElemInfo())); -// System.err.println(Arrays.toString(geo2.getOrdinatesArray())); - assertEquals(geo2, geo); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/spatial/PGgeometryConverterTest.java b/querydsl-sql/src/test/java/com/mysema/query/sql/spatial/PGgeometryConverterTest.java deleted file mode 100644 index 11c5dbf1d0..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/spatial/PGgeometryConverterTest.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.mysema.query.sql.spatial; - -import static org.junit.Assert.assertEquals; - -import java.util.List; - -import org.geolatte.geom.Geometry; -import org.junit.Test; - -public class PGgeometryConverterTest extends AbstractConverterTest { - - @Test - public void RoundTrip() { - List geometries = getGeometries(); - for (Geometry geometry : geometries) { - org.postgis.Geometry converted = PGgeometryConverter.convert(geometry); - Geometry back = PGgeometryConverter.convert(converted); - assertEquals(geometry, back); - } - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/spatial/QShapes.java b/querydsl-sql/src/test/java/com/mysema/query/sql/spatial/QShapes.java deleted file mode 100644 index cbc4590529..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/spatial/QShapes.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.mysema.query.sql.spatial; - -import static com.mysema.query.types.PathMetadataFactory.forVariable; - -import javax.annotation.Generated; - -import org.geolatte.geom.Geometry; - -import com.mysema.query.spatial.path.GeometryPath; -import com.mysema.query.sql.ColumnMetadata; -import com.mysema.query.types.Path; -import com.mysema.query.types.PathMetadata; -import com.mysema.query.types.path.NumberPath; - -/** - * QShapes is a Querydsl query type for QShapes - */ -@Generated("com.mysema.query.sql.codegen.MetaDataSerializer") -public class QShapes extends RelationalPathSpatial { - - private static final long serialVersionUID = 563213127; - - public static final QShapes shapes = new QShapes("SHAPES"); - - public final GeometryPath geometry = createGeometry("geometry", Geometry.class); - - public final NumberPath id = createNumber("id", Integer.class); - - public final com.mysema.query.sql.PrimaryKey shapesPkey = createPrimaryKey(id); - - public QShapes(String variable) { - super(Shapes.class, forVariable(variable), "PUBLIC", "SHAPES"); - addMetadata(); - } - - public QShapes(String variable, String schema, String table) { - super(Shapes.class, forVariable(variable), schema, table); - addMetadata(); - } - - public QShapes(Path path) { - super(path.getType(), path.getMetadata(), "PUBLIC", "SHAPES"); - addMetadata(); - } - - public QShapes(PathMetadata metadata) { - super(Shapes.class, metadata, "PUBLIC", "SHAPES"); - addMetadata(); - } - - public void addMetadata() { - addMetadata(geometry, ColumnMetadata.named("GEOMETRY").ofType(1111).withSize(2147483647)); - addMetadata(id, ColumnMetadata.named("ID").ofType(4).withSize(10).notNull()); - } - -} - diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/spatial/SQLServerGeometryWriterTest.java b/querydsl-sql/src/test/java/com/mysema/query/sql/spatial/SQLServerGeometryWriterTest.java deleted file mode 100644 index d5d0fe0b73..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/spatial/SQLServerGeometryWriterTest.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.mysema.query.sql.spatial; - -import static org.junit.Assert.assertEquals; - -import java.io.IOException; - -import org.geolatte.geom.Geometry; -import org.junit.Test; - -public class SQLServerGeometryWriterTest extends AbstractConverterTest { - - @Test - public void RoundTrip() throws IOException { - for (Geometry geometry : getGeometries()) { - byte[] bytes = new SQLServerGeometryWriter().write(geometry); - Geometry geometry2 = new SQLServerGeometryReader().read(bytes); - assertEquals(geometry, geometry2); - } - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/teradata/SetQueryBandClauseTest.java b/querydsl-sql/src/test/java/com/mysema/query/sql/teradata/SetQueryBandClauseTest.java deleted file mode 100644 index d701ff8960..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/teradata/SetQueryBandClauseTest.java +++ /dev/null @@ -1,54 +0,0 @@ -package com.mysema.query.sql.teradata; - -import static org.junit.Assert.assertEquals; - -import org.junit.Before; -import org.junit.Test; - -import com.mysema.query.sql.Configuration; -import com.mysema.query.sql.SQLTemplates; - -public class SetQueryBandClauseTest { - - private Configuration conf; - - private SetQueryBandClause clause; - - @Before - public void setUp() { - conf = new Configuration(SQLTemplates.DEFAULT); - conf.setUseLiterals(true); - clause = new SetQueryBandClause(null, conf); - } - - @Test - public void ToString() { - clause.set("a", "b"); - assertEquals("set query_band='a=b;' for session", clause.toString()); - } - - @Test - public void ToString2() { - conf.setUseLiterals(false); - clause.set("a", "b"); - clause.forTransaction(); - assertEquals("set query_band=? for transaction", clause.toString()); - } - - @Test - public void ForTransaction() { - clause.forTransaction(); - clause.set("a", "b"); - clause.set("b", "c"); - assertEquals("set query_band='b=c;a=b;' for transaction", clause.toString()); - } - - @Test - public void GetSQL() { - clause.forTransaction(); - clause.set("a", "b"); - clause.set("b", "c"); - assertEquals("set query_band='b=c;a=b;' for transaction", clause.getSQL().get(0).getSQL()); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/types/LocaleTypeTest.java b/querydsl-sql/src/test/java/com/mysema/query/sql/types/LocaleTypeTest.java deleted file mode 100644 index dfedc5d933..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/types/LocaleTypeTest.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.mysema.query.sql.types; - -import static org.junit.Assert.assertEquals; - -import java.util.Locale; - -import org.junit.Test; - -import com.mysema.query.sql.types.LocaleType; - -public class LocaleTypeTest { - - @Test - public void Lang() { - Locale l = new Locale("en"); - assertEquals(l, LocaleType.toLocale(l.toString())); - } - - @Test - public void Lang_Country() { - Locale l = new Locale("en", "US"); - assertEquals(l, LocaleType.toLocale(l.toString())); - } - - @Test - public void Lang_Country_Variant() { - Locale l = new Locale("en", "US", "X"); - assertEquals(l, LocaleType.toLocale(l.toString())); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/types/TypeTest.java b/querydsl-sql/src/test/java/com/mysema/query/sql/types/TypeTest.java deleted file mode 100644 index 90e9e0e074..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/types/TypeTest.java +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright 2011, Mysema Ltd - * - * 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. - */ -package com.mysema.query.sql.types; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; - -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Method; -import java.lang.reflect.Proxy; -import java.math.BigDecimal; -import java.math.BigInteger; -import java.net.MalformedURLException; -import java.net.URL; -import java.sql.Blob; -import java.sql.Clob; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Time; -import java.sql.Timestamp; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Currency; -import java.util.List; - -import org.easymock.EasyMock; -import org.joda.time.DateTime; -import org.joda.time.LocalDate; -import org.joda.time.LocalDateTime; -import org.joda.time.LocalTime; -import org.junit.Test; - -import com.mysema.commons.lang.Pair; -import com.mysema.query.sql.types.BigDecimalType; -import com.mysema.query.sql.types.BigIntegerType; -import com.mysema.query.sql.types.BlobType; -import com.mysema.query.sql.types.ByteType; -import com.mysema.query.sql.types.BytesType; -import com.mysema.query.sql.types.CalendarType; -import com.mysema.query.sql.types.CharacterType; -import com.mysema.query.sql.types.ClobType; -import com.mysema.query.sql.types.CurrencyType; -import com.mysema.query.sql.types.DateTimeType; -import com.mysema.query.sql.types.DateType; -import com.mysema.query.sql.types.DoubleType; -import com.mysema.query.sql.types.EnumByNameType; -import com.mysema.query.sql.types.EnumByOrdinalType; -import com.mysema.query.sql.types.FloatType; -import com.mysema.query.sql.types.IntegerType; -import com.mysema.query.sql.types.LocalDateTimeType; -import com.mysema.query.sql.types.LocalDateType; -import com.mysema.query.sql.types.LocalTimeType; -import com.mysema.query.sql.types.LongType; -import com.mysema.query.sql.types.NumericBooleanType; -import com.mysema.query.sql.types.ObjectType; -import com.mysema.query.sql.types.ShortType; -import com.mysema.query.sql.types.StringType; -import com.mysema.query.sql.types.TimeType; -import com.mysema.query.sql.types.TimestampType; -import com.mysema.query.sql.types.TrueFalseType; -import com.mysema.query.sql.types.Type; -import com.mysema.query.sql.types.URLType; -import com.mysema.query.sql.types.UtilDateType; -import com.mysema.query.sql.types.YesNoType; - -public class TypeTest implements InvocationHandler{ - - public enum Gender { - MALE, FEMALE - } - - private Object value; - - @Override - public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { - if (method.getName().startsWith("get")) { - return value; - } else { - value = args[1]; - return null; - } - } - - private final ResultSet resultSet = (ResultSet) Proxy.newProxyInstance(getClass().getClassLoader(), new Class[]{ResultSet.class}, this); - - private final PreparedStatement statement = (PreparedStatement) Proxy.newProxyInstance(getClass().getClassLoader(), new Class[]{PreparedStatement.class}, this); - - @SuppressWarnings("unchecked") - @Test - public void test() throws MalformedURLException, SQLException{ - List> valueAndType = new ArrayList>(); - valueAndType.add(Pair.of(new BigDecimal("1"), new BigDecimalType())); - valueAndType.add(Pair.of(new BigInteger("2"), new BigIntegerType())); - //valueAndType.add(Pair.of(Boolean.TRUE, new BooleanType())); - valueAndType.add(Pair.of(Byte.valueOf((byte)1), new ByteType())); - valueAndType.add(Pair.of(new byte[0], new BytesType())); - valueAndType.add(Pair.of(Calendar.getInstance(), new CalendarType())); - valueAndType.add(Pair.of(new Character('c'), new CharacterType())); - valueAndType.add(Pair.of(Currency.getInstance("EUR"), new CurrencyType())); - valueAndType.add(Pair.of(new java.sql.Date(0),new DateType())); - valueAndType.add(Pair.of(Double.valueOf(1), new DoubleType())); - valueAndType.add(Pair.of(Float.valueOf(1), new FloatType())); - valueAndType.add(Pair.of(Integer.valueOf(1), new IntegerType())); - valueAndType.add(Pair.of(true, new NumericBooleanType())); - valueAndType.add(Pair.of(Long.valueOf(1), new LongType())); - valueAndType.add(Pair.of(new Object(), new ObjectType())); - valueAndType.add(Pair.of(Short.valueOf((short)1), new ShortType())); - valueAndType.add(Pair.of("", new StringType())); - valueAndType.add(Pair.of(true, new TrueFalseType())); - valueAndType.add(Pair.of(true, new YesNoType())); - valueAndType.add(Pair.of(new Timestamp(0), new TimestampType())); - valueAndType.add(Pair.of(new Time(0), new TimeType())); - valueAndType.add(Pair.of(new URL("http://www.mysema.com"), new URLType())); - valueAndType.add(Pair.of(new java.util.Date(),new UtilDateType())); - - valueAndType.add(Pair.of(new DateTime(), new DateTimeType())); - valueAndType.add(Pair.of(new LocalDateTime(), new LocalDateTimeType())); - valueAndType.add(Pair.of(new LocalDate(), new LocalDateType())); - valueAndType.add(Pair.of(new LocalTime(), new LocalTimeType())); - - valueAndType.add(Pair.of(Gender.MALE, new EnumByNameType(Gender.class))); - valueAndType.add(Pair.of(Gender.MALE, new EnumByOrdinalType(Gender.class))); - - valueAndType.add(Pair.of(EasyMock.createNiceMock(Blob.class), new BlobType())); - valueAndType.add(Pair.of(EasyMock.createNiceMock(Clob.class), new ClobType())); - - for (Pair pair : valueAndType) { - value = null; - Type type = (Type) pair.getSecond(); - assertNull(type.getValue(resultSet, 0)); - type.setValue(statement, 0, pair.getFirst()); - assertEquals(type.toString(), pair.getFirst(), type.getValue(resultSet, 0)); - } - } - - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/suites/AbstractSuite.java b/querydsl-sql/src/test/java/com/mysema/query/suites/AbstractSuite.java deleted file mode 100644 index 22a217fa86..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/suites/AbstractSuite.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.mysema.query.suites; - -import java.sql.SQLException; - -import org.junit.AfterClass; -import org.junit.runner.RunWith; - -import com.mysema.query.Connections; -import com.mysema.testutil.CustomSuite; - -@RunWith(CustomSuite.class) -public abstract class AbstractSuite { - - @AfterClass - public static void tearDown() throws SQLException { - Connections.close(); - } - -} \ No newline at end of file diff --git a/querydsl-sql/src/test/java/com/mysema/query/suites/CUBRIDSuiteTest.java b/querydsl-sql/src/test/java/com/mysema/query/suites/CUBRIDSuiteTest.java deleted file mode 100644 index 8a7ef58277..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/suites/CUBRIDSuiteTest.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.mysema.query.suites; - -import org.junit.BeforeClass; -import org.junit.experimental.categories.Category; - -import com.mysema.query.BeanPopulationBase; -import com.mysema.query.Connections; -import com.mysema.query.DeleteBase; -import com.mysema.query.InsertBase; -import com.mysema.query.LikeEscapeBase; -import com.mysema.query.MergeBase; -import com.mysema.query.SelectBase; -import com.mysema.query.SelectUseLiteralsBase; -import com.mysema.query.SubqueriesBase; -import com.mysema.query.TypesBase; -import com.mysema.query.UnionBase; -import com.mysema.query.UpdateBase; -import com.mysema.query.sql.CUBRIDTemplates; -import com.mysema.testutil.ExternalDB; - -@Category(ExternalDB.class) -public class CUBRIDSuiteTest extends AbstractSuite { - - public static class BeanPopulation extends BeanPopulationBase {} - public static class Delete extends DeleteBase {} - public static class Insert extends InsertBase {} - public static class LikeEscape extends LikeEscapeBase {} - public static class Merge extends MergeBase {} - public static class Select extends SelectBase {} - public static class SelectUseLiterals extends SelectUseLiteralsBase {} - public static class Subqueries extends SubqueriesBase {} - public static class Types extends TypesBase {} - public static class Union extends UnionBase {} - public static class Update extends UpdateBase {} - - @BeforeClass - public static void setUp() throws Exception { - Connections.initCubrid(); - Connections.setTemplates(CUBRIDTemplates.builder().newLineToSingleSpace().build()); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/suites/DerbySuiteTest.java b/querydsl-sql/src/test/java/com/mysema/query/suites/DerbySuiteTest.java deleted file mode 100644 index 611c8fe0f7..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/suites/DerbySuiteTest.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.mysema.query.suites; - -import org.junit.BeforeClass; - -import com.mysema.query.BeanPopulationBase; -import com.mysema.query.Connections; -import com.mysema.query.DeleteBase; -import com.mysema.query.InsertBase; -import com.mysema.query.LikeEscapeBase; -import com.mysema.query.MergeBase; -import com.mysema.query.SelectBase; -import com.mysema.query.SelectUseLiteralsBase; -import com.mysema.query.SubqueriesBase; -import com.mysema.query.TypesBase; -import com.mysema.query.UnionBase; -import com.mysema.query.UpdateBase; -import com.mysema.query.sql.DerbyTemplates; - -public class DerbySuiteTest extends AbstractSuite { - - public static class BeanPopulation extends BeanPopulationBase {} - public static class Delete extends DeleteBase {} - public static class Insert extends InsertBase {} - public static class LikeEscape extends LikeEscapeBase {} - public static class Merge extends MergeBase {} - public static class Select extends SelectBase {} - public static class SelectUseLiterals extends SelectUseLiteralsBase {} - public static class Subqueries extends SubqueriesBase {} - public static class Types extends TypesBase {} - public static class Union extends UnionBase {} - public static class Update extends UpdateBase {} - - @BeforeClass - public static void setUp() throws Exception { - Connections.initDerby(); - Connections.setTemplates(DerbyTemplates.builder().newLineToSingleSpace().build()); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/suites/H2SuiteTest.java b/querydsl-sql/src/test/java/com/mysema/query/suites/H2SuiteTest.java deleted file mode 100644 index cd50218984..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/suites/H2SuiteTest.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.mysema.query.suites; - -import com.mysema.query.*; -import com.mysema.query.SpatialBase; -import com.mysema.query.sql.spatial.GeoDBTemplates; -import org.junit.BeforeClass; - -public class H2SuiteTest extends AbstractSuite { - - public static class BeanPopulation extends BeanPopulationBase {} - public static class Delete extends DeleteBase {} - public static class Insert extends InsertBase {} - public static class LikeEscape extends LikeEscapeBase {} - public static class Merge extends MergeBase {} - public static class Select extends SelectBase {} - public static class SelectUseLiterals extends SelectUseLiteralsBase {} - public static class Spatial extends SpatialBase {} - public static class Subqueries extends SubqueriesBase {} - public static class Types extends TypesBase {} - public static class Union extends UnionBase {} - public static class Update extends UpdateBase {} - - @BeforeClass - public static void setUp() throws Exception { - Connections.initH2(); - Connections.setTemplates(GeoDBTemplates.builder().newLineToSingleSpace().build()); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/suites/H2WithQuotingTest.java b/querydsl-sql/src/test/java/com/mysema/query/suites/H2WithQuotingTest.java deleted file mode 100644 index a88f0cfbe9..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/suites/H2WithQuotingTest.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.mysema.query.suites; - -import org.junit.BeforeClass; - -import com.mysema.query.BeanPopulationBase; -import com.mysema.query.Connections; -import com.mysema.query.DeleteBase; -import com.mysema.query.InsertBase; -import com.mysema.query.LikeEscapeBase; -import com.mysema.query.MergeBase; -import com.mysema.query.SelectBase; -import com.mysema.query.SelectUseLiteralsBase; -import com.mysema.query.SubqueriesBase; -import com.mysema.query.TypesBase; -import com.mysema.query.UnionBase; -import com.mysema.query.UpdateBase; -import com.mysema.query.sql.H2Templates; - -public class H2WithQuotingTest extends AbstractSuite { - - public static class BeanPopulation extends BeanPopulationBase {} - public static class Delete extends DeleteBase {} - public static class Insert extends InsertBase {} - public static class LikeEscape extends LikeEscapeBase {} - public static class Merge extends MergeBase {} - public static class Select extends SelectBase {} - public static class SelectUseLiterals extends SelectUseLiteralsBase {} - public static class Subqueries extends SubqueriesBase {} - public static class Types extends TypesBase {} - public static class Union extends UnionBase {} - public static class Update extends UpdateBase {} - - @BeforeClass - public static void setUp() throws Exception { - Connections.initH2(); - Connections.setTemplates(H2Templates.builder().quote().newLineToSingleSpace().build()); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/suites/H2WithSchemaTest.java b/querydsl-sql/src/test/java/com/mysema/query/suites/H2WithSchemaTest.java deleted file mode 100644 index aec392bc4e..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/suites/H2WithSchemaTest.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.mysema.query.suites; - -import org.junit.BeforeClass; - -import com.mysema.query.BeanPopulationBase; -import com.mysema.query.Connections; -import com.mysema.query.DeleteBase; -import com.mysema.query.InsertBase; -import com.mysema.query.LikeEscapeBase; -import com.mysema.query.MergeBase; -import com.mysema.query.SelectBase; -import com.mysema.query.SelectUseLiteralsBase; -import com.mysema.query.SubqueriesBase; -import com.mysema.query.TypesBase; -import com.mysema.query.UnionBase; -import com.mysema.query.UpdateBase; -import com.mysema.query.sql.H2Templates; - -public class H2WithSchemaTest extends AbstractSuite { - - public static class BeanPopulation extends BeanPopulationBase {} - public static class Delete extends DeleteBase {} - public static class Insert extends InsertBase {} - public static class LikeEscape extends LikeEscapeBase {} - public static class Merge extends MergeBase {} - public static class Select extends SelectBase {} - public static class SelectUseLiterals extends SelectUseLiteralsBase {} - public static class Subqueries extends SubqueriesBase {} - public static class Types extends TypesBase {} - public static class Union extends UnionBase {} - public static class Update extends UpdateBase {} - - @BeforeClass - public static void setUp() throws Exception { - Connections.initH2(); - Connections.setTemplates(H2Templates.builder().printSchema().newLineToSingleSpace().build()); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/suites/HsqldbSuiteTest.java b/querydsl-sql/src/test/java/com/mysema/query/suites/HsqldbSuiteTest.java deleted file mode 100644 index f8294c068d..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/suites/HsqldbSuiteTest.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.mysema.query.suites; - -import org.junit.BeforeClass; - -import com.mysema.query.BeanPopulationBase; -import com.mysema.query.Connections; -import com.mysema.query.DeleteBase; -import com.mysema.query.InsertBase; -import com.mysema.query.LikeEscapeBase; -import com.mysema.query.MergeBase; -import com.mysema.query.SelectBase; -import com.mysema.query.SelectUseLiteralsBase; -import com.mysema.query.SubqueriesBase; -import com.mysema.query.TypesBase; -import com.mysema.query.UnionBase; -import com.mysema.query.UpdateBase; -import com.mysema.query.sql.HSQLDBTemplates; - -public class HsqldbSuiteTest extends AbstractSuite { - - public static class BeanPopulation extends BeanPopulationBase {} - public static class Delete extends DeleteBase {} - public static class Insert extends InsertBase {} - public static class LikeEscape extends LikeEscapeBase {} - public static class Merge extends MergeBase {} - public static class Select extends SelectBase {} - public static class SelectUseLiterals extends SelectUseLiteralsBase {} - public static class Subqueries extends SubqueriesBase {} - public static class Types extends TypesBase {} - public static class Union extends UnionBase {} - public static class Update extends UpdateBase {} - - @BeforeClass - public static void setUp() throws Exception { - Connections.initHSQL(); - Connections.setTemplates(HSQLDBTemplates.builder().newLineToSingleSpace().build()); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/suites/MSSQLSuiteTest.java b/querydsl-sql/src/test/java/com/mysema/query/suites/MSSQLSuiteTest.java deleted file mode 100644 index fbe71d637f..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/suites/MSSQLSuiteTest.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.mysema.query.suites; - -import org.junit.BeforeClass; -import org.junit.experimental.categories.Category; - -import com.mysema.query.BeanPopulationBase; -import com.mysema.query.Connections; -import com.mysema.query.DeleteBase; -import com.mysema.query.InsertBase; -import com.mysema.query.LikeEscapeBase; -import com.mysema.query.MergeBase; -import com.mysema.query.SelectBase; -import com.mysema.query.SelectUseLiteralsBase; -import com.mysema.query.SpatialBase; -import com.mysema.query.SelectWindowFunctionsBase; -import com.mysema.query.SubqueriesBase; -import com.mysema.query.TypesBase; -import com.mysema.query.UnionBase; -import com.mysema.query.UpdateBase; -import com.mysema.query.sql.spatial.SQLServer2008SpatialTemplates; -import com.mysema.testutil.ExternalDB; - -@Category(ExternalDB.class) -public class MSSQLSuiteTest extends AbstractSuite { - - public static class BeanPopulation extends BeanPopulationBase {} - public static class Delete extends DeleteBase {} - public static class Insert extends InsertBase {} - public static class LikeEscape extends LikeEscapeBase {} - public static class Merge extends MergeBase {} - public static class Select extends SelectBase {} - public static class SelectUseLiterals extends SelectUseLiteralsBase {} - public static class Spatial extends SpatialBase {} - public static class SelectWindowFunctions extends SelectWindowFunctionsBase {} - public static class Subqueries extends SubqueriesBase {} - public static class Types extends TypesBase {} - public static class Union extends UnionBase {} - public static class Update extends UpdateBase {} - - @BeforeClass - public static void setUp() throws Exception { - Connections.initSQLServer(); - Connections.setTemplates(SQLServer2008SpatialTemplates.builder().newLineToSingleSpace().build()); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/suites/MySQLSuiteTest.java b/querydsl-sql/src/test/java/com/mysema/query/suites/MySQLSuiteTest.java deleted file mode 100644 index 4a0321d99b..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/suites/MySQLSuiteTest.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.mysema.query.suites; - -import org.junit.BeforeClass; -import org.junit.experimental.categories.Category; - -import com.mysema.query.BeanPopulationBase; -import com.mysema.query.Connections; -import com.mysema.query.DeleteBase; -import com.mysema.query.InsertBase; -import com.mysema.query.LikeEscapeBase; -import com.mysema.query.MergeBase; -import com.mysema.query.SelectBase; -import com.mysema.query.SelectUseLiteralsBase; -import com.mysema.query.SpatialBase; -import com.mysema.query.SelectMySQLBase; -import com.mysema.query.SubqueriesBase; -import com.mysema.query.TypesBase; -import com.mysema.query.UnionBase; -import com.mysema.query.UpdateBase; -import com.mysema.query.sql.spatial.MySQLSpatialTemplates; -import com.mysema.testutil.ExternalDB; - -@Category(ExternalDB.class) -public class MySQLSuiteTest extends AbstractSuite { - - public static class BeanPopulation extends BeanPopulationBase {} - public static class Delete extends DeleteBase {} - public static class Insert extends InsertBase {} - public static class LikeEscape extends LikeEscapeBase {} - public static class Merge extends MergeBase {} - public static class Select extends SelectBase {} - public static class SelectMySQL extends SelectMySQLBase {} - public static class Spatial extends SpatialBase {} - public static class SelectUseLiterals extends SelectUseLiteralsBase {} - public static class Subqueries extends SubqueriesBase {} - public static class Types extends TypesBase {} - public static class Union extends UnionBase {} - public static class Update extends UpdateBase {} - - @BeforeClass - public static void setUp() throws Exception { - Connections.initMySQL(); - Connections.setTemplates(MySQLSpatialTemplates.builder().newLineToSingleSpace().build()); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/suites/MySQLWithQuotingTest.java b/querydsl-sql/src/test/java/com/mysema/query/suites/MySQLWithQuotingTest.java deleted file mode 100644 index ae2125e84d..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/suites/MySQLWithQuotingTest.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.mysema.query.suites; - -import org.junit.BeforeClass; -import org.junit.experimental.categories.Category; - -import com.mysema.query.BeanPopulationBase; -import com.mysema.query.Connections; -import com.mysema.query.DeleteBase; -import com.mysema.query.InsertBase; -import com.mysema.query.LikeEscapeBase; -import com.mysema.query.MergeBase; -import com.mysema.query.SelectBase; -import com.mysema.query.SelectUseLiteralsBase; -import com.mysema.query.SubqueriesBase; -import com.mysema.query.TypesBase; -import com.mysema.query.UnionBase; -import com.mysema.query.UpdateBase; -import com.mysema.query.sql.spatial.MySQLSpatialTemplates; -import com.mysema.testutil.ExternalDB; - -@Category(ExternalDB.class) -public class MySQLWithQuotingTest extends AbstractSuite { - - public static class BeanPopulation extends BeanPopulationBase {} - public static class Delete extends DeleteBase {} - public static class Insert extends InsertBase {} - public static class LikeEscape extends LikeEscapeBase {} - public static class Merge extends MergeBase {} - public static class Select extends SelectBase {} - public static class SelectUseLiterals extends SelectUseLiteralsBase {} - public static class Subqueries extends SubqueriesBase {} - public static class Types extends TypesBase {} - public static class Union extends UnionBase {} - public static class Update extends UpdateBase {} - - @BeforeClass - public static void setUp() throws Exception { - Connections.initMySQL(); - Connections.setTemplates(MySQLSpatialTemplates.builder().quote().newLineToSingleSpace().build()); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/suites/OracleSuiteTest.java b/querydsl-sql/src/test/java/com/mysema/query/suites/OracleSuiteTest.java deleted file mode 100644 index 18597e9322..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/suites/OracleSuiteTest.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.mysema.query.suites; - -import org.junit.BeforeClass; -import org.junit.experimental.categories.Category; - -import com.mysema.query.BeanPopulationBase; -import com.mysema.query.Connections; -import com.mysema.query.DeleteBase; -import com.mysema.query.InsertBase; -import com.mysema.query.LikeEscapeBase; -import com.mysema.query.MergeBase; -import com.mysema.query.SelectBase; -import com.mysema.query.SelectOracleBase; -import com.mysema.query.SelectUseLiteralsBase; -import com.mysema.query.SelectWindowFunctionsBase; -import com.mysema.query.SubqueriesBase; -import com.mysema.query.TypesBase; -import com.mysema.query.UnionBase; -import com.mysema.query.UpdateBase; -import com.mysema.query.sql.spatial.OracleSpatialTemplates; -import com.mysema.testutil.ExternalDB; - -@Category(ExternalDB.class) -public class OracleSuiteTest extends AbstractSuite { - - public static class BeanPopulation extends BeanPopulationBase {} - public static class Delete extends DeleteBase {} - public static class Insert extends InsertBase {} - public static class LikeEscape extends LikeEscapeBase {} - public static class Merge extends MergeBase {} - public static class Select extends SelectBase {} - public static class SelectOracle extends SelectOracleBase {} - public static class SelectUseLiterals extends SelectUseLiteralsBase {} - public static class SelectWindowFunctions extends SelectWindowFunctionsBase {} - public static class Subqueries extends SubqueriesBase {} - public static class Types extends TypesBase {} - public static class Union extends UnionBase {} - public static class Update extends UpdateBase {} - - @BeforeClass - public static void setUp() throws Exception { - Connections.initOracle(); - Connections.setTemplates(OracleSpatialTemplates.builder().newLineToSingleSpace().build()); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/suites/OracleWithQuotingTest.java b/querydsl-sql/src/test/java/com/mysema/query/suites/OracleWithQuotingTest.java deleted file mode 100644 index 9d623c9d68..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/suites/OracleWithQuotingTest.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.mysema.query.suites; - -import org.junit.BeforeClass; -import org.junit.experimental.categories.Category; - -import com.mysema.query.BeanPopulationBase; -import com.mysema.query.Connections; -import com.mysema.query.DeleteBase; -import com.mysema.query.InsertBase; -import com.mysema.query.LikeEscapeBase; -import com.mysema.query.MergeBase; -import com.mysema.query.SelectBase; -import com.mysema.query.SelectUseLiteralsBase; -import com.mysema.query.SubqueriesBase; -import com.mysema.query.TypesBase; -import com.mysema.query.UnionBase; -import com.mysema.query.UpdateBase; -import com.mysema.query.sql.OracleTemplates; -import com.mysema.testutil.ExternalDB; - -@Category(ExternalDB.class) -public class OracleWithQuotingTest extends AbstractSuite { - - public static class BeanPopulation extends BeanPopulationBase {} - public static class Delete extends DeleteBase {} - public static class Insert extends InsertBase {} - public static class LikeEscape extends LikeEscapeBase {} - public static class Merge extends MergeBase {} - public static class Select extends SelectBase {} - public static class SelectUseLiterals extends SelectUseLiteralsBase {} - public static class Subqueries extends SubqueriesBase {} - public static class Types extends TypesBase {} - public static class Union extends UnionBase {} - public static class Update extends UpdateBase {} - - @BeforeClass - public static void setUp() throws Exception { - Connections.initOracle(); - Connections.setTemplates(OracleTemplates.builder().quote().newLineToSingleSpace().build()); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/suites/PostgreSQLSuiteTest.java b/querydsl-sql/src/test/java/com/mysema/query/suites/PostgreSQLSuiteTest.java deleted file mode 100644 index beacc2b8b9..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/suites/PostgreSQLSuiteTest.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.mysema.query.suites; - -import org.junit.BeforeClass; -import org.junit.experimental.categories.Category; - -import com.mysema.query.BeanPopulationBase; -import com.mysema.query.Connections; -import com.mysema.query.DeleteBase; -import com.mysema.query.InsertBase; -import com.mysema.query.LikeEscapeBase; -import com.mysema.query.MergeBase; -import com.mysema.query.SelectBase; -import com.mysema.query.SelectUseLiteralsBase; -import com.mysema.query.SpatialBase; -import com.mysema.query.SelectWindowFunctionsBase; -import com.mysema.query.SubqueriesBase; -import com.mysema.query.TypesBase; -import com.mysema.query.UnionBase; -import com.mysema.query.UpdateBase; -import com.mysema.query.sql.spatial.PostGISTemplates; -import com.mysema.testutil.ExternalDB; - -@Category(ExternalDB.class) -public class PostgreSQLSuiteTest extends AbstractSuite { - - public static class BeanPopulation extends BeanPopulationBase {} - public static class Delete extends DeleteBase {} - public static class Insert extends InsertBase {} - public static class LikeEscape extends LikeEscapeBase {} - public static class Merge extends MergeBase {} - public static class Select extends SelectBase {} - public static class SelectUseLiterals extends SelectUseLiteralsBase {} - public static class Spatial extends SpatialBase {} - public static class SelectWindowFunctions extends SelectWindowFunctionsBase {} - public static class Subqueries extends SubqueriesBase {} - public static class Types extends TypesBase {} - public static class Union extends UnionBase {} - public static class Update extends UpdateBase {} - - @BeforeClass - public static void setUp() throws Exception { - Connections.initPostgres(); - Connections.setTemplates(PostGISTemplates.builder().quote().newLineToSingleSpace().build()); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/suites/SQLiteSuiteTest.java b/querydsl-sql/src/test/java/com/mysema/query/suites/SQLiteSuiteTest.java deleted file mode 100644 index d479f9c144..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/suites/SQLiteSuiteTest.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.mysema.query.suites; - -import org.junit.BeforeClass; - -import com.mysema.query.BeanPopulationBase; -import com.mysema.query.Connections; -import com.mysema.query.DeleteBase; -import com.mysema.query.InsertBase; -import com.mysema.query.LikeEscapeBase; -import com.mysema.query.MergeBase; -import com.mysema.query.SelectBase; -import com.mysema.query.SelectUseLiteralsBase; -import com.mysema.query.SubqueriesBase; -import com.mysema.query.TypesBase; -import com.mysema.query.UnionBase; -import com.mysema.query.UpdateBase; -import com.mysema.query.sql.SQLiteTemplates; - -public class SQLiteSuiteTest extends AbstractSuite { - - public static class BeanPopulation extends BeanPopulationBase {} - public static class Delete extends DeleteBase {} - public static class Insert extends InsertBase {} - public static class LikeEscape extends LikeEscapeBase {} - public static class Merge extends MergeBase {} - public static class Select extends SelectBase {} - public static class SelectUseLiterals extends SelectUseLiteralsBase {} - public static class Subqueries extends SubqueriesBase {} - public static class Types extends TypesBase {} - public static class Union extends UnionBase {} - public static class Update extends UpdateBase {} - - @BeforeClass - public static void setUp() throws Exception { - Connections.initSQLite(); - Connections.setTemplates(SQLiteTemplates.builder().newLineToSingleSpace().build()); - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/suites/SpatialTest.java b/querydsl-sql/src/test/java/com/mysema/query/suites/SpatialTest.java deleted file mode 100644 index 9816f84f16..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/suites/SpatialTest.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.mysema.query.suites; - -import java.sql.Connection; -import java.sql.DatabaseMetaData; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.mysema.query.Connections; - -public class SpatialTest { - - @Before - public void setUp() throws ClassNotFoundException, SQLException { - Connections.initH2(); -// Connections.initMySQL(); -// Connections.initPostgres(); -// Connections.initTeradata(); - } - - @After - public void tearDown() throws SQLException { - Connections.close(); - } - - @Test - public void test() throws SQLException { - Statement stmt = Connections.getStatement(); - ResultSet rs = stmt.executeQuery("select \"GEOMETRY\" from \"SHAPES\""); - try { - while (rs.next()) { - System.err.println(rs.getObject(1).getClass().getName()); - System.err.println(rs.getString(1)); -// Clob clob = rs.getClob(1); -// System.err.println(clob.getSubString(1, (int) clob.length())); - } - } finally { - rs.close(); - } - } - - @Test - public void Metadata() throws SQLException { - Connection conn = Connections.getConnection(); - DatabaseMetaData md = conn.getMetaData(); - ResultSet rs = md.getColumns(null, null, "SHAPES", "GEOMETRY"); - try { - rs.next(); - int type = rs.getInt("DATA_TYPE"); - String typeName = rs.getString("TYPE_NAME"); - System.err.println(type + " " + typeName); - } finally { - rs.close(); - } - } - -} diff --git a/querydsl-sql/src/test/java/com/mysema/query/suites/TeradataSuiteTest.java b/querydsl-sql/src/test/java/com/mysema/query/suites/TeradataSuiteTest.java deleted file mode 100644 index cd6cc46036..0000000000 --- a/querydsl-sql/src/test/java/com/mysema/query/suites/TeradataSuiteTest.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.mysema.query.suites; - -import org.junit.BeforeClass; -import org.junit.experimental.categories.Category; - -import com.mysema.query.BeanPopulationBase; -import com.mysema.query.Connections; -import com.mysema.query.DeleteBase; -import com.mysema.query.InsertBase; -import com.mysema.query.LikeEscapeBase; -import com.mysema.query.MergeBase; -import com.mysema.query.SelectBase; -import com.mysema.query.SelectTeradataBase; -import com.mysema.query.SpatialBase; -import com.mysema.query.SelectUseLiteralsBase; -import com.mysema.query.SelectWindowFunctionsBase; -import com.mysema.query.SubqueriesBase; -import com.mysema.query.TypesBase; -import com.mysema.query.UnionBase; -import com.mysema.query.UpdateBase; -import com.mysema.query.sql.spatial.TeradataSpatialTemplates; -import com.mysema.testutil.ExternalDB; - -@Category(ExternalDB.class) -public class TeradataSuiteTest extends AbstractSuite { - - public static class BeanPopulation extends BeanPopulationBase {} - public static class Delete extends DeleteBase {} - public static class Insert extends InsertBase {} - public static class LikeEscape extends LikeEscapeBase {} - public static class Merge extends MergeBase {} - public static class Select extends SelectBase {} - public static class SelectTeradata extends SelectTeradataBase {} - public static class Spatial extends SpatialBase {} - public static class SelectUseLiterals extends SelectUseLiteralsBase {} - public static class SelectWindowFunctions extends SelectWindowFunctionsBase {} - public static class Subqueries extends SubqueriesBase {} - public static class Types extends TypesBase {} - public static class Union extends UnionBase {} - public static class Update extends UpdateBase {} - - @BeforeClass - public static void setUp() throws Exception { - Connections.initTeradata(); - Connections.setTemplates(TeradataSpatialTemplates.builder().newLineToSingleSpace().build()); - } - -} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/AbstractBaseTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/AbstractBaseTest.java new file mode 100644 index 0000000000..e084b06509 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/AbstractBaseTest.java @@ -0,0 +1,179 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import static org.junit.Assert.assertEquals; + +import java.sql.Connection; +import java.util.List; +import java.util.logging.Logger; + +import org.jetbrains.annotations.Nullable; + +import org.junit.ClassRule; +import org.junit.Rule; +import org.junit.rules.MethodRule; +import org.junit.rules.TestRule; + +import com.querydsl.core.DefaultQueryMetadata; +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.Target; +import com.querydsl.core.dml.DMLClause; +import com.querydsl.sql.dml.SQLDeleteClause; +import com.querydsl.sql.dml.SQLInsertClause; +import com.querydsl.sql.dml.SQLMergeClause; +import com.querydsl.sql.dml.SQLUpdateClause; +import com.querydsl.sql.mysql.MySQLReplaceClause; +import com.querydsl.sql.teradata.TeradataQuery; +import com.querydsl.sql.types.XMLAsStringType; + +public abstract class AbstractBaseTest { + + protected static final Logger logger = Logger.getLogger(AbstractBaseTest.class.getName()); + + protected final class TestQuery extends SQLQuery { + + private TestQuery(Connection conn, Configuration configuration) { + super(conn, configuration); + } + + private TestQuery(Connection conn, Configuration configuration, QueryMetadata metadata) { + super(conn, configuration, metadata); + } + + @Override + protected SQLSerializer serialize(boolean countRow) { + SQLSerializer serializer = super.serialize(countRow); + String rv = serializer.toString(); + if (expectedQuery != null) { + assertEquals(expectedQuery, rv.replace('\n', ' ')); + expectedQuery = null; + } + logger.fine(rv); + return serializer; + } + + public TestQuery clone(Connection conn) { + TestQuery q = new TestQuery(conn, getConfiguration(), getMetadata().clone()); + q.union = union; + q.unionAll = unionAll; + q.firstUnionSubQuery = firstUnionSubQuery; + return q; + } + + } + + protected Connection connection = Connections.getConnection(); + + protected Target target = Connections.getTarget(); + + protected Configuration configuration = Connections.getConfiguration(); + + @Nullable + protected String expectedQuery; + + public AbstractBaseTest() { + // TODO enable registration of (jdbc type, java type) -> usertype mappings + if (target == Target.POSTGRESQL || target == Target.ORACLE) { + configuration.register("XML_TEST", "COL", new XMLAsStringType()); + } + } + + @Rule + public MethodRule skipForQuotedRule = new SkipForQuotedRule(configuration); + + @Rule + @ClassRule + public static TestRule targetRule = new TargetRule(); + + protected void add(List list, T arg, Target... exclusions) { + if (exclusions.length > 0) { + for (Target t : exclusions) { + if (t.equals(target)) { + return; + } + } + } + list.add(arg); + } + + protected SQLUpdateClause update(RelationalPath e) { + SQLUpdateClause sqlUpdateClause = new SQLUpdateClause(connection, configuration, e); + sqlUpdateClause.addListener(new TestLoggingListener()); + return sqlUpdateClause; + } + + protected SQLInsertClause insert(RelationalPath e) { + SQLInsertClause sqlInsertClause = new SQLInsertClause(connection, configuration, e); + sqlInsertClause.addListener(new TestLoggingListener()); + return sqlInsertClause; + } + + protected SQLInsertClause insert(RelationalPath e, SQLQuery sq) { + SQLInsertClause sqlInsertClause = new SQLInsertClause(connection, configuration, e, sq); + sqlInsertClause.addListener(new TestLoggingListener()); + return sqlInsertClause; + } + + protected SQLDeleteClause delete(RelationalPath e) { + SQLDeleteClause sqlDeleteClause = new SQLDeleteClause(connection, configuration, e); + sqlDeleteClause.addListener(new TestLoggingListener()); + return sqlDeleteClause; + } + + protected SQLMergeClause merge(RelationalPath e) { + SQLMergeClause sqlMergeClause = new SQLMergeClause(connection, configuration, e); + sqlMergeClause.addListener(new TestLoggingListener()); + return sqlMergeClause; + } + + protected ExtendedSQLQuery extQuery() { + ExtendedSQLQuery extendedSQLQuery = new ExtendedSQLQuery(connection, configuration); + extendedSQLQuery.addListener(new TestLoggingListener()); + return extendedSQLQuery; + } + + protected SQLInsertClause mysqlReplace(RelationalPath path) { + MySQLReplaceClause mySQLReplaceClause = new MySQLReplaceClause(connection, configuration, path); + mySQLReplaceClause.addListener(new TestLoggingListener()); + return mySQLReplaceClause; + } + + protected SQLQuery query() { + SQLQuery testQuery = new TestQuery(connection, configuration); + testQuery.addListener(new TestLoggingListener()); + return testQuery; + } + + protected TeradataQuery teradataQuery() { + TeradataQuery teradataQuery = new TeradataQuery(connection, configuration); + teradataQuery.addListener(new TestLoggingListener()); + return teradataQuery; + } + + protected TestQuery testQuery() { + TestQuery testQuery = new TestQuery(connection, configuration, new DefaultQueryMetadata()); + testQuery.addListener(new TestLoggingListener()); + return testQuery; + } + + protected long execute(DMLClause... clauses) { + long execute = 0; + for (DMLClause clause : clauses) { + execute += clause.execute(); + } + return execute; + } + +} diff --git a/querydsl-sql/src/test/java/com/mysema/query/AbstractJDBCTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/AbstractJDBCTest.java similarity index 87% rename from querydsl-sql/src/test/java/com/mysema/query/AbstractJDBCTest.java rename to querydsl-sql/src/test/java/com/querydsl/sql/AbstractJDBCTest.java index 7f8c9173d8..6258b8267e 100644 --- a/querydsl-sql/src/test/java/com/mysema/query/AbstractJDBCTest.java +++ b/querydsl-sql/src/test/java/com/querydsl/sql/AbstractJDBCTest.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query; +package com.querydsl.sql; import java.sql.Connection; import java.sql.DriverManager; @@ -36,12 +36,12 @@ public void setUp() throws ClassNotFoundException, SQLException { } @After - public void tearDown() throws SQLException{ - try{ + public void tearDown() throws SQLException { + try { statement.close(); - }finally{ + } finally { connection.close(); } } - + } diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/AbstractSQLTemplatesTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/AbstractSQLTemplatesTest.java new file mode 100644 index 0000000000..34404c064f --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/AbstractSQLTemplatesTest.java @@ -0,0 +1,188 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import static com.querydsl.sql.SQLExpressions.select; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.Collection; + +import org.junit.Before; +import org.junit.Test; + +import com.querydsl.core.types.*; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberExpression; +import com.querydsl.sql.domain.QSurvey; + +public abstract class AbstractSQLTemplatesTest { + + protected static final QSurvey survey1 = new QSurvey("survey1"); + + protected static final QSurvey survey2 = new QSurvey("survey2"); + + private SQLTemplates templates; + + protected SQLQuery query; + + protected abstract SQLTemplates createTemplates(); + + @Before + public void setUp() { + templates = createTemplates(); + templates.newLineToSingleSpace(); + query = new SQLQuery(new Configuration(templates)); + } + + @Test + public void noFrom() { + query.getMetadata().setProjection(Expressions.ONE); + if (templates.getDummyTable() == null) { + assertEquals("select 1", query.toString()); + } else { + assertEquals("select 1 from " + templates.getDummyTable(), query.toString()); + } + } + + @SuppressWarnings("unchecked") + @Test + public void union() { + NumberExpression one = Expressions.ONE; + NumberExpression two = Expressions.TWO; + NumberExpression three = Expressions.THREE; + Path col1 = Expressions.path(Integer.class,"col1"); + Union union = query.union( + select(one.as(col1)), + select(two), + select(three)); + + if (templates.getDummyTable() == null) { + if (templates.isUnionsWrapped()) { + assertEquals( + "(select 1 as col1)\n" + + "union\n" + + "(select 2)\n" + + "union\n" + + "(select 3)", union.toString()); + } else { + assertEquals( + "select 1 as col1)\n" + + "union\n" + + "select 2\n" + + "union\n" + + "select 3", union.toString()); + } + } else { + String dummyTable = templates.getDummyTable(); + if (templates.isUnionsWrapped()) { + assertEquals( + "(select 1 as col1 from " + dummyTable + ")\n" + + "union\n" + + "(select 2 from " + dummyTable + ")\n" + + "union\n" + + "(select 3 from " + dummyTable + ")", union.toString()); + } else { + assertEquals( + "select 1 as col1 from " + dummyTable + "\n" + + "union\n" + + "select 2 from " + dummyTable + "\n" + + "union\n" + + "select 3 from " + dummyTable, union.toString()); + } + } + } + + @Test + public void innerJoin() { + query.from(survey1).innerJoin(survey2); + assertEquals("from SURVEY survey1 inner join SURVEY survey2", query.toString()); + } + + protected int getPrecedence(Operator... ops) { + int precedence = templates.getPrecedence(ops[0]); + for (int i = 1; i < ops.length; i++) { + assertEquals(ops[i].name(), precedence, templates.getPrecedence(ops[i])); + } + return precedence; + } + + @Test + public void generic_precedence() { + TemplatesTestUtils.testPrecedence(templates); + } + + @Test + public void arithmetic() { + NumberExpression one = Expressions.numberPath(Integer.class, "one"); + NumberExpression two = Expressions.numberPath(Integer.class, "two"); + + // add + assertSerialized(one.add(two), "one + two"); + assertSerialized(one.add(two).multiply(1), "(one + two) * ?"); + assertSerialized(one.add(two).divide(1), "(one + two) / ?"); + assertSerialized(one.add(two).add(1), "one + two + ?"); + + assertSerialized(one.add(two.multiply(1)), "one + two * ?"); + assertSerialized(one.add(two.divide(1)), "one + two / ?"); + assertSerialized(one.add(two.add(1)), "one + (two + ?)"); // XXX could be better + + // sub + assertSerialized(one.subtract(two), "one - two"); + assertSerialized(one.subtract(two).multiply(1), "(one - two) * ?"); + assertSerialized(one.subtract(two).divide(1), "(one - two) / ?"); + assertSerialized(one.subtract(two).add(1), "one - two + ?"); + + assertSerialized(one.subtract(two.multiply(1)), "one - two * ?"); + assertSerialized(one.subtract(two.divide(1)), "one - two / ?"); + assertSerialized(one.subtract(two.add(1)), "one - (two + ?)"); + + // mult + assertSerialized(one.multiply(two), "one * two"); + assertSerialized(one.multiply(two).multiply(1), "one * two * ?"); + assertSerialized(one.multiply(two).divide(1), "one * two / ?"); + assertSerialized(one.multiply(two).add(1), "one * two + ?"); + + assertSerialized(one.multiply(two.multiply(1)), "one * (two * ?)"); // XXX could better + assertSerialized(one.multiply(two.divide(1)), "one * (two / ?)"); + assertSerialized(one.multiply(two.add(1)), "one * (two + ?)"); + } + + @Test + public void booleanTemplate() { + assertSerialized(Expressions.booleanPath("b").eq(Expressions.TRUE), "b = 1"); + assertSerialized(Expressions.booleanPath("b").eq(Expressions.FALSE), "b = 0"); + query.setUseLiterals(true); + query.where(Expressions.booleanPath("b").eq(true)); + assertTrue(query.toString(), query.toString().endsWith("where b = 1")); + } + + protected void assertSerialized(Expression expr, String serialized) { + SQLSerializer serializer = new SQLSerializer(new Configuration(templates)); + serializer.handle(expr); + assertEquals(serialized, serializer.toString()); + } + + @Test + public void in() { + CollectionExpression, Integer> ints = Expressions.collectionOperation(Integer.class, Ops.LIST, + Expressions.collectionOperation(Integer.class, Ops.LIST, Expressions.ONE, Expressions.TWO), + Expressions.THREE); + query.from(survey1).where(survey1.id.in(ints)); + query.getMetadata().setProjection(survey1.name); + assertEquals("select survey1.NAME from SURVEY survey1 where survey1.ID in (1, 2, 3)", query.toString()); + } + + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/ArrayTypesTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/ArrayTypesTest.java new file mode 100644 index 0000000000..45fc4c0f46 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/ArrayTypesTest.java @@ -0,0 +1,29 @@ +package com.querydsl.sql; + +import static org.junit.Assert.assertEquals; + +import java.sql.Types; + +import org.junit.Before; +import org.junit.Test; + +public class ArrayTypesTest { + + private Configuration configuration; + + @Before + public void setUp() { + configuration = Configuration.DEFAULT; + } + + @Test + public void test() { + assertEquals(Integer[].class, getJavaType("_integer")); + assertEquals(Integer[].class, getJavaType("integer[]")); + assertEquals(Integer[].class, getJavaType("INTEGER ARRAY")); + } + + private Class getJavaType(String typeName) { + return configuration.getJavaType(Types.ARRAY, typeName, 0, 0, "", ""); + } +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/BeanPopulationBase.java b/querydsl-sql/src/test/java/com/querydsl/sql/BeanPopulationBase.java new file mode 100644 index 0000000000..faaaebb8fa --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/BeanPopulationBase.java @@ -0,0 +1,103 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import static com.querydsl.core.Target.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import org.junit.After; +import org.junit.Test; + +import com.querydsl.core.testutil.ExcludeIn; +import com.querydsl.sql.dml.BeanMapper; +import com.querydsl.sql.domain.Employee; +import com.querydsl.sql.domain.QEmployee; + +@ExcludeIn({CUBRID, DB2, DERBY, ORACLE, SQLSERVER, POSTGRESQL, SQLITE, TERADATA}) +public class BeanPopulationBase extends AbstractBaseTest { + + private final QEmployee e = new QEmployee("e"); + + @After + public void tearDown() { + delete(e).where(e.firstname.eq("John")).execute(); + } + + @Test + public void custom_projection() { + // Insert + Employee employee = new Employee(); + employee.setFirstname("John"); + Integer id = insert(e).populate(employee).executeWithKey(e.id); + employee.setId(id); + + // Update + employee.setLastname("S"); + assertEquals(1L, update(e).populate(employee).where(e.id.eq(employee.getId())).execute()); + + // Query + Employee smith = extQuery().from(e).where(e.lastname.eq("S")) + .limit(1) + .uniqueResult(Employee.class, e.lastname, e.firstname); + assertEquals("John", smith.getFirstname()); + assertEquals("S", smith.getLastname()); + + // Query with alias + smith = extQuery().from(e).where(e.lastname.eq("S")) + .limit(1) + .uniqueResult(Employee.class, e.lastname.as("lastname"), e.firstname.as("firstname")); + assertEquals("John", smith.getFirstname()); + assertEquals("S", smith.getLastname()); + + // Query into custom type + OtherEmployee other = extQuery().from(e).where(e.lastname.eq("S")) + .limit(1) + .uniqueResult(OtherEmployee.class, e.lastname, e.firstname); + assertEquals("John", other.getFirstname()); + assertEquals("S", other.getLastname()); + + // Delete (no changes needed) + assertEquals(1L, delete(e).where(e.id.eq(employee.getId())).execute()); + } + + @Test + public void insert_update_query_and_delete() { + // Insert + Employee employee = new Employee(); + employee.setFirstname("John"); + Integer id = insert(e).populate(employee).executeWithKey(e.id); + assertNotNull(id); + employee.setId(id); + + // Update + employee.setLastname("S"); + assertEquals(1L, update(e).populate(employee).where(e.id.eq(employee.getId())).execute()); + + // Query + Employee smith = query().from(e).where(e.lastname.eq("S")).limit(1).select(e).fetchFirst(); + assertEquals("John", smith.getFirstname()); + + // Delete (no changes needed) + assertEquals(1L, delete(e).where(e.id.eq(employee.getId())).execute()); + } + + @Test + public void populate_with_beanMapper() { + Employee employee = new Employee(); + employee.setFirstname("John"); + insert(e).populate(employee, new BeanMapper()).execute(); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/CUBRIDTemplatesTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/CUBRIDTemplatesTest.java new file mode 100644 index 0000000000..969997d0ad --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/CUBRIDTemplatesTest.java @@ -0,0 +1,26 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import org.junit.Ignore; + +@Ignore +public class CUBRIDTemplatesTest extends AbstractSQLTemplatesTest { + + @Override + protected SQLTemplates createTemplates() { + return new CUBRIDTemplates(); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/CoalesceTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/CoalesceTest.java new file mode 100644 index 0000000000..c46f0bc237 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/CoalesceTest.java @@ -0,0 +1,21 @@ +package com.querydsl.sql; + +import org.junit.Test; + +import com.querydsl.core.types.dsl.Coalesce; + +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + +public class CoalesceTest { + + @Test + public void coalesce_supports_subquery() { + Coalesce coalesce = + new Coalesce(SQLExpressions.select(QCompanies.companies.name).from(QCompanies.companies), QCompanies.companies.name); + assertThat(SQLExpressions.select(coalesce).toString(), + is(equalTo("select coalesce((select COMPANIES.NAME\nfrom COMPANIES COMPANIES), COMPANIES.NAME)\nfrom dual"))); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/ColumnMetadataTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/ColumnMetadataTest.java new file mode 100644 index 0000000000..04c45c3761 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/ColumnMetadataTest.java @@ -0,0 +1,45 @@ +package com.querydsl.sql; + +import static org.junit.Assert.*; + +import java.sql.Types; + +import org.junit.Test; + +import com.querydsl.sql.domain.QEmployee; + +public class ColumnMetadataTest { + + @Test + public void defaultColumn() { + ColumnMetadata column = ColumnMetadata.named("Person"); + assertEquals("Person", column.getName()); + assertFalse(column.hasJdbcType()); + assertFalse(column.hasSize()); + assertTrue(column.isNullable()); + } + + @Test + public void fullyConfigured() { + ColumnMetadata column = ColumnMetadata.named("Person").withSize(10) + .notNull().ofType(Types.BIGINT); + assertEquals("Person", column.getName()); + assertTrue(column.hasJdbcType()); + assertEquals(Types.BIGINT, column.getJdbcType()); + assertTrue(column.hasSize()); + assertEquals(10, column.getSize()); + assertFalse(column.isNullable()); + } + + @Test + public void extractFromRelationalPath() { + ColumnMetadata column = ColumnMetadata.getColumnMetadata(QEmployee.employee.id); + assertEquals("ID", column.getName()); + } + + @Test + public void fallBackToDefaultWhenMissing() { + ColumnMetadata column = ColumnMetadata.getColumnMetadata(QEmployee.employee.salary); + assertEquals("SALARY", column.getName()); + } +} \ No newline at end of file diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/ConfigurationTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/ConfigurationTest.java new file mode 100644 index 0000000000..440ecd66e5 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/ConfigurationTest.java @@ -0,0 +1,143 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import static org.junit.Assert.assertEquals; + +import java.io.InputStream; +import java.math.BigInteger; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.sql.Types; +import java.util.Locale; + +import org.easymock.EasyMock; +import org.junit.Test; + +import com.querydsl.core.alias.Gender; +import com.querydsl.sql.domain.QSurvey; +import com.querydsl.sql.namemapping.ChainedNameMapping; +import com.querydsl.sql.namemapping.ChangeLetterCaseNameMapping; +import com.querydsl.sql.namemapping.ChangeLetterCaseNameMapping.LetterCase; +import com.querydsl.sql.namemapping.NameMapping; +import com.querydsl.sql.namemapping.PreConfiguredNameMapping; +import com.querydsl.sql.types.EnumByNameType; +import com.querydsl.sql.types.InputStreamType; +import com.querydsl.sql.types.Null; +import com.querydsl.sql.types.StringType; +import com.querydsl.sql.types.UtilDateType; + +public class ConfigurationTest { + + @Test + public void various() { + Configuration configuration = new Configuration(new H2Templates()); +// configuration.setJavaType(Types.DATE, java.util.Date.class); + configuration.register(new UtilDateType()); + configuration.register("person", "secureId", new EncryptedString()); + configuration.register("person", "gender", new EnumByNameType(Gender.class)); + configuration.register(new StringType()); + assertEquals(Gender.class, configuration.getJavaType(java.sql.Types.VARCHAR, null, 0,0,"person", "gender")); + } + + @Test + public void custom_type() { + Configuration configuration = new Configuration(new H2Templates()); +// configuration.setJavaType(Types.BLOB, InputStream.class); + configuration.register(new InputStreamType()); + assertEquals(InputStream.class, configuration.getJavaType(Types.BLOB, null, 0,0,"", "")); + } + + @Test + public void set_null() throws SQLException { + Configuration configuration = new Configuration(new H2Templates()); +// configuration.register(new UntypedNullType()); + configuration.register("SURVEY", "NAME", new EncryptedString()); + PreparedStatement stmt = EasyMock. createNiceMock(PreparedStatement.class); + configuration.set(stmt, QSurvey.survey.name, 0, Null.DEFAULT); + } + + @Test + public void get_schema() { + Configuration configuration = new Configuration(new H2Templates()); + configuration.registerSchemaOverride("public", "pub"); + configuration.registerTableOverride("employee", "emp"); + configuration.registerTableOverride("public", "employee", "employees"); + + assertEquals("pub", configuration.getOverride(new SchemaAndTable("public", "")).getSchema()); + assertEquals("emp", configuration.getOverride(new SchemaAndTable("", "employee")).getTable()); + assertEquals("employees", configuration.getOverride(new SchemaAndTable("public", "employee")).getTable()); + + configuration.setDynamicNameMapping(new PreConfiguredNameMapping()); + SchemaAndTable notOverriddenSchemaAndTable = new SchemaAndTable("notoverridden", "notoverridden"); + assertEquals(notOverriddenSchemaAndTable, configuration.getOverride(notOverriddenSchemaAndTable)); + + configuration.setDynamicNameMapping(new ChangeLetterCaseNameMapping(LetterCase.UPPER, Locale.ENGLISH)); + String notDirectOverriden = "notDirectOverriden"; + assertEquals(notDirectOverriden.toUpperCase(Locale.ENGLISH), + configuration.getOverride(new SchemaAndTable("public", notDirectOverriden)).getTable()); + + } + + @Test + public void columnOverride() { + Configuration configuration = new Configuration(new H2Templates()); + assertEquals("notoverriddencolumn", configuration.getColumnOverride(new SchemaAndTable("myschema", "mytable"), "notoverriddencolumn")); + + // Testing when chained name mapping does not give back any result. + configuration.setDynamicNameMapping(new PreConfiguredNameMapping()); + assertEquals("notoverriddencolumn", configuration.getColumnOverride(new SchemaAndTable("myschema", "mytable"), "notoverriddencolumn")); + + // Testing all other use-cases when letter case changing is in the end of the chain + configuration.setDynamicNameMapping(new ChangeLetterCaseNameMapping(LetterCase.LOWER, Locale.ENGLISH)); + + configuration.registerColumnOverride("mytable", "oldcolumn", "newcolumn"); + configuration.registerColumnOverride("mytable", "oldcolumn2", "newcolumn2"); + assertEquals("newcolumn", configuration.getColumnOverride(new SchemaAndTable("myschema", "mytable"), "oldcolumn")); + assertEquals("newcolumn2", configuration.getColumnOverride(new SchemaAndTable("myschema", "mytable"), "oldcolumn2")); + + configuration.registerColumnOverride("myschema", "mytable", "oldcolumn", "newcolumnwithschema"); + configuration.registerColumnOverride("myschema", "mytable", "oldcolumn2", "newcolumnwithschema2"); + assertEquals("newcolumnwithschema2", configuration.getColumnOverride(new SchemaAndTable("myschema", "mytable"), "oldcolumn2")); + assertEquals("notoverriddencolumn", configuration.getColumnOverride(new SchemaAndTable("myschema", "mytable"), "notoverriddencolumn")); + + assertEquals("lower", configuration.getColumnOverride(new SchemaAndTable("myschema", "mytable"), "LOWER")); + } + + @Test(expected = NullPointerException.class) + public void npeWithNullParameterOfChainedNameMappingConstructor() { + new ChainedNameMapping((NameMapping[]) null); + } + + @Test(expected = NullPointerException.class) + public void npeWithNullElementInParameterOfChainedNameMappingConstructor() { + new ChainedNameMapping(new NameMapping[] {null}); + } + + @Test + public void numericOverriden() { + Configuration configuration = new Configuration(new H2Templates()); + configuration.registerNumeric(19, 0, BigInteger.class); + assertEquals(configuration.getJavaType(Types.NUMERIC, "", 19, 0, "", ""), BigInteger.class); + } + + @Test + public void numericOverriden2() { + Configuration configuration = new Configuration(new H2Templates()); + configuration.registerNumeric(18, 19, 0, 0, BigInteger.class); + assertEquals(configuration.getJavaType(Types.NUMERIC, "", 18, 0, "", ""), BigInteger.class); + assertEquals(configuration.getJavaType(Types.NUMERIC, "", 19, 0, "", ""), BigInteger.class); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/Connections.java b/querydsl-sql/src/test/java/com/querydsl/sql/Connections.java new file mode 100644 index 0000000000..2c730f0c45 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/Connections.java @@ -0,0 +1,1159 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import java.sql.*; +import java.util.HashMap; +import java.util.Map; + +import org.hsqldb.types.Types; + +import com.querydsl.core.Target; +import com.querydsl.sql.ddl.CreateTableClause; +import com.querydsl.sql.ddl.DropTableClause; + +/** + * @author tiwe + * + */ +public final class Connections { + + public static final int TEST_ROW_COUNT = 100; + + private static ThreadLocal connHolder = new ThreadLocal(); + + private static ThreadLocal targetHolder = new ThreadLocal(); + + private static ThreadLocal configurationHolder = new ThreadLocal(); + + // datetest + private static final String CREATE_TABLE_DATETEST = "create table DATE_TEST(DATE_TEST date)"; + + // survey + private static final String CREATE_TABLE_SURVEY = + "create table SURVEY(ID int auto_increment, NAME varchar(30), NAME2 varchar(30))"; + + // test + private static final String CREATE_TABLE_TEST = "create table TEST(NAME varchar(255))"; + + // timetest + private static final String CREATE_TABLE_TIMETEST = "create table TIME_TEST(TIME_TEST time)"; + + // employee + private static final String INSERT_INTO_EMPLOYEE = "insert into EMPLOYEE " + + "(ID, FIRSTNAME, LASTNAME, SALARY, DATEFIELD, TIMEFIELD, SUPERIOR_ID) " + + "values (?,?,?,?,?,?,?)"; + + private static final String INSERT_INTO_TEST_VALUES = "insert into TEST values(?)"; + + private static ThreadLocal stmtHolder = new ThreadLocal(); + + private static boolean db2Inited, derbyInited, sqlServerInited, h2Inited, hsqlInited, mysqlInited, cubridInited, oracleInited, postgresqlInited, sqliteInited, teradataInited, firebirdInited; + + public static void close() throws SQLException { + if (stmtHolder.get() != null) { + stmtHolder.get().close(); + } + if (connHolder.get() != null) { + connHolder.get().close(); + } + } + + public static Connection getConnection() { + return connHolder.get(); + } + + public static Target getTarget() { + return targetHolder.get(); + } + + public static Configuration getConfiguration() { + return configurationHolder.get(); + } + + public static void initConfiguration(SQLTemplates templates) { + configurationHolder.set(new Configuration(templates)); + } + + private static Connection getDB2() throws SQLException, ClassNotFoundException { + Class.forName("com.ibm.db2.jcc.DB2Driver"); + String url = "jdbc:db2://localhost:50000/sample"; + return DriverManager.getConnection(url, "db2inst1", "a3sd!fDj"); + } + + private static Connection getDerby() throws SQLException, ClassNotFoundException { + Class.forName("org.apache.derby.jdbc.EmbeddedDriver"); + String url = "jdbc:derby:target/demoDB;create=true"; + return DriverManager.getConnection(url, "", ""); + } + + private static Connection getFirebird() throws SQLException, ClassNotFoundException { + Class.forName("org.firebirdsql.jdbc.FBDriver"); + String url = "jdbc:firebirdsql:localhost/3050:/firebird/data/querydsl.fdb"; + return DriverManager.getConnection(url, "sysdba", "masterkey"); + } + + private static Connection getHSQL() throws SQLException, ClassNotFoundException { + Class.forName("org.hsqldb.jdbcDriver"); + String url = "jdbc:hsqldb:target/tutorial"; + return DriverManager.getConnection(url, "sa", ""); + } + + public static Connection getH2() throws SQLException, ClassNotFoundException { + Class.forName("org.h2.Driver"); + String url = "jdbc:h2:./target/h2-test;LOCK_MODE=0;AUTO_SERVER=TRUE"; + return DriverManager.getConnection(url, "sa", ""); + } + + private static Connection getMySQL() throws SQLException, ClassNotFoundException { + Class.forName("com.mysql.jdbc.Driver"); + String url = "jdbc:mysql://localhost:3306/querydsl?useLegacyDatetimeCode=false"; + return DriverManager.getConnection(url, "querydsl", "querydsl"); + } + + private static Connection getOracle() throws SQLException, ClassNotFoundException { + Class.forName("oracle.jdbc.driver.OracleDriver"); + String url = "jdbc:oracle:thin:@localhost:1521:xe"; + return DriverManager.getConnection(url, "querydsl", "querydsl"); + } + + private static Connection getPostgreSQL() throws ClassNotFoundException, SQLException { + Class.forName("org.postgresql.Driver"); + String url = "jdbc:postgresql://localhost:5433/querydsl"; + return DriverManager.getConnection(url, "querydsl", "querydsl"); + } + + private static Connection getSQLServer() throws ClassNotFoundException, SQLException { + Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver"); + String url = "jdbc:sqlserver://localhost:1433;databaseName=tempdb;sendTimeAsDatetime=false;trustServerCertificate=true"; + return DriverManager.getConnection(url, "sa", "Password1!"); + } + + private static Connection getCubrid() throws ClassNotFoundException, SQLException { + Class.forName("cubrid.jdbc.driver.CUBRIDDriver"); + String url = "jdbc:cubrid:localhost:30000:demodb:public::"; + return DriverManager.getConnection(url); + } + + private static Connection getSQLite() throws SQLException, ClassNotFoundException { + //System.setProperty("sqlite.purejava", "true"); + Class.forName("org.sqlite.JDBC"); + return DriverManager.getConnection("jdbc:sqlite:target/sample.db"); + } + + private static Connection getTeradata() throws SQLException, ClassNotFoundException { + Class.forName("com.teradata.jdbc.TeraDriver"); + return DriverManager.getConnection("jdbc:teradata://teradata/dbc", "querydsl", "querydsl"); + } + + private static CreateTableClause createTable(SQLTemplates templates, String table) { + return new CreateTableClause(connHolder.get(), new Configuration(templates), table); + } + + public static void dropTable(SQLTemplates templates, String table) throws SQLException { + new DropTableClause(connHolder.get(), new Configuration(templates), table).execute(); + } + + public static void dropType(Statement stmt, String type) throws SQLException { + try { + stmt.execute("drop type " + type); + } catch (SQLException e) { + if (!e.getMessage().contains("does not exist")) { + throw e; + } + } + } + + public static Statement getStatement() { + return stmtHolder.get(); + } + + private static void createEmployeeTable(SQLTemplates templates) { + createTable(templates, "EMPLOYEE") + .column("ID", Integer.class).notNull() + .column("FIRSTNAME", String.class).size(50) + .column("LASTNAME", String.class).size(50) + .column("SALARY", Double.class) + .column("DATEFIELD", Date.class) + .column("TIMEFIELD", Time.class) + .column("SUPERIOR_ID", Integer.class) + .primaryKey("PK_EMPLOYEE", "ID") + .foreignKey("FK_SUPERIOR","SUPERIOR_ID").references("EMPLOYEE","ID") + .execute(); + } + + public static Map getSpatialData() { + Map m = new HashMap<>(); + // point + m.put(1, "POINT (2 2)"); + m.put(2, "POINT (8 7)"); + m.put(3, "POINT (1 9)"); + m.put(4, "POINT (9 2)"); + m.put(5, "POINT (4 4)"); + // linestring + m.put(6, "LINESTRING (30 10, 10 30)"); + m.put(7, "LINESTRING (30 10, 10 30, 40 40)"); + // polygon + m.put(8, "POLYGON ((30 10, 40 40, 20 40, 10 20, 30 10), (20 30, 35 35, 30 20, 20 30))"); + m.put(9, "POLYGON ((35 10, 45 45, 15 40, 10 20, 35 10), (20 30, 35 35, 30 20, 20 30))"); + // multipoint + m.put(11, "MULTIPOINT (10 40, 40 30)"); + m.put(11, "MULTIPOINT (10 40, 40 30, 20 20, 30 10)"); + // multilinestring + m.put(12, "MULTILINESTRING ((10 10, 20 20, 10 40), (40 40, 30 30, 40 20, 30 10))"); + m.put(13, "MULTILINESTRING ((10 10, 20 20, 10 40))"); + // multipolygon + m.put(14, "MULTIPOLYGON (((30 20, 45 40, 10 40, 30 20)), ((15 5, 40 10, 10 20, 5 10, 15 5)))"); + m.put(15, "MULTIPOLYGON (((40 40, 20 45, 45 30, 40 40)), " + + "((20 35, 10 30, 10 10, 30 5, 45 20, 20 35), " + + "(30 20, 20 15, 20 25, 30 20)))"); + + // XXX POLYHEDRALSURFACE not supported + + /* GEOMETRYCOLLECTION(POINT(4 6),LINESTRING(4 6,7 10)) + CIRCULARSTRING(1 5, 6 2, 7 3) + COMPOUNDCURVE(CIRCULARSTRING(0 0,1 1,1 0),(1 0,0 1)) + CURVEPOLYGON(CIRCULARSTRING(-2 0,-1 -1,0 0,1 -1,2 0,0 2,-2 0),(-1 0,0 0.5,1 0,0 1,-1 0)) + MULTICURVE((5 5,3 5,3 3,0 3),CIRCULARSTRING(0 0,2 1,2 2)) + TRIANGLE((0 0 0,0 1 0,1 1 0,0 0 0)) + TIN (((0 0 0, 0 0 1, 0 1 0, 0 0 0)), ((0 0 0, 0 1 0, 1 1 0, 0 0 0))) + */ + return m; + } + + public static void initCubrid() throws SQLException, ClassNotFoundException { + targetHolder.set(Target.CUBRID); + //SQLTemplates templates = new MySQLTemplates(); + Connection c = getCubrid(); + connHolder.set(c); + Statement stmt = c.createStatement(); + stmtHolder.set(stmt); + + if (cubridInited) { + return; + } + + // survey + stmt.execute("drop table if exists SURVEY"); + stmt.execute("create table SURVEY(ID int auto_increment(16693,2), " + + "NAME varchar(30)," + + "NAME2 varchar(30)," + + "constraint suryey_pk primary key(ID))"); + stmt.execute("insert into SURVEY values (1,'Hello World','Hello');"); + + // test + stmt.execute("drop table if exists \"TEST\""); + stmt.execute("create table \"TEST\"(NAME varchar(255))"); + try (PreparedStatement pstmt = c.prepareStatement("insert into \"TEST\" values(?)")) { + for (int i = 0; i < TEST_ROW_COUNT; i++) { + pstmt.setString(1, "name" + i); + pstmt.addBatch(); + } + pstmt.executeBatch(); + } + + // employee + stmt.execute("drop table if exists EMPLOYEE"); + //createEmployeeTable(templates); + stmt.execute("create table EMPLOYEE ( " + + "ID INT PRIMARY KEY AUTO_INCREMENT, " + + "FIRSTNAME VARCHAR(50), " + + "LASTNAME VARCHAR(50), " + + "SALARY DECIMAL, " + + "DATEFIELD DATE, " + + "TIMEFIELD TIME, " + + "SUPERIOR_ID INT, " + + "CONSTRAINT FK_SUPERIOR FOREIGN KEY(SUPERIOR_ID) REFERENCES EMPLOYEE(ID) " + + ")"); + + addEmployees(INSERT_INTO_EMPLOYEE); + + // date_test and time_test + stmt.execute("drop table if exists TIME_TEST"); + stmt.execute("drop table if exists DATE_TEST"); + stmt.execute(CREATE_TABLE_TIMETEST); + stmt.execute(CREATE_TABLE_DATETEST); + + // numbers + stmt.execute("drop table if exists NUMBER_TEST"); + stmt.execute("create table NUMBER_TEST(col1 int)"); + + // xml + stmt.execute("drop table if exists XML_TEST"); + stmt.execute("create table XML_TEST(COL varchar(128))"); + + cubridInited = true; + } + + public static void initDB2() throws SQLException, ClassNotFoundException { + targetHolder.set(Target.DB2); + SQLTemplates templates = new DB2Templates(); + Connection c = getDB2(); + connHolder.set(c); + Statement stmt = c.createStatement(); + stmtHolder.set(stmt); + + if (db2Inited) { + return; + } + + // survey + dropTable(templates, "SURVEY"); + stmt.execute("create table SURVEY(" + + "ID int generated by default as identity(start with 1, increment by 1), " + + "NAME varchar(30)," + + "NAME2 varchar(30))"); + stmt.execute("insert into SURVEY values (1,'Hello World','Hello')"); + + // test + dropTable(templates, "TEST"); + stmt.execute(CREATE_TABLE_TEST); + stmt.execute("create index test_name on test(name)"); + try (PreparedStatement pstmt = c.prepareStatement(INSERT_INTO_TEST_VALUES)) { + for (int i = 0; i < TEST_ROW_COUNT; i++) { + pstmt.setString(1, "name" + i); + pstmt.addBatch(); + } + pstmt.executeBatch(); + } + + // employee + dropTable(templates, "EMPLOYEE"); + + createEmployeeTable(templates); + + addEmployees(INSERT_INTO_EMPLOYEE); + + // date_test and time_test + dropTable(templates, "TIME_TEST"); + stmt.execute(CREATE_TABLE_TIMETEST); + + dropTable(templates, "DATE_TEST"); + stmt.execute(CREATE_TABLE_DATETEST); + + // numbers + dropTable(templates, "NUMBER_TEST"); + stmt.execute("create table NUMBER_TEST(col1 smallint)"); + + // xml + dropTable(templates, "XML_TEST"); + stmt.execute("create table XML_TEST(COL varchar(128))"); + + db2Inited = true; + } + + + public static void initDerby() throws SQLException, ClassNotFoundException { + targetHolder.set(Target.DERBY); + SQLTemplates templates = new DerbyTemplates(); + Connection c = getDerby(); + connHolder.set(c); + Statement stmt = c.createStatement(); + stmtHolder.set(stmt); + + if (derbyInited) { + return; + } + + // types + dropType(stmt, "price restrict"); + stmt.execute("create type price external name 'com.example.Price' language java"); + + // survey + dropTable(templates, "SURVEY"); + stmt.execute("create table SURVEY(" + + "ID int generated by default as identity(start with 1, increment by 1), " + + "NAME varchar(30)," + + "NAME2 varchar(30))"); + stmt.execute("insert into SURVEY values (1,'Hello World','Hello')"); + + // test + dropTable(templates, "TEST"); + stmt.execute(CREATE_TABLE_TEST); + stmt.execute("create index test_name on test(name)"); + try (PreparedStatement pstmt = c.prepareStatement(INSERT_INTO_TEST_VALUES)) { + for (int i = 0; i < TEST_ROW_COUNT; i++) { + pstmt.setString(1, "name" + i); + pstmt.addBatch(); + } + pstmt.executeBatch(); + } + + // employee + dropTable(templates, "EMPLOYEE"); + + createEmployeeTable(templates); + + addEmployees(INSERT_INTO_EMPLOYEE); + + // date_test and time_test + dropTable(templates, "TIME_TEST"); + stmt.execute(CREATE_TABLE_TIMETEST); + + dropTable(templates, "DATE_TEST"); + stmt.execute(CREATE_TABLE_DATETEST); + + // numbers + dropTable(templates, "NUMBER_TEST"); + stmt.execute("create table NUMBER_TEST(col1 boolean)"); + + // xml + dropTable(templates, "XML_TEST"); + stmt.execute("create table XML_TEST(COL varchar(128))"); + + derbyInited = true; + } + + public static void initFirebird() throws SQLException, ClassNotFoundException { + targetHolder.set(Target.FIREBIRD); + SQLTemplates templates = new FirebirdTemplates(); + Connection c = getFirebird(); + connHolder.set(c); + Statement stmt = c.createStatement(); + stmtHolder.set(stmt); + + if (firebirdInited) { + return; + } + + try { + stmt.execute("DECLARE EXTERNAL FUNCTION ltrim\n" + + " CSTRING(255)\n" + + " RETURNS CSTRING(255) FREE_IT\n" + + " ENTRY_POINT 'IB_UDF_ltrim' MODULE_NAME 'ib_udf'"); + } catch (SQLException e) { + // do nothing + } + try { + stmt.execute("DECLARE EXTERNAL FUNCTION rtrim\n" + + " CSTRING(255) NULL\n" + + " RETURNS CSTRING(255) FREE_IT\n" + + " ENTRY_POINT 'IB_UDF_rtrim' MODULE_NAME 'ib_udf'"); + } catch (SQLException e) { + // do nothing + } + + // survey + dropTable(templates, "SURVEY"); + stmt.execute("create table SURVEY(ID int primary key, " + + "NAME varchar(30)," + + "NAME2 varchar(30))"); + + stmt.execute("insert into SURVEY values (1,'Hello World','Hello');"); + + try { + //stmt.execute("DROP TRIGGER survey_auto_id;"); + stmt.execute("DROP GENERATOR survey_gen_id;"); + } catch (SQLException e) { + // do nothing + } + + stmt.execute("CREATE GENERATOR survey_gen_id;"); + stmt.execute("SET GENERATOR survey_gen_id TO 30;"); + stmt.execute("CREATE TRIGGER survey_auto_id FOR survey\n" + + "ACTIVE BEFORE INSERT POSITION 0\n" + + "AS\n" + + "BEGIN\n" + + "IF (NEW.id IS NULL) THEN\n" + + "NEW.id = GEN_ID(survey_gen_id,1);\n" + + "END "); + + // test + dropTable(templates, "TEST"); + stmt.execute(CREATE_TABLE_TEST); + try (PreparedStatement pstmt = c.prepareStatement(INSERT_INTO_TEST_VALUES)) { + for (int i = 0; i < TEST_ROW_COUNT; i++) { + pstmt.setString(1, "name" + i); + pstmt.addBatch(); + } + pstmt.executeBatch(); + } + + // employee + dropTable(templates, "EMPLOYEE"); + //createEmployeeTable(templates); + stmt.execute("create table EMPLOYEE ( " + + "ID INT PRIMARY KEY, " + + "FIRSTNAME VARCHAR(50), " + + "LASTNAME VARCHAR(50), " + + "SALARY DECIMAL, " + + "DATEFIELD DATE, " + + "TIMEFIELD TIME, " + + "SUPERIOR_ID INT, " + + "CONSTRAINT FK_SUPERIOR FOREIGN KEY(SUPERIOR_ID) REFERENCES EMPLOYEE(ID) " + + ")"); + + try { + //stmt.execute("DROP TRIGGER employee_auto_id;"); + stmt.execute("DROP GENERATOR employee_gen_id;"); + } catch (SQLException e) { + // do nothing + } + + stmt.execute("CREATE GENERATOR employee_gen_id;"); + stmt.execute("SET GENERATOR employee_gen_id TO 30;"); + stmt.execute("CREATE TRIGGER employee_auto_id FOR employee\n" + + "ACTIVE BEFORE INSERT POSITION 0\n" + + "AS\n" + + "BEGIN\n" + + "IF (NEW.id IS NULL) THEN\n" + + "NEW.id = GEN_ID(employee_gen_id,1);\n" + + "END "); + + addEmployees(INSERT_INTO_EMPLOYEE); + + // date_test and time_test + dropTable(templates, "TIME_TEST"); + dropTable(templates, "DATE_TEST"); + stmt.execute(CREATE_TABLE_TIMETEST); + stmt.execute(CREATE_TABLE_DATETEST); + + // numbers + dropTable(templates, "NUMBER_TEST"); + stmt.execute("create table NUMBER_TEST(col1 char(1))"); + + // xml + dropTable(templates, "XML_TEST"); + stmt.execute("create table XML_TEST(COL varchar(128))"); + + firebirdInited = true; + } + + public static void initH2() throws SQLException, ClassNotFoundException { + targetHolder.set(Target.H2); + SQLTemplates templates = new H2Templates(); + Connection c = getH2(); + connHolder.set(c); + Statement stmt = c.createStatement(); + stmtHolder.set(stmt); + + if (h2Inited) { + return; + } + + stmt.execute("DROP ALIAS IF EXISTS H2GIS_SPATIAL"); + stmt.execute("CREATE ALIAS IF NOT EXISTS H2GIS_SPATIAL FOR \"org.h2gis.functions.factory.H2GISFunctions.load\""); + stmt.execute("CALL H2GIS_SPATIAL();"); + + // shapes + dropTable(templates, "SHAPES"); + stmt.execute("create table SHAPES (ID int not null primary key, GEOMETRY geometry)"); + for (Map.Entry entry : getSpatialData().entrySet()) { + stmt.execute("insert into SHAPES values(" + entry.getKey() + + ", ST_GeomFromText('" + entry.getValue() + "'))"); + } + + // qtest + stmt.execute("drop table QTEST if exists"); + stmt.execute("create table QTEST (ID int IDENTITY(1,1) NOT NULL, C1 int NULL)"); + + // uuids + stmt.execute("drop table if exists UUIDS"); + stmt.execute("create table UUIDS (FIELD uuid)"); + + // survey + stmt.execute("drop table SURVEY if exists"); + stmt.execute(CREATE_TABLE_SURVEY); + stmt.execute("insert into SURVEY values (1, 'Hello World', 'Hello');"); + stmt.execute("alter table SURVEY alter column id int auto_increment"); + + // test + stmt.execute("drop table TEST if exists"); + stmt.execute(CREATE_TABLE_TEST); + try (PreparedStatement pstmt = c.prepareStatement(INSERT_INTO_TEST_VALUES)) { + for (int i = 0; i < TEST_ROW_COUNT; i++) { + pstmt.setString(1, "name" + i); + pstmt.addBatch(); + } + pstmt.executeBatch(); + } + + // employee + stmt.execute("drop table EMPLOYEE if exists"); + createEmployeeTable(templates); + stmt.execute("alter table EMPLOYEE alter column id int auto_increment"); + addEmployees(INSERT_INTO_EMPLOYEE); + + // date_test and time_test + stmt.execute("drop table TIME_TEST if exists"); + stmt.execute("drop table DATE_TEST if exists"); + stmt.execute(CREATE_TABLE_TIMETEST); + stmt.execute(CREATE_TABLE_DATETEST); + + // numbers + dropTable(templates, "NUMBER_TEST"); + stmt.execute("create table NUMBER_TEST(col1 boolean)"); + + // xml + dropTable(templates, "XML_TEST"); + stmt.execute("create table XML_TEST(COL varchar(128))"); + + h2Inited = true; + } + + public static void initHSQL() throws SQLException, ClassNotFoundException { + targetHolder.set(Target.HSQLDB); + SQLTemplates templates = new HSQLDBTemplates(); + Connection c = getHSQL(); + connHolder.set(c); + Statement stmt = c.createStatement(); + stmtHolder.set(stmt); + + if (hsqlInited) { + return; + } + + // arrays + stmt.execute("drop table ARRAYTEST if exists"); + stmt.execute("create table ARRAYTEST ( " + + "ID bigint primary key, " + + "INTEGERS integer array, " + + "MYARRAY varchar(8) array)"); + + // dual + stmt.execute("drop table DUAL if exists"); + stmt.execute("create table DUAL ( DUMMY varchar(1) )"); + stmt.execute("insert into DUAL (DUMMY) values ('X')"); + + // survey + stmt.execute("drop table SURVEY if exists"); + //stmt.execute(CREATE_TABLE_SURVEY); + stmt.execute("create table SURVEY(" + + "ID int generated by default as identity, " + + "NAME varchar(30)," + + "NAME2 varchar(30))"); + stmt.execute("insert into SURVEY values (1, 'Hello World', 'Hello')"); + + // test + stmt.execute("drop table TEST if exists"); + stmt.execute(CREATE_TABLE_TEST); + try (PreparedStatement pstmt = c.prepareStatement(INSERT_INTO_TEST_VALUES)) { + for (int i = 0; i < TEST_ROW_COUNT; i++) { + pstmt.setString(1, "name" + i); + pstmt.addBatch(); + } + pstmt.executeBatch(); + } + + // employee + stmt.execute("drop table EMPLOYEE if exists"); + createEmployeeTable(templates); + stmt.execute("alter table EMPLOYEE alter column id int generated by default as identity"); + addEmployees(INSERT_INTO_EMPLOYEE); + + // date_test and time_test + stmt.execute("drop table TIME_TEST if exists"); + stmt.execute("drop table DATE_TEST if exists"); + stmt.execute(CREATE_TABLE_TIMETEST); + stmt.execute(CREATE_TABLE_DATETEST); + + // numbers + dropTable(templates, "NUMBER_TEST"); + stmt.execute("create table NUMBER_TEST(col1 boolean)"); + + // xml + dropTable(templates, "XML_TEST"); + stmt.execute("create table XML_TEST(COL varchar(128))"); + + hsqlInited = true; + } + + public static void initMySQL() throws SQLException, ClassNotFoundException { + targetHolder.set(Target.MYSQL); + //SQLTemplates templates = new MySQLTemplates(); + Connection c = getMySQL(); + connHolder.set(c); + Statement stmt = c.createStatement(); + stmtHolder.set(stmt); + + if (mysqlInited) { + return; + } + + // shapes + stmt.execute("drop table if exists SHAPES"); + stmt.execute("create table SHAPES (ID int not null primary key, GEOMETRY geometry)"); + for (Map.Entry entry : getSpatialData().entrySet()) { + stmt.execute("insert into SHAPES values(" + entry.getKey() + + ", GeomFromText('" + entry.getValue() + "'))"); + } + + // survey + stmt.execute("drop table if exists SURVEY"); + stmt.execute("create table SURVEY(ID int primary key auto_increment, " + + "NAME varchar(30)," + + "NAME2 varchar(30))"); + stmt.execute("insert into SURVEY values (1,'Hello World','Hello');"); + + // test + stmt.execute("drop table if exists TEST"); + stmt.execute(CREATE_TABLE_TEST); + try (PreparedStatement pstmt = c.prepareStatement(INSERT_INTO_TEST_VALUES)) { + for (int i = 0; i < TEST_ROW_COUNT; i++) { + pstmt.setString(1, "name" + i); + pstmt.addBatch(); + } + pstmt.executeBatch(); + } + + // employee + stmt.execute("drop table if exists EMPLOYEE"); + //createEmployeeTable(templates); + stmt.execute("create table EMPLOYEE ( " + + "ID INT PRIMARY KEY AUTO_INCREMENT, " + + "FIRSTNAME VARCHAR(50), " + + "LASTNAME VARCHAR(50), " + + "SALARY DECIMAL, " + + "DATEFIELD DATE, " + + "TIMEFIELD TIME, " + + "SUPERIOR_ID INT, " + + "CONSTRAINT FK_SUPERIOR FOREIGN KEY(SUPERIOR_ID) REFERENCES EMPLOYEE(ID) " + + ")"); + + addEmployees(INSERT_INTO_EMPLOYEE); + + // date_test and time_test + stmt.execute("drop table if exists TIME_TEST"); + stmt.execute("drop table if exists DATE_TEST"); + stmt.execute(CREATE_TABLE_TIMETEST); + stmt.execute(CREATE_TABLE_DATETEST); + + // numbers + stmt.execute("drop table if exists NUMBER_TEST"); + stmt.execute("create table NUMBER_TEST(col1 tinyint(1))"); + + // xml + stmt.execute("drop table if exists XML_TEST"); + stmt.execute("create table XML_TEST(COL varchar(128))"); + + mysqlInited = true; + } + + public static void initOracle() throws SQLException, ClassNotFoundException { + targetHolder.set(Target.ORACLE); + SQLTemplates templates = new OracleTemplates(); + Connection c = getOracle(); + connHolder.set(c); + Statement stmt = c.createStatement(); + stmtHolder.set(stmt); + + if (oracleInited) { + return; + } + + // types + stmt.execute("create or replace type ssn_t as object (ssn_type char(11))"); + + // survey + dropTable(templates, "SURVEY"); + stmt.execute("create table SURVEY (ID number(10,0), " + + "NAME varchar(30 char)," + + "NAME2 varchar(30 char))"); + + try { + stmt.execute("drop sequence survey_seq"); + } catch (SQLException e) { + if (!e.getMessage().contains("sequence does not exist")) { + throw e; + } + } + + stmt.execute("create sequence survey_seq"); + stmt.execute("create or replace trigger survey_trigger\n" + + "before insert on survey\n" + + "for each row\n" + + "when (new.id is null)\n" + + "begin\n" + + " select survey_seq.nextval into :new.id from dual;\n" + + "end;\n"); + + stmt.execute("insert into SURVEY values (1,'Hello World','Hello')"); + + // test + dropTable(templates, "TEST"); + stmt.execute("create table TEST(name varchar(255))"); + String sql = "insert into TEST values(?)"; + PreparedStatement pstmt = c.prepareStatement(sql); + for (int i = 0; i < TEST_ROW_COUNT; i++) { + pstmt.setString(1, "name" + i); + pstmt.addBatch(); + } + pstmt.executeBatch(); + + // employee + dropTable(templates, "EMPLOYEE"); + stmt.execute("create table EMPLOYEE ( " + + "ID NUMBER(10,0), " + + "FIRSTNAME VARCHAR2(50 CHAR), " + + "LASTNAME VARCHAR2(50 CHAR), " + + "SALARY DOUBLE PRECISION, " + + "DATEFIELD DATE, " + + "TIMEFIELD TIMESTAMP, " + + "SUPERIOR_ID NUMBER(10,0), " + + "CONSTRAINT PK_EMPLOYEE PRIMARY KEY(ID), " + + "CONSTRAINT FK_SUPERIOR FOREIGN KEY(SUPERIOR_ID) REFERENCES EMPLOYEE(ID)" + + ")"); + + addEmployees(INSERT_INTO_EMPLOYEE); + + // date_test and time_test + dropTable(templates, "DATE_TEST"); + stmt.execute("create table date_test(date_test date)"); + + // numbers + dropTable(templates, "NUMBER_TEST"); + stmt.execute("create table NUMBER_TEST(col1 number(1,0))"); + + // xml + dropTable(templates, "XML_TEST"); + stmt.execute("create table XML_TEST(COL XMLTYPE)"); + + oracleInited = true; + } + + public static void initPostgreSQL() throws SQLException, ClassNotFoundException { + targetHolder.set(Target.POSTGRESQL); + SQLTemplates templates = new PostgreSQLTemplates(true); + // NOTE : unquoted identifiers are converted to lower case in PostgreSQL + Connection c = getPostgreSQL(); + connHolder.set(c); + Statement stmt = c.createStatement(); + stmtHolder.set(stmt); + + if (postgresqlInited) { + return; + } + + // shapes + dropTable(templates, "SHAPES"); +// stmt.execute("create table \"SHAPES\" (\"ID\" int not null primary key, \"GEOMETRY\" geography(POINT,4326))"); + stmt.execute("create table \"SHAPES\" (\"ID\" int not null primary key)"); + stmt.execute("select AddGeometryColumn('SHAPES', 'GEOMETRY', -1, 'GEOMETRY', 2)"); + for (Map.Entry entry : getSpatialData().entrySet()) { + stmt.execute("insert into \"SHAPES\" values(" + entry.getKey() + + ", '" + entry.getValue() + "')"); + } + + // types + dropType(stmt, "u_country"); + stmt.execute("create type u_country as enum ('Brazil', 'England', 'Germany')"); + + dropType(stmt, "u_street_type"); + stmt.execute("create type u_street_type as (street VARCHAR(100), number VARCHAR(30))"); + + // arrays + dropTable(templates, "ARRAYTEST"); + stmt.execute("create table \"ARRAYTEST\" (\n" + + "\"ID\" bigint primary key,\n" + + "\"INTEGERS\" integer[],\n" + + "\"MYARRAY\" varchar(8)[])"); + + // uuids + dropTable(templates, "UUIDS"); + stmt.execute("create table \"UUIDS\" (\"FIELD\" uuid)"); + + // survey + dropTable(templates, "SURVEY"); + try { + stmt.execute("drop sequence SURVEY_SEQ"); + } catch (SQLException e) { + if (!e.getMessage().contains("does not exist")) { + throw e; + } + } + stmt.execute("create sequence SURVEY_SEQ"); + stmt.execute("create table \"SURVEY\"(" + + "\"ID\" int DEFAULT NEXTVAL('SURVEY_SEQ'), " + + "\"NAME\" varchar(30), \"NAME2\" varchar(30))"); + stmt.execute("insert into \"SURVEY\" values (1, 'Hello World', 'Hello')"); + + // test + dropTable(templates, "TEST"); + stmt.execute(quote(CREATE_TABLE_TEST,"TEST","NAME")); + String sql = quote(INSERT_INTO_TEST_VALUES,"TEST"); + try (PreparedStatement pstmt = c.prepareStatement(sql)) { + for (int i = 0; i < TEST_ROW_COUNT; i++) { + pstmt.setString(1, "name" + i); + pstmt.addBatch(); + } + pstmt.executeBatch(); + } + + // employee + // stmt.execute("drop table employee if exists"); + dropTable(templates, "EMPLOYEE"); + createEmployeeTable(templates); + addEmployees("insert into \"EMPLOYEE\" " + + "(\"ID\", \"FIRSTNAME\", \"LASTNAME\", \"SALARY\", \"DATEFIELD\", \"TIMEFIELD\", \"SUPERIOR_ID\") " + + "values (?,?,?,?,?,?,?)"); + + // date_test and time_test + dropTable(templates, "TIME_TEST"); + dropTable(templates, "DATE_TEST"); + stmt.execute(quote(CREATE_TABLE_TIMETEST, "TIME_TEST")); + stmt.execute(quote(CREATE_TABLE_DATETEST, "DATE_TEST")); + + // numbers + dropTable(templates, "NUMBER_TEST"); + stmt.execute("create table \"NUMBER_TEST\"(\"COL1\" boolean)"); + + // xml + dropTable(templates, "XML_TEST"); + stmt.execute("create table \"XML_TEST\"(\"COL\" XML)"); + + postgresqlInited = true; + } + + public static void initSQLite() throws SQLException, ClassNotFoundException { + targetHolder.set(Target.SQLITE); +// SQLTemplates templates = new SQLiteTemplates(); + Connection c = getSQLite(); + connHolder.set(c); + Statement stmt = c.createStatement(); + stmtHolder.set(stmt); + + if (sqliteInited) { + return; + } + + // qtest + stmt.execute("drop table if exists QTEST"); + stmt.execute("create table QTEST (ID int IDENTITY(1,1) NOT NULL, C1 int NULL)"); + + // survey + stmt.execute("drop table if exists SURVEY"); + stmt.execute("create table SURVEY(ID int auto_increment, " + + "NAME varchar(30)," + + "NAME2 varchar(30)," + + "constraint survey_pk primary key(ID))"); + stmt.execute("insert into SURVEY values (1,'Hello World','Hello');"); + + // test + stmt.execute("drop table if exists TEST"); + stmt.execute(CREATE_TABLE_TEST); + try (PreparedStatement pstmt = c.prepareStatement(INSERT_INTO_TEST_VALUES)) { + for (int i = 0; i < TEST_ROW_COUNT; i++) { + pstmt.setString(1, "name" + i); + pstmt.addBatch(); + } + pstmt.executeBatch(); + } + + // employee + stmt.execute("drop table if exists EMPLOYEE"); + stmt.execute("create table EMPLOYEE ( " + + "ID INT AUTO_INCREMENT, " + + "FIRSTNAME VARCHAR(50), " + + "LASTNAME VARCHAR(50), " + + "SALARY DECIMAL, " + + "DATEFIELD DATE, " + + "TIMEFIELD TIME, " + + "SUPERIOR_ID INT, " + + "CONSTRAINT PK_EMPLOYEE PRIMARY KEY(ID)," + + "CONSTRAINT FK_SUPERIOR FOREIGN KEY(SUPERIOR_ID) REFERENCES EMPLOYEE(ID) " + + ")"); + addEmployees(INSERT_INTO_EMPLOYEE); + + + // date_test and time_test + stmt.execute("drop table if exists TIME_TEST"); + stmt.execute("drop table if exists DATE_TEST"); + stmt.execute(CREATE_TABLE_TIMETEST); + stmt.execute(CREATE_TABLE_DATETEST); + + // numbers + stmt.execute("drop table if exists NUMBER_TEST"); + stmt.execute("create table NUMBER_TEST(col1 integer)"); + + // xml + stmt.execute("drop table if exists XML_TEST"); + stmt.execute("create table XML_TEST(COL varchar(128))"); + + sqliteInited = true; + } + + public static void initSQLServer() throws SQLException, ClassNotFoundException { + targetHolder.set(Target.SQLSERVER); + SQLTemplates templates = new SQLServerTemplates(); + Connection c = getSQLServer(); + connHolder.set(c); + Statement stmt = c.createStatement(); + stmtHolder.set(stmt); + + if (sqlServerInited) { + return; + } + + dropTable(templates, "SHAPES"); + stmt.execute("create table SHAPES (ID int not null primary key, GEOMETRY geometry)"); + for (Map.Entry entry : getSpatialData().entrySet()) { + stmt.execute("insert into SHAPES values(" + entry.getKey() + + ", geometry::STGeomFromText('" + entry.getValue() + "', 0))"); + } + + // survey + dropTable(templates, "SURVEY"); + stmt.execute("create table SURVEY(ID int, NAME varchar(30), NAME2 varchar(30))"); + stmt.execute("insert into SURVEY values (1, 'Hello World', 'Hello')"); + + // test + dropTable(templates, "TEST"); + stmt.execute(CREATE_TABLE_TEST); + try (PreparedStatement pstmt = c.prepareStatement(INSERT_INTO_TEST_VALUES)) { + for (int i = 0; i < TEST_ROW_COUNT; i++) { + pstmt.setString(1, "name" + i); + pstmt.addBatch(); + } + pstmt.executeBatch(); + } + + // employee + dropTable(templates, "EMPLOYEE"); + createEmployeeTable(templates); + addEmployees(INSERT_INTO_EMPLOYEE); + + // date_test and time_test + dropTable(templates, "TIME_TEST"); + dropTable(templates, "DATE_TEST"); + stmt.execute(CREATE_TABLE_TIMETEST); + stmt.execute(CREATE_TABLE_DATETEST); + + // numbers + dropTable(templates, "NUMBER_TEST"); + stmt.execute("create table NUMBER_TEST(col1 bit)"); + + // xml + dropTable(templates, "XML_TEST"); + stmt.execute("create table XML_TEST(COL XML)"); + + sqlServerInited = true; + } + + public static void initTeradata() throws SQLException, ClassNotFoundException { + targetHolder.set(Target.TERADATA); + SQLTemplates templates = new TeradataTemplates(); + Connection c = getTeradata(); + connHolder.set(c); + Statement stmt = c.createStatement(); + stmtHolder.set(stmt); + + if (teradataInited) { + return; + } + + String identity = "GENERATED ALWAYS AS IDENTITY(START WITH 1 INCREMENT BY 1)"; + + // shapes + dropTable(templates, "SHAPES"); + stmt.execute("create table SHAPES (ID int not null primary key, GEOMETRY ST_GEOMETRY)"); + for (Map.Entry entry : getSpatialData().entrySet()) { + stmt.execute("insert into SHAPES values(" + entry.getKey() + + ", '" + entry.getValue() + "')"); + } + + // qtest + dropTable(templates, "QTEST"); + stmt.execute("create table QTEST (ID int " + identity + " NOT NULL, C1 int NULL)"); + + // survey + dropTable(templates, "SURVEY"); + stmt.execute("create table SURVEY(ID int " + identity + ", NAME varchar(30), NAME2 varchar(30))"); + stmt.execute("insert into SURVEY values (1, 'Hello World', 'Hello');"); + + // test + dropTable(templates, "TEST"); + stmt.execute(CREATE_TABLE_TEST); + try (PreparedStatement pstmt = c.prepareStatement(INSERT_INTO_TEST_VALUES)) { + for (int i = 0; i < TEST_ROW_COUNT; i++) { + pstmt.setString(1, "name" + i); + pstmt.addBatch(); + } + pstmt.executeBatch(); + } + + // employee + dropTable(templates, "EMPLOYEE"); + stmt.execute("create table EMPLOYEE (\n" + + "ID INTEGER NOT NULL PRIMARY KEY, \n" + + "FIRSTNAME VARCHAR(100),\n" + + "LASTNAME VARCHAR(100),\n" + + "SALARY DOUBLE PRECISION,\n" + + "DATEFIELD DATE,\n" + + "TIMEFIELD TIME,\n" + + "SUPERIOR_ID INTEGER,\n" + + "CONSTRAINT FK_SUPERIOR FOREIGN KEY(SUPERIOR_ID) REFERENCES EMPLOYEE(ID))"); + addEmployees(INSERT_INTO_EMPLOYEE); + + // date_test and time_test + dropTable(templates, "TIME_TEST"); + dropTable(templates, "DATE_TEST"); + stmt.execute(CREATE_TABLE_TIMETEST); + stmt.execute(CREATE_TABLE_DATETEST); + + // numbers + dropTable(templates, "NUMBER_TEST"); + stmt.execute("create table NUMBER_TEST(ID int " + identity + " NOT NULL, col1 int)"); + + // xml + dropTable(templates, "XML_TEST"); + stmt.execute("create table XML_TEST(ID int " + identity + " NOT NULL, COL varchar(128))"); + + teradataInited = true; + } + + static void addEmployee(String sql, int id, String firstName, String lastName, + double salary, int superiorId) throws SQLException { + PreparedStatement stmt = connHolder.get().prepareStatement(sql); + stmt.setInt(1, id); + stmt.setString(2, firstName); + stmt.setString(3,lastName); + stmt.setDouble(4, salary); + stmt.setDate(5, Constants.date); + stmt.setTime(6, Constants.time); + if (superiorId <= 0) { + stmt.setNull(7, Types.INTEGER); + } else { + stmt.setInt(7, superiorId); + } + stmt.execute(); + stmt.close(); + } + + private static void addEmployees(String sql) throws SQLException { + addEmployee(sql, 1, "Mike", "Smith", 160000, -1); + addEmployee(sql, 2, "Mary", "Smith", 140000, -1); + + // Employee under Mike + addEmployee(sql, 10, "Joe", "Divis", 50000, 1); + addEmployee(sql, 11, "Peter", "Mason", 45000, 1); + addEmployee(sql, 12, "Steve", "Johnson", 40000, 1); + addEmployee(sql, 13, "Jim", "Hood", 35000, 1); + + // Employee under Mike + addEmployee(sql, 20, "Jennifer", "Divis", 60000, 2); + addEmployee(sql, 21, "Helen", "Mason", 50000, 2); + addEmployee(sql, 22, "Daisy", "Johnson", 40000, 2); + addEmployee(sql, 23, "Barbara", "Hood", 30000, 2); + } + + private static String quote(String sql, String... identifiers) { + String rv = sql; + for (String id : identifiers) { + rv = rv.replace(id, "\"" + id + "\""); + } + return rv; + } + + private Connections() { } +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/ConnectionsTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/ConnectionsTest.java new file mode 100644 index 0000000000..55aa7bc529 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/ConnectionsTest.java @@ -0,0 +1,17 @@ +package com.querydsl.sql; + +import static org.junit.Assert.assertNotNull; + +import org.geolatte.geom.codec.Wkt; +import org.junit.Test; + +public class ConnectionsTest { + + @Test + public void valid_wkt() { + for (String wkt : Connections.getSpatialData().values()) { + assertNotNull(Wkt.newDecoder(Wkt.Dialect.POSTGIS_EWKT_1).decode(wkt)); + } + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/Constants.java b/querydsl-sql/src/test/java/com/querydsl/sql/Constants.java new file mode 100644 index 0000000000..447cd4c847 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/Constants.java @@ -0,0 +1,49 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import java.util.Calendar; + +import org.joda.time.LocalDate; + +import com.querydsl.sql.domain.QEmployee; +import com.querydsl.sql.domain.QSurvey; + +public final class Constants { + + private Constants() { } + + public static final java.sql.Date date; + + public static final java.sql.Time time; + + public static final QEmployee employee = new QEmployee("e"); + + public static final QEmployee employee2 = new QEmployee("e2"); + + public static final QSurvey survey = new QSurvey("s"); + + public static final QSurvey survey2 = new QSurvey("s2"); + + static { + LocalDate localDate = new LocalDate(2000, 2, 10); + date = new java.sql.Date(localDate.toDateMidnight().getMillis()); + + Calendar cal = Calendar.getInstance(); + cal.set(1970, 0, 1, 3, 4); + cal.set(Calendar.SECOND, 30); + cal.set(Calendar.MILLISECOND, 0); + time = new java.sql.Time(cal.getTimeInMillis()); + } +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/DB2TemplatesTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/DB2TemplatesTest.java new file mode 100644 index 0000000000..555b5f152b --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/DB2TemplatesTest.java @@ -0,0 +1,54 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +import com.querydsl.core.types.Ops; + +public class DB2TemplatesTest extends AbstractSQLTemplatesTest { + + @Override + protected SQLTemplates createTemplates() { + return new DB2Templates(); + } + + @Test + public void precedence() { + // Expressions within parentheses are evaluated first. When the order of evaluation is not + // specified by parentheses, prefix operators are applied before multiplication and division, + // and multiplication, division, and concatenation are applied before addition and subtraction. + // Operators at the same precedence level are applied from left to right. + + int p1 = getPrecedence(Ops.NEGATE); + int p2 = getPrecedence(Ops.MULT, Ops.DIV, Ops.CONCAT); + int p3 = getPrecedence(Ops.ADD, Ops.SUB); + int p4 = getPrecedence(Ops.EQ, Ops.NE, Ops.LT, Ops.GT, Ops.LOE, Ops.GOE); + int p5 = getPrecedence(Ops.IS_NULL, Ops.IS_NOT_NULL, Ops.LIKE, Ops.LIKE_ESCAPE, Ops.BETWEEN, Ops.IN, Ops.NOT_IN, Ops.EXISTS); + int p6 = getPrecedence(Ops.NOT); + int p7 = getPrecedence(Ops.AND); + int p8 = getPrecedence(Ops.OR); + + assertTrue(p1 < p2); + assertTrue(p2 < p3); + assertTrue(p3 < p4); + assertTrue(p4 < p5); + assertTrue(p5 < p6); + assertTrue(p6 < p7); + assertTrue(p7 < p8); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/DateArithmeticTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/DateArithmeticTest.java new file mode 100644 index 0000000000..80264ec82f --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/DateArithmeticTest.java @@ -0,0 +1,59 @@ +package com.querydsl.sql; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import org.junit.Test; +import org.junit.experimental.categories.Category; + +import com.querydsl.core.testutil.ReportingOnly; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.dsl.DateTimePath; +import com.querydsl.core.types.dsl.Expressions; + +@Category(ReportingOnly.class) +public class DateArithmeticTest { + + private String serialize(Expression expr, SQLTemplates templates) { + SQLSerializer serializer = new SQLSerializer(new Configuration(templates)); + serializer.handle(expr); + return serializer.toString(); + } + + @Test + public void test() { + List list = new ArrayList<>(); + list.add(new CUBRIDTemplates()); + list.add(new DerbyTemplates()); + list.add(new H2Templates()); + list.add(new HSQLDBTemplates()); + list.add(new MySQLTemplates()); + list.add(new OracleTemplates()); + list.add(new PostgreSQLTemplates()); + list.add(new SQLiteTemplates()); + list.add(new SQLServerTemplates()); + list.add(new SQLServer2005Templates()); + list.add(new SQLServer2012Templates()); + list.add(new TeradataTemplates()); + + List> exprs = new ArrayList<>(); + DateTimePath path = Expressions.dateTimePath(Date.class, "date"); + exprs.add(SQLExpressions.addYears(path, 2)); + exprs.add(SQLExpressions.addMonths(path, 2)); + exprs.add(SQLExpressions.addDays(path, 2)); + exprs.add(SQLExpressions.addHours(path, 2)); + exprs.add(SQLExpressions.addMinutes(path, 2)); + exprs.add(SQLExpressions.addSeconds(path, 2)); + + for (SQLTemplates templates : list) { + System.out.println(templates.getClass().getSimpleName()); + for (Expression expr : exprs) { + System.err.println(serialize(expr, templates)); + } + System.out.println(); + + } + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/DeleteBase.java b/querydsl-sql/src/test/java/com/querydsl/sql/DeleteBase.java new file mode 100644 index 0000000000..7197d5fbca --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/DeleteBase.java @@ -0,0 +1,139 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import static com.querydsl.core.Target.*; +import static com.querydsl.sql.Constants.survey; +import static org.junit.Assert.assertEquals; + +import java.sql.SQLException; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.querydsl.core.testutil.ExcludeIn; +import com.querydsl.core.testutil.IncludeIn; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.Param; +import com.querydsl.sql.dml.SQLDeleteClause; +import com.querydsl.sql.domain.QEmployee; +import com.querydsl.sql.domain.QSurvey; + +public class DeleteBase extends AbstractBaseTest { + + private void reset() throws SQLException { + delete(survey).where(survey.name.isNotNull()).execute(); + insert(survey).values(1, "Hello World", "Hello").execute(); + } + + @Before + public void setUp() throws SQLException { + reset(); + } + + @After + public void tearDown() throws SQLException { + reset(); + } + + @Test + public void batch() throws SQLException { + insert(survey).values(2, "A","B").execute(); + insert(survey).values(3, "B","C").execute(); + + SQLDeleteClause delete = delete(survey); + delete.where(survey.name.eq("A")).addBatch(); + assertEquals(1, delete.getBatchCount()); + delete.where(survey.name.eq("B")).addBatch(); + assertEquals(2, delete.getBatchCount()); + assertEquals(2, delete.execute()); + } + + @Test + @ExcludeIn({CUBRID, SQLITE}) + public void batch_templates() throws SQLException { + insert(survey).values(2, "A","B").execute(); + insert(survey).values(3, "B","C").execute(); + + SQLDeleteClause delete = delete(survey); + delete.where(survey.name.eq(Expressions.stringTemplate("'A'"))).addBatch(); + delete.where(survey.name.eq(Expressions.stringTemplate("'B'"))).addBatch(); + assertEquals(2, delete.execute()); + } + + @Test + @ExcludeIn(MYSQL) + public void delete() throws SQLException { + long count = query().from(survey).fetchCount(); + assertEquals(0, delete(survey).where(survey.name.eq("XXX")).execute()); + assertEquals(count, delete(survey).execute()); + } + + @Test + @IncludeIn({CUBRID, H2, MYSQL, ORACLE, SQLSERVER}) + public void delete_limit() { + insert(survey).values(2, "A","B").execute(); + insert(survey).values(3, "B","C").execute(); + insert(survey).values(4, "D","E").execute(); + + assertEquals(2, delete(survey).limit(2).execute()); + } + + @Test + public void delete_with_subQuery_exists() { + QSurvey survey1 = new QSurvey("s1"); + QEmployee employee = new QEmployee("e"); + SQLDeleteClause delete = delete(survey1); + delete.where(survey1.name.eq("XXX"), + query().from(employee).where(survey1.id.eq(employee.id)).exists()); + assertEquals(0, delete.execute()); + } + + @Test + public void delete_with_subQuery_exists_Params() { + QSurvey survey1 = new QSurvey("s1"); + QEmployee employee = new QEmployee("e"); + + Param param = new Param(Integer.class, "param"); + SQLQuery sq = query().from(employee).where(employee.id.eq(param)); + sq.set(param, -12478923); + + SQLDeleteClause delete = delete(survey1); + delete.where(survey1.name.eq("XXX"), sq.exists()); + assertEquals(0, delete.execute()); + } + + @Test + public void delete_with_subQuery_exists2() { + QSurvey survey1 = new QSurvey("s1"); + QEmployee employee = new QEmployee("e"); + SQLDeleteClause delete = delete(survey1); + delete.where(survey1.name.eq("XXX"), + query().from(employee).where(survey1.name.eq(employee.lastname)).exists()); + assertEquals(0, delete.execute()); + } + + + @Test + @ExcludeIn({CUBRID, SQLITE}) + public void delete_with_tempateExpression_in_batch() { + assertEquals(1, delete(survey) + .where(survey.name.eq(Expressions.stringTemplate("'Hello World'"))) + .addBatch() + .execute()); + } + + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/DependenciesTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/DependenciesTest.java new file mode 100644 index 0000000000..4c7a467664 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/DependenciesTest.java @@ -0,0 +1,45 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import static org.junit.Assert.assertFalse; + +import java.io.IOException; + +import org.junit.Ignore; +import org.junit.Test; + +import jdepend.framework.JDepend; + +public class DependenciesTest { + + @Test + @Ignore + public void test() throws IOException { + JDepend jdepend = new JDepend(); + jdepend.addDirectory("target/classes/com/querydsl/sql"); + jdepend.addDirectory("target/classes/com/querydsl/sql/ddl"); + jdepend.addDirectory("target/classes/com/querydsl/sql/dml"); + jdepend.addDirectory("target/classes/com/querydsl/sql/mssql"); + jdepend.addDirectory("target/classes/com/querydsl/sql/mysql"); + jdepend.addDirectory("target/classes/com/querydsl/sql/oracle"); + jdepend.addDirectory("target/classes/com/querydsl/sql/support"); + jdepend.addDirectory("target/classes/com/querydsl/sql/types"); + + jdepend.analyze(); + assertFalse(jdepend.containsCycles()); + + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/DerbyTemplatesTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/DerbyTemplatesTest.java new file mode 100644 index 0000000000..2fd176dcb1 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/DerbyTemplatesTest.java @@ -0,0 +1,76 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +import com.querydsl.core.types.ConstantImpl; +import com.querydsl.core.types.ExpressionUtils; +import com.querydsl.core.types.Operation; +import com.querydsl.core.types.Ops; +import com.querydsl.core.types.dsl.Expressions; + +public class DerbyTemplatesTest extends AbstractSQLTemplatesTest { + + @Override + protected SQLTemplates createTemplates() { + return new DerbyTemplates(); + } + + @Test + public void nextVal() { + Operation nextval = ExpressionUtils.operation(String.class, SQLOps.NEXTVAL, ConstantImpl.create("myseq")); + assertEquals("next value for myseq", new SQLSerializer(new Configuration(new DerbyTemplates())).handle(nextval).toString()); + } + + @Test + public void precedence() { + // unary + and - + int p1 = getPrecedence(Ops.NEGATE); + // *, /, || (concatenation) + int p2 = getPrecedence(Ops.MULT, Ops.DIV); + // binary + and - + int p3 = getPrecedence(Ops.ADD, Ops.SUB); + // comparisons, quantified comparisons, EXISTS, IN, IS NULL, LIKE, BETWEEN, IS + int p4 = getPrecedence(Ops.EQ, Ops.NE, Ops.LT, Ops.GT, Ops.LOE, Ops.GOE, Ops.EXISTS, + Ops.IN, Ops.IS_NULL, Ops.LIKE, Ops.BETWEEN, Ops.IS_NOT_NULL); + // NOT + int p5 = getPrecedence(Ops.NOT); + // AND + int p6 = getPrecedence(Ops.AND); + // OR + int p7 = getPrecedence(Ops.OR); + + assertTrue(p1 < p2); + assertTrue(p2 < p3); + assertTrue(p3 < p4); + assertTrue(p4 < p5); + assertTrue(p5 < p6); + assertTrue(p6 < p7); + } + + @Test + @Override + public void booleanTemplate() { + assertSerialized(Expressions.booleanPath("b").eq(Expressions.TRUE), "b = true"); + assertSerialized(Expressions.booleanPath("b").eq(Expressions.FALSE), "b = false"); + query.setUseLiterals(true); + query.where(Expressions.booleanPath("b").eq(true)); + assertTrue(query.toString(), query.toString().endsWith("where b = true")); + } + +} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/DummyBlob.java b/querydsl-sql/src/test/java/com/querydsl/sql/DummyBlob.java similarity index 94% rename from querydsl-sql/src/test/java/com/mysema/query/sql/DummyBlob.java rename to querydsl-sql/src/test/java/com/querydsl/sql/DummyBlob.java index a024103123..ebcce2519a 100644 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/DummyBlob.java +++ b/querydsl-sql/src/test/java/com/querydsl/sql/DummyBlob.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,19 +11,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql; +package com.querydsl.sql; import java.io.InputStream; import java.io.OutputStream; import java.sql.Blob; import java.sql.SQLException; -public class DummyBlob implements Blob{ +public class DummyBlob implements Blob { @Override public void free() throws SQLException { // TODO Auto-generated method stub - + } @Override @@ -85,7 +85,7 @@ public int setBytes(long pos, byte[] bytes, int offset, int len) @Override public void truncate(long len) throws SQLException { // TODO Auto-generated method stub - + } } diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/EncryptedString.java b/querydsl-sql/src/test/java/com/querydsl/sql/EncryptedString.java new file mode 100644 index 0000000000..77083aec07 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/EncryptedString.java @@ -0,0 +1,20 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import com.querydsl.sql.types.StringType; + +public class EncryptedString extends StringType { + +} \ No newline at end of file diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/ExtendedSQLQuery.java b/querydsl-sql/src/test/java/com/querydsl/sql/ExtendedSQLQuery.java new file mode 100644 index 0000000000..b912775495 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/ExtendedSQLQuery.java @@ -0,0 +1,93 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import java.sql.Connection; +import java.util.List; + +import com.mysema.commons.lang.CloseableIterator; +import com.querydsl.core.DefaultQueryMetadata; +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.QueryResults; +import com.querydsl.core.Tuple; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.FactoryExpression; +import com.querydsl.core.types.Projections; + +/** + * @author tiwe + * + */ +public class ExtendedSQLQuery extends AbstractSQLQuery> { + + public ExtendedSQLQuery(SQLTemplates templates) { + super((Connection) null, new Configuration(templates), new DefaultQueryMetadata()); + } + + public ExtendedSQLQuery(Connection conn, SQLTemplates templates) { + super(conn, new Configuration(templates), new DefaultQueryMetadata()); + } + + public ExtendedSQLQuery(Connection conn, Configuration configuration) { + super(conn, configuration, new DefaultQueryMetadata()); + } + + public ExtendedSQLQuery(Connection conn, Configuration configuration, QueryMetadata metadata) { + super(conn, configuration, metadata); + } + + public CloseableIterator iterate(Class type, Expression... exprs) { + return select(createProjection(type, exprs)).iterate(); + } + + public RT uniqueResult(Class type, Expression... exprs) { + return select(createProjection(type, exprs)).fetchOne(); + } + + public List list(Class type, Expression... exprs) { + return select(createProjection(type, exprs)).fetch(); + } + + public QueryResults listResults(Class type, Expression... exprs) { + return select(createProjection(type, exprs)).fetchResults(); + } + + private FactoryExpression createProjection(Class type, Expression... exprs) { + return Projections.bean(type, exprs); + } + + @Override + public ExtendedSQLQuery clone(Connection connection) { + ExtendedSQLQuery query = new ExtendedSQLQuery(connection, getConfiguration(), getMetadata().clone()); + query.clone(this); + return query; + } + + @Override + public ExtendedSQLQuery select(Expression expr) { + queryMixin.setProjection(expr); + @SuppressWarnings("unchecked") // This is the new type + ExtendedSQLQuery newType = (ExtendedSQLQuery) this; + return newType; + } + + @Override + public ExtendedSQLQuery select(Expression... exprs) { + queryMixin.setProjection(exprs); + @SuppressWarnings("unchecked") // This is the new type + ExtendedSQLQuery newType = (ExtendedSQLQuery) this; + return newType; + } + +} diff --git a/querydsl-sql/src/test/java/com/mysema/query/ExtendedSQLTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/ExtendedSQLTest.java similarity index 77% rename from querydsl-sql/src/test/java/com/mysema/query/ExtendedSQLTest.java rename to querydsl-sql/src/test/java/com/querydsl/sql/ExtendedSQLTest.java index a9a070164d..de87b9e66a 100644 --- a/querydsl-sql/src/test/java/com/mysema/query/ExtendedSQLTest.java +++ b/querydsl-sql/src/test/java/com/querydsl/sql/ExtendedSQLTest.java @@ -1,16 +1,18 @@ -package com.mysema.query; +package com.querydsl.sql; + +import static org.junit.Assert.assertEquals; import java.util.Date; -import com.mysema.query.sql.*; -import com.mysema.query.sql.mysql.MySQLQuery; -import com.mysema.query.types.PathMetadataFactory; -import com.mysema.query.types.expr.Wildcard; -import com.mysema.query.types.path.DatePath; -import com.mysema.query.types.path.NumberPath; -import com.mysema.query.types.path.StringPath; import org.junit.Test; -import static org.junit.Assert.assertEquals; + +import com.querydsl.core.types.PathMetadataFactory; +import com.querydsl.core.types.Projections; +import com.querydsl.core.types.dsl.DatePath; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.StringPath; +import com.querydsl.core.types.dsl.Wildcard; +import com.querydsl.sql.mysql.MySQLQuery; public class ExtendedSQLTest { @@ -81,7 +83,7 @@ public void test() { QAuthor author = QAuthor.author; QBook book = QBook.book; - MySQLQuery query = new MySQLQuery(null); + MySQLQuery query = new MySQLQuery(null); query.from(author) .join(book).on(author.id.eq(book.authorId)) .where(book.language.eq("DE"), book.published.eq(new Date())) @@ -93,23 +95,21 @@ public void test() { .forUpdate(); // of(author.firstName, author.lastName) - query.getMetadata().addProjection(author.firstName); - query.getMetadata().addProjection(author.lastName); - query.getMetadata().addProjection(Wildcard.count); + query.getMetadata().setProjection(Projections.tuple(author.firstName, author.lastName, Wildcard.count)); SQLSerializer serializer = new SQLSerializer(new Configuration(new MySQLTemplates())); serializer.serialize(query.getMetadata(), false); - assertEquals("select author.FIRST_NAME, author.LAST_NAME, count(*)\n"+ - "from AUTHOR author\n"+ - "join BOOK book\n"+ - "on author.ID = book.AUTHOR_ID\n"+ - "where book.LANGUAGE = ? and book.PUBLISHED = ?\n"+ - "group by author.FIRST_NAME, author.LAST_NAME\n"+ - "having count(*) > ?\n"+ - "order by author.LAST_NAME asc\n"+ - "limit ?\n"+ - "offset ?\n"+ + assertEquals("select author.FIRST_NAME, author.LAST_NAME, count(*)\n" + + "from AUTHOR author\n" + + "join BOOK book\n" + + "on author.ID = book.AUTHOR_ID\n" + + "where book.LANGUAGE = ? and book.PUBLISHED = ?\n" + + "group by author.FIRST_NAME, author.LAST_NAME\n" + + "having count(*) > ?\n" + + "order by author.LAST_NAME asc\n" + + "limit ?\n" + + "offset ?\n" + "for update", serializer.toString()); } diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/FirebirdTemplatesTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/FirebirdTemplatesTest.java new file mode 100644 index 0000000000..e65ef084c7 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/FirebirdTemplatesTest.java @@ -0,0 +1,90 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import static com.querydsl.sql.SQLExpressions.select; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +import com.querydsl.core.types.Ops; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberExpression; + +public class FirebirdTemplatesTest extends AbstractSQLTemplatesTest { + + @Override + protected SQLTemplates createTemplates() { + return new FirebirdTemplates(); + } + + @Override + public void arithmetic() { + // uses additional casts + } + + @SuppressWarnings("unchecked") + @Test + @Override + public void union() { + NumberExpression one = Expressions.ONE; + NumberExpression two = Expressions.TWO; + NumberExpression three = Expressions.THREE; + Path col1 = Expressions.numberPath(Integer.class,"col1"); + Union union = query.union( + select(one.as(col1)), + select(two), + select(three)); + + assertEquals( + "select 1 as col1 from RDB$DATABASE\n" + + "union\n" + + "select 2 from RDB$DATABASE\n" + + "union\n" + + "select 3 from RDB$DATABASE", union.toString()); + } + + @Test + public void precedence() { + // concat + // *, /, +, - + // comparison + // NOT + // AND + // OR + + int p1 = getPrecedence(Ops.CONCAT); + int p2 = getPrecedence(Ops.NEGATE); + int p3 = getPrecedence(Ops.MULT, Ops.DIV); + int p4 = getPrecedence(Ops.SUB, Ops.ADD); + int p5 = getPrecedence(Ops.EQ, Ops.GOE, Ops.GT, Ops.LT, Ops.NE, Ops.IS_NULL, Ops.IS_NOT_NULL, + Ops.MATCHES, Ops.IN, Ops.LIKE, Ops.LIKE_ESCAPE, Ops.BETWEEN); + int p6 = getPrecedence(Ops.NOT); + int p7 = getPrecedence(Ops.AND); + int p8 = getPrecedence(Ops.XOR, Ops.XNOR); + int p9 = getPrecedence(Ops.OR); + + assertTrue(p1 < p2); + assertTrue(p2 < p3); + assertTrue(p3 < p4); + assertTrue(p4 < p5); + assertTrue(p5 < p6); + assertTrue(p6 < p7); + assertTrue(p7 < p8); + assertTrue(p8 < p9); + } + +} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/ForeignKeyTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/ForeignKeyTest.java similarity index 77% rename from querydsl-sql/src/test/java/com/mysema/query/sql/ForeignKeyTest.java rename to querydsl-sql/src/test/java/com/querydsl/sql/ForeignKeyTest.java index d62c1451a9..08bca342b8 100644 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/ForeignKeyTest.java +++ b/querydsl-sql/src/test/java/com/querydsl/sql/ForeignKeyTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2011, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,20 +11,21 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql; +package com.querydsl.sql; import static org.junit.Assert.assertEquals; import org.junit.Test; -import com.google.common.collect.ImmutableList; -import com.mysema.query.sql.domain.Employee; -import com.mysema.query.sql.domain.QEmployee; +import com.querydsl.sql.domain.Employee; +import com.querydsl.sql.domain.QEmployee; + +import java.util.Arrays; public class ForeignKeyTest { @Test - public void On() { + public void on() { QEmployee employee = new QEmployee("employee"); QEmployee employee2 = new QEmployee("employee2"); @@ -32,8 +33,8 @@ public void On() { assertEquals("employee.superiorId = employee2.ID", foreignKey.on(employee2).toString()); foreignKey = new ForeignKey(employee, - ImmutableList.of(employee.superiorId, employee.firstname), - ImmutableList.of("ID", "FN")); + Arrays.asList(employee.superiorId, employee.firstname), + Arrays.asList("ID", "FN")); assertEquals("employee.superiorId = employee2.ID && employee.firstname = employee2.FN", foreignKey.on(employee2).toString()); } diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/H2TemplatesTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/H2TemplatesTest.java new file mode 100644 index 0000000000..41f398255a --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/H2TemplatesTest.java @@ -0,0 +1,67 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +import com.querydsl.core.types.Ops; + +public class H2TemplatesTest extends AbstractSQLTemplatesTest { + + @Override + protected SQLTemplates createTemplates() { + return new H2Templates(); + } + + @Test + public void builder() { + SQLTemplates templates = H2Templates.builder().quote() + .newLineToSingleSpace() + .build(); + + assertNotNull(templates); + } + + @Test + public void precedence() { + // unary + // *, /, % + // +, - + // || + // comparison + // NOT + // AND + // OR + + int p1 = getPrecedence(Ops.NEGATE); + int p2 = getPrecedence(Ops.MULT, Ops.DIV, Ops.MOD); + int p3 = getPrecedence(Ops.ADD, Ops.SUB); + int p4 = getPrecedence(Ops.CONCAT); + int p5 = getPrecedence(Ops.EQ, Ops.NE, Ops.LT, Ops.GT); // ... + int p6 = getPrecedence(Ops.NOT); + int p7 = getPrecedence(Ops.AND); + int p8 = getPrecedence(Ops.OR); + + assertTrue(p1 < p2); + assertTrue(p2 < p3); + assertTrue(p3 < p4); + assertTrue(p4 < p5); + assertTrue(p5 < p6); + assertTrue(p6 < p7); + assertTrue(p7 < p8); + } +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/HSQLDBTemplatesTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/HSQLDBTemplatesTest.java new file mode 100644 index 0000000000..bcbb75971e --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/HSQLDBTemplatesTest.java @@ -0,0 +1,56 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +import com.querydsl.core.types.Ops; + +public class HSQLDBTemplatesTest extends AbstractSQLTemplatesTest { + + @Override + protected SQLTemplates createTemplates() { + return new HSQLDBTemplates(); + } + + @Test + public void precedence() { + // Evaluation from left to right. Parentheses group operations. + // Multiplication and division take precedence over addition and subtraction. + // AND takes precedence over OR. + // NOT applies to the immediate term. + // LIKE applies to the result of any string concatenation to the right. + // Comparison ops are not combined without logical ops so there is no precedence issue. + + //int p1 = getPrecedence(Ops.NEGATE); + int p2 = getPrecedence(Ops.MULT, Ops.DIV, Ops.CONCAT); + int p3 = getPrecedence(Ops.ADD, Ops.SUB); + int p4 = getPrecedence(Ops.NOT); + int p5 = getPrecedence(Ops.EQ, Ops.NE, Ops.LT, Ops.GT, Ops.LOE, Ops.GOE); + int p6 = getPrecedence(Ops.IS_NULL, Ops.IS_NOT_NULL, Ops.LIKE, Ops.LIKE_ESCAPE, Ops.BETWEEN, Ops.IN, Ops.NOT_IN, Ops.EXISTS); + int p7 = getPrecedence(Ops.AND); + int p8 = getPrecedence(Ops.OR); + + //assertTrue(p1 < p2); + assertTrue(p2 < p3); + assertTrue(p3 < p4); + assertTrue(p4 < p5); + assertTrue(p5 < p6); + assertTrue(p6 < p7); + assertTrue(p7 < p8); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/InsertBase.java b/querydsl-sql/src/test/java/com/querydsl/sql/InsertBase.java new file mode 100644 index 0000000000..91c7ed19e7 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/InsertBase.java @@ -0,0 +1,511 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import static com.querydsl.core.Target.*; +import static com.querydsl.sql.Constants.survey; +import static com.querydsl.sql.Constants.survey2; +import static com.querydsl.sql.SQLExpressions.select; +import static org.junit.Assert.*; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.UUID; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.joda.time.DateTime; +import org.joda.time.LocalDate; +import org.junit.After; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; + +import com.querydsl.core.QueryException; +import com.querydsl.core.QueryFlag.Position; +import com.querydsl.core.Tuple; +import com.querydsl.core.testutil.ExcludeIn; +import com.querydsl.core.testutil.IncludeIn; +import com.querydsl.core.types.ExpressionUtils; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.Param; +import com.querydsl.sql.dml.DefaultMapper; +import com.querydsl.sql.dml.Mapper; +import com.querydsl.sql.dml.SQLInsertClause; +import com.querydsl.sql.domain.*; + +public class InsertBase extends AbstractBaseTest { + + private void reset() throws SQLException { + delete(survey).execute(); + insert(survey).values(1, "Hello World", "Hello").execute(); + + delete(QDateTest.qDateTest).execute(); + } + + @Before + public void setUp() throws SQLException { + reset(); + } + + @After + public void tearDown() throws SQLException { + reset(); + } + + @Test + @ExcludeIn({CUBRID, SQLITE}) // https://bitbucket.org/xerial/sqlite-jdbc/issue/133/prepstmtsetdate-int-date-calendar-seems + public void insert_dates() { + QDateTest dateTest = QDateTest.qDateTest; + LocalDate localDate = new LocalDate(1978, 1, 2); + + Path localDateProperty = ExpressionUtils.path(LocalDate.class, "DATE_TEST"); + Path dateTimeProperty = ExpressionUtils.path(DateTime.class, "DATE_TEST"); + SQLInsertClause insert = insert(dateTest); + insert.set(localDateProperty, localDate); + insert.execute(); + + Tuple result = query().from(dateTest).select( + dateTest.dateTest.year(), + dateTest.dateTest.month(), + dateTest.dateTest.dayOfMonth(), + dateTimeProperty).fetchFirst(); + assertEquals(Integer.valueOf(1978), result.get(0, Integer.class)); + assertEquals(Integer.valueOf(1), result.get(1, Integer.class)); + assertEquals(Integer.valueOf(2), result.get(2, Integer.class)); + + DateTime dateTime = result.get(dateTimeProperty); + if (target == CUBRID) { + // XXX Cubrid adds random milliseconds for some reason + dateTime = dateTime.withMillisOfSecond(0); + } + assertEquals(localDate.toDateTimeAtStartOfDay(), dateTime); + } + + @Test + public void complex1() { + // related to #584795 + QSurvey survey = new QSurvey("survey"); + QEmployee emp1 = new QEmployee("emp1"); + QEmployee emp2 = new QEmployee("emp2"); + SQLInsertClause insert = insert(survey); + insert.columns(survey.id, survey.name); + insert.select(select(survey.id, emp2.firstname).from(survey) + .innerJoin(emp1) + .on(survey.id.eq(emp1.id)) + .innerJoin(emp2) + .on(emp1.superiorId.eq(emp2.superiorId), emp1.firstname.eq(emp2.firstname))); + + assertEquals(0, insert.execute()); + } + + @Test + public void insert_alternative_syntax() { + // with columns + assertEquals(1, insert(survey) + .set(survey.id, 3) + .set(survey.name, "Hello") + .execute()); + } + + @Test + public void insert_batch() { + SQLInsertClause insert = insert(survey) + .set(survey.id, 5) + .set(survey.name, "55") + .addBatch(); + + assertEquals(1, insert.getBatchCount()); + + insert.set(survey.id, 6) + .set(survey.name, "66") + .addBatch(); + + assertEquals(2, insert.getBatchCount()); + assertEquals(2, insert.execute()); + + assertEquals(1L, query().from(survey).where(survey.name.eq("55")).fetchCount()); + assertEquals(1L, query().from(survey).where(survey.name.eq("66")).fetchCount()); + } + + @Test + public void insert_batch_to_bulk() { + SQLInsertClause insert = insert(survey); + insert.setBatchToBulk(true); + + insert.set(survey.id, 5) + .set(survey.name, "55") + .addBatch(); + + assertEquals(1, insert.getBatchCount()); + + insert.set(survey.id, 6) + .set(survey.name, "66") + .addBatch(); + + assertEquals(2, insert.getBatchCount()); + assertEquals(2, insert.execute()); + + assertEquals(1L, query().from(survey).where(survey.name.eq("55")).fetchCount()); + assertEquals(1L, query().from(survey).where(survey.name.eq("66")).fetchCount()); + } + + @Test + public void insert_batch_Templates() { + SQLInsertClause insert = insert(survey) + .set(survey.id, 5) + .set(survey.name, Expressions.stringTemplate("'55'")) + .addBatch(); + + insert.set(survey.id, 6) + .set(survey.name, Expressions.stringTemplate("'66'")) + .addBatch(); + + assertEquals(2, insert.execute()); + + assertEquals(1L, query().from(survey).where(survey.name.eq("55")).fetchCount()); + assertEquals(1L, query().from(survey).where(survey.name.eq("66")).fetchCount()); + } + + @Test + public void insert_batch2() { + SQLInsertClause insert = insert(survey) + .set(survey.id, 5) + .set(survey.name, "55") + .addBatch(); + + insert.set(survey.id, 6) + .setNull(survey.name) + .addBatch(); + + assertEquals(2, insert.execute()); + } + + @Test + public void insert_null_with_columns() { + assertEquals(1, insert(survey) + .columns(survey.id, survey.name) + .values(3, null).execute()); + } + + @Test + @ExcludeIn({DB2, DERBY}) + public void insert_null_without_columns() { + assertEquals(1, insert(survey) + .values(4, null, null).execute()); + } + + @Test + @ExcludeIn({FIREBIRD, HSQLDB, DB2, DERBY, ORACLE}) + public void insert_without_values() { + assertEquals(1, insert(survey).execute()); + } + + @Test + @ExcludeIn(ORACLE) + public void insert_nulls_in_batch() { +// QFoo f= QFoo.foo; +// SQLInsertClause sic = new SQLInsertClause(c, new H2Templates(), f); +// sic.columns(f.c1,f.c2).values(null,null).addBatch(); +// sic.columns(f.c1,f.c2).values(null,1).addBatch(); +// sic.execute(); + SQLInsertClause sic = insert(survey); + sic.columns(survey.name, survey.name2).values(null, null).addBatch(); + sic.columns(survey.name, survey.name2).values(null, "X").addBatch(); + assertEquals(2, sic.execute()); + } + + @Test + @Ignore + @ExcludeIn({DERBY}) + public void insert_nulls_in_batch2() { + Mapper mapper = DefaultMapper.WITH_NULL_BINDINGS; +// QFoo f= QFoo.foo; +// SQLInsertClause sic = new SQLInsertClause(c, new H2Templates(), f); +// Foo f1=new Foo(); +// sic.populate(f1).addBatch(); +// f1=new Foo(); +// f1.setC1(1); +// sic.populate(f1).addBatch(); +// sic.execute(); + QEmployee employee = QEmployee.employee; + SQLInsertClause sic = insert(employee); + Employee e = new Employee(); + sic.populate(e, mapper).addBatch(); + e = new Employee(); + e.setFirstname("X"); + sic.populate(e, mapper).addBatch(); + assertEquals(0, sic.execute()); + + } + + @Test + public void insert_with_columns() { + assertEquals(1, insert(survey) + .columns(survey.id, survey.name) + .values(3, "Hello").execute()); + } + + @Test + @ExcludeIn({CUBRID, SQLSERVER}) + public void insert_with_keys() throws SQLException { + ResultSet rs = insert(survey).set(survey.name, "Hello World").executeWithKeys(); + assertTrue(rs.next()); + assertTrue(rs.getObject(1) != null); + rs.close(); + } + + @Test + @ExcludeIn({CUBRID, SQLSERVER}) + public void insert_with_keys_listener() throws SQLException { + final AtomicBoolean result = new AtomicBoolean(); + SQLListener listener = new SQLBaseListener() { + @Override + public void end(SQLListenerContext context) { + result.set(true); + } + }; + SQLInsertClause clause = insert(survey).set(survey.name, "Hello World"); + clause.addListener(listener); + ResultSet rs = clause.executeWithKeys(); + assertFalse(result.get()); + assertTrue(rs.next()); + assertTrue(rs.getObject(1) != null); + rs.close(); + assertTrue(result.get()); + } + + @Test + @ExcludeIn({CUBRID, SQLSERVER}) + public void insert_with_keys_Projected() throws SQLException { + assertNotNull(insert(survey).set(survey.name, "Hello you").executeWithKey(survey.id)); + } + + @Test + @ExcludeIn({CUBRID, SQLSERVER}) + public void insert_with_keys_Projected2() throws SQLException { + Path idPath = ExpressionUtils.path(Object.class, "id"); + Object id = insert(survey).set(survey.name, "Hello you").executeWithKey(idPath); + assertNotNull(id); + } + + @Test(expected = QueryException.class) + @IncludeIn({DERBY, HSQLDB}) + public void insert_with_keys_OverriddenColumn() throws SQLException { + String originalColumnName = ColumnMetadata.getName(survey.id); + try { + configuration.registerColumnOverride(survey.getSchemaName(), survey.getTableName(), + originalColumnName, "wrongColumnName"); + + SQLInsertClause sqlInsertClause = new SQLInsertClause(connection, configuration, survey); + sqlInsertClause.addListener(new TestLoggingListener()); + Object id = sqlInsertClause.set(survey.name, "Hello you").executeWithKey(survey.id); + assertNotNull(id); + } finally { + configuration.registerColumnOverride(survey.getSchemaName(), survey.getTableName(), + originalColumnName, originalColumnName); + } + } + + // http://sourceforge.net/tracker/index.php?func=detail&aid=3513432&group_id=280608&atid=2377440 + + @Test + public void insert_with_set() { + assertEquals(1, insert(survey) + .set(survey.id, 5) + .set(survey.name, (String) null) + .execute()); + } + + @Test + @IncludeIn(MYSQL) + @SkipForQuoted + public void insert_with_special_options() { + SQLInsertClause clause = insert(survey) + .columns(survey.id, survey.name) + .values(3, "Hello"); + + clause.addFlag(Position.START_OVERRIDE, "insert ignore into "); + + assertEquals("insert ignore into SURVEY (ID, NAME) values (?, ?)", clause.toString()); + assertEquals(1, clause.execute()); + } + + @Test + @ExcludeIn(FIREBIRD) // too slow + public void insert_with_subQuery() { + int count = (int) query().from(survey).fetchCount(); + assertEquals(count, insert(survey) + .columns(survey.id, survey.name) + .select(query().from(survey2).select(survey2.id.add(20), survey2.name)) + .execute()); + } + + @Test + @ExcludeIn({DB2, HSQLDB, CUBRID, DERBY, FIREBIRD}) + public void insert_with_subQuery2() { +// insert into modules(name) +// select 'MyModule' +// where not exists +// (select 1 from modules where modules.name = 'MyModule') + + assertEquals(1, insert(survey).set(survey.name, + query().where(query().from(survey2) + .where(survey2.name.eq("MyModule")).notExists()) + .select(Expressions.constant("MyModule")).fetchFirst()) + .execute()); + + assertEquals(1L, query().from(survey).where(survey.name.eq("MyModule")).fetchCount()); + } + + @Test + @ExcludeIn({HSQLDB, CUBRID, DERBY}) + public void insert_with_subQuery3() { +// insert into modules(name) +// select 'MyModule' +// where not exists +// (select 1 from modules where modules.name = 'MyModule') + + assertEquals(1, insert(survey).columns(survey.name).select( + query().where(query().from(survey2) + .where(survey2.name.eq("MyModule2")).notExists()) + .select(Expressions.constant("MyModule2"))) + .execute()); + + assertEquals(1L, query().from(survey).where(survey.name.eq("MyModule2")).fetchCount()); + } + + @Test + @ExcludeIn(FIREBIRD) // too slow + public void insert_with_subQuery_Params() { + Param param = new Param(Integer.class, "param"); + SQLQuery sq = query().from(survey2); + sq.set(param, 20); + + int count = (int) query().from(survey).fetchCount(); + assertEquals(count, insert(survey) + .columns(survey.id, survey.name) + .select(sq.select(survey2.id.add(param), survey2.name)) + .execute()); + } + + @Test + @ExcludeIn(FIREBIRD) // too slow + public void insert_with_subQuery_Via_Constructor() { + int count = (int) query().from(survey).fetchCount(); + SQLInsertClause insert = insert(survey, query().from(survey2)); + insert.set(survey.id, survey2.id.add(20)); + insert.set(survey.name, survey2.name); + assertEquals(count, insert.execute()); + } + + @Test + @ExcludeIn(FIREBIRD) // too slow + public void insert_with_subQuery_Without_Columns() { + int count = (int) query().from(survey).fetchCount(); + assertEquals(count, insert(survey) + .select(query().from(survey2).select(survey2.id.add(10), survey2.name, survey2.name2)) + .execute()); + + } + + @Test + @ExcludeIn(FIREBIRD) // too slow + public void insert_without_columns() { + assertEquals(1, insert(survey).values(4, "Hello", "World").execute()); + + } + + @Test + @ExcludeIn(FIREBIRD) // too slow + public void insertBatch_with_subquery() { + SQLInsertClause insert = insert(survey) + .columns(survey.id, survey.name) + .select(query().from(survey2).select(survey2.id.add(20), survey2.name)) + .addBatch(); + + insert(survey) + .columns(survey.id, survey.name) + .select(query().from(survey2).select(survey2.id.add(40), survey2.name)) + .addBatch(); + + assertEquals(1, insert.execute()); + } + + @Test + public void like() { + insert(survey).values(11, "Hello World", "a\\b").execute(); + assertEquals(1L, query().from(survey).where(survey.name2.contains("a\\b")).fetchCount()); + } + + @Test + public void like_with_escape() { + SQLInsertClause insert = insert(survey); + insert.set(survey.id, 5).set(survey.name, "aaa").addBatch(); + insert.set(survey.id, 6).set(survey.name, "a_").addBatch(); + insert.set(survey.id, 7).set(survey.name, "a%").addBatch(); + assertEquals(3, insert.execute()); + + assertEquals(1L, query().from(survey).where(survey.name.like("a|%", '|')).fetchCount()); + assertEquals(1L, query().from(survey).where(survey.name.like("a|_", '|')).fetchCount()); + assertEquals(3L, query().from(survey).where(survey.name.like("a%")).fetchCount()); + assertEquals(2L, query().from(survey).where(survey.name.like("a_")).fetchCount()); + + assertEquals(1L, query().from(survey).where(survey.name.startsWith("a_")).fetchCount()); + assertEquals(1L, query().from(survey).where(survey.name.startsWith("a%")).fetchCount()); + } + + @Test + @IncludeIn(MYSQL) + @SkipForQuoted + public void replace() { + SQLInsertClause clause = mysqlReplace(survey); + clause.columns(survey.id, survey.name) + .values(3, "Hello"); + + assertEquals("replace into SURVEY (ID, NAME) values (?, ?)", clause.toString()); + clause.execute(); + } + + @Test + public void insert_with_tempateExpression_in_batch() { + assertEquals(1, insert(survey) + .set(survey.id, 3) + .set(survey.name, Expressions.stringTemplate("'Hello'")) + .addBatch() + .execute()); + } + + @Test + @IncludeIn({H2, POSTGRESQL}) + @SkipForQuoted + public void uuids() { + delete(QUuids.uuids).execute(); + QUuids uuids = QUuids.uuids; + UUID uuid = UUID.randomUUID(); + insert(uuids).set(uuids.field, uuid).execute(); + assertEquals(uuid, query().from(uuids).select(uuids.field).fetchFirst()); + } + + @Test + @ExcludeIn({ORACLE}) + public void xml() { + delete(QXmlTest.xmlTest).execute(); + QXmlTest xmlTest = QXmlTest.xmlTest; + String contents = "ab"; + insert(xmlTest).set(xmlTest.col, contents).execute(); + assertEquals(contents, query().from(xmlTest).select(xmlTest.col).fetchFirst()); + } + +} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/JDBCTypeMappingTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/JDBCTypeMappingTest.java similarity index 75% rename from querydsl-sql/src/test/java/com/mysema/query/sql/JDBCTypeMappingTest.java rename to querydsl-sql/src/test/java/com/querydsl/sql/JDBCTypeMappingTest.java index 64b36ea829..808f3f84eb 100644 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/JDBCTypeMappingTest.java +++ b/querydsl-sql/src/test/java/com/querydsl/sql/JDBCTypeMappingTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2011, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql; +package com.querydsl.sql; import static org.junit.Assert.assertEquals; @@ -21,19 +21,22 @@ import java.sql.Types; import org.junit.Test; +import org.junit.experimental.categories.Category; + +import com.querydsl.core.testutil.ReportingOnly; public class JDBCTypeMappingTest { private JDBCTypeMapping typeMapping = new JDBCTypeMapping(); @Test - public void Get() { + public void get() { assertEquals(Float.class, typeMapping.get(Types.FLOAT,0,0)); assertEquals(Float.class, typeMapping.get(Types.REAL,0,0)); } @Test - public void StringTypes() { + public void stringTypes() { assertEquals(String.class, typeMapping.get(Types.CHAR,0,0)); assertEquals(String.class, typeMapping.get(Types.NCHAR,0,0)); assertEquals(String.class, typeMapping.get(Types.CLOB,0,0)); @@ -46,28 +49,26 @@ public void StringTypes() { } @Test - public void BlobTypes() { + public void blobTypes() { assertEquals(Blob.class, typeMapping.get(Types.BLOB,0,0)); } @Test - public void BytesTypes() { + public void bytesTypes() { assertEquals(byte[].class, typeMapping.get(Types.BINARY,0,0)); assertEquals(byte[].class, typeMapping.get(Types.VARBINARY,0,0)); assertEquals(byte[].class, typeMapping.get(Types.LONGVARBINARY,0,0)); } @Test - public void NumericTypes() { + public void numericTypes() { // 19,0 -> BigInteger // 10-18,0 -> Long // 5-9,0 -> Integer // 3-4,0 -> Short -// 2,0 -> Byte -// 0-1,0 -> Boolean +// 1-2,0 -> Byte -// 17-...,? -> BigDecimal -// 0-16,? -> Double +// ?,? -> BigDecimal assertEquals(typeMapping.get(Types.NUMERIC, 20, 0), BigInteger.class); assertEquals(typeMapping.get(Types.NUMERIC, 19, 0), BigInteger.class); assertEquals(typeMapping.get(Types.NUMERIC, 15, 0), Long.class); @@ -80,11 +81,12 @@ public void NumericTypes() { assertEquals(typeMapping.get(Types.NUMERIC, 0, 0), BigInteger.class); assertEquals(typeMapping.get(Types.NUMERIC, 17, 2), BigDecimal.class); - assertEquals(typeMapping.get(Types.NUMERIC, 5, 2), Double.class); + assertEquals(typeMapping.get(Types.NUMERIC, 5, 2), BigDecimal.class); } @Test - public void Max() { + @Category(ReportingOnly.class) + public void max() { System.err.println("Byte: " + String.valueOf(Byte.MAX_VALUE).length()); System.err.println("Short: " + String.valueOf(Short.MAX_VALUE).length()); System.err.println("Integer: " + String.valueOf(Integer.MAX_VALUE).length()); @@ -92,9 +94,23 @@ public void Max() { } @Test - public void NumericOverriden() { + public void numericOverriden() { typeMapping.registerNumeric(19, 0, BigInteger.class); assertEquals(typeMapping.get(Types.NUMERIC, 19, 0), BigInteger.class); } + @Test + public void numericOverriden2() { + typeMapping.registerNumeric(19, 0, BigInteger.class); + assertEquals(typeMapping.get(Types.INTEGER, 19, 0), BigInteger.class); + assertEquals(typeMapping.get(Types.INTEGER, 18, 0), Integer.class); + } + + @Test + public void numericOverriden3() { + typeMapping.registerNumeric(5, 2, BigDecimal.class); + assertEquals(typeMapping.get(Types.DOUBLE, 5, 2), BigDecimal.class); + assertEquals(typeMapping.get(Types.DOUBLE, 5, 1), Double.class); + } + } diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/JavaTypeMappingTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/JavaTypeMappingTest.java new file mode 100644 index 0000000000..c72bea501a --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/JavaTypeMappingTest.java @@ -0,0 +1,59 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.io.FileInputStream; +import java.io.InputStream; + +import org.junit.Test; + +import com.querydsl.sql.types.*; + +public class JavaTypeMappingTest { + + private JavaTypeMapping typeMapping = new JavaTypeMapping(); + + @Test + public void getType_with_subtypes() { + typeMapping.register(new InputStreamType()); + assertNotNull(typeMapping.getType(InputStream.class)); + assertNotNull(typeMapping.getType(FileInputStream.class)); + } + + @Test + public void getType_with_interfaces() { + assertEquals(BlobType.class, typeMapping.getType(DummyBlob.class).getClass()); + } + + @Test + public void getType_for_object() { + assertEquals(ObjectType.class, typeMapping.getType(Object.class).getClass()); + } + + @Test + public void getType_for_primitive() { + assertEquals(ByteType.class, typeMapping.getType(byte.class).getClass()); + assertEquals(ShortType.class, typeMapping.getType(short.class).getClass()); + assertEquals(IntegerType.class, typeMapping.getType(int.class).getClass()); + assertEquals(LongType.class, typeMapping.getType(long.class).getClass()); + assertEquals(FloatType.class, typeMapping.getType(float.class).getClass()); + assertEquals(DoubleType.class, typeMapping.getType(double.class).getClass()); + assertEquals(BooleanType.class, typeMapping.getType(boolean.class).getClass()); + assertEquals(CharacterType.class, typeMapping.getType(char.class).getClass()); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/JoinFlagsTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/JoinFlagsTest.java new file mode 100644 index 0000000000..2b389e4293 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/JoinFlagsTest.java @@ -0,0 +1,103 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import static org.junit.Assert.assertEquals; + +import java.sql.Connection; + +import org.easymock.EasyMock; +import org.junit.Before; +import org.junit.Test; + +import com.querydsl.core.JoinFlag; +import com.querydsl.sql.domain.QSurvey; + +public class JoinFlagsTest { + + private Connection connection = EasyMock.createMock(Connection.class); + + private QSurvey s1, s2, s3, s4, s5, s6; + + private SQLQuery query; + + @SuppressWarnings("unchecked") + @Before + public void setUp() { + s1 = new QSurvey("s"); + s2 = new QSurvey("s2"); + s3 = new QSurvey("s3"); + s4 = new QSurvey("s4"); + s5 = new QSurvey("s5"); + s6 = new QSurvey("s6"); + query = new SQLQuery(connection,SQLTemplates.DEFAULT); + query.from(s1); + } + + @SuppressWarnings("unchecked") + @Test + public void joinFlags_beforeCondition() { + query.innerJoin(s2).on(s1.eq(s2)); + query.addJoinFlag(" a ", JoinFlag.Position.BEFORE_CONDITION); + + assertEquals("from SURVEY s\n" + + "inner join SURVEY s2 a \n" + + "on s.ID = s2.ID", query.toString()); + } + + @SuppressWarnings("unchecked") + @Test + public void joinFlags_beforeTarget() { + query.innerJoin(s3).on(s1.eq(s3)); + query.addJoinFlag(" b ", JoinFlag.Position.BEFORE_TARGET); + + assertEquals("from SURVEY s\n" + + "inner join b SURVEY s3\n" + + "on s.ID = s3.ID", query.toString()); + } + + @SuppressWarnings("unchecked") + @Test + public void joinFlags_end() { + query.innerJoin(s4).on(s1.eq(s4)); + query.addJoinFlag(" c ", JoinFlag.Position.END); + + assertEquals("from SURVEY s\n" + + "inner join SURVEY s4\n" + + "on s.ID = s4.ID c", query.toString()); + } + + @SuppressWarnings("unchecked") + @Test + public void joinFlags_override() { + query.innerJoin(s5).on(s1.eq(s5)); + query.addJoinFlag(" d ", JoinFlag.Position.OVERRIDE); + + assertEquals("from SURVEY s d SURVEY s5\n" + + "on s.ID = s5.ID", query.toString()); + } + + @SuppressWarnings("unchecked") + @Test + public void joinFlags_start() { + query.innerJoin(s6).on(s1.eq(s6)); + query.addJoinFlag(" e ", JoinFlag.Position.START); + + assertEquals("from SURVEY s e \n" + + "inner join SURVEY s6\n" + + "on s.ID = s6.ID", query.toString()); + } + + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/JoinUsageTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/JoinUsageTest.java new file mode 100644 index 0000000000..be545bfb94 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/JoinUsageTest.java @@ -0,0 +1,32 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import static com.querydsl.sql.SQLExpressions.selectFrom; + +import org.junit.Ignore; +import org.junit.Test; + +import com.querydsl.sql.domain.QSurvey; + +public class JoinUsageTest { + + @Test(expected = IllegalStateException.class) + @Ignore + public void join_already_declared() { + QSurvey survey = QSurvey.survey; + selectFrom(survey).fullJoin(survey); + } + +} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/KeyAccessorsTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/KeyAccessorsTest.java similarity index 90% rename from querydsl-sql/src/test/java/com/mysema/query/sql/KeyAccessorsTest.java rename to querydsl-sql/src/test/java/com/querydsl/sql/KeyAccessorsTest.java index a709cdac27..70e6705b7a 100644 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/KeyAccessorsTest.java +++ b/querydsl-sql/src/test/java/com/querydsl/sql/KeyAccessorsTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2011, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,14 +11,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql; +package com.querydsl.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; +import static org.junit.Assert.assertNotNull; import java.io.Serializable; -import com.mysema.query.types.path.NumberPath; import org.junit.Test; -import static com.mysema.query.types.PathMetadataFactory.forVariable; -import static org.junit.Assert.assertNotNull; + +import com.querydsl.core.types.dsl.NumberPath; public class KeyAccessorsTest { @@ -68,7 +70,7 @@ protected void addMetadata() { } @Test - public void Keys() { + public void keys() { QEmployee employee = QEmployee.employee; assertNotNull(employee.pk.sysIdx53); assertNotNull(employee.fk.superiorFk); diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/KeyTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/KeyTest.java similarity index 89% rename from querydsl-sql/src/test/java/com/mysema/query/sql/KeyTest.java rename to querydsl-sql/src/test/java/com/querydsl/sql/KeyTest.java index 241eebb678..f33567f6fc 100644 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/KeyTest.java +++ b/querydsl-sql/src/test/java/com/querydsl/sql/KeyTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2011, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,18 +11,20 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql; +package com.querydsl.sql; + +import static com.querydsl.sql.SQLExpressions.selectOne; import org.junit.Test; -import com.mysema.query.types.PathMetadataFactory; -import com.mysema.query.types.path.NumberPath; +import com.querydsl.core.types.PathMetadataFactory; +import com.querydsl.core.types.dsl.NumberPath; @SuppressWarnings("serial") public class KeyTest { // @Table("USER") - public static class QUser extends RelationalPathBase{ + public static class QUser extends RelationalPathBase { public final NumberPath id = createNumber("id", Integer.class); @@ -98,16 +100,12 @@ public void test() { QCompany company = new QCompany("company"); // superiorId -> id - query().from(user).innerJoin(user.superiorIdKey, user2); + selectOne().from(user).innerJoin(user.superiorIdKey, user2); // department -> id / company -> id - query().from(user) + selectOne().from(user) .innerJoin(user.departmentKey, department) .innerJoin(department.companyKey, company); } - private SQLQuery query() { - return new SQLQuery(SQLTemplates.DEFAULT); - } - } diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/KeywordQuotingBase.java b/querydsl-sql/src/test/java/com/querydsl/sql/KeywordQuotingBase.java new file mode 100644 index 0000000000..cb5a2b04ff --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/KeywordQuotingBase.java @@ -0,0 +1,85 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team). + * + * 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. + */ +package com.querydsl.sql; + + +import static org.junit.Assert.assertEquals; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.PathMetadataFactory; +import com.querydsl.core.types.dsl.BooleanPath; +import com.querydsl.core.types.dsl.StringPath; +import com.querydsl.sql.ddl.CreateTableClause; +import com.querydsl.sql.ddl.DropTableClause; + +public class KeywordQuotingBase extends AbstractBaseTest { + + private static class Quoting extends RelationalPathBase { + + public static final Quoting quoting = new Quoting("quoting"); + + public final StringPath from = createString("from"); + public final BooleanPath all = createBoolean("all"); + + private Quoting(String path) { + super(Quoting.class, PathMetadataFactory.forVariable(path), "PUBLIC", "quoting"); + addMetadata(); + } + + Quoting(PathMetadata metadata) { + super(Quoting.class, metadata, "PUBLIC", "quoting"); + addMetadata(); + } + + protected void addMetadata() { + addMetadata(from, ColumnMetadata.named("from")); + addMetadata(all, ColumnMetadata.named("all")); + } + } + + private final Quoting quoting = Quoting.quoting; + + @Before + public void setUp() throws Exception { + new CreateTableClause(connection, configuration, "quoting") + .column("from", String.class).size(30) + .column("all", Boolean.class) + .execute(); + execute(insert(quoting) + .columns(quoting.from, quoting.all) + .values("from", true)); + } + + @After + public void tearDown() throws Exception { + new DropTableClause(connection, configuration, "quoting") + .execute(); + } + + @Test + public void keywords() { + Quoting from = new Quoting("from"); + assertEquals("from", query().from(quoting.as(from)) + .where(from.from.eq("from") + .and(from.all.isNotNull())) + .select(from.from).fetchFirst()); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/LikeEscapeBase.java b/querydsl-sql/src/test/java/com/querydsl/sql/LikeEscapeBase.java new file mode 100644 index 0000000000..e81694c9f4 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/LikeEscapeBase.java @@ -0,0 +1,74 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import static com.querydsl.sql.Constants.survey; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.sql.SQLException; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.querydsl.sql.dml.SQLInsertClause; + +public class LikeEscapeBase extends AbstractBaseTest { + + @Before + public void setUp() throws SQLException { + delete(survey).execute(); + SQLInsertClause insert = insert(survey); + insert.set(survey.id, 5).set(survey.name, "aaa").addBatch(); + insert.set(survey.id, 6).set(survey.name, "a_").addBatch(); + insert.set(survey.id, 7).set(survey.name, "a%").addBatch(); + insert.execute(); + } + + @After + public void tearDown() throws SQLException { + delete(survey).execute(); + insert(survey).values(1, "Hello World", "Hello").execute(); + } + + @Test + public void like() { + assertEquals(0, query().from(survey).where(survey.name.like("a!%")).fetchCount()); + assertEquals(0, query().from(survey).where(survey.name.like("a!_")).fetchCount()); + assertEquals(3, query().from(survey).where(survey.name.like("a%")).fetchCount()); + assertEquals(2, query().from(survey).where(survey.name.like("a_")).fetchCount()); + + assertEquals(1, query().from(survey).where(survey.name.startsWith("a_")).fetchCount()); + assertEquals(1, query().from(survey).where(survey.name.startsWith("a%")).fetchCount()); + } + + @Test + public void like_with_escape() { + assertEquals(1, query().from(survey).where(survey.name.like("a!%", '!')).fetchCount()); + assertEquals(1, query().from(survey).where(survey.name.like("a!_", '!')).fetchCount()); + assertEquals(3, query().from(survey).where(survey.name.like("a%", '!')).fetchCount()); + assertEquals(2, query().from(survey).where(survey.name.like("a_", '!')).fetchCount()); + } + + @Test + public void like_escaping_conclusion() { + assertTrue("Escaped like construct must return more results", + query().from(survey).where(survey.name.like("a!%")).fetchCount() + < query().from(survey).where(survey.name.like("a!%", '!')).fetchCount()); + assertTrue("Escaped like construct must return more results", + query().from(survey).where(survey.name.like("a!_")).fetchCount() + < query().from(survey).where(survey.name.like("a!_", '!')).fetchCount()); + } +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/ListSubQueryTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/ListSubQueryTest.java new file mode 100644 index 0000000000..f48210ff55 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/ListSubQueryTest.java @@ -0,0 +1,43 @@ +package com.querydsl.sql; + +import static com.querydsl.sql.SQLExpressions.select; +import static org.junit.Assert.assertEquals; + +import java.util.HashSet; +import java.util.Set; + +import org.junit.Test; + +import com.querydsl.core.Tuple; +import com.querydsl.core.types.SubQueryExpression; +import com.querydsl.sql.domain.QEmployee; +import com.querydsl.sql.domain.QSurvey; + +public class ListSubQueryTest { + + @Test + public void hashCode1() { + QSurvey survey = QSurvey.survey; + QSurvey survey2 = new QSurvey("survey2"); + SubQueryExpression query1 = select(survey.all()).from(survey); + SubQueryExpression query2 = select(survey2.all()).from(survey2); + + Set> queries = new HashSet<>(); + queries.add(query1); + queries.add(query2); + assertEquals(2, queries.size()); + } + + @Test + public void hashCode2() { + QSurvey survey = new QSurvey("entity"); + QEmployee employee = new QEmployee("entity"); + SubQueryExpression query1 = select(survey.id).from(survey); + SubQueryExpression query2 = select(employee.id).from(employee); + + Set> queries = new HashSet<>(); + queries.add(query1); + queries.add(query2); + assertEquals(1, queries.size()); + } +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/MergeBase.java b/querydsl-sql/src/test/java/com/querydsl/sql/MergeBase.java new file mode 100644 index 0000000000..22f11a6a78 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/MergeBase.java @@ -0,0 +1,247 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import static com.querydsl.core.Target.*; +import static com.querydsl.sql.Constants.survey; +import static com.querydsl.sql.Constants.survey2; +import static org.junit.Assert.*; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.querydsl.core.testutil.ExcludeIn; +import com.querydsl.core.testutil.IncludeIn; +import com.querydsl.core.types.ExpressionUtils; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.sql.dml.SQLMergeClause; +import com.querydsl.sql.domain.QSurvey; + +public class MergeBase extends AbstractBaseTest { + + private void reset() throws SQLException { + delete(survey).execute(); + insert(survey).values(1, "Hello World", "Hello").execute(); + } + + @Before + public void setUp() throws SQLException { + reset(); + } + + @After + public void tearDown() throws SQLException { + reset(); + } + + @Test + @ExcludeIn({H2, CUBRID, SQLSERVER}) + public void merge_with_keys() throws SQLException { + ResultSet rs = merge(survey).keys(survey.id) + .set(survey.id, 7) + .set(survey.name, "Hello World").executeWithKeys(); + assertTrue(rs.next()); + assertTrue(rs.getObject(1) != null); + rs.close(); + } + + @Test + @ExcludeIn({H2, CUBRID, SQLSERVER}) + public void merge_with_keys_listener() throws SQLException { + final AtomicBoolean result = new AtomicBoolean(); + SQLListener listener = new SQLBaseListener() { + @Override + public void end(SQLListenerContext context) { + result.set(true); + } + }; + SQLMergeClause clause = merge(survey).keys(survey.id) + .set(survey.id, 7) + .set(survey.name, "Hello World"); + clause.addListener(listener); + ResultSet rs = clause.executeWithKeys(); + assertTrue(rs.next()); + assertTrue(rs.getObject(1) != null); + rs.close(); + assertTrue(result.get()); + } + + @Test + @IncludeIn(H2) + public void merge_with_keys_and_subQuery() { + assertEquals(1, insert(survey).set(survey.id, 6).set(survey.name, "H").execute()); + + // keys + subquery + QSurvey survey2 = new QSurvey("survey2"); + assertEquals(2, merge(survey).keys(survey.id).select( + query().from(survey2).select(survey2.id.add(1), survey2.name, survey2.name2)).execute()); + } + + @Test + @IncludeIn(H2) + public void merge_with_keys_and_values() { + // NOTE : doesn't work with composite merge implementation + // keys + values + assertEquals(1, merge(survey).keys(survey.id).values(5, "Hello World", "Hello").execute()); + } + + @Test + public void merge_with_keys_columns_and_values() { + // keys + columns + values + assertEquals(1, merge(survey).keys(survey.id) + .set(survey.id, 5) + .set(survey.name, "Hello World").execute()); + } + + @Test + public void merge_with_keys_columns_and_values_using_null() { + // keys + columns + values + assertEquals(1, merge(survey).keys(survey.id) + .set(survey.id, 5) + .set(survey.name, (String) null).execute()); + } + + @Test + @ExcludeIn({CUBRID, DB2, DERBY, POSTGRESQL, SQLSERVER, TERADATA}) + public void merge_with_keys_Null_Id() throws SQLException { + ResultSet rs = merge(survey).keys(survey.id) + .setNull(survey.id) + .set(survey.name, "Hello World").executeWithKeys(); + assertTrue(rs.next()); + assertTrue(rs.getObject(1) != null); + rs.close(); + } + + @Test + @ExcludeIn({H2, CUBRID, SQLSERVER}) + public void merge_with_keys_Projected() throws SQLException { + assertNotNull(merge(survey).keys(survey.id) + .set(survey.id, 8) + .set(survey.name, "Hello you").executeWithKey(survey.id)); + } + + @Test + @ExcludeIn({H2, CUBRID, SQLSERVER}) + public void merge_with_keys_Projected2() throws SQLException { + Path idPath = ExpressionUtils.path(Object.class, "id"); + Object id = merge(survey).keys(survey.id) + .set(survey.id, 9) + .set(survey.name, "Hello you").executeWithKey(idPath); + assertNotNull(id); + } + + @Test + @IncludeIn(H2) + public void mergeBatch() { + SQLMergeClause merge = merge(survey) + .keys(survey.id) + .set(survey.id, 5) + .set(survey.name, "5") + .addBatch(); + assertEquals(1, merge.getBatchCount()); + assertFalse(merge.isEmpty()); + + merge + .keys(survey.id) + .set(survey.id, 6) + .set(survey.name, "6") + .addBatch(); + + assertEquals(2, merge.getBatchCount()); + assertEquals(2, merge.execute()); + + assertEquals(1L, query().from(survey).where(survey.name.eq("5")).fetchCount()); + assertEquals(1L, query().from(survey).where(survey.name.eq("6")).fetchCount()); + } + + @Test + @IncludeIn(H2) + public void mergeBatch_templates() { + SQLMergeClause merge = merge(survey) + .keys(survey.id) + .set(survey.id, 5) + .set(survey.name, Expressions.stringTemplate("'5'")) + .addBatch(); + + merge + .keys(survey.id) + .set(survey.id, 6) + .set(survey.name, Expressions.stringTemplate("'6'")) + .addBatch(); + + assertEquals(2, merge.execute()); + + assertEquals(1L, query().from(survey).where(survey.name.eq("5")).fetchCount()); + assertEquals(1L, query().from(survey).where(survey.name.eq("6")).fetchCount()); + } + + + @Test + @IncludeIn(H2) + public void mergeBatch_with_subquery() { + SQLMergeClause merge = merge(survey) + .keys(survey.id) + .columns(survey.id, survey.name) + .select(query().from(survey2).select(survey2.id.add(20), survey2.name)) + .addBatch(); + + merge(survey) + .keys(survey.id) + .columns(survey.id, survey.name) + .select(query().from(survey2).select(survey2.id.add(40), survey2.name)) + .addBatch(); + + assertEquals(1, merge.execute()); + } + + @Test + @IncludeIn(H2) + public void merge_with_templateExpression_in_batch() { + SQLMergeClause merge = merge(survey) + .keys(survey.id) + .set(survey.id, 5) + .set(survey.name, Expressions.stringTemplate("'5'")) + .addBatch(); + + assertEquals(1, merge.execute()); + } + + @Test + public void merge_listener() { + final AtomicInteger calls = new AtomicInteger(0); + SQLListener listener = new SQLBaseListener() { + @Override + public void end(SQLListenerContext context) { + if (context.getData(AbstractSQLQuery.PARENT_CONTEXT) == null) { + calls.incrementAndGet(); + } + } + }; + + SQLMergeClause clause = merge(survey).keys(survey.id) + .set(survey.id, 5) + .set(survey.name, "Hello World"); + clause.addListener(listener); + assertEquals(1, clause.execute()); + assertEquals(1, calls.intValue()); + } + +} diff --git a/querydsl-sql/src/test/java/com/mysema/query/MetadataTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/MetadataTest.java similarity index 93% rename from querydsl-sql/src/test/java/com/mysema/query/MetadataTest.java rename to querydsl-sql/src/test/java/com/querydsl/sql/MetadataTest.java index abe57719e9..327a8a1506 100644 --- a/querydsl-sql/src/test/java/com/mysema/query/MetadataTest.java +++ b/querydsl-sql/src/test/java/com/querydsl/sql/MetadataTest.java @@ -1,4 +1,4 @@ -package com.mysema.query; +package com.querydsl.sql; import java.sql.Connection; import java.sql.SQLException; @@ -8,7 +8,7 @@ @Ignore public class MetadataTest { - + // CUBRID // Apache Derby // H2 @@ -17,7 +17,7 @@ public class MetadataTest { // Oracle // PostgreSQL // SQLite - + @Test public void test() throws SQLException, ClassNotFoundException { Connections.initCubrid(); @@ -32,7 +32,7 @@ public void test() throws SQLException, ClassNotFoundException { printMetadata(); Connections.initOracle(); printMetadata(); - Connections.initPostgres(); + Connections.initPostgreSQL(); printMetadata(); Connections.initSQLite(); printMetadata(); diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/Multikey.java b/querydsl-sql/src/test/java/com/querydsl/sql/Multikey.java similarity index 91% rename from querydsl-sql/src/test/java/com/mysema/query/sql/Multikey.java rename to querydsl-sql/src/test/java/com/querydsl/sql/Multikey.java index c184162b56..b428d201e4 100644 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/Multikey.java +++ b/querydsl-sql/src/test/java/com/querydsl/sql/Multikey.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql; +package com.querydsl.sql; import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; @@ -68,7 +68,7 @@ public boolean equals(Object o) { if (!(o instanceof Multikey)) { return false; } - Multikey obj = (Multikey)o; + Multikey obj = (Multikey) o; return id.equals(obj.id) && id2.equals(obj.id2) && id3.equals(obj.id3); } @@ -87,7 +87,7 @@ public int hashCode() { @Override public String toString() { - return "Multikey#" + id+ ";" + id2+ ";" + id3; + return "Multikey#" + id + ";" + id2 + ";" + id3; } } diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/MultikeyTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/MultikeyTest.java similarity index 85% rename from querydsl-sql/src/test/java/com/mysema/query/sql/MultikeyTest.java rename to querydsl-sql/src/test/java/com/querydsl/sql/MultikeyTest.java index 5d8e9085ae..835650571f 100644 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/MultikeyTest.java +++ b/querydsl-sql/src/test/java/com/querydsl/sql/MultikeyTest.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql; +package com.querydsl.sql; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -22,47 +22,47 @@ public class MultikeyTest { Multikey multiKey1 = new Multikey(); Multikey multiKey2 = new Multikey(); - + @Test - public void HashCode() { + public void hashCode_() { int hashCode = multiKey1.hashCode(); multiKey1.setId(1); assertEquals(hashCode, multiKey1.hashCode()); - + multiKey1.setId2("2"); multiKey1.setId3(3); - + multiKey2.setId(1); multiKey2.setId2("2"); multiKey2.setId3(3); - - assertEquals(multiKey1.hashCode(), multiKey2.hashCode()); + + assertEquals(multiKey1.hashCode(), multiKey2.hashCode()); } - + @Test - public void Equals() { + public void equals() { multiKey1.setId(1); multiKey1.setId2("2"); multiKey1.setId3(3); - + assertFalse(multiKey1.equals(multiKey2)); - multiKey2.setId(1); + multiKey2.setId(1); assertFalse(multiKey1.equals(multiKey2)); - + multiKey2.setId2("2"); multiKey2.setId3(3); - + assertEquals(multiKey1, multiKey2); } - + @Test - public void ToString() { + public void toString_() { assertEquals("Multikey#null;null;null", multiKey1.toString()); - + multiKey1.setId(1); multiKey1.setId2("2"); multiKey1.setId3(3); assertEquals("Multikey#1;2;3", multiKey1.toString()); } - + } diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/MySQLTemplatesTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/MySQLTemplatesTest.java new file mode 100644 index 0000000000..baa333dcd7 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/MySQLTemplatesTest.java @@ -0,0 +1,102 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import com.querydsl.core.types.dsl.Expressions; +import org.junit.Test; + +import com.querydsl.core.types.Ops; + + +public class MySQLTemplatesTest extends AbstractSQLTemplatesTest { + + @Override + protected SQLTemplates createTemplates() { + return new MySQLTemplates(); + } + + @SuppressWarnings("unchecked") + @Test + public void test() { + SQLTemplates templates = MySQLTemplates.builder() + .printSchema() + .build(); + Configuration conf = new Configuration(templates); + System.out.println(new SQLQuery(conf).from(survey1).toString()); + } + + @Test + public void order_nullsFirst() { + query.from(survey1).orderBy(survey1.name.asc().nullsFirst()); + assertEquals("from SURVEY survey1 order by (case when survey1.NAME is null then 0 else 1 end), survey1.NAME asc", query.toString()); + } + + @Test + public void order_nullsLast() { + query.from(survey1).orderBy(survey1.name.asc().nullsLast()); + assertEquals("from SURVEY survey1 order by (case when survey1.NAME is null then 1 else 0 end), survey1.NAME asc", query.toString()); + } + + @Test + public void precedence() { + // INTERVAL + // BINARY, COLLATE + // ! + // - (unary minus), ~ (unary bit inversion) + int p0 = getPrecedence(Ops.NEGATE); + // ^ + // *, /, DIV, %, MOD + int p1 = getPrecedence(Ops.MULT, Ops.DIV, Ops.MOD); + // -, + + int p2 = getPrecedence(Ops.SUB, Ops.ADD); + // <<, >> + // & + // | + // = (comparison), <=>, >=, >, <=, <, <>, !=, IS, LIKE, REGEXP, IN + int p3 = getPrecedence(Ops.EQ, Ops.GOE, Ops.GT, Ops.LT, Ops.NE, Ops.IS_NULL, Ops.IS_NOT_NULL, Ops.MATCHES, Ops.IN, Ops.LIKE, Ops.LIKE_ESCAPE); + // BETWEEN, CASE, WHEN, THEN, ELSE + int p4 = getPrecedence(Ops.BETWEEN, Ops.CASE, Ops.CASE_ELSE); + // NOT + int p5 = getPrecedence(Ops.NOT); + // &&, AND + int p6 = getPrecedence(Ops.AND); + // XOR + int p7 = getPrecedence(Ops.XOR, Ops.XNOR); + // ||, OR + int p8 = getPrecedence(Ops.OR); + // = (assignment), := + + assertTrue(p0 < p1); + assertTrue(p1 < p2); + assertTrue(p2 < p3); + assertTrue(p3 < p4); + assertTrue(p4 < p5); + assertTrue(p5 < p6); + assertTrue(p6 < p7); + assertTrue(p7 < p8); + } + + @SuppressWarnings("rawtypes") + @Test + public void truncateWeek() { + final SQLQuery expression = query.select( + SQLExpressions.datetrunc(DatePart.week, + Expressions.dateTimeTemplate(Comparable.class, "dateExpression"))); + assertEquals("select str_to_date(concat(date_format(dateExpression,'%Y-%u'),'-1'),'%Y-%u-%w') from dual", + expression.toString()); + } +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/OracleTemplatesTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/OracleTemplatesTest.java new file mode 100644 index 0000000000..9178547aa4 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/OracleTemplatesTest.java @@ -0,0 +1,138 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import com.querydsl.core.QueryFlag; +import com.querydsl.core.types.ConstantImpl; +import com.querydsl.core.types.ExpressionUtils; +import com.querydsl.core.types.Operation; +import com.querydsl.core.types.Ops; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.SimpleExpression; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.List; + +import static com.querydsl.sql.SQLExpressions.select; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class OracleTemplatesTest extends AbstractSQLTemplatesTest { + + @Override + protected SQLTemplates createTemplates() { + return new OracleTemplates(); + } + + @Override + @SuppressWarnings("unchecked") + @Test + public void union() { + SimpleExpression one = Expressions.template(Integer.class, "1"); + SimpleExpression two = Expressions.template(Integer.class,"2"); + SimpleExpression three = Expressions.template(Integer.class,"3"); + NumberPath col1 = Expressions.numberPath(Integer.class, "col1"); + Union union = query.union( + select(one.as(col1)), + select(two), + select(three)); + assertEquals( + "(select 1 col1 from dual)\n" + + "union\n" + + "(select 2 from dual)\n" + + "union\n" + + "(select 3 from dual)", union.toString()); + } + + @Test + public void modifiers() { + query.from(survey1).limit(5).offset(3); + query.getMetadata().setProjection(survey1.id); + assertEquals("select * from ( " + + "select a.*, rownum rn from ( " + + "select survey1.ID from SURVEY survey1 ) " + + "a) " + + "where rn > 3 and rownum <= 5", query.toString()); + } + + @Test + public void modifiers2() { + query.from(survey1).limit(5).offset(3); + query.getMetadata().setProjection(survey1.id); + query.getMetadata().addFlag(new QueryFlag(QueryFlag.Position.AFTER_PROJECTION, ", count(*) over() ")); + + assertEquals("select * from ( " + + "select a.*, rownum rn from ( " + + "select survey1.ID, count(*) over() from SURVEY survey1 ) " + + "a) " + + "where rn > 3 and rownum <= 5", query.toString()); + } + + @Test + public void in() { + List ids = new ArrayList(); + for (int i = 0; i < 2000; i++) { + ids.add(i); + } + query.where(survey1.id.isNotNull()); + query.where(survey1.id.in(ids)); + assertTrue(query.toString().startsWith("from dual where survey1.ID is not null and (survey1.ID in ")); + } + + @Test + public void nextVal() { + Operation nextval = ExpressionUtils.operation(String.class, SQLOps.NEXTVAL, ConstantImpl.create("myseq")); + assertEquals("myseq.nextval", new SQLSerializer(new Configuration(new OracleTemplates())).handle(nextval).toString()); + } + + @Test + public void precedence() { + // +, - (as unary operators), PRIOR, CONNECT_BY_ROOT identity, negation, location in hierarchy + int p1 = getPrecedence(Ops.NEGATE); + // *, / multiplication, division + int p2 = getPrecedence(Ops.MULT, Ops.DIV); + // +, - (as binary operators), || addition, subtraction, concatenation + int p3 = getPrecedence(Ops.ADD, Ops.SUB, Ops.CONCAT); + // =, !=, <, >, <=, >=, comparison + int p4 = getPrecedence(Ops.EQ, Ops.NE, Ops.LT, Ops.GT, Ops.LOE, Ops.GOE); + // IS [NOT] NULL, LIKE, [NOT] BETWEEN, [NOT] IN, EXISTS, IS OF type comparison + int p5 = getPrecedence(Ops.IS_NULL, Ops.IS_NOT_NULL, Ops.LIKE, Ops.LIKE_ESCAPE, Ops.BETWEEN, Ops.IN, Ops.NOT_IN, Ops.EXISTS); + // NOT exponentiation, logical negation + int p6 = getPrecedence(Ops.NOT); + // AND conjunction + int p7 = getPrecedence(Ops.AND); + // OR disjunction + int p8 = getPrecedence(Ops.OR); + + assertTrue(p1 < p2); + assertTrue(p2 < p3); + assertTrue(p3 < p4); + assertTrue(p4 < p5); + assertTrue(p5 < p6); + assertTrue(p6 < p7); + assertTrue(p7 < p8); + } + + @SuppressWarnings("rawtypes") + @Test + public void truncateWeek() { + final SQLQuery expression = query.select( + SQLExpressions.datetrunc(DatePart.week, + Expressions.dateTimeTemplate(Comparable.class, "dateExpression"))); + assertEquals("select trunc(dateExpression, 'iw') from dual", + expression.toString()); + } +} diff --git a/querydsl-sql/src/test/java/com/mysema/query/OracleTimeTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/OracleTimeTest.java similarity index 97% rename from querydsl-sql/src/test/java/com/mysema/query/OracleTimeTest.java rename to querydsl-sql/src/test/java/com/querydsl/sql/OracleTimeTest.java index c544beb663..47982fa876 100644 --- a/querydsl-sql/src/test/java/com/mysema/query/OracleTimeTest.java +++ b/querydsl-sql/src/test/java/com/querydsl/sql/OracleTimeTest.java @@ -1,4 +1,4 @@ -package com.mysema.query; +package com.querydsl.sql; import java.sql.Connection; import java.sql.ResultSet; diff --git a/querydsl-sql/src/test/java/com/mysema/query/OtherEmployee.java b/querydsl-sql/src/test/java/com/querydsl/sql/OtherEmployee.java similarity index 90% rename from querydsl-sql/src/test/java/com/mysema/query/OtherEmployee.java rename to querydsl-sql/src/test/java/com/querydsl/sql/OtherEmployee.java index a0abe7326a..2e317e7184 100644 --- a/querydsl-sql/src/test/java/com/mysema/query/OtherEmployee.java +++ b/querydsl-sql/src/test/java/com/querydsl/sql/OtherEmployee.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,10 +11,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query; +package com.querydsl.sql; public class OtherEmployee { - + private String firstname, lastname; public String getFirstname() { @@ -32,5 +32,5 @@ public String getLastname() { public void setLastname(String lastname) { this.lastname = lastname; } - + } \ No newline at end of file diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/PaginationTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/PaginationTest.java new file mode 100644 index 0000000000..b9fefacd6b --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/PaginationTest.java @@ -0,0 +1,73 @@ +package com.querydsl.sql; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Test; +import org.junit.experimental.categories.Category; + +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.QueryModifiers; +import com.querydsl.core.support.QueryMixin; +import com.querydsl.core.testutil.ReportingOnly; +import com.querydsl.sql.domain.QEmployee; + +@Category(ReportingOnly.class) +public class PaginationTest { + + private String serialize(QueryMetadata metadata, SQLTemplates templates) { + SQLSerializer serializer = new SQLSerializer(new Configuration(templates)); + serializer.serialize(metadata, false); + return serializer.toString(); + } + + @Test + public void test() { + List list = new ArrayList<>(); + list.add(new CUBRIDTemplates()); + list.add(new DerbyTemplates()); + list.add(new H2Templates()); + list.add(new HSQLDBTemplates()); + list.add(new MySQLTemplates()); + list.add(new OracleTemplates()); // inner query + list.add(new PostgreSQLTemplates()); + list.add(new SQLiteTemplates()); + list.add(new SQLServerTemplates()); + list.add(new SQLServer2005Templates()); // inner query + list.add(new SQLServer2012Templates()); + list.add(new TeradataTemplates()); // qualify + + for (SQLTemplates templates : list) { + QEmployee employee = QEmployee.employee; + QueryMixin query = new QueryMixin(); + query.from(employee); + query.orderBy(employee.firstname.asc()); + query.setProjection(employee.id); + + System.out.println(templates.getClass().getSimpleName()); + System.out.println(); + + // limit + query.restrict(QueryModifiers.limit(10L)); + System.out.println("* limit"); + System.out.println(serialize(query.getMetadata(), templates)); + System.out.println(); + + if (!templates.getClass().equals(SQLServerTemplates.class)) { + // offset + query.restrict(QueryModifiers.offset(10L)); + System.out.println("* offset"); + System.out.println(serialize(query.getMetadata(), templates)); + System.out.println(); + + // limit and offset + query.restrict(new QueryModifiers(10L, 10L)); + System.out.println("* limit and offset"); + System.out.println(serialize(query.getMetadata(), templates)); + System.out.println(); + } + + } + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/PostgreSQLTemplatesTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/PostgreSQLTemplatesTest.java new file mode 100644 index 0000000000..e9289c962b --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/PostgreSQLTemplatesTest.java @@ -0,0 +1,118 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import static com.querydsl.sql.SQLExpressions.select; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +import com.querydsl.core.types.Ops; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberExpression; + + +public class PostgreSQLTemplatesTest extends AbstractSQLTemplatesTest { + + @Override + protected SQLTemplates createTemplates() { + return new PostgreSQLTemplates(); + } + + @Test + public void noFrom() { + query.getMetadata().setProjection(Expressions.ONE); + assertEquals("select 1", query.toString()); + } + + @SuppressWarnings("unchecked") + @Test + public void union() { + NumberExpression one = Expressions.ONE; + NumberExpression two = Expressions.TWO; + NumberExpression three = Expressions.THREE; + Path col1 = Expressions.path(Integer.class,"col1"); + Union union = query.union( + select(one.as(col1)), + select(two), + select(three)); + assertEquals( + "(select 1 as col1)\n" + + "union\n" + + "(select 2)\n" + + "union\n" + + "(select 3)", union.toString()); + } + + @Test + public void precedence() { + //. left table/column name separator + // :: left PostgreSQL-style typecast + //[ ] left array element selection + //+ - right unary plus, unary minus + int p0 = getPrecedence(Ops.NEGATE); + // ^ left exponentiation + // * / % left multiplication, division, modulo + int p1 = getPrecedence(Ops.MULT, Ops.DIV, Ops.MOD); + //+ - left addition, subtraction + int p2 = getPrecedence(Ops.ADD, Ops.SUB); + //IS IS TRUE, IS FALSE, IS NULL, etc + int p3 = getPrecedence(Ops.IS_NULL, Ops.IS_NOT_NULL); + //ISNULL test for null + //NOTNULL test for not null + //(any other) left all other native and user-defined operators + //IN set membership + int p4 = getPrecedence(Ops.IN); + //BETWEEN range containment + int p5 = getPrecedence(Ops.BETWEEN); + //OVERLAPS time interval overlap + //LIKE ILIKE SIMILAR string pattern matching + int p6 = getPrecedence(Ops.LIKE, Ops.LIKE_ESCAPE); + //< > less than, greater than + int p7 = getPrecedence(Ops.LT, Ops.GT); + // = right equality, assignment + int p8 = getPrecedence(Ops.EQ); + //NOT right logical negation + int p9 = getPrecedence(Ops.NOT); + //AND left logical conjunction + int p10 = getPrecedence(Ops.AND); + //OR left logical disjunction + int p11 = getPrecedence(Ops.OR); + + assertTrue(p0 < p1); + assertTrue(p1 < p2); + assertTrue(p2 < p3); + assertTrue(p3 < p4); + assertTrue(p4 < p5); + assertTrue(p5 < p6); + assertTrue(p6 < p7); + assertTrue(p7 < p8); + assertTrue(p8 < p9); + assertTrue(p9 < p10); + assertTrue(p10 < p11); + } + + @Test + @Override + public void booleanTemplate() { + assertSerialized(Expressions.booleanPath("b").eq(Expressions.TRUE), "b = true"); + assertSerialized(Expressions.booleanPath("b").eq(Expressions.FALSE), "b = false"); + query.setUseLiterals(true); + query.where(Expressions.booleanPath("b").eq(true)); + assertTrue(query.toString(), query.toString().endsWith("where b = true")); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/PrecedenceTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/PrecedenceTest.java new file mode 100644 index 0000000000..22da8d042b --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/PrecedenceTest.java @@ -0,0 +1,24 @@ +package com.querydsl.sql; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import com.querydsl.core.types.dsl.BooleanExpression; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.StringPath; + +public class PrecedenceTest { + + @Test + public void test() { + StringPath str1 = Expressions.stringPath("str1"); + StringPath str2 = Expressions.stringPath("str2"); + BooleanExpression pending = str1.eq("3").and(str2.eq("1")); + BooleanExpression notNew = str1.ne("1").and(str2.in("2", "3")); + BooleanExpression whereClause = str1.eq("a").and(pending.or(notNew)); + String str = new SQLSerializer(Configuration.DEFAULT).handle(whereClause).toString(); + assertEquals("str1 = ? and (str1 = ? and str2 = ? or str1 != ? and str2 in (?, ?))", str); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/Projection.java b/querydsl-sql/src/test/java/com/querydsl/sql/Projection.java new file mode 100644 index 0000000000..c11e120b1a --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/Projection.java @@ -0,0 +1,36 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import org.jetbrains.annotations.Nullable; + +import com.querydsl.core.types.Expression; + +public interface Projection { + + @Nullable + T get(Expression expr); + + @Nullable + T get(int index, Class type); + + @Nullable + Expression getExpr(Expression expr); + + @Nullable + Expression getExpr(int index, Class type); + + Object[] toArray(); + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/QBean2Test.java b/querydsl-sql/src/test/java/com/querydsl/sql/QBean2Test.java new file mode 100644 index 0000000000..e25647b819 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/QBean2Test.java @@ -0,0 +1,97 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.PathMetadataFactory; +import com.querydsl.core.types.Projections; +import com.querydsl.core.types.QBean; +import com.querydsl.core.types.dsl.BeanPath; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.StringPath; + +public class QBean2Test { + +// @Table("PERSON") + public static class QPerson extends RelationalPathBase { + private static final long serialVersionUID = 609527362; + public static final QPerson person = new QPerson("PERSON"); + public final StringPath firstName = createString("firstName"); + public final NumberPath id = createNumber("id", Integer.class); + public final StringPath lastName = createString("lastName"); + + public QPerson(String variable) { + super(QPerson.class, PathMetadataFactory.forVariable(variable), "", "PERSON"); + addMetadata(); + } + + public QPerson(BeanPath entity) { + super(entity.getType(), entity.getMetadata(), "", "PERSON"); + addMetadata(); + } + + public QPerson(PathMetadata metadata) { + super(QPerson.class, metadata, "", "PERSON"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(firstName, ColumnMetadata.named("FIRST_NAME")); + addMetadata(lastName, ColumnMetadata.named("LAST_NAME")); + addMetadata(id, ColumnMetadata.named("ID")); + } + + } + + public static class Person { + private int id; + private String firstName; + private String lastName; + public int getId() { + return id; + } + public void setId(int id) { + this.id = id; + } + public String getFirstName() { + return firstName; + } + public void setFirstName(String firstName) { + this.firstName = firstName; + } + public String getLastName() { + return lastName; + } + public void setLastName(String lastName) { + this.lastName = lastName; + } + + } + + @Test + public void newInstance() { + QPerson p = QPerson.person; + QBean projection = Projections.bean(Person.class, p.id, p.firstName.as("firstName"), p.lastName.as("lastName")); + + Person person = projection.newInstance(3, "John", "Doe"); + assertEquals(3, person.getId()); + assertEquals("John", person.getFirstName()); + assertEquals("Doe", person.getLastName()); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/QBeanTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/QBeanTest.java new file mode 100644 index 0000000000..3830b8913d --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/QBeanTest.java @@ -0,0 +1,59 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import com.querydsl.core.types.FactoryExpression; +import com.querydsl.core.types.Projections; +import com.querydsl.sql.domain.Employee; +import com.querydsl.sql.domain.QEmployee; + +public class QBeanTest { + + private final QEmployee e = new QEmployee("e"); + + @Test + public void direct_to_managed_type() { + FactoryExpression expr = Projections.bean(Employee.class, e.superiorId); + Employee e = expr.newInstance(3); + assertEquals(Integer.valueOf(3), e.getSuperiorId()); + } + + @Test + public void direct_to_custom_type() { + FactoryExpression expr = Projections.bean(Employee.class, e.firstname, e.lastname); + Employee e = expr.newInstance("John","Smith"); + assertEquals("John", e.getFirstname()); + assertEquals("Smith", e.getLastname()); + } + + @Test + public void alias_to_managed_type() { + FactoryExpression expr = Projections.bean(Employee.class, e.superiorId.as("id")); + Employee e = expr.newInstance(3); + assertEquals(3, e.getId().intValue()); + } + + @Test + public void alias_to_custom_type() { + FactoryExpression expr = Projections.bean(Employee.class, e.firstname.as("lastname"), e.lastname.as("firstname")); + Employee e = expr.newInstance("John","Smith"); + assertEquals("Smith", e.getFirstname()); + assertEquals("John", e.getLastname()); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/QCompanies.java b/querydsl-sql/src/test/java/com/querydsl/sql/QCompanies.java new file mode 100644 index 0000000000..e3f88f67da --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/QCompanies.java @@ -0,0 +1,49 @@ +package com.querydsl.sql; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.StringPath; + + +/** + * QCompanies is a Querydsl query type for QCompanies + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class QCompanies extends com.querydsl.sql.RelationalPathBase { + + private static final long serialVersionUID = 1808918375; + + public static final QCompanies companies = new QCompanies("COMPANIES"); + + public final NumberPath id = createNumber("id", Long.class); + + public final StringPath name = createString("name"); + + public final com.querydsl.sql.PrimaryKey constraint5 = createPrimaryKey(id); + + public QCompanies(String variable) { + super(QCompanies.class, forVariable(variable), "PUBLIC", "COMPANIES"); + addMetadata(); + } + + public QCompanies(Path path) { + super(path.getType(), path.getMetadata(), "PUBLIC", "COMPANIES"); + addMetadata(); + } + + public QCompanies(PathMetadata metadata) { + super(QCompanies.class, metadata, "PUBLIC", "COMPANIES"); + addMetadata(); + } + + protected void addMetadata() { + addMetadata(id, ColumnMetadata.named("ID")); + addMetadata(name, ColumnMetadata.named("NAME")); + } + +} diff --git a/querydsl-sql/src/test/java/com/mysema/query/QGeneratedKeysEntity.java b/querydsl-sql/src/test/java/com/querydsl/sql/QGeneratedKeysEntity.java similarity index 78% rename from querydsl-sql/src/test/java/com/mysema/query/QGeneratedKeysEntity.java rename to querydsl-sql/src/test/java/com/querydsl/sql/QGeneratedKeysEntity.java index c8d9d627b0..48a6536080 100644 --- a/querydsl-sql/src/test/java/com/mysema/query/QGeneratedKeysEntity.java +++ b/querydsl-sql/src/test/java/com/querydsl/sql/QGeneratedKeysEntity.java @@ -1,5 +1,5 @@ /* - * Copyright 2011, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,16 +11,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query; +package com.querydsl.sql; -import com.mysema.query.sql.ColumnMetadata; -import com.mysema.query.sql.RelationalPathBase; -import com.mysema.query.types.PathMetadataFactory; -import com.mysema.query.types.path.NumberPath; -import com.mysema.query.types.path.StringPath; +import com.querydsl.core.types.PathMetadataFactory; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.StringPath; //@Table("GENERATED_KEYS") -public class QGeneratedKeysEntity extends RelationalPathBase{ +public class QGeneratedKeysEntity extends RelationalPathBase { private static final long serialVersionUID = 2002306246819687158L; diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/QPerson.java b/querydsl-sql/src/test/java/com/querydsl/sql/QPerson.java new file mode 100644 index 0000000000..17f1598264 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/QPerson.java @@ -0,0 +1,62 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.PathMetadataFactory; +import com.querydsl.core.types.dsl.BeanPath; +import com.querydsl.core.types.dsl.EnumPath; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.StringPath; + +//@Table("PERSON") +public class QPerson extends RelationalPathBase { + + private static final long serialVersionUID = 475064746; + + public static final QPerson person = new QPerson("PERSON"); + + public final StringPath firstname = createString("firstname"); + + public final EnumPath gender = createEnum("gender", com.querydsl.core.alias.Gender.class); + + public final NumberPath id = createNumber("id", Integer.class); + + public final StringPath securedid = createString("securedid"); + + public final PrimaryKey sysIdx118 = createPrimaryKey(id); + + public QPerson(String variable) { + super(QPerson.class, PathMetadataFactory.forVariable(variable), "", "PERSON"); + addMetadata(); + } + + public QPerson(BeanPath entity) { + super(entity.getType(), entity.getMetadata(), "", "PERSON"); + addMetadata(); + } + + public QPerson(PathMetadata metadata) { + super(QPerson.class, metadata, "", "PERSON"); + addMetadata(); + } + + protected void addMetadata() { + addMetadata(id, ColumnMetadata.named("ID")); + addMetadata(firstname, ColumnMetadata.named("FIRSTNAME")); + addMetadata(securedid, ColumnMetadata.named("SECUREDID")); + addMetadata(gender, ColumnMetadata.named("GENDER")); + } + +} \ No newline at end of file diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/QPersonTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/QPersonTest.java similarity index 82% rename from querydsl-sql/src/test/java/com/mysema/query/sql/QPersonTest.java rename to querydsl-sql/src/test/java/com/querydsl/sql/QPersonTest.java index dd37210a71..731a5abedc 100644 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/QPersonTest.java +++ b/querydsl-sql/src/test/java/com/querydsl/sql/QPersonTest.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,13 +11,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql; +package com.querydsl.sql; import static org.junit.Assert.assertEquals; import org.junit.Test; -import com.mysema.query.types.QBean; +import com.querydsl.core.types.Projections; +import com.querydsl.core.types.QBean; public class QPersonTest { @@ -54,9 +55,9 @@ public void setSecuredid(String securedid) { } @Test - public void Populate() { + public void populate() { QPerson person = QPerson.person; - QBean personProjection = new QBean(Person.class, person.id, person.firstname, person.securedid); + QBean personProjection = Projections.bean(Person.class, person.id, person.firstname, person.securedid); Person p = personProjection.newInstance(3, "X", "Y"); assertEquals(3, p.getId()); assertEquals("X", p.getFirstname()); diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/QProjection.java b/querydsl-sql/src/test/java/com/querydsl/sql/QProjection.java new file mode 100644 index 0000000000..05724ebc16 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/QProjection.java @@ -0,0 +1,85 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import java.util.Arrays; +import java.util.List; + +import com.querydsl.core.SimpleConstant; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.ExpressionBase; +import com.querydsl.core.types.FactoryExpression; +import com.querydsl.core.types.Visitor; +import org.jetbrains.annotations.Unmodifiable; + +public class QProjection extends ExpressionBase implements FactoryExpression { + + private static final long serialVersionUID = -7330905848558102164L; + + @Unmodifiable + private final List> args; + + public QProjection(Expression... args) { + super(Projection.class); + this.args = Arrays.asList(args); + } + + @SuppressWarnings("unchecked") + @Override + public Projection newInstance(final Object... args) { + return new Projection() { + + @Override + public T get(int index, Class type) { + return (T) args[index]; + } + + @Override + public T get(Expression expr) { + int index = getArgs().indexOf(expr); + return index != -1 ? (T) args[index] : null; + } + + @Override + public Expression getExpr(Expression expr) { + T val = get(expr); + return val != null ? SimpleConstant.create(val) : null; + } + + @Override + public Expression getExpr(int index, Class type) { + T val = (T) args[index]; + return val != null ? SimpleConstant.create(val) : null; + } + + @Override + public Object[] toArray() { + return args; + } + + }; + } + + @Override + @Unmodifiable + public List> getArgs() { + return args; + } + + @Override + public R accept(Visitor v, C context) { + return v.visit(this, context); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/QueryMutabilityTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/QueryMutabilityTest.java new file mode 100644 index 0000000000..e77be1d9ae --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/QueryMutabilityTest.java @@ -0,0 +1,69 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import static org.junit.Assert.assertEquals; + +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.sql.Connection; +import java.sql.SQLException; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +import com.querydsl.core.QueryMutability; +import com.querydsl.core.testutil.Derby; +import com.querydsl.sql.domain.QSurvey; + +@Category(Derby.class) +public class QueryMutabilityTest { + + private static final QSurvey survey = new QSurvey("survey"); + + private Connection connection; + + @Before + public void setUp() throws Exception { + Connections.initDerby(); + connection = Connections.getConnection(); + } + + @After + public void tearDown() throws SQLException { + Connections.close(); + } + + @Test + public void test() throws IOException, SecurityException, + IllegalArgumentException, NoSuchMethodException, + IllegalAccessException, InvocationTargetException { + SQLQuery query = new SQLQuery(connection, DerbyTemplates.DEFAULT); + query.from(survey); + query.addListener(new TestLoggingListener()); + new QueryMutability(query).test(survey.id, survey.name); + } + + @Test + public void clone_() { + SQLQuery query = new SQLQuery(DerbyTemplates.DEFAULT).from(survey); + SQLQuery query2 = query.clone(connection); + assertEquals(query.getMetadata().getJoins(), query2.getMetadata().getJoins()); + assertEquals(query.getMetadata().getWhere(), query2.getMetadata().getWhere()); + query2.select(survey.id).fetch(); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/QueryPerformanceTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/QueryPerformanceTest.java new file mode 100644 index 0000000000..a1eef0ff77 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/QueryPerformanceTest.java @@ -0,0 +1,252 @@ +package com.querydsl.sql; + +import com.mysema.commons.lang.CloseableIterator; +import com.querydsl.core.DefaultQueryMetadata; +import com.querydsl.core.JoinType; +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.testutil.H2; +import com.querydsl.core.testutil.Performance; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; +import org.openjdk.jmh.runner.options.TimeValue; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.concurrent.ThreadLocalRandom; +import java.util.concurrent.TimeUnit; + +import static org.junit.Assert.assertNotNull; + +@Category({H2.class, Performance.class}) +public class QueryPerformanceTest { + + private static final String QUERY = "select COMPANIES.NAME\n" + + "from COMPANIES COMPANIES\n" + + "where COMPANIES.ID = ?"; + + private static final SQLTemplates templates = new H2Templates(); + + private static final Configuration conf = new Configuration(templates); + + @BeforeClass + public static void setUpClass() throws SQLException, ClassNotFoundException { + Connections.initH2(); + Connection conn = Connections.getConnection(); + Statement stmt = conn.createStatement(); + stmt.execute("create or replace table companies (id identity, name varchar(30) unique not null);"); + + PreparedStatement pstmt = conn.prepareStatement("insert into companies (name) values (?)"); + final int iterations = 1000000; + for (int i = 0; i < iterations; i++) { + pstmt.setString(1, String.valueOf(i)); + pstmt.execute(); + pstmt.clearParameters(); + } + pstmt.close(); + stmt.close(); + + conn.setAutoCommit(false); + } + + @AfterClass + public static void tearDownClass() throws SQLException { + Connection conn = Connections.getConnection(); + Statement stmt = conn.createStatement(); + stmt.execute("drop table companies"); + stmt.close(); + Connections.close(); + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.MICROSECONDS) + public void jDBC() throws Exception { + try (Connection conn = Connections.getH2(); + PreparedStatement stmt = conn.prepareStatement(QUERY)) { + stmt.setLong(1, ThreadLocalRandom.current().nextLong()); + try (ResultSet rs = stmt.executeQuery()) { + while (rs.next()) { + rs.getString(1); + } + } + + } + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.MICROSECONDS) + public void jDBC2() throws Exception { + try (Connection conn = Connections.getH2(); + PreparedStatement stmt = conn.prepareStatement(QUERY)) { + stmt.setString(1, String.valueOf(ThreadLocalRandom.current().nextLong())); + try (ResultSet rs = stmt.executeQuery()) { + while (rs.next()) { + rs.getString(1); + } + } + + } + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.MICROSECONDS) + public void querydsl1() throws Exception { + try (Connection conn = Connections.getH2()) { + QCompanies companies = QCompanies.companies; + SQLQuery query = new SQLQuery(conn, conf); + query.from(companies).where(companies.id.eq((long) ThreadLocalRandom.current().nextLong())) + .select(companies.name).fetch(); + } + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.MICROSECONDS) + public void querydsl12() throws Exception { + try (Connection conn = Connections.getH2()) { + QCompanies companies = QCompanies.companies; + SQLQuery query = new SQLQuery(conn, conf); + try (CloseableIterator it = query.from(companies) + .where(companies.id.eq((long) ThreadLocalRandom.current().nextLong())).select(companies.name).iterate()) { + while (it.hasNext()) { + it.next(); + } + } + } + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.MICROSECONDS) + public void querydsl13() throws Exception { + try (Connection conn = Connections.getH2()) { + QCompanies companies = QCompanies.companies; + SQLQuery query = new SQLQuery(conn, conf); + try (ResultSet rs = query.select(companies.name).from(companies) + .where(companies.id.eq((long) ThreadLocalRandom.current().nextLong())).getResults()) { + while (rs.next()) { + rs.getString(1); + } + } + } + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.MICROSECONDS) + public void querydsl14() throws Exception { + try (Connection conn = Connections.getH2()) { + QCompanies companies = QCompanies.companies; + SQLQuery query = new SQLQuery(conn, conf, new DefaultQueryMetadata()); + query.from(companies).where(companies.id.eq((long) ThreadLocalRandom.current().nextLong())) + .select(companies.name).fetch(); + } + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.MICROSECONDS) + public void querydsl15() throws Exception { + try (Connection conn = Connections.getH2()) { + QCompanies companies = QCompanies.companies; + SQLQuery query = new SQLQuery(conn, conf); + query.from(companies).where(companies.id.eq((long) ThreadLocalRandom.current().nextLong())) + .select(companies.id, companies.name).fetch(); + } + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.MICROSECONDS) + public void querydsl2() throws Exception { + try (Connection conn = Connections.getH2()) { + QCompanies companies = QCompanies.companies; + SQLQuery query = new SQLQuery(conn, conf); + query.from(companies).where(companies.name.eq(String.valueOf(ThreadLocalRandom.current().nextLong()))) + .select(companies.name).fetch(); + } + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.MICROSECONDS) + public void querydsl22() throws Exception { + try (Connection conn = Connections.getH2()) { + QCompanies companies = QCompanies.companies; + SQLQuery query = new SQLQuery(conn, conf); + try (CloseableIterator it = query.from(companies) + .where(companies.name.eq(String.valueOf(ThreadLocalRandom.current().nextLong()))) + .select(companies.name).iterate()) { + while (it.hasNext()) { + it.next(); + } + } + } + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.MICROSECONDS) + public void querydsl23() throws Exception { + try (Connection conn = Connections.getH2()) { + QCompanies companies = QCompanies.companies; + SQLQuery query = new SQLQuery(conn, conf, new DefaultQueryMetadata()); + query.from(companies) + .where(companies.name.eq(String.valueOf(ThreadLocalRandom.current().nextLong()))) + .select(companies.name).fetch(); + } + } + + @Benchmark + @BenchmarkMode(Mode.AverageTime) + @OutputTimeUnit(TimeUnit.MICROSECONDS) + public void serialization() throws Exception { + try (Connection conn = Connections.getH2()) { + QCompanies companies = QCompanies.companies; + final QueryMetadata md = new DefaultQueryMetadata(); + md.addJoin(JoinType.DEFAULT, companies); + md.addWhere(companies.id.eq(1L)); + md.setProjection(companies.name); + + SQLSerializer serializer = new SQLSerializer(conf); + serializer.serialize(md, false); + serializer.getConstants(); + serializer.getConstantPaths(); + assertNotNull(serializer.toString()); + } + } + + @Test + public void launchBenchmark() throws Exception { + Options opt = new OptionsBuilder() + .include(this.getClass().getName() + ".*") + .mode(Mode.AverageTime) + .timeUnit(TimeUnit.MICROSECONDS) + .warmupTime(TimeValue.seconds(1)) + .warmupIterations(1) + .measurementTime(TimeValue.seconds(1)) + .measurementIterations(3) + .threads(1) + .forks(1) + .shouldFailOnError(true) + .shouldDoGC(true) + .build(); + + new Runner(opt).run(); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/RelationalFunctionCallTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/RelationalFunctionCallTest.java new file mode 100644 index 0000000000..6f124febc3 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/RelationalFunctionCallTest.java @@ -0,0 +1,74 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import static com.querydsl.sql.SQLExpressions.selectOne; +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import com.querydsl.core.types.ConstantImpl; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.PathBuilder; +import com.querydsl.core.types.dsl.StringPath; +import com.querydsl.sql.domain.QSurvey; + +public class RelationalFunctionCallTest { + + private static Expression[] serializeCollection(String... tokens) { + Expression[] rv = new Expression[tokens.length]; + for (int i = 0; i < tokens.length; i++) { + rv[i] = ConstantImpl.create(tokens[i]); + } + return rv; + } + + private static class TokenizeFunction extends RelationalFunctionCall { + final PathBuilder alias; + final StringPath token; + + TokenizeFunction(String alias, String... tokens) { + super(String.class, "tokenize", serializeCollection(tokens)); + this.alias = new PathBuilder(String.class, alias); + this.token = Expressions.stringPath(this.alias, "token"); + } + + } + + @Test + public void validation() { + QSurvey survey = QSurvey.survey; + TokenizeFunction func = new TokenizeFunction("func", "a", "b"); + SQLQuery sub = selectOne().from(func.as(func.alias)).where(survey.name.like(func.token)); + System.out.println(sub); + + } + + @Test + public void noArgs() { + RelationalFunctionCall functionCall = SQLExpressions.relationalFunctionCall(String.class, "getElements"); + assertEquals("getElements()", functionCall.getTemplate().toString()); + } + + @Test + public void twoArgs() { + StringPath str = Expressions.stringPath("str"); + RelationalFunctionCall functionCall = SQLExpressions.relationalFunctionCall(String.class, "getElements", "a", str); + assertEquals("getElements({0}, {1})", functionCall.getTemplate().toString()); + assertEquals("a", functionCall.getArg(0)); + assertEquals(str, functionCall.getArg(1)); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/RelationalPathExtractorTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/RelationalPathExtractorTest.java new file mode 100644 index 0000000000..fabb60ee42 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/RelationalPathExtractorTest.java @@ -0,0 +1,56 @@ +package com.querydsl.sql; + +import static com.querydsl.sql.Constants.employee; +import static com.querydsl.sql.RelationalPathExtractor.extract; +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.sql.domain.QEmployee; + +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; + +public class RelationalPathExtractorTest { + + private SQLQuery query() { + return new SQLQuery(); + } + + @Test + public void simpleQuery() { + QEmployee employee2 = new QEmployee("employee2"); + SQLQuery query = query().from(employee, employee2); + + assertEquals(new HashSet<>(Arrays.asList(employee, employee2)), extract(query.getMetadata())); + } + + @Test + public void joins() { + QEmployee employee2 = new QEmployee("employee2"); + SQLQuery query = query().from(employee) + .innerJoin(employee2).on(employee.superiorId.eq(employee2.id)); + + assertEquals(new HashSet<>(Arrays.asList(employee, employee2)), extract(query.getMetadata())); + } + + @Test + public void subQuery() { + SQLQuery query = query().from(employee) + .where(employee.id.eq(query().from(employee).select(employee.id.max()))); + assertEquals(Collections.singleton(employee), extract(query.getMetadata())); + } + + @Test + public void subQuery2() { + QEmployee employee2 = new QEmployee("employee2"); + SQLQuery query = query().from(employee) + .where(Expressions.list(employee.id, employee.lastname) + .in(query().from(employee2).select(employee2.id, employee2.lastname))); + + assertEquals(new HashSet<>(Arrays.asList(employee, employee2)), extract(query.getMetadata())); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/RelationalPathTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/RelationalPathTest.java new file mode 100644 index 0000000000..623a50acad --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/RelationalPathTest.java @@ -0,0 +1,35 @@ +package com.querydsl.sql; + +import static com.querydsl.core.testutil.Serialization.serialize; +import static org.junit.Assert.assertEquals; + +import java.io.IOException; +import java.util.Arrays; + +import org.junit.Test; + +import com.querydsl.core.types.Projections; +import com.querydsl.core.types.QTuple; +import com.querydsl.sql.domain.QSurvey; + +public class RelationalPathTest { + + @Test + public void path() throws ClassNotFoundException, IOException { + QSurvey survey = QSurvey.survey; + QSurvey survey2 = serialize(survey); + assertEquals(Arrays.asList(survey.all()), Arrays.asList(survey2.all())); + assertEquals(survey.getMetadata(), survey2.getMetadata()); + assertEquals(survey.getMetadata(survey.id), survey2.getMetadata(survey.id)); + } + + @Test + public void in_tuple() throws ClassNotFoundException, IOException { + //(survey.id, survey.name) + QSurvey survey = QSurvey.survey; + QTuple tuple = Projections.tuple(survey.id, survey.name); + serialize(tuple); + serialize(tuple.newInstance(1, "a")); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/SQLBindingsTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/SQLBindingsTest.java new file mode 100644 index 0000000000..fa5000ae34 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/SQLBindingsTest.java @@ -0,0 +1,52 @@ +package com.querydsl.sql; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.Arrays; +import java.util.Collections; + +import org.junit.Test; + +import com.querydsl.core.types.dsl.Param; +import com.querydsl.sql.domain.QSurvey; + +public class SQLBindingsTest { + + private QSurvey survey = QSurvey.survey; + + private SQLQuery query = new SQLQuery(); + + @Test + public void empty() { + SQLBindings bindings = query.getSQL(); + assertEquals("\nfrom dual", bindings.getSQL()); + assertTrue(bindings.getNullFriendlyBindings().isEmpty()); + } + + @Test + public void singleArg() { + query.from(survey).where(survey.name.eq("Bob")).select(survey.id); + SQLBindings bindings = query.getSQL(); + assertEquals("select SURVEY.ID\nfrom SURVEY SURVEY\nwhere SURVEY.NAME = ?", bindings.getSQL()); + assertEquals(Collections.singletonList("Bob"), bindings.getNullFriendlyBindings()); + } + + @Test + public void twoArgs() { + query.from(survey).where(survey.name.eq("Bob"), survey.name2.eq("A")).select(survey.id); + SQLBindings bindings = query.getSQL(); + assertEquals("select SURVEY.ID\nfrom SURVEY SURVEY\nwhere SURVEY.NAME = ? and SURVEY.NAME2 = ?", bindings.getSQL()); + assertEquals(Arrays.asList("Bob", "A"), bindings.getNullFriendlyBindings()); + } + + @Test + public void params() { + Param name = new Param(String.class, "name"); + query.from(survey).where(survey.name.eq(name), survey.name2.eq("A")).select(survey.id); + query.set(name, "Bob"); + SQLBindings bindings = query.getSQL(); + assertEquals("select SURVEY.ID\nfrom SURVEY SURVEY\nwhere SURVEY.NAME = ? and SURVEY.NAME2 = ?", bindings.getSQL()); + assertEquals(Arrays.asList("Bob", "A"), bindings.getNullFriendlyBindings()); + } +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/SQLCloseListenerTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/SQLCloseListenerTest.java new file mode 100644 index 0000000000..df8900d706 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/SQLCloseListenerTest.java @@ -0,0 +1,66 @@ +package com.querydsl.sql; + +import static com.querydsl.sql.Constants.employee; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; + +import java.sql.SQLException; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +import com.mysema.commons.lang.CloseableIterator; +import com.querydsl.core.testutil.H2; +import com.querydsl.sql.domain.Employee; + +@Category(H2.class) +public class SQLCloseListenerTest { + + private SQLQuery query; + + @Before + public void setUp() throws SQLException, ClassNotFoundException { + Connections.initH2(); + Configuration conf = new Configuration(H2Templates.DEFAULT); + conf.addListener(SQLCloseListener.DEFAULT); + query = new SQLQuery(Connections.getConnection(), conf).select(employee).from(employee); + } + + @After + public void tearDown() throws SQLException { + Connections.close(); + } + + @Test + public void fetch() { + assertFalse(query.fetch().isEmpty()); + } + + @Test + public void fetchOne() { + assertNotNull(query.limit(1).fetchOne()); + } + + @Test + public void fetchFirst() { + assertNotNull(query.fetchFirst()); + } + + @Test + public void fetchResults() { + assertNotNull(query.fetchResults()); + } + + @Test + public void iterate() { + try (CloseableIterator it = query.iterate()) { + while (it.hasNext()) { + it.next(); + } + } + } + + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/SQLListenersTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/SQLListenersTest.java new file mode 100644 index 0000000000..7b1177923b --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/SQLListenersTest.java @@ -0,0 +1,190 @@ +package com.querydsl.sql; + +import static org.easymock.EasyMock.*; +import static org.junit.Assert.assertThat; + +import java.util.List; +import java.util.Map; + +import org.hamcrest.CoreMatchers; +import org.junit.Test; + +import com.querydsl.core.DefaultQueryMetadata; +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.SubQueryExpression; +import com.querydsl.sql.dml.SQLInsertBatch; +import com.querydsl.sql.dml.SQLMergeBatch; +import com.querydsl.sql.dml.SQLUpdateBatch; + +public class SQLListenersTest { + + @Test + public void notifyQuery() { + SQLListener listener = createMock(SQLListener.class); + SQLListeners listeners = new SQLListeners(); + listeners.add(listener); + + QueryMetadata md = new DefaultQueryMetadata(); + listener.notifyQuery(md); + replay(listener); + + listeners.notifyQuery(md); + verify(listener); + } + + @Test + public void notifyQuery_parent() { + SQLListener listener = createMock(SQLListener.class); + SQLListeners listeners = new SQLListeners(listener); + + QueryMetadata md = new DefaultQueryMetadata(); + listener.notifyQuery(md); + replay(listener); + + listeners.notifyQuery(md); + verify(listener); + } + + + @Test + public void notifyQuery_detailedListener_start() { + SQLListenerContext sqlListenerContext = createMock(SQLListenerContext.class); + SQLDetailedListener listenerParent = createMock(SQLDetailedListener.class); + SQLDetailedListener listener1 = createMock(SQLDetailedListener.class); + SQLDetailedListener listener2 = createMock(SQLDetailedListener.class); + + listenerParent.start(sqlListenerContext); + replay(listenerParent); + + listener1.start(sqlListenerContext); + replay(listener1); + + listener2.start(sqlListenerContext); + replay(listener2); + + + SQLListeners listeners = new SQLListeners(listenerParent); + listeners.add(listener1); + listeners.add(listener2); + + listeners.start(sqlListenerContext); + verify(listenerParent); + verify(listener1); + verify(listener2); + } + + + @Test + public void notifyQuery_detailedListener_contexSetting() { + SQLListenerContext sqlListenerContext = new SQLListenerContextImpl(new DefaultQueryMetadata()); + SQLDetailedListener listenerParent = new AssertingDetailedListener("keyParent", "valueParent"); + SQLDetailedListener listener1 = new AssertingDetailedListener("key1", "value1"); + SQLDetailedListener listener2 = new AssertingDetailedListener("key1", "value1"); + + SQLListeners listeners = new SQLListeners(listenerParent); + listeners.add(listener1); + listeners.add(listener2); + + listeners.start(sqlListenerContext); + listeners.preRender(sqlListenerContext); + listeners.rendered(sqlListenerContext); + listeners.prePrepare(sqlListenerContext); + listeners.prepared(sqlListenerContext); + listeners.preExecute(sqlListenerContext); + listeners.preExecute(sqlListenerContext); + } + + static class AssertingDetailedListener implements SQLDetailedListener { + private final String key; + private final Object value; + + AssertingDetailedListener(String key, Object value) { + this.key = key; + this.value = value; + } + + @Override + public void start(SQLListenerContext context) { + context.setData(key, value); + } + + @Override + public void preRender(SQLListenerContext context) { + assertThat(this.value, CoreMatchers.equalTo(context.getData(key))); + } + + @Override + public void rendered(SQLListenerContext context) { + assertThat(this.value, CoreMatchers.equalTo(context.getData(key))); + } + + @Override + public void prePrepare(SQLListenerContext context) { + assertThat(this.value, CoreMatchers.equalTo(context.getData(key))); + } + + @Override + public void prepared(SQLListenerContext context) { + assertThat(this.value, CoreMatchers.equalTo(context.getData(key))); + } + + @Override + public void preExecute(SQLListenerContext context) { + assertThat(this.value, CoreMatchers.equalTo(context.getData(key))); + } + + @Override + public void executed(SQLListenerContext context) { + assertThat(this.value, CoreMatchers.equalTo(context.getData(key))); + } + + @Override + public void exception(SQLListenerContext context) { + assertThat(this.value, CoreMatchers.equalTo(context.getData(key))); + } + + @Override + public void end(SQLListenerContext context) { + assertThat(this.value, CoreMatchers.equalTo(context.getData(key))); + } + + @Override + public void notifyQuery(QueryMetadata md) { + } + + @Override + public void notifyDelete(RelationalPath entity, QueryMetadata md) { + } + + @Override + public void notifyDeletes(RelationalPath entity, List batches) { + } + + @Override + public void notifyMerge(RelationalPath entity, QueryMetadata md, List> keys, List> columns, List> values, SubQueryExpression subQuery) { + } + + @Override + public void notifyMerges(RelationalPath entity, QueryMetadata md, List batches) { + } + + @Override + public void notifyInsert(RelationalPath entity, QueryMetadata md, List> columns, List> values, SubQueryExpression subQuery) { + } + + @Override + public void notifyInserts(RelationalPath entity, QueryMetadata md, List batches) { + } + + @Override + public void notifyUpdate(RelationalPath entity, QueryMetadata md, Map, Expression> updates) { + } + + @Override + public void notifyUpdates(RelationalPath entity, List batches) { + } + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/SQLQueryFactoryTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/SQLQueryFactoryTest.java new file mode 100644 index 0000000000..447dd0b874 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/SQLQueryFactoryTest.java @@ -0,0 +1,67 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import static org.junit.Assert.assertNotNull; + +import java.sql.Connection; +import java.util.function.Supplier; + +import org.easymock.EasyMock; +import org.junit.Before; +import org.junit.Test; + +import com.querydsl.sql.domain.QSurvey; + +public class SQLQueryFactoryTest { + + private SQLQueryFactory queryFactory; + + @Before + public void setUp() { + Supplier provider = () -> EasyMock. createNiceMock(Connection.class); + queryFactory = new SQLQueryFactory(SQLTemplates.DEFAULT, provider); + } + + @Test + public void query() { + assertNotNull(queryFactory.query()); + } + + @Test + public void from() { + assertNotNull(queryFactory.from(QSurvey.survey)); + } + + @Test + public void delete() { + assertNotNull(queryFactory.delete(QSurvey.survey)); + } + + @Test + public void insert() { + assertNotNull(queryFactory.insert(QSurvey.survey)); + } + + @Test + public void update() { + assertNotNull(queryFactory.update(QSurvey.survey)); + } + + @Test + public void merge() { + assertNotNull(queryFactory.merge(QSurvey.survey)); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/SQLQueryTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/SQLQueryTest.java new file mode 100644 index 0000000000..0b8bc33d11 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/SQLQueryTest.java @@ -0,0 +1,15 @@ +package com.querydsl.sql; + +import org.junit.Test; + +import com.querydsl.sql.domain.QSurvey; + +public class SQLQueryTest { + + @Test(expected = IllegalStateException.class) + public void noConnection() { + QSurvey survey = QSurvey.survey; + SQLExpressions.select(survey.id).from(survey).fetch(); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/SQLSerializerTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/SQLSerializerTest.java new file mode 100644 index 0000000000..c5cfb17e64 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/SQLSerializerTest.java @@ -0,0 +1,460 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import static com.querydsl.sql.SQLExpressions.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; + +import java.sql.Connection; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.TimeZone; + +import com.querydsl.core.types.*; +import com.querydsl.sql.dml.SQLDeleteClause; +import org.easymock.EasyMock; +import org.junit.Test; + +import com.querydsl.core.BooleanBuilder; +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.Tuple; +import com.querydsl.core.types.dsl.*; +import com.querydsl.sql.domain.QEmployee; +import com.querydsl.sql.domain.QEmployeeNoPK; +import com.querydsl.sql.domain.QSurvey; + +public class SQLSerializerTest { + + private static final QEmployee employee = QEmployee.employee; + + private static final QSurvey survey = QSurvey.survey; + + @Test + public void count() { + SQLSerializer serializer = new SQLSerializer(Configuration.DEFAULT); + serializer.handle(employee.id.count().add(employee.id.countDistinct())); + assertEquals("count(EMPLOYEE.ID) + count(distinct EMPLOYEE.ID)", serializer.toString()); + } + + @Test + public void countDistinct() { + SQLSerializer serializer = new SQLSerializer(Configuration.DEFAULT); + SQLQuery query = new SQLQuery(); + query.from(QEmployeeNoPK.employee); + query.distinct(); + serializer.serializeForQuery(query.getMetadata(), true); + assertEquals("select count(*)\n" + + "from (select distinct EMPLOYEE.ID, EMPLOYEE.FIRSTNAME, EMPLOYEE.LASTNAME, EMPLOYEE.SALARY, " + + "EMPLOYEE.DATEFIELD, EMPLOYEE.TIMEFIELD, EMPLOYEE.SUPERIOR_ID\n" + + "from EMPLOYEE EMPLOYEE) internal", serializer.toString()); + } + + @Test + public void countDistinct_postgreSQL() { + Configuration postgresql = new Configuration(new PostgreSQLTemplates()); + SQLSerializer serializer = new SQLSerializer(postgresql); + SQLQuery query = new SQLQuery(); + query.from(QEmployeeNoPK.employee); + query.distinct(); + serializer.serializeForQuery(query.getMetadata(), true); + assertEquals("select count(" + + "distinct (EMPLOYEE.ID, EMPLOYEE.FIRSTNAME, EMPLOYEE.LASTNAME, EMPLOYEE.SALARY, " + + "EMPLOYEE.DATEFIELD, EMPLOYEE.TIMEFIELD, EMPLOYEE.SUPERIOR_ID))\n" + + "from EMPLOYEE EMPLOYEE", serializer.toString()); + } + + @Test + public void dynamicQuery() { + Path userPath = Expressions.path(Object.class, "user"); + NumberPath idPath = Expressions.numberPath(Long.class, userPath, "id"); + StringPath usernamePath = Expressions.stringPath(userPath, "username"); + Expression sq = select(idPath, usernamePath) + .from(userPath).where(idPath.eq(1L)); + + SQLSerializer serializer = new SQLSerializer(Configuration.DEFAULT); + serializer.handle(sq); + //USER is a reserved word in ANSI SQL 2008 + assertEquals("(select \"user\".id, \"user\".username\n" + + "from \"user\"\n" + + "where \"user\".id = ?)", serializer.toString()); + } + + @Test + public void dynamicQuery2() { + PathBuilder userPath = new PathBuilder(Object.class, "user"); + NumberPath idPath = userPath.getNumber("id", Long.class); + StringPath usernamePath = userPath.getString("username"); + Expression sq = select(idPath, usernamePath) + .from(userPath).where(idPath.eq(1L)); + + SQLSerializer serializer = new SQLSerializer(Configuration.DEFAULT); + serializer.handle(sq); + //USER is a reserved word in ANSI SQL 2008 + assertEquals("(select \"user\".id, \"user\".username\n" + + "from \"user\"\n" + + "where \"user\".id = ?)", serializer.toString()); + } + + @Test + public void in() { + StringPath path = Expressions.stringPath("str"); + Expression expr = ExpressionUtils.in(path, Arrays.asList("1", "2", "3")); + + SQLSerializer serializer = new SQLSerializer(Configuration.DEFAULT); + serializer.handle(expr); + assertEquals(Arrays.asList(path, path, path), serializer.getConstantPaths()); + assertEquals(3, serializer.getConstants().size()); + } + + @Test + public void fullJoinWithoutCodeGeneration() { + SQLQuery sqlQuery = queryForMYSQLTemplate(); + + PathBuilder customerPath = new PathBuilder(Object.class, "customer"); + PathBuilder deptPath = new PathBuilder(Object.class, "department"); + Path deptAliasPath = new PathBuilder(Object.class, "d"); + sqlQuery = sqlQuery.from(customerPath.as("c")); + NumberPath idPath = Expressions.numberPath(Long.class, deptAliasPath, "id"); + + sqlQuery = sqlQuery.fullJoin(deptPath, deptAliasPath).select(idPath); + + assertEquals("select d.id from customer as c full join department as d", sqlQuery.toString()); + } + + @Test + public void innerJoinWithoutCodeGeneration() { + SQLQuery sqlQuery = queryForMYSQLTemplate(); + + PathBuilder customerPath = new PathBuilder(Object.class, "customer"); + PathBuilder deptPath = new PathBuilder(Object.class, "department"); + Path deptAliasPath = new PathBuilder(Object.class, "d"); + sqlQuery = sqlQuery.from(customerPath.as("c")); + NumberPath idPath = Expressions.numberPath(Long.class, deptAliasPath, "id"); + + sqlQuery = sqlQuery.innerJoin(deptPath, deptAliasPath).select(idPath); + + assertEquals("select d.id from customer as c inner join department as d", sqlQuery.toString()); + } + + @Test + public void joinWithoutCodeGeneration() { + SQLQuery sqlQuery = queryForMYSQLTemplate(); + + PathBuilder customerPath = new PathBuilder(Object.class, "customer"); + PathBuilder deptPath = new PathBuilder(Object.class, "department"); + Path deptAliasPath = new PathBuilder(Object.class, "d"); + sqlQuery = sqlQuery.from(customerPath.as("c")); + NumberPath idPath = Expressions.numberPath(Long.class, deptAliasPath, "id"); + + sqlQuery = sqlQuery.join(deptPath, deptAliasPath).select(idPath); + + assertEquals("select d.id from customer as c join department as d", sqlQuery.toString()); + } + + @Test + public void leftJoinWithoutCodeGeneration() { + SQLQuery sqlQuery = queryForMYSQLTemplate(); + + PathBuilder customerPath = new PathBuilder(Object.class, "customer"); + PathBuilder deptPath = new PathBuilder(Object.class, "department"); + Path deptAliasPath = new PathBuilder(Object.class, "d"); + sqlQuery = sqlQuery.from(customerPath.as("c")); + NumberPath idPath = Expressions.numberPath(Long.class, deptAliasPath, "id"); + + sqlQuery = sqlQuery.leftJoin(deptPath, deptAliasPath).select(idPath); + + assertEquals("select d.id from customer as c left join department as d", sqlQuery.toString()); + } + + @Test + public void or_in() { + StringPath path = Expressions.stringPath("str"); + Expression expr = ExpressionUtils.anyOf( + ExpressionUtils.in(path, Arrays.asList("1", "2", "3")), + ExpressionUtils.in(path, Arrays.asList("4", "5", "6"))); + + SQLSerializer serializer = new SQLSerializer(Configuration.DEFAULT); + serializer.handle(expr); + assertEquals(Arrays.asList(path, path, path, path, path, path), serializer.getConstantPaths()); + assertEquals(6, serializer.getConstants().size()); + } + + @Test + public void some() { + //select some((e.FIRSTNAME is not null)) from EMPLOYEE + SQLSerializer serializer = new SQLSerializer(Configuration.DEFAULT); + serializer.handle(SQLExpressions.any(employee.firstname.isNotNull())); + assertEquals("some(EMPLOYEE.FIRSTNAME is not null)", serializer.toString()); + } + + @Test + public void startsWith() { + SQLSerializer serializer = new SQLSerializer(Configuration.DEFAULT); + QSurvey s1 = new QSurvey("s1"); + serializer.handle(s1.name.startsWith("X")); + assertEquals("s1.NAME like ? escape '\\'", serializer.toString()); + assertEquals(Collections.singletonList("X%"), serializer.getConstants()); + } + + @Test + public void from_function() { + SQLQuery query = query(); + query.from(Expressions.template(Survey.class, "functionCall()")).join(survey); + query.where(survey.name.isNotNull()); + assertEquals("from functionCall()\njoin SURVEY SURVEY\nwhere SURVEY.NAME is not null", query.toString()); + } + + @Test + public void join_to_function_with_alias() { + SQLQuery query = query(); + query.from(survey).join(SQLExpressions.relationalFunctionCall(Survey.class, "functionCall"), Expressions.path(Survey.class, "fc")); + query.where(survey.name.isNotNull()); + assertEquals("from SURVEY SURVEY\njoin functionCall() as fc\nwhere SURVEY.NAME is not null", query.toString()); + } + + @Test + public void join_to_function_in_derby() { + SQLQuery query = new SQLQuery(DerbyTemplates.DEFAULT); + query.from(survey).join(SQLExpressions.relationalFunctionCall(Survey.class, "functionCall"), Expressions.path(Survey.class, "fc")); + query.where(survey.name.isNotNull()); + assertEquals("from SURVEY SURVEY\njoin table(functionCall()) as fc\nwhere SURVEY.NAME is not null", query.toString()); + } + + @Test + public void crossJoin() { + SQLTemplates templates = new DerbyTemplates(); + templates.setCrossJoin(" cross join "); + SQLQuery query = new SQLQuery(templates); + query.from(survey, employee); + assertEquals("from SURVEY SURVEY cross join EMPLOYEE EMPLOYEE", query.toString()); + } + + @Test + public void keyword_after_dot() { + SQLQuery query = new SQLQuery(MySQLTemplates.DEFAULT); + PathBuilder surveyBuilder = new PathBuilder(Survey.class, "survey"); + query.from(surveyBuilder).where(surveyBuilder.get("not").isNotNull()); + assertFalse(query.toString().contains("`")); + } + + @Test + public void like() { + Expression expr = Expressions.stringTemplate("'%a%'").contains("%a%"); + SQLSerializer serializer = new SQLSerializer(Configuration.DEFAULT); + serializer.handle(expr); + assertEquals("'%a%' like ? escape '\\'", serializer.toString()); + } + + @Test + public void override() { + Configuration conf = new Configuration(new DerbyTemplates()); + conf.registerTableOverride("SURVEY", "surveys"); + + SQLQuery query = new SQLQuery(conf); + query.from(survey); + assertEquals("from surveys SURVEY", query.toString()); + } + + @Test + public void columnOverrides() { + Configuration conf = new Configuration(new DerbyTemplates()); + conf.registerColumnOverride("SURVEY", "NAME", "LABEL"); + + SQLQuery query = new SQLQuery(conf); + query.from(survey).where(survey.name.isNull()); + assertEquals("from SURVEY SURVEY\n" + + "where SURVEY.LABEL is null", query.toString()); + } + + @Test + public void columnOverrides2() { + Configuration conf = new Configuration(new DerbyTemplates()); + conf.registerColumnOverride("PUBLIC", "SURVEY", "NAME", "LABEL"); + + SQLQuery query = new SQLQuery(conf); + query.from(survey).where(survey.name.isNull()); + assertEquals("from SURVEY SURVEY\n" + + "where SURVEY.LABEL is null", query.toString()); + } + + @Test + public void complex_subQuery() { + // create sub queries + List> sq = new ArrayList>(); + String[] strs = new String[]{"a","b","c"}; + for (String str : strs) { + Expression alias = Expressions.cases().when(survey.name.eq(str)).then(true).otherwise(false); + sq.add(select(survey.name, alias).from(survey).distinct()); + } + + // master query + PathBuilder subAlias = new PathBuilder(Tuple.class, "sub"); + SubQueryExpression master = selectOne() + .from(union(sq).as(subAlias)) + .groupBy(subAlias.get("prop1")); + + SQLSerializer serializer = new SQLSerializer(Configuration.DEFAULT); + serializer.serialize(master.getMetadata(), false); + System.err.println(serializer); + } + + @Test + public void boolean_() { + QSurvey s = new QSurvey("s"); + BooleanBuilder bb1 = new BooleanBuilder(); + bb1.and(s.name.eq(s.name)); + + BooleanBuilder bb2 = new BooleanBuilder(); + bb2.or(s.name.eq(s.name)); + bb2.or(s.name.eq(s.name)); + + String str = new SQLSerializer(Configuration.DEFAULT).handle(bb1.and(bb2)).toString(); + assertEquals("s.NAME = s.NAME and (s.NAME = s.NAME or s.NAME = s.NAME)", str); + } + + @Test + public void list_in_query() { + Expression expr = Expressions.list(survey.id, survey.name).in(select(survey.id, survey.name).from(survey)); + + String str = new SQLSerializer(Configuration.DEFAULT).handle(expr).toString(); + assertEquals("(SURVEY.ID, SURVEY.NAME) in (select SURVEY.ID, SURVEY.NAME\nfrom SURVEY SURVEY)", str); + } + + @SuppressWarnings("unchecked") + @Test + public void withRecursive() { + /*with sub (id, firstname, superior_id) as ( + select id, firstname, superior_id from employee where firstname like 'Mike' + union all + select employee.id, employee.firstname, employee.superior_id from sub, employee + where employee.superior_id = sub.id) + select * from sub;*/ + + QEmployee e = QEmployee.employee; + PathBuilder sub = new PathBuilder(Tuple.class, "sub"); + SQLQuery query = new SQLQuery(SQLTemplates.DEFAULT); + query.withRecursive(sub, + unionAll( + select(e.id, e.firstname, e.superiorId).from(e).where(e.firstname.eq("Mike")), + select(e.id, e.firstname, e.superiorId).from(e, sub).where(e.superiorId.eq(sub.get(e.id))))) + .from(sub); + + QueryMetadata md = query.getMetadata(); + md.setProjection(Wildcard.all); + SQLSerializer serializer = new SQLSerializer(Configuration.DEFAULT); + serializer.serialize(md, false); + assertEquals("with recursive sub as ((select EMPLOYEE.ID, EMPLOYEE.FIRSTNAME, EMPLOYEE.SUPERIOR_ID\n" + + "from EMPLOYEE EMPLOYEE\n" + + "where EMPLOYEE.FIRSTNAME = ?)\n" + + "union all\n" + + "(select EMPLOYEE.ID, EMPLOYEE.FIRSTNAME, EMPLOYEE.SUPERIOR_ID\n" + + "from EMPLOYEE EMPLOYEE, sub\n" + + "where EMPLOYEE.SUPERIOR_ID = sub.ID))\n" + + "select *\n" + + "from sub", serializer.toString()); + + } + + @SuppressWarnings("unchecked") + @Test + public void withRecursive2() { + /*with sub (id, firstname, superior_id) as ( + select id, firstname, superior_id from employee where firstname like 'Mike' + union all + select employee.id, employee.firstname, employee.superior_id from sub, employee + where employee.superior_id = sub.id) + select * from sub;*/ + + QEmployee e = QEmployee.employee; + PathBuilder sub = new PathBuilder(Tuple.class, "sub"); + SQLQuery query = new SQLQuery(SQLTemplates.DEFAULT); + query.withRecursive(sub, sub.get(e.id), sub.get(e.firstname), sub.get(e.superiorId)).as( + unionAll( + select(e.id, e.firstname, e.superiorId).from(e).where(e.firstname.eq("Mike")), + select(e.id, e.firstname, e.superiorId).from(e, sub).where(e.superiorId.eq(sub.get(e.id))))) + .from(sub); + + QueryMetadata md = query.getMetadata(); + md.setProjection(Wildcard.all); + SQLSerializer serializer = new SQLSerializer(Configuration.DEFAULT); + serializer.serialize(md, false); + assertEquals("with recursive sub (ID, FIRSTNAME, SUPERIOR_ID) as ((select EMPLOYEE.ID, EMPLOYEE.FIRSTNAME, EMPLOYEE.SUPERIOR_ID\n" + + "from EMPLOYEE EMPLOYEE\n" + + "where EMPLOYEE.FIRSTNAME = ?)\n" + + "union all\n" + + "(select EMPLOYEE.ID, EMPLOYEE.FIRSTNAME, EMPLOYEE.SUPERIOR_ID\n" + + "from EMPLOYEE EMPLOYEE, sub\n" + + "where EMPLOYEE.SUPERIOR_ID = sub.ID))\n" + + "select *\n" + + "from sub", serializer.toString()); + + } + + @Test + public void useLiterals() { + SQLSerializer serializer = new SQLSerializer(Configuration.DEFAULT); + serializer.setUseLiterals(true); + + int offset = TimeZone.getDefault().getRawOffset(); + Expression expr = SQLExpressions.datediff(DatePart.year, employee.datefield, new java.sql.Date(-offset)); + serializer.handle(expr); + assertEquals("datediff('year',EMPLOYEE.DATEFIELD,(date '1970-01-01'))", serializer.toString()); + } + + @Test + public void select_normalization() { + SQLSerializer serializer = new SQLSerializer(Configuration.DEFAULT); + serializer.visit(select( + Expressions.stringPath("id"), Expressions.stringPath("ID")), null); + assertEquals("(select id, ID as col__ID1\n" + + "from dual)", serializer.toString()); + } + + @Test + public void noSchemaInWhere() { + Configuration defaultWithPrintSchema = new Configuration(new SQLTemplates(Keywords.DEFAULT, "\"", '\\', false, false)); + defaultWithPrintSchema.getTemplates().setPrintSchema(true); + + QEmployee e = QEmployee.employee; + SQLDeleteClause delete = new SQLDeleteClause(EasyMock. createNiceMock(Connection.class), defaultWithPrintSchema, e); + delete.where(e.id.gt(100)); + + assertEquals("delete from PUBLIC.EMPLOYEE\n" + + "where EMPLOYEE.ID > ?", delete.toString()); + } + + @Test + public void schemaInWhere() { + Configuration derbyWithPrintSchema = new Configuration(DerbyTemplates.builder().printSchema().build()); + + QEmployee e = QEmployee.employee; + SQLDeleteClause delete = new SQLDeleteClause(EasyMock. createNiceMock(Connection.class), derbyWithPrintSchema, e); + delete.where(e.id.gt(100)); + + assertEquals("delete from \"PUBLIC\".EMPLOYEE\n" + + "where \"PUBLIC\".EMPLOYEE.ID > ?", delete.toString()); + } + + private SQLQuery query() { + return new SQLQuery(); + } + + private SQLQuery queryForMYSQLTemplate() { + return new SQLQuery(MySQLTemplates.builder().printSchema().newLineToSingleSpace().build()); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/SQLServer2005TemplatesTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/SQLServer2005TemplatesTest.java new file mode 100644 index 0000000000..863c3cc420 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/SQLServer2005TemplatesTest.java @@ -0,0 +1,116 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import static com.querydsl.sql.SQLExpressions.select; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +import com.querydsl.core.types.*; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberExpression; + +public class SQLServer2005TemplatesTest extends AbstractSQLTemplatesTest { + + @Override + @Test + public void noFrom() { + query.getMetadata().setProjection(Expressions.ONE); + assertEquals("select 1", query.toString()); + } + + @Override + protected SQLTemplates createTemplates() { + return new SQLServer2005Templates(); + } + + @SuppressWarnings("unchecked") + @Test + @Override + public void union() { + NumberExpression one = Expressions.ONE; + NumberExpression two = Expressions.TWO; + NumberExpression three = Expressions.THREE; + Path col1 = Expressions.path(Integer.class, "col1"); + Union union = query.union( + select(one.as(col1)), + select(two), + select(three)); + assertEquals( + "(select 1 as col1)\n" + + "union\n" + + "(select 2)\n" + + "union\n" + + "(select 3)", union.toString()); + } + + @Test + public void limit() { + query.from(survey1).limit(5); + query.getMetadata().setProjection(survey1.id); + assertEquals("select top (?) survey1.ID from SURVEY survey1", query.toString()); + } + + @Test + public void modifiers() { + query.from(survey1).limit(5).offset(3); + query.orderBy(survey1.id.asc()); + query.getMetadata().setProjection(survey1.id); + assertEquals("select * from (" + + " select survey1.ID, row_number() over (order by survey1.ID asc) as rn from SURVEY survey1) a " + + "where rn > ? and rn <= ? order by rn", query.toString()); + } + + @Test + public void modifiers_noOrder() { + query.from(survey1).limit(5).offset(3); + query.getMetadata().setProjection(survey1.id); + assertEquals("select * from (" + + " select survey1.ID, row_number() over (order by current_timestamp asc) as rn from SURVEY survey1) a " + + "where rn > ? and rn <= ? order by rn", query.toString()); + } + + @Test + public void nextVal() { + Operation nextval = ExpressionUtils.operation(String.class, SQLOps.NEXTVAL, ConstantImpl.create("myseq")); + assertEquals("myseq.nextval", new SQLSerializer(new Configuration(new SQLServerTemplates())).handle(nextval).toString()); + } + + @Test + public void precedence() { + // 1 ~ (Bitwise NOT) + // 2 (Multiply), / (Division), % (Modulo) + int p2 = getPrecedence(Ops.MULT, Ops.DIV, Ops.MOD); + // 3 + (Positive), - (Negative), + (Add), (+ Concatenate), - (Subtract), & (Bitwise AND), ^ (Bitwise Exclusive OR), | (Bitwise OR) + int p3 = getPrecedence(Ops.NEGATE, Ops.ADD, Ops.SUB, Ops.CONCAT); + // 4 =, >, <, >=, <=, <>, !=, !>, !< (Comparison operators) + int p4 = getPrecedence(Ops.EQ, Ops.GT, Ops.LT, Ops.GOE, Ops.LOE, Ops.NE); + // 5 NOT + int p5 = getPrecedence(Ops.NOT); + // 6 AND + int p6 = getPrecedence(Ops.AND); + // 7 ALL, ANY, BETWEEN, IN, LIKE, OR, SOME + int p7 = getPrecedence(Ops.BETWEEN, Ops.IN, Ops.LIKE, Ops.LIKE_ESCAPE, Ops.OR); + // 8 = (Assignment) + + assertTrue(p2 < p3); + assertTrue(p3 < p4); + assertTrue(p4 < p5); + assertTrue(p5 < p6); + assertTrue(p6 < p7); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/SQLServer2012TemplatesTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/SQLServer2012TemplatesTest.java new file mode 100644 index 0000000000..694e3b00b1 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/SQLServer2012TemplatesTest.java @@ -0,0 +1,112 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import static com.querydsl.sql.SQLExpressions.select; +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import com.querydsl.core.types.ConstantImpl; +import com.querydsl.core.types.ExpressionUtils; +import com.querydsl.core.types.Operation; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberExpression; +import com.querydsl.sql.dml.SQLDeleteClause; +import com.querydsl.sql.dml.SQLUpdateClause; + + +public class SQLServer2012TemplatesTest extends AbstractSQLTemplatesTest { + + @Override + @Test + public void noFrom() { + query.getMetadata().setProjection(Expressions.ONE); + assertEquals("select 1", query.toString()); + } + + @Override + protected SQLTemplates createTemplates() { + return new SQLServer2012Templates(); + } + + @SuppressWarnings("unchecked") + @Test + @Override + public void union() { + NumberExpression one = Expressions.ONE; + NumberExpression two = Expressions.TWO; + NumberExpression three = Expressions.THREE; + Path col1 = Expressions.path(Integer.class,"col1"); + Union union = query.union( + select(one.as(col1)), + select(two), + select(three)); + assertEquals( + "(select 1 as col1)\n" + + "union\n" + + "(select 2)\n" + + "union\n" + + "(select 3)", union.toString()); + } + + @Test + public void limit() { + query.from(survey1).limit(5); + query.getMetadata().setProjection(survey1.id); + assertEquals("select top 5 survey1.ID from SURVEY survey1", query.toString()); + } + + @Test + public void limitOffset() { + query.from(survey1).limit(5).offset(5); + query.getMetadata().setProjection(survey1.id); + assertEquals("select survey1.ID from SURVEY survey1 " + + "order by 1 asc " + + "offset ? rows fetch next ? rows only", query.toString()); + } + + @Test + public void delete_limit() { + SQLDeleteClause clause = new SQLDeleteClause(null, createTemplates(), survey1); + clause.where(survey1.name.eq("Bob")); + clause.limit(5); + assertEquals("delete top 5 from SURVEY\n" + + "where SURVEY.NAME = ?", clause.toString()); + } + + @Test + public void update_limit() { + SQLUpdateClause clause = new SQLUpdateClause(null, createTemplates(), survey1); + clause.set(survey1.name, "Bob"); + clause.limit(5); + assertEquals("update top 5 SURVEY\n" + + "set NAME = ?", clause.toString()); + } + + @Test + public void modifiers() { + query.from(survey1).limit(5).offset(3).orderBy(survey1.id.asc()); + query.getMetadata().setProjection(survey1.id); + assertEquals("select survey1.ID from SURVEY survey1 order by survey1.ID asc offset ? rows fetch next ? rows only", query.toString()); + } + + @Test + public void nextVal() { + Operation nextval = ExpressionUtils.operation(String.class, SQLOps.NEXTVAL, ConstantImpl.create("myseq")); + assertSerialized(nextval, "next value for myseq"); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/SQLServerTemplatesTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/SQLServerTemplatesTest.java new file mode 100644 index 0000000000..1fa0729aae --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/SQLServerTemplatesTest.java @@ -0,0 +1,86 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import static com.querydsl.sql.SQLExpressions.select; +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import com.querydsl.core.types.ConstantImpl; +import com.querydsl.core.types.ExpressionUtils; +import com.querydsl.core.types.Operation; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberExpression; + + +public class SQLServerTemplatesTest extends AbstractSQLTemplatesTest { + + @Override + @Test + public void noFrom() { + query.getMetadata().setProjection(Expressions.ONE); + assertEquals("select 1", query.toString()); + } + + @Override + protected SQLTemplates createTemplates() { + return new SQLServerTemplates(); + } + + @SuppressWarnings("unchecked") + @Test + @Override + public void union() { + NumberExpression one = Expressions.ONE; + NumberExpression two = Expressions.TWO; + NumberExpression three = Expressions.THREE; + Path col1 = Expressions.path(Integer.class,"col1"); + Union union = query.union( + select(one.as(col1)), + select(two), + select(three)); + assertEquals( + "(select 1 as col1)\n" + + "union\n" + + "(select 2)\n" + + "union\n" + + "(select 3)", union.toString()); + } + + @Test + public void limit() { + query.from(survey1).limit(5); + query.getMetadata().setProjection(survey1.id); + assertEquals("select top 5 survey1.ID from SURVEY survey1", query.toString()); + } + + @Test + public void nextVal() { + Operation nextval = ExpressionUtils.operation(String.class, SQLOps.NEXTVAL, ConstantImpl.create("myseq")); + assertEquals("myseq.nextval", new SQLSerializer(new Configuration(new SQLServerTemplates())).handle(nextval).toString()); + } + + @SuppressWarnings("rawtypes") + @Test + public void truncateWeek() { + final SQLQuery expression = query.select( + SQLExpressions.datetrunc(DatePart.week, + Expressions.dateTimeTemplate(Comparable.class, "dateExpression"))); + assertEquals("select DATEADD(WEEK, DATEDIFF(WEEK, 0, dateExpression - 1), 0)", + expression.toString()); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/SQLSubQueryTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/SQLSubQueryTest.java new file mode 100644 index 0000000000..ea7d141809 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/SQLSubQueryTest.java @@ -0,0 +1,180 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import static com.querydsl.sql.SQLExpressions.select; +import static com.querydsl.sql.SQLExpressions.union; +import static org.junit.Assert.assertEquals; + +import java.util.List; + +import org.junit.Test; + +import com.querydsl.core.types.*; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.Wildcard; +import com.querydsl.sql.domain.QEmployee; +import com.querydsl.sql.domain.QSurvey; + +public class SQLSubQueryTest { + + private static final QEmployee employee = QEmployee.employee; + + @Test(expected = IllegalArgumentException.class) + public void unknownOperator() { + Operator op = new Operator() { + public String name() { + return "unknownfn"; + } + public String toString() { + return name(); + } + public Class getType() { + return Object.class; + } + }; + SQLQuery query = new SQLQuery(); + query.from(employee) + .where(Expressions.booleanOperation(op, employee.id)).toString(); + } + + @SuppressWarnings("unchecked") + @Test + public void list() { + SubQueryExpression subQuery = select(employee.id, Expressions.constant("XXX"), employee.firstname).from(employee); + List> exprs = ((FactoryExpression) subQuery.getMetadata().getProjection()).getArgs(); + assertEquals(employee.id, exprs.get(0)); + assertEquals(ConstantImpl.create("XXX"), exprs.get(1)); + assertEquals(employee.firstname, exprs.get(2)); + } + + @Test + public void list_entity() { + QEmployee employee2 = new QEmployee("employee2"); + Expression expr = select(employee, employee2.id).from(employee) + .innerJoin(employee.superiorIdKey, employee2); + + SQLSerializer serializer = new SQLSerializer(new Configuration(SQLTemplates.DEFAULT)); + serializer.handle(expr); + + assertEquals("(select EMPLOYEE.ID, EMPLOYEE.FIRSTNAME, EMPLOYEE.LASTNAME, EMPLOYEE.SALARY, EMPLOYEE.DATEFIELD, EMPLOYEE.TIMEFIELD, EMPLOYEE.SUPERIOR_ID, employee2.ID as col__ID7\n" + + "from EMPLOYEE EMPLOYEE\n" + + "inner join EMPLOYEE employee2\n" + + "on EMPLOYEE.SUPERIOR_ID = employee2.ID)", serializer.toString()); + } + + @Test + public void in() { + SubQueryExpression ints = select(employee.id).from(employee); + QEmployee.employee.id.in(ints); + } + + @SuppressWarnings("unchecked") + @Test + public void in_union() { + SubQueryExpression ints1 = select(employee.id).from(employee); + SubQueryExpression ints2 = select(employee.id).from(employee); + QEmployee.employee.id.in(union(ints1, ints2)); + } + + @SuppressWarnings("unchecked") + @Test + public void in_union2() { + SubQueryExpression ints1 = select(employee.id).from(employee); + SubQueryExpression ints2 = select(employee.id).from(employee); + QEmployee.employee.id.in(union(ints1, ints2)); + } + + @SuppressWarnings("unchecked") + @Test + public void unique() { + SubQueryExpression subQuery = select(employee.id, Expressions.constant("XXX"), employee.firstname).from(employee); + List> exprs = ((FactoryExpression) subQuery.getMetadata().getProjection()).getArgs(); + assertEquals(employee.id, exprs.get(0)); + assertEquals(ConstantImpl.create("XXX"), exprs.get(1)); + assertEquals(employee.firstname, exprs.get(2)); + } + + @Test + public void complex() { + // related to #584795 + QSurvey survey = new QSurvey("survey"); + QEmployee emp1 = new QEmployee("emp1"); + QEmployee emp2 = new QEmployee("emp2"); + SubQueryExpression subQuery = select(survey.id, emp2.firstname).from(survey) + .innerJoin(emp1) + .on(survey.id.eq(emp1.id)) + .innerJoin(emp2) + .on(emp1.superiorId.eq(emp2.superiorId), emp1.firstname.eq(emp2.firstname)); + + assertEquals(3, subQuery.getMetadata().getJoins().size()); + } + + @Test + public void validate() { + NumberPath operatorTotalPermits = Expressions.numberPath(Long.class, "operator_total_permits"); + QSurvey survey = new QSurvey("survey"); + + // select survey.name, count(*) as operator_total_permits + // from survey + // where survey.name >= "A" + // group by survey.name + // order by operator_total_permits asc + // limit 10 + + Expression e = select(survey.name, Wildcard.count.as(operatorTotalPermits)).from(survey) + .where(survey.name.goe("A")) + .groupBy(survey.name) + .orderBy(operatorTotalPermits.asc()) + .limit(10) + .as("top"); + + select(Wildcard.all).from(e); + } + + @SuppressWarnings("unchecked") + @Test + public void union1() { + QSurvey survey = QSurvey.survey; + SubQueryExpression q1 = select(survey.id).from(survey); + SubQueryExpression q2 = select(survey.id).from(survey); + union(q1, q2); + union(q1); + } + + @SuppressWarnings("unchecked") + @Test + public void union1_with() { + QSurvey survey1 = new QSurvey("survey1"); + QSurvey survey2 = new QSurvey("survey2"); + QSurvey survey3 = new QSurvey("survey3"); + + SQLQuery query = new SQLQuery(); + query.with(survey1, select(survey1.all()).from(survey1)); + query.union( + select(survey2.all()).from(survey2), + select(survey3.all()).from(survey3)); + + assertEquals("with survey1 as (select survey1.NAME, survey1.NAME2, survey1.ID\n" + + "from SURVEY survey1)\n" + + "(select survey2.NAME, survey2.NAME2, survey2.ID\n" + + "from SURVEY survey2)\n" + + "union\n" + + "(select survey3.NAME, survey3.NAME2, survey3.ID\n" + + "from SURVEY survey3)", query.toString()); + + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/SQLTemplatesRegistryDump.java b/querydsl-sql/src/test/java/com/querydsl/sql/SQLTemplatesRegistryDump.java new file mode 100644 index 0000000000..c00c57d053 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/SQLTemplatesRegistryDump.java @@ -0,0 +1,43 @@ +package com.querydsl.sql; + +import java.sql.DatabaseMetaData; +import java.sql.SQLException; + +public final class SQLTemplatesRegistryDump { + + private SQLTemplatesRegistryDump() { } + + public static void main(String[] args) throws SQLException, ClassNotFoundException { + Connections.initCubrid(); + dump(); + Connections.initDerby(); + dump(); + Connections.initFirebird(); + dump(); + Connections.initH2(); + dump(); + Connections.initHSQL(); + dump(); + Connections.initMySQL(); + dump(); + Connections.initOracle(); + dump(); + Connections.initPostgreSQL(); + dump(); + Connections.initSQLite(); + dump(); + Connections.initSQLServer(); + dump(); + /*Connections.initTeradata(); + dump();*/ + } + + private static void dump() throws SQLException { + DatabaseMetaData md = Connections.getConnection().getMetaData(); + System.out.println(md.getDatabaseProductName()); + System.out.println(md.getDatabaseMajorVersion()); + System.out.println(md.getDatabaseMinorVersion()); + System.out.println(); + Connections.close(); + } +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/SQLTemplatesTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/SQLTemplatesTest.java new file mode 100644 index 0000000000..c7bbfae81e --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/SQLTemplatesTest.java @@ -0,0 +1,123 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.sql.Date; +import java.sql.Time; +import java.sql.Timestamp; + +import org.joda.time.DateTime; +import org.joda.time.LocalDate; +import org.joda.time.LocalTime; +import org.junit.Test; + +import com.querydsl.core.types.*; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberPath; + +public class SQLTemplatesTest { + + private static final String DATETIME = "\\(timestamp '\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}'\\)"; + private static final String TIME = "\\(time '\\d{2}:\\d{2}:\\d{2}'\\)"; + private static final String DATE = "\\(date '\\d{4}-\\d{2}-\\d{2}'\\)"; + + private static void assertMatches(String regex, String str) { + assertTrue(str, str.matches(regex)); + } + + @Test + public void test() { + Template template = TemplateFactory.DEFAULT.create("fetch first {0s} rows only"); + assertTrue(template.getElements().get(1) instanceof Template.AsString); + + SQLSerializer serializer = new SQLSerializer(new Configuration(new DerbyTemplates())); + serializer.handle(Expressions.template(Object.class, template, ConstantImpl.create(5))); + assertEquals("fetch first 5 rows only", serializer.toString()); + } + + @Test + public void testRequiresQuotes() { + assertTrue(SQLTemplates.DEFAULT.requiresQuotes("First Name", false)); + } + + @Test + public void asLiteral() { + SQLTemplates templates = SQLTemplates.DEFAULT; + Configuration conf = new Configuration(templates); + assertMatches(DATE, conf.asLiteral(new Date(0))); + assertMatches(TIME, conf.asLiteral(new Time(0))); + assertMatches(DATETIME, conf.asLiteral(new Timestamp(0))); + } + + @Test + public void asLiteral_jodaTime() { + SQLTemplates templates = SQLTemplates.DEFAULT; + Configuration conf = new Configuration(templates); + assertMatches(DATE, conf.asLiteral(new LocalDate(0))); + assertMatches(TIME, conf.asLiteral(new LocalTime(0))); + assertMatches(DATETIME, conf.asLiteral(new DateTime(0))); + } + + @Test + public void quote() { + SQLTemplates templates = SQLTemplates.DEFAULT; + // non quoted + assertEquals("employee", templates.quoteIdentifier("employee")); + assertEquals("Employee", templates.quoteIdentifier("Employee")); + assertEquals("employee1", templates.quoteIdentifier("employee1")); + assertEquals("employee_", templates.quoteIdentifier("employee_")); + // quoted + assertEquals("\"e e\"", templates.quoteIdentifier("e e")); + assertEquals("\"1phoenix2\"", templates.quoteIdentifier("1phoenix2")); + } + + @Test + public void quoting_performance() { + // 385 -> 63 + SQLTemplates templates = new H2Templates(); + long start = System.currentTimeMillis(); + int iterations = 1000000; + for (int i = 0; i < iterations; i++) { + templates.quoteIdentifier("companies"); + } + System.err.println(System.currentTimeMillis() - start); + } + + @Test + public void nextVal() { + Operation nextval = ExpressionUtils.operation(String.class, SQLOps.NEXTVAL, ConstantImpl.create("myseq")); + assertEquals("nextval('myseq')", new SQLSerializer(new Configuration(SQLTemplates.DEFAULT)).handle(nextval).toString()); + // Derby OK + // H2 OK + // HSQLDB OK + // MSSQL OK + // MySQL + // Oracle OK + // PostgreSQL OK + + } + + @Test + public void numeric_operations() { + NumberPath intPath = Expressions.numberPath(Integer.class, "intPath"); + NumberPath intPath2 = Expressions.numberPath(Integer.class, "intPath2"); + SQLSerializer serializer = new SQLSerializer(new Configuration(SQLTemplates.DEFAULT)); + serializer.handle(intPath.subtract(intPath2.add(2))); + assertEquals("intPath - (intPath2 + ?)", serializer.toString()); + } + +} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/SQLTypeMappingTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/SQLTypeMappingTest.java similarity index 80% rename from querydsl-sql/src/test/java/com/mysema/query/sql/SQLTypeMappingTest.java rename to querydsl-sql/src/test/java/com/querydsl/sql/SQLTypeMappingTest.java index 50442f9efd..861f2f0ec3 100644 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/SQLTypeMappingTest.java +++ b/querydsl-sql/src/test/java/com/querydsl/sql/SQLTypeMappingTest.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql; +package com.querydsl.sql; import static org.junit.Assert.fail; @@ -22,13 +22,13 @@ public class SQLTypeMappingTest { @Test - public void Get() throws IllegalArgumentException, IllegalAccessException { + public void get() throws IllegalArgumentException, IllegalAccessException { JDBCTypeMapping mapping = new JDBCTypeMapping(); for (Field field : java.sql.Types.class.getFields()) { if (field.getType().equals(int.class)) { int val = field.getInt(null); if (mapping.get(val,0,0) == null) { - fail("Got no value for " + field.getName()); + fail("Got no value for " + field.getName() + " (" + val + ")"); } } } diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/SQLiteTemplatesTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/SQLiteTemplatesTest.java new file mode 100644 index 0000000000..5c1271378c --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/SQLiteTemplatesTest.java @@ -0,0 +1,79 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import static com.querydsl.sql.SQLExpressions.select; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +import com.querydsl.core.types.Ops; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberExpression; + +public class SQLiteTemplatesTest extends AbstractSQLTemplatesTest { + + @Override + protected SQLTemplates createTemplates() { + return new SQLiteTemplates(); + } + + @SuppressWarnings("unchecked") + @Override + public void union() { + NumberExpression one = Expressions.ONE; + NumberExpression two = Expressions.TWO; + NumberExpression three = Expressions.THREE; + Path col1 = Expressions.path(Integer.class,"col1"); + Union union = query.union( + select(one.as(col1)), + select(two), + select(three)); + + assertEquals( + "select 1 as col1\n" + + "union\n" + + "select 2\n" + + "union\n" + + "select 3", union.toString()); + } + + @Test + public void precedence() { + // || + // * / % + int p1 = getPrecedence(Ops.MULT, Ops.DIV, Ops.MOD); + // + - + int p2 = getPrecedence(Ops.ADD, Ops.SUB); + // << >> & | + // < <= > >= + int p3 = getPrecedence(Ops.LT, Ops.GT, Ops.LOE, Ops.GOE); + // = == != <> IS IS NOT IN LIKE GLOB MATCH REGEXP + int p4 = getPrecedence(Ops.EQ, Ops.EQ_IGNORE_CASE, Ops.IS_NULL, Ops.IS_NOT_NULL, + Ops.IN, Ops.LIKE, Ops.LIKE_ESCAPE, Ops.MATCHES); + // AND + int p5 = getPrecedence(Ops.AND); + // OR + int p6 = getPrecedence(Ops.OR); + + assertTrue(p1 < p2); + assertTrue(p2 < p3); + assertTrue(p3 < p4); + assertTrue(p4 < p5); + assertTrue(p5 < p6); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/SchemaAndTableTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/SchemaAndTableTest.java new file mode 100644 index 0000000000..6487319b5a --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/SchemaAndTableTest.java @@ -0,0 +1,17 @@ +package com.querydsl.sql; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +public class SchemaAndTableTest { + + @Test + public void equalsAndHashCode() { + SchemaAndTable st1 = new SchemaAndTable(null, "table"); + SchemaAndTable st2 = new SchemaAndTable(null, "table"); + assertEquals(st1, st2); + assertEquals(st1.hashCode(), st2.hashCode()); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/SelectBase.java b/querydsl-sql/src/test/java/com/querydsl/sql/SelectBase.java new file mode 100644 index 0000000000..f5ed839b2d --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/SelectBase.java @@ -0,0 +1,2184 @@ +//CHECKSTYLERULE:OFF: FileLength +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import static com.querydsl.core.Target.*; +import static com.querydsl.sql.Constants.*; +import static org.junit.Assert.*; + +import java.io.IOException; +import java.math.BigDecimal; +import java.sql.Date; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Timestamp; +import java.util.*; +import java.util.concurrent.atomic.AtomicLong; + +import org.joda.time.*; +import org.junit.Assert; +import org.junit.Ignore; +import org.junit.Test; + +import com.mysema.commons.lang.CloseableIterator; +import com.mysema.commons.lang.Pair; +import com.querydsl.core.*; +import com.querydsl.core.group.Group; +import com.querydsl.core.group.GroupBy; +import com.querydsl.core.testutil.ExcludeIn; +import com.querydsl.core.testutil.IncludeIn; +import com.querydsl.core.testutil.Serialization; +import com.querydsl.core.types.*; +import com.querydsl.core.types.dsl.*; +import com.querydsl.sql.domain.*; + +public class SelectBase extends AbstractBaseTest { + + private static final Expression[] NO_EXPRESSIONS = new Expression[0]; + + private final QueryExecution standardTest = new QueryExecution(QuerydslModule.SQL, Connections.getTarget()) { + @Override + protected Fetchable createQuery() { + return testQuery().from(employee, employee2); + } + @Override + protected Fetchable createQuery(Predicate filter) { + return testQuery().from(employee, employee2).where(filter).select(employee.firstname); + } + }; + + private T firstResult(Expression expr) { + return query().select(expr).fetchFirst(); + } + + private Tuple firstResult(Expression... exprs) { + return query().select(exprs).fetchFirst(); + } + + @Test + public void aggregate_list() { + int min = 30000, avg = 65000, max = 160000; + // fetch + assertEquals(min, query().from(employee).select(employee.salary.min()).fetch().get(0).intValue()); + assertEquals(avg, query().from(employee).select(employee.salary.avg()).fetch().get(0).intValue()); + assertEquals(max, query().from(employee).select(employee.salary.max()).fetch().get(0).intValue()); + } + + @Test + public void aggregate_uniqueResult() { + int min = 30000, avg = 65000, max = 160000; + // fetchOne + assertEquals(min, query().from(employee).select(employee.salary.min()).fetchOne().intValue()); + assertEquals(avg, query().from(employee).select(employee.salary.avg()).fetchOne().intValue()); + assertEquals(max, query().from(employee).select(employee.salary.max()).fetchOne().intValue()); + } + + @Test + @ExcludeIn(ORACLE) + @SkipForQuoted + public void alias() { + expectedQuery = "select e.ID as id from EMPLOYEE e"; + query().from().select(employee.id.as(employee.id)).from(employee).fetch(); + } + + @Test + @ExcludeIn({MYSQL, ORACLE}) + @SkipForQuoted + public void alias_quotes() { + expectedQuery = "select e.FIRSTNAME as \"First Name\" from EMPLOYEE e"; + query().from(employee).select(employee.firstname.as("First Name")).fetch(); + } + + @Test + @IncludeIn(MYSQL) + @SkipForQuoted + public void alias_quotes_MySQL() { + expectedQuery = "select e.FIRSTNAME as `First Name` from EMPLOYEE e"; + query().from(employee).select(employee.firstname.as("First Name")).fetch(); + } + + @Test + @IncludeIn(ORACLE) + @SkipForQuoted + public void alias_quotes_Oracle() { + expectedQuery = "select e.FIRSTNAME \"First Name\" from EMPLOYEE e"; + query().from(employee).select(employee.firstname.as("First Name")); + } + + @Test + public void all() { + for (Expression expr : survey.all()) { + Path path = (Path) expr; + assertEquals(survey, path.getMetadata().getParent()); + } + } + + private void arithmeticTests(NumberExpression one, NumberExpression two, + NumberExpression three, NumberExpression four) { + assertEquals(1, firstResult(one).intValue()); + assertEquals(2, firstResult(two).intValue()); + assertEquals(4, firstResult(four).intValue()); + + assertEquals(3, firstResult(one.subtract(two).add(four)).intValue()); + assertEquals(-5, firstResult(one.subtract(two.add(four))).intValue()); + assertEquals(-1, firstResult(one.add(two).subtract(four)).intValue()); + assertEquals(-1, firstResult(one.add(two.subtract(four))).intValue()); + + assertEquals(12, firstResult(one.add(two).multiply(four)).intValue()); + assertEquals(2, firstResult(four.multiply(one).divide(two)).intValue()); + assertEquals(6, firstResult(four.divide(two).multiply(three)).intValue()); + assertEquals(1, firstResult(four.divide(two.multiply(two))).intValue()); + } + + @Test + public void arithmetic() { + NumberExpression one = Expressions.numberTemplate(Integer.class, "(1.0)"); + NumberExpression two = Expressions.numberTemplate(Integer.class, "(2.0)"); + NumberExpression three = Expressions.numberTemplate(Integer.class, "(3.0)"); + NumberExpression four = Expressions.numberTemplate(Integer.class, "(4.0)"); + arithmeticTests(one, two, three, four); + // the following one doesn't work with integer arguments + assertEquals(2, firstResult(four.multiply(one.divide(two))).intValue()); + } + + @Test + public void arithmetic2() { + NumberExpression one = Expressions.ONE; + NumberExpression two = Expressions.TWO; + NumberExpression three = Expressions.THREE; + NumberExpression four = Expressions.FOUR; + arithmeticTests(one, two, three, four); + } + + @Test + public void arithmetic_mod() { + NumberExpression one = Expressions.numberTemplate(Integer.class, "(1)"); + NumberExpression two = Expressions.numberTemplate(Integer.class, "(2)"); + NumberExpression three = Expressions.numberTemplate(Integer.class, "(3)"); + NumberExpression four = Expressions.numberTemplate(Integer.class, "(4)"); + + assertEquals(4, firstResult(four.mod(three).add(three)).intValue()); + assertEquals(1, firstResult(four.mod(two.add(one))).intValue()); + assertEquals(0, firstResult(four.mod(two.multiply(one))).intValue()); + assertEquals(2, firstResult(four.add(one).mod(three)).intValue()); + } + + @Test + @IncludeIn(POSTGRESQL) // TODO generalize array literal projections + public void array() { + Expression expr = Expressions.template(Integer[].class, "'{1,2,3}'::int[]"); + Integer[] result = firstResult(expr); + assertEquals(3, result.length); + assertEquals(1, result[0].intValue()); + assertEquals(2, result[1].intValue()); + assertEquals(3, result[2].intValue()); + } + + @Test + @IncludeIn(POSTGRESQL) // TODO generalize array literal projections + public void array2() { + Expression expr = Expressions.template(int[].class, "'{1,2,3}'::int[]"); + int[] result = firstResult(expr); + assertEquals(3, result.length); + assertEquals(1, result[0]); + assertEquals(2, result[1]); + assertEquals(3, result[2]); + } + + @Test + @ExcludeIn({DERBY, HSQLDB}) + public void array_null() { + Expression expr = Expressions.template(Integer[].class, "null"); + assertNull(firstResult(expr)); + } + + @Test + public void array_projection() { + List results = query().from(employee).select( + new ArrayConstructorExpression(String[].class, employee.firstname)).fetch(); + assertFalse(results.isEmpty()); + for (String[] result : results) { + assertNotNull(result[0]); + } + } + + @Test + public void beans() { + List rows = query().from(employee, employee2).select(new QBeans(employee, employee2)).fetch(); + assertFalse(rows.isEmpty()); + for (Beans row : rows) { + assertEquals(Employee.class, row.get(employee).getClass()); + assertEquals(Employee.class, row.get(employee2).getClass()); + } + } + + @Test + public void between() { + // 11-13 + assertEquals(Arrays.asList(11, 12, 13), + query().from(employee).where(employee.id.between(11, 13)).orderBy(employee.id.asc()) + .select(employee.id).fetch()); + } + + @Test + @ExcludeIn({ORACLE, CUBRID, FIREBIRD, DB2, DERBY, SQLSERVER, SQLITE, TERADATA}) + public void boolean_all() { + assertTrue(query().from(employee).select(SQLExpressions.all(employee.firstname.isNotNull())).fetchOne()); + } + + @Test + @ExcludeIn({ORACLE, CUBRID, FIREBIRD, DB2, DERBY, SQLSERVER, SQLITE, TERADATA}) + public void boolean_any() { + assertTrue(query().from(employee).select(SQLExpressions.any(employee.firstname.isNotNull())).fetchOne()); + } + + @Test + public void case_() { + NumberExpression numExpression = employee.salary.floatValue().divide(employee2.salary.floatValue()).multiply(100.1); + NumberExpression numExpression2 = employee.id.when(0).then(0.0F).otherwise(numExpression); + assertEquals(Arrays.asList(87, 90, 88, 87, 83, 80, 75), + query().from(employee, employee2) + .where(employee.id.eq(employee2.id.add(1))) + .orderBy(employee.id.asc(), employee2.id.asc()) + .select(numExpression2.floor().intValue()).fetch()); + } + + @Test + public void casts() throws SQLException { + NumberExpression num = employee.id; + List> exprs = new ArrayList<>(); + + add(exprs, num.byteValue(), MYSQL); + add(exprs, num.doubleValue()); + add(exprs, num.floatValue()); + add(exprs, num.intValue()); + add(exprs, num.longValue(), MYSQL); + add(exprs, num.shortValue(), MYSQL); + add(exprs, num.stringValue(), DERBY); + + for (Expression expr : exprs) { + for (Object o : query().from(employee).select(expr).fetch()) { + assertEquals(expr.getType(), o.getClass()); + } + } + } + + @Test + public void coalesce() { + Coalesce c = new Coalesce(employee.firstname, employee.lastname).add("xxx"); + assertEquals(Collections.emptyList(), + query().from(employee).where(c.getValue().eq("xxx")).select(employee.id).fetch()); + } + + @Test + public void compact_join() { + // verbose + assertEquals(8, query().from(employee) + .innerJoin(employee2) + .on(employee.superiorId.eq(employee2.id)) + .select(employee.id, employee2.id).fetch().size()); + + // compact + assertEquals(8, query().from(employee) + .innerJoin(employee.superiorIdKey, employee2) + .select(employee.id, employee2.id).fetch().size()); + + } + + @Test + public void complex_boolean() { + BooleanExpression first = employee.firstname.eq("Mike").and(employee.lastname.eq("Smith")); + BooleanExpression second = employee.firstname.eq("Joe").and(employee.lastname.eq("Divis")); + assertEquals(2, query().from(employee).where(first.or(second)).fetchCount()); + + assertEquals(0, query().from(employee).where( + employee.firstname.eq("Mike"), + employee.lastname.eq("Smith").or(employee.firstname.eq("Joe")), + employee.lastname.eq("Divis") + ).fetchCount()); + } + + @Test + public void complex_subQuery() { + // alias for the salary + NumberPath sal = Expressions.numberPath(BigDecimal.class, "sal"); + // alias for the subquery + PathBuilder sq = new PathBuilder(BigDecimal.class, "sq"); + // query execution + query().from( + query().from(employee) + .select(employee.salary.add(employee.salary).add(employee.salary).as(sal)).as(sq) + ).select(sq.get(sal).avg(), sq.get(sal).min(), sq.get(sal).max()).fetch(); + } + + @Test + public void constructor_projection() { + for (IdName idAndName : query().from(survey).select(new QIdName(survey.id, survey.name)).fetch()) { + assertNotNull(idAndName); + assertNotNull(idAndName.getId()); + assertNotNull(idAndName.getName()); + } + } + + @Test + public void constructor_projection2() { + List projections = query().from(employee).select( + Projections.constructor(SimpleProjection.class, + employee.firstname, employee.lastname)).fetch(); + assertFalse(projections.isEmpty()); + for (SimpleProjection projection : projections) { + assertNotNull(projection); + } + } + + private double cot(double x) { + return Math.cos(x) / Math.sin(x); + } + + private double coth(double x) { + return Math.cosh(x) / Math.sinh(x); + } + + @Test + public void count_with_pK() { + assertEquals(10, query().from(employee).fetchCount()); + } + + @Test + public void count_without_pK() { + assertEquals(10, query().from(QEmployeeNoPK.employee).fetchCount()); + } + + @Test + public void count2() { + assertEquals(10, query().from(employee).select(employee.count()).fetchFirst().intValue()); + } + + @Test + @SkipForQuoted + @ExcludeIn(ORACLE) + public void count_all() { + expectedQuery = "select count(*) as rc from EMPLOYEE e"; + NumberPath rowCount = Expressions.numberPath(Long.class, "rc"); + assertEquals(10, query().from(employee).select(Wildcard.count.as(rowCount)).fetchOne().intValue()); + } + + @Test + @SkipForQuoted + @IncludeIn(ORACLE) + public void count_all_Oracle() { + expectedQuery = "select count(*) rc from EMPLOYEE e"; + NumberPath rowCount = Expressions.numberPath(Long.class, "rc"); + assertEquals(10, query().from(employee).select(Wildcard.count.as(rowCount)).fetchOne().intValue()); + } + + @Test + public void count_distinct_with_pK() { + assertEquals(10, query().from(employee).distinct().fetchCount()); + } + + @Test + public void count_distinct_without_pK() { + assertEquals(10, query().from(QEmployeeNoPK.employee).distinct().fetchCount()); + } + + @Test + public void count_distinct2() { + query().from(employee).select(employee.countDistinct()).fetchFirst(); + } + + @Test + public void custom_projection() { + List tuples = query().from(employee).select( + new QProjection(employee.firstname, employee.lastname)).fetch(); + assertFalse(tuples.isEmpty()); + for (Projection tuple : tuples) { + assertNotNull(tuple.get(employee.firstname)); + assertNotNull(tuple.get(employee.lastname)); + assertNotNull(tuple.getExpr(employee.firstname)); + assertNotNull(tuple.getExpr(employee.lastname)); + } + } + + @Test + @ExcludeIn({CUBRID, DB2, DERBY, HSQLDB, POSTGRESQL, SQLITE, TERADATA}) + public void dates() throws SQLException { + if (!configuration.getUseLiterals()) { + dates(false); + } + } + + @Test + @ExcludeIn({CUBRID, DB2, DERBY, SQLITE, TERADATA}) + public void dates_literals() throws SQLException { + if (configuration.getUseLiterals()) { + dates(true); + } + } + + private void dates(boolean literals) throws SQLException { + long ts = ((long) Math.floor(System.currentTimeMillis() / 1000)) * 1000; + long tsDate = new org.joda.time.LocalDate(ts).toDateMidnight().getMillis(); + long tsTime = new org.joda.time.LocalTime(ts).getMillisOfDay(); + + List data = new ArrayList<>(); + data.add(Constants.date); + data.add(Constants.time); + data.add(new java.util.Date(ts)); + data.add(new java.util.Date(tsDate)); + data.add(new java.util.Date(tsTime)); + data.add(new java.sql.Timestamp(ts)); + data.add(new java.sql.Timestamp(tsDate)); + data.add(new java.sql.Date(110, 0, 1)); + data.add(new java.sql.Date(tsDate)); + data.add(new java.sql.Time(0, 0, 0)); + data.add(new java.sql.Time(12, 30, 0)); + data.add(new java.sql.Time(23, 59, 59)); + //data.add(new java.sql.Time(tsTime)); + data.add(new DateTime(ts)); + data.add(new DateTime(tsDate)); + data.add(new DateTime(tsTime)); + data.add(new LocalDateTime(ts)); + data.add(new LocalDateTime(tsDate)); + data.add(new LocalDateTime(2014, 3, 30, 2, 0)); + data.add(new LocalDate(2010, 1, 1)); + data.add(new LocalDate(ts)); + data.add(new LocalDate(tsDate)); + data.add(new LocalTime(0, 0, 0)); + data.add(new LocalTime(12, 30, 0)); + data.add(new LocalTime(23, 59, 59)); + data.add(new LocalTime(ts)); + data.add(new LocalTime(tsTime)); + + java.time.Instant javaInstant = java.time.Instant.now().truncatedTo(java.time.temporal.ChronoUnit.SECONDS); + java.time.LocalDateTime javaDateTime = java.time.LocalDateTime.ofInstant(javaInstant, java.time.ZoneId.of("Z")); + java.time.LocalDate javaDate = javaDateTime.toLocalDate(); + java.time.LocalTime javaTime = javaDateTime.toLocalTime(); + data.add(javaInstant); //java.time.Instant + data.add(javaDateTime); //java.time.LocalDateTime + data.add(javaDate); //java.time.LocalDate + data.add(javaTime); //java.time.LocalTime + + // have to explicitly list these + // connection.getMetaData().getTypeInfo() is not helpful in this case for most drivers + boolean supportsTimeZones; + switch (target) { + case FIREBIRD: + case H2: + case HSQLDB: + case ORACLE: + case SQLSERVER: + supportsTimeZones = true; + break; + default: + supportsTimeZones = false; + break; + } + if (supportsTimeZones) { + // java.time.OffsetTime + // SQL Server does not support TIME WITH TIME ZONE + // H2 supports it starting in 1.4.200 but we are stuck on 1.4.197 due to h2gis + if (target != SQLSERVER && target != H2) { + data.add(javaTime.atOffset(java.time.ZoneOffset.UTC)); + data.add(javaTime.atOffset(java.time.ZoneOffset.ofHours(-6))); + } + + /* + * TIMESTAMP WITH TIME ZONE is complicated. + * Contrary to the name, most databases that support this type do not actually support time zones. + * Instead, they support zone offsets which is not the same thing. + * E.g. America/New_York could be UTC-5 or UTC-4 depending on the time of year and acts of Congress. + * Which means if a database actually stores the zone ID, the time value can change. + * E.g. you put an entry in the database for 10 years in the future but then Congress abolishes DST. + * Other than Oracle, it does not look like any databases support storing the actual zone ID. + * Some databases, like H2, support specifying a time zone but convert it to an offset before storing it. + * Also, the JDBC specification does not say anything about ZonedDateTime. + * Therefore, we only test ZonedDateTime on Oracle because its behavior is poorly defined on anything else. + */ + + // java.time.OffsetDateTime + data.add(javaDateTime.atOffset(java.time.ZoneOffset.UTC)); + data.add(javaDateTime.atOffset(java.time.ZoneOffset.ofHours(-6))); + + // java.time.ZonedDateTime + if (target == ORACLE) { + data.add(javaDateTime.atZone(java.time.ZoneId.of("UTC"))); + data.add(javaDateTime.atZone(java.time.ZoneId.of("America/Chicago"))); + } + } + + Map failures = new IdentityHashMap<>(); + for (Object dt : data) { + try { + Object dt2 = firstResult(Expressions.constant(dt)); + if (!dt.equals(dt2)) { + failures.put(dt, dt2); + } + } catch (Exception e) { + throw new RuntimeException("Error executing query for " + dt.getClass().getName() + " " + dt, e); + } + } + if (!failures.isEmpty()) { + for (Map.Entry entry : failures.entrySet()) { + System.out.println(entry.getKey().getClass().getName() + + ": " + entry.getKey() + " != " + entry.getValue()); + } + Assert.fail("Failed with " + failures); + } + } + + @Test + @ExcludeIn({SQLITE}) + public void date_add() { + SQLQuery query = query().from(employee); + Date date1 = query.select(employee.datefield).fetchFirst(); + Date date2 = query.select(SQLExpressions.addYears(employee.datefield, 1)).fetchFirst(); + Date date3 = query.select(SQLExpressions.addMonths(employee.datefield, 1)).fetchFirst(); + Date date4 = query.select(SQLExpressions.addDays(employee.datefield, 1)).fetchFirst(); + + assertTrue(date2.getTime() > date1.getTime()); + assertTrue(date3.getTime() > date1.getTime()); + assertTrue(date4.getTime() > date1.getTime()); + } + + @Test + @ExcludeIn({SQLITE}) + public void date_add_Timestamp() { + List> exprs = new ArrayList<>(); + DateTimeExpression dt = Expressions.currentTimestamp(); + + add(exprs, SQLExpressions.addYears(dt, 1)); + add(exprs, SQLExpressions.addMonths(dt, 1), ORACLE); + add(exprs, SQLExpressions.addDays(dt, 1)); + add(exprs, SQLExpressions.addHours(dt, 1), TERADATA); + add(exprs, SQLExpressions.addMinutes(dt, 1), TERADATA); + add(exprs, SQLExpressions.addSeconds(dt, 1), TERADATA); + + for (Expression expr : exprs) { + assertNotNull(firstResult(expr)); + } + } + + @Test + @ExcludeIn({DB2, SQLITE, TERADATA}) + public void date_diff() { + QEmployee employee2 = new QEmployee("employee2"); + SQLQuery query = query().from(employee).orderBy(employee.id.asc()); + SQLQuery query2 = query().from(employee, employee2) + .orderBy(employee.id.asc(), employee2.id.desc()); + + List dps = new ArrayList<>(); + add(dps, DatePart.year); + add(dps, DatePart.month); + add(dps, DatePart.week); + add(dps, DatePart.day); + add(dps, DatePart.hour, HSQLDB); + add(dps, DatePart.minute, HSQLDB); + add(dps, DatePart.second, HSQLDB); + + LocalDate localDate = new LocalDate(1970, 1, 10); + Date date = new Date(localDate.toDateMidnight().getMillis()); + + for (DatePart dp : dps) { + int diff1 = query.select(SQLExpressions.datediff(dp, date, employee.datefield)).fetchFirst(); + int diff2 = query.select(SQLExpressions.datediff(dp, employee.datefield, date)).fetchFirst(); + int diff3 = query2.select(SQLExpressions.datediff(dp, employee.datefield, employee2.datefield)).fetchFirst(); + assertEquals(diff1, -diff2); + } + + Timestamp timestamp = new Timestamp(new java.util.Date().getTime()); + for (DatePart dp : dps) { + query.select(SQLExpressions.datediff(dp, Expressions.currentTimestamp(), timestamp)).fetchOne(); + } + } + + // TDO Date_diff with timestamps + + @Test + @ExcludeIn({DB2, HSQLDB, SQLITE, TERADATA}) + public void date_diff2() { + SQLQuery query = query().from(employee).orderBy(employee.id.asc()); + + LocalDate localDate = new LocalDate(1970, 1, 10); + Date date = new Date(localDate.toDateMidnight().getMillis()); + + int years = query.select(SQLExpressions.datediff(DatePart.year, date, employee.datefield)).fetchFirst(); + int months = query.select(SQLExpressions.datediff(DatePart.month, date, employee.datefield)).fetchFirst(); + // weeks + int days = query.select(SQLExpressions.datediff(DatePart.day, date, employee.datefield)).fetchFirst(); + int hours = query.select(SQLExpressions.datediff(DatePart.hour, date, employee.datefield)).fetchFirst(); + int minutes = query.select(SQLExpressions.datediff(DatePart.minute, date, employee.datefield)).fetchFirst(); + int seconds = query.select(SQLExpressions.datediff(DatePart.second, date, employee.datefield)).fetchFirst(); + + assertEquals(949363200, seconds); + assertEquals(15822720, minutes); + assertEquals(263712, hours); + assertEquals(10988, days); + assertEquals(361, months); + assertEquals(30, years); + } + + @Test + @ExcludeIn({SQLITE}) // FIXME + public void date_trunc() { + DateTimeExpression expr = DateTimeExpression.currentTimestamp(); + + List dps = new ArrayList<>(); + add(dps, DatePart.year); + add(dps, DatePart.month); + add(dps, DatePart.week, DERBY, FIREBIRD, SQLSERVER); + add(dps, DatePart.day); + add(dps, DatePart.hour); + add(dps, DatePart.minute); + add(dps, DatePart.second); + + for (DatePart dp : dps) { + firstResult(SQLExpressions.datetrunc(dp, expr)); + } + } + + @Test + @ExcludeIn({SQLITE, TERADATA}) // FIXME + public void date_trunc2() { + DateTimeExpression expr = DateTimeExpression.currentTimestamp(DateTime.class); + + Tuple tuple = firstResult( + expr, + SQLExpressions.datetrunc(DatePart.year, expr), + SQLExpressions.datetrunc(DatePart.month, expr), + SQLExpressions.datetrunc(DatePart.day, expr), + SQLExpressions.datetrunc(DatePart.hour, expr), + SQLExpressions.datetrunc(DatePart.minute, expr), + SQLExpressions.datetrunc(DatePart.second, expr)); + DateTime date = tuple.get(expr); + DateTime toYear = tuple.get(SQLExpressions.datetrunc(DatePart.year, expr)); + DateTime toMonth = tuple.get(SQLExpressions.datetrunc(DatePart.month, expr)); + DateTime toDay = tuple.get(SQLExpressions.datetrunc(DatePart.day, expr)); + DateTime toHour = tuple.get(SQLExpressions.datetrunc(DatePart.hour, expr)); + DateTime toMinute = tuple.get(SQLExpressions.datetrunc(DatePart.minute, expr)); + DateTime toSecond = tuple.get(SQLExpressions.datetrunc(DatePart.second, expr)); + + assertEquals(date.getZone(), toYear.getZone()); + assertEquals(date.getZone(), toMonth.getZone()); + assertEquals(date.getZone(), toDay.getZone()); + assertEquals(date.getZone(), toHour.getZone()); + assertEquals(date.getZone(), toMinute.getZone()); + assertEquals(date.getZone(), toSecond.getZone()); + + // year + assertEquals(date.getYear(), toYear.getYear()); + assertEquals(date.getYear(), toMonth.getYear()); + assertEquals(date.getYear(), toDay.getYear()); + assertEquals(date.getYear(), toHour.getYear()); + assertEquals(date.getYear(), toMinute.getYear()); + assertEquals(date.getYear(), toSecond.getYear()); + + // month + assertEquals(1, toYear.getMonthOfYear()); + assertEquals(date.getMonthOfYear(), toMonth.getMonthOfYear()); + assertEquals(date.getMonthOfYear(), toDay.getMonthOfYear()); + assertEquals(date.getMonthOfYear(), toHour.getMonthOfYear()); + assertEquals(date.getMonthOfYear(), toMinute.getMonthOfYear()); + assertEquals(date.getMonthOfYear(), toSecond.getMonthOfYear()); + + // day + assertEquals(1, toYear.getDayOfMonth()); + assertEquals(1, toMonth.getDayOfMonth()); + assertEquals(date.getDayOfMonth(), toDay.getDayOfMonth()); + assertEquals(date.getDayOfMonth(), toHour.getDayOfMonth()); + assertEquals(date.getDayOfMonth(), toMinute.getDayOfMonth()); + assertEquals(date.getDayOfMonth(), toSecond.getDayOfMonth()); + + // hour + assertEquals(0, toYear.getHourOfDay()); + assertEquals(0, toMonth.getHourOfDay()); + assertEquals(0, toDay.getHourOfDay()); + assertEquals(date.getHourOfDay(), toHour.getHourOfDay()); + assertEquals(date.getHourOfDay(), toMinute.getHourOfDay()); + assertEquals(date.getHourOfDay(), toSecond.getHourOfDay()); + + // minute + assertEquals(0, toYear.getMinuteOfHour()); + assertEquals(0, toMonth.getMinuteOfHour()); + assertEquals(0, toDay.getMinuteOfHour()); + assertEquals(0, toHour.getMinuteOfHour()); + assertEquals(date.getMinuteOfHour(), toMinute.getMinuteOfHour()); + assertEquals(date.getMinuteOfHour(), toSecond.getMinuteOfHour()); + + // second + assertEquals(0, toYear.getSecondOfMinute()); + assertEquals(0, toMonth.getSecondOfMinute()); + assertEquals(0, toDay.getSecondOfMinute()); + assertEquals(0, toHour.getSecondOfMinute()); + assertEquals(0, toMinute.getSecondOfMinute()); + assertEquals(date.getSecondOfMinute(), toSecond.getSecondOfMinute()); + } + + @Test + public void dateTime() { + SQLQuery query = query().from(employee).orderBy(employee.id.asc()); + assertEquals(Integer.valueOf(10), query.select(employee.datefield.dayOfMonth()).fetchFirst()); + assertEquals(Integer.valueOf(2), query.select(employee.datefield.month()).fetchFirst()); + assertEquals(Integer.valueOf(2000), query.select(employee.datefield.year()).fetchFirst()); + assertEquals(Integer.valueOf(200002), query.select(employee.datefield.yearMonth()).fetchFirst()); + } + + @Test + @ExcludeIn({SQLITE}) + public void dateTime_to_date() { + firstResult(SQLExpressions.date(DateTimeExpression.currentTimestamp())); + } + + private double degrees(double x) { + return x * 180.0 / Math.PI; + } + + @Test + public void distinct_count() { + long count1 = query().from(employee).distinct().fetchCount(); + long count2 = query().from(employee).distinct().fetchCount(); + assertEquals(count1, count2); + } + + @Test + public void distinct_list() { + List lengths1 = query().from(employee).distinct().select(employee.firstname.length()).fetch(); + List lengths2 = query().from(employee).distinct().select(employee.firstname.length()).fetch(); + assertEquals(lengths1, lengths2); + } + + @Test + public void duplicate_columns() { + assertEquals(10, query().from(employee) + .select(employee.id, employee.id).fetch().size()); + } + + @Test + public void duplicate_columns_In_Subquery() { + QEmployee employee2 = new QEmployee("e2"); + assertEquals(10, query().from(employee).where( + query().from(employee2) + .where(employee2.id.eq(employee.id)) + .select(employee2.id, employee2.id).exists()).fetchCount()); + } + + @Test + public void factoryExpression_in_groupBy() { + Expression empBean = Projections.bean(Employee.class, employee.id, employee.superiorId); + assertTrue(query().from(employee).groupBy(empBean).select(empBean).fetchFirst() != null); + } + + @Test + @ExcludeIn({H2, SQLITE, DERBY, CUBRID, MYSQL}) + public void full_join() throws SQLException { + assertEquals(18, query().from(employee).fullJoin(employee2) + .on(employee.superiorIdKey.on(employee2)) + .select(employee.id, employee2.id).fetch().size()); + } + + @Test + public void getResultSet() throws IOException, SQLException { + ResultSet results = query().select(survey.id, survey.name).from(survey).getResults(); + while (results.next()) { + assertNotNull(results.getObject(1)); + assertNotNull(results.getObject(2)); + } + results.close(); + } + + @Test + public void groupBy_superior() { + SQLQuery qry = query() + .from(employee) + .innerJoin(employee._superiorIdKey, employee2); + + QTuple subordinates = Projections.tuple(employee2.id, employee2.firstname, employee2.lastname); + + Map results = qry.transform( + GroupBy.groupBy(employee.id).as(employee.firstname, employee.lastname, + GroupBy.map(employee2.id, subordinates))); + + assertEquals(2, results.size()); + + // Mike Smith + Group group = results.get(1); + assertEquals("Mike", group.getOne(employee.firstname)); + assertEquals("Smith", group.getOne(employee.lastname)); + + Map emps = group.getMap(employee2.id, subordinates); + assertEquals(4, emps.size()); + assertEquals("Steve", emps.get(12).get(employee2.firstname)); + + // Mary Smith + group = results.get(2); + assertEquals("Mary", group.getOne(employee.firstname)); + assertEquals("Smith", group.getOne(employee.lastname)); + + emps = group.getMap(employee2.id, subordinates); + assertEquals(4, emps.size()); + assertEquals("Mason", emps.get(21).get(employee2.lastname)); + } + + @Test + public void groupBy_yearMonth() { + assertEquals(Collections.singletonList(10L), query().from(employee) + .groupBy(employee.datefield.yearMonth()) + .orderBy(employee.datefield.yearMonth().asc()) + .select(employee.id.count()).fetch()); + } + + @Test + @ExcludeIn({H2, DB2, DERBY, ORACLE, SQLSERVER}) + public void groupBy_validate() { + NumberPath alias = Expressions.numberPath(BigDecimal.class, "alias"); + assertEquals(8, query().from(employee) + .groupBy(alias) + .select(employee.salary.multiply(100).as(alias), + employee.salary.avg()).fetch().size()); + } + + @Test + @ExcludeIn({FIREBIRD}) + public void groupBy_count() { + List ids = query().from(employee).groupBy(employee.id).select(employee.id).fetch(); + long count = query().from(employee).groupBy(employee.id).fetchCount(); + QueryResults results = query().from(employee).groupBy(employee.id) + .limit(1).select(employee.id).fetchResults(); + + assertEquals(10, ids.size()); + assertEquals(10, count); + assertEquals(1, results.getResults().size()); + assertEquals(10, results.getTotal()); + } + + @Test + @ExcludeIn({FIREBIRD, SQLSERVER, TERADATA}) + public void groupBy_Distinct_count() { + List ids = query().from(employee).groupBy(employee.id).distinct().select(Expressions.ONE).fetch(); + QueryResults results = query().from(employee).groupBy(employee.id) + .limit(1).distinct().select(Expressions.ONE).fetchResults(); + + assertEquals(1, ids.size()); + assertEquals(1, results.getResults().size()); + assertEquals(1, results.getTotal()); + } + + @Test + @ExcludeIn({FIREBIRD}) + public void having_count() { + //Produces empty resultset https://github.com/querydsl/querydsl/issues/1055 + query().from(employee) + .innerJoin(employee2).on(employee.id.eq(employee2.id)) + .groupBy(employee.id) + .having(Wildcard.count.eq(4L)) + .select(employee.id, employee.firstname).fetchResults(); + } + + @SuppressWarnings("unchecked") + @Test(expected = IllegalArgumentException.class) + public void illegalUnion() throws SQLException { + SubQueryExpression sq1 = query().from(employee).select(employee.id.max()); + SubQueryExpression sq2 = query().from(employee).select(employee.id.max()); + assertEquals(0, query().from(employee).union(sq1, sq2).list().size()); + } + + @Test + public void in() { + assertEquals(2, query().from(employee) + .where(employee.id.in(Arrays.asList(1, 2))) + .select(employee).fetch().size()); + } + + @Test + @ExcludeIn({DERBY, FIREBIRD, SQLITE, SQLSERVER, TERADATA}) + public void in_long_list() { + List ids = new ArrayList<>(); + for (int i = 0; i < 20000; i++) { + ids.add(i); + } + assertEquals( + query().from(employee).fetchCount(), + query().from(employee).where(employee.id.in(ids)).fetchCount()); + } + + @Test + @ExcludeIn({DERBY, FIREBIRD, SQLITE, SQLSERVER, TERADATA}) + public void notIn_long_list() { + List ids = new ArrayList<>(); + for (int i = 0; i < 20000; i++) { + ids.add(i); + } + assertEquals(0, query().from(employee).where(employee.id.notIn(ids)).fetchCount()); + } + + @Test + public void in_empty() { + assertEquals(0, query().from(employee).where(employee.id.in(Collections.emptyList())).fetchCount()); + } + + @Test + @ExcludeIn(DERBY) + public void in_null() { + assertEquals(1, query().from(employee).where(employee.id.in(1, null)).fetchCount()); + } + + @Test + @ExcludeIn({MYSQL, TERADATA}) + public void in_subqueries() { + QEmployee e1 = new QEmployee("e1"); + QEmployee e2 = new QEmployee("e2"); + assertEquals(2, query().from(employee).where(employee.id.in( + query().from(e1).where(e1.firstname.eq("Mike")).select(e1.id), + query().from(e2).where(e2.firstname.eq("Mary")).select(e2.id) + )).fetchCount()); + } + + @Test + public void notIn_empty() { + long count = query().from(employee).fetchCount(); + assertEquals(count, query().from(employee).where(employee.id.notIn(Collections.emptyList())).fetchCount()); + } + + @Test + public void inner_join() throws SQLException { + assertEquals(8, query().from(employee).innerJoin(employee2) + .on(employee.superiorIdKey.on(employee2)) + .select(employee.id, employee2.id).fetch().size()); + } + + @Test + public void inner_join_2Conditions() { + assertEquals(8, query().from(employee).innerJoin(employee2) + .on(employee.superiorIdKey.on(employee2)) + .on(employee2.firstname.isNotNull()) + .select(employee.id, employee2.id).fetch().size()); + } + + @Test + public void join() throws Exception { + for (String name : query().from(survey, survey2) + .where(survey.id.eq(survey2.id)).select(survey.name).fetch()) { + assertNotNull(name); + } + } + + @Test + public void joins() throws SQLException { + for (Tuple row : query().from(employee).innerJoin(employee2) + .on(employee.superiorId.eq(employee2.superiorId)) + .where(employee2.id.eq(10)) + .select(employee.id, employee2.id).fetch()) { + assertNotNull(row.get(employee.id)); + assertNotNull(row.get(employee2.id)); + } + } + + @Test + public void left_join() throws SQLException { + assertEquals(10, query().from(employee).leftJoin(employee2) + .on(employee.superiorIdKey.on(employee2)) + .select(employee.id, employee2.id).fetch().size()); + } + + @Test + public void like() { + assertEquals(0, query().from(employee).where(employee.firstname.like("\\")).fetchCount()); + assertEquals(0, query().from(employee).where(employee.firstname.like("\\\\")).fetchCount()); + } + + @Test + public void like_ignore_case() { + assertEquals(3, query().from(employee).where(employee.firstname.likeIgnoreCase("%m%")).fetchCount()); + } + + @Test + @ExcludeIn(FIREBIRD) + public void like_escape() { + List strs = Arrays.asList("%a", "a%", "%a%", "_a", "a_", "_a_", "[C-P]arsen", "a\nb"); + + for (String str : strs) { + assertTrue(str, query() + .from(employee) + .where(Expressions.predicate(Ops.STRING_CONTAINS, + Expressions.constant(str), + Expressions.constant(str))).fetchCount() > 0); + } + } + + @Test + @ExcludeIn({DB2, DERBY}) + public void like_number() { + assertEquals(5, query().from(employee) + .where(employee.id.like("1%")).fetchCount()); + } + + @Test + public void limit() throws SQLException { + assertEquals(Arrays.asList(23, 22, 21, 20), query().from(employee) + .orderBy(employee.firstname.asc()) + .limit(4).select(employee.id).fetch()); + } + + @Test + public void limit_and_offset() throws SQLException { + assertEquals(Arrays.asList(20, 13, 10, 2), + query().from(employee) + .orderBy(employee.firstname.asc()) + .limit(4).offset(3) + .select(employee.id).fetch()); + } + + @Test + public void limit_and_offset_Group() { + assertEquals(9, + query().from(employee) + .orderBy(employee.id.asc()) + .limit(100).offset(1) + .transform(GroupBy.groupBy(employee.id).as(employee)).size()); + } + + @Test + public void limit_and_offset_and_Order() { + List names2 = Arrays.asList("Helen","Jennifer","Jim","Joe"); + assertEquals(names2, query().from(employee) + .orderBy(employee.firstname.asc()) + .limit(4).offset(2) + .select(employee.firstname).fetch()); + } + + @Test + @IncludeIn(DERBY) + public void limit_and_offset_In_Derby() throws SQLException { + expectedQuery = "select e.ID from EMPLOYEE e offset 3 rows fetch next 4 rows only"; + query().from(employee).limit(4).offset(3).select(employee.id).fetch(); + + // limit + expectedQuery = "select e.ID from EMPLOYEE e fetch first 4 rows only"; + query().from(employee).limit(4).select(employee.id).fetch(); + + // offset + expectedQuery = "select e.ID from EMPLOYEE e offset 3 rows"; + query().from(employee).offset(3).select(employee.id).fetch(); + + } + + @Test + @IncludeIn(ORACLE) + @SkipForQuoted + public void limit_and_offset_In_Oracle() throws SQLException { + if (configuration.getUseLiterals()) { + return; + } + + // limit + expectedQuery = "select * from ( select e.ID from EMPLOYEE e ) where rownum <= ?"; + query().from(employee).limit(4).select(employee.id).fetch(); + + // offset + expectedQuery = "select * from ( select a.*, rownum rn from ( select e.ID from EMPLOYEE e ) a) where rn > ?"; + query().from(employee).offset(3).select(employee.id).fetch(); + + // limit offset + expectedQuery = "select * from ( select a.*, rownum rn from ( select e.ID from EMPLOYEE e ) a) where rn > 3 and rownum <= 4"; + query().from(employee).limit(4).offset(3).select(employee.id).fetch(); + } + + @Test + @ExcludeIn({ORACLE, DB2, DERBY, FIREBIRD, SQLSERVER, CUBRID, TERADATA}) + @SkipForQuoted + public void limit_and_offset2() throws SQLException { + // limit + expectedQuery = "select e.ID from EMPLOYEE e limit ?"; + query().from(employee).limit(4).select(employee.id).fetch(); + + // limit offset + expectedQuery = "select e.ID from EMPLOYEE e limit ? offset ?"; + query().from(employee).limit(4).offset(3).select(employee.id).fetch(); + + } + + @Test + public void limit_and_order() { + List names1 = Arrays.asList("Barbara","Daisy","Helen","Jennifer"); + assertEquals(names1, query().from(employee) + .orderBy(employee.firstname.asc()) + .limit(4) + .select(employee.firstname).fetch()); + } + + @Test + public void listResults() { + QueryResults results = query().from(employee) + .limit(10).offset(1).orderBy(employee.id.asc()) + .select(employee.id).fetchResults(); + assertEquals(10, results.getTotal()); + } + + @Test + public void listResults2() { + QueryResults results = query().from(employee) + .limit(2).offset(10).orderBy(employee.id.asc()) + .select(employee.id).fetchResults(); + assertEquals(10, results.getTotal()); + } + + @Test + public void listResults_factoryExpression() { + QueryResults results = query().from(employee) + .limit(10).offset(1).orderBy(employee.id.asc()) + .select(employee).fetchResults(); + assertEquals(10, results.getTotal()); + } + + @Test + @ExcludeIn({DB2, DERBY}) + public void literals() { + assertEquals(1L, firstResult(ConstantImpl.create(1)).intValue()); + assertEquals(2L, firstResult(ConstantImpl.create(2L)).longValue()); + assertEquals(3.0, firstResult(ConstantImpl.create(3.0)), 0.001); + assertEquals(4.0f, firstResult(ConstantImpl.create(4.0f)), 0.001); + assertEquals(true, firstResult(ConstantImpl.create(true))); + assertEquals(false, firstResult(ConstantImpl.create(false))); + assertEquals("abc", firstResult(ConstantImpl.create("abc"))); + assertEquals("'", firstResult(ConstantImpl.create("'"))); + assertEquals("\"", firstResult(ConstantImpl.create("\""))); + assertEquals("\n", firstResult(ConstantImpl.create("\n"))); + assertEquals("\r\n", firstResult(ConstantImpl.create("\r\n"))); + assertEquals("\t", firstResult(ConstantImpl.create("\t"))); + } + + @Test + public void literals_literals() { + if (configuration.getUseLiterals()) { + literals(); + } + } + + private double log(double x, int y) { + return Math.log(x) / Math.log(y); + } + + @Test + @ExcludeIn({SQLITE, DERBY}) + public void lPad() { + assertEquals(" ab", firstResult(StringExpressions.lpad(ConstantImpl.create("ab"), 4))); + assertEquals("!!ab", firstResult(StringExpressions.lpad(ConstantImpl.create("ab"), 4, '!'))); + } + +// @Test +// public void map() { +// Map idToName = query().from(employee).map(employee.id.as("id"), employee.firstname); +// for (Map.Entry entry : idToName.entrySet()) { +// assertNotNull(entry.getKey()); +// assertNotNull(entry.getValue()); +// } +// } + + @Test + @SuppressWarnings("serial") + public void mappingProjection() { + List> pairs = query().from(employee) + .select(new MappingProjection>(Pair.class, + employee.firstname, employee.lastname) { + @Override + protected Pair map(Tuple row) { + return Pair.of(row.get(employee.firstname), row.get(employee.lastname)); + } + }).fetch(); + + for (Pair pair : pairs) { + assertNotNull(pair.getFirst()); + assertNotNull(pair.getSecond()); + } + } + + @Test + @ExcludeIn({HSQLDB}) // FIXME + public void math() { + math(Expressions.numberTemplate(Double.class, "0.50")); + } + + @Test + @ExcludeIn({FIREBIRD, SQLSERVER, HSQLDB}) // FIXME + public void math2() { + math(Expressions.constant(0.5)); + } + + private void math(Expression expr) { + double precision = 0.001; + assertEquals(Math.acos(0.5), firstResult(MathExpressions.acos(expr)), precision); + assertEquals(Math.asin(0.5), firstResult(MathExpressions.asin(expr)), precision); + assertEquals(Math.atan(0.5), firstResult(MathExpressions.atan(expr)), precision); + assertEquals(Math.cos(0.5), firstResult(MathExpressions.cos(expr)), precision); + assertEquals(Math.cosh(0.5), firstResult(MathExpressions.cosh(expr)), precision); + assertEquals(cot(0.5), firstResult(MathExpressions.cot(expr)), precision); + if (target != Target.DERBY || expr instanceof Constant) { + // FIXME: The resulting value is outside the range for the data type DECIMAL/NUMERIC(4,4). + assertEquals(coth(0.5), firstResult(MathExpressions.coth(expr)), precision); + } + + assertEquals(degrees(0.5), firstResult(MathExpressions.degrees(expr)), precision); + assertEquals(Math.exp(0.5), firstResult(MathExpressions.exp(expr)), precision); + assertEquals(Math.log(0.5), firstResult(MathExpressions.ln(expr)), precision); + assertEquals(log(0.5, 10), firstResult(MathExpressions.log(expr, 10)), precision); + assertEquals(0.25, firstResult(MathExpressions.power(expr, 2)), precision); + assertEquals(radians(0.5), firstResult(MathExpressions.radians(expr)), precision); + assertEquals(Integer.valueOf(1), + firstResult(MathExpressions.sign(expr))); + assertEquals(Math.sin(0.5), firstResult(MathExpressions.sin(expr)), precision); + assertEquals(Math.sinh(0.5), firstResult(MathExpressions.sinh(expr)), precision); + assertEquals(Math.tan(0.5), firstResult(MathExpressions.tan(expr)), precision); + assertEquals(Math.tanh(0.5), firstResult(MathExpressions.tanh(expr)), precision); + } + + @Test + @ExcludeIn(DERBY) // Derby doesn't support mod with decimal operands + public void math3() { + // 1.0 + 2.0 * 3.0 - 4.0 / 5.0 + 6.0 % 3.0 + NumberTemplate one = Expressions.numberTemplate(Double.class, "1.0"); + NumberTemplate two = Expressions.numberTemplate(Double.class, "2.0"); + NumberTemplate three = Expressions.numberTemplate(Double.class, "3.0"); + NumberTemplate four = Expressions.numberTemplate(Double.class, "4.0"); + NumberTemplate five = Expressions.numberTemplate(Double.class, "5.0"); + NumberTemplate six = Expressions.numberTemplate(Double.class, "6.0"); + Double num = query().select(one.add(two.multiply(three)).subtract(four.divide(five)).add(six.mod(three))).fetchFirst(); + assertEquals(6.2, num, 0.001); + } + + @Test + public void nested_tuple_projection() { + Concatenation concat = new Concatenation(employee.firstname, employee.lastname); + List tuples = query().from(employee) + .select(employee.firstname, employee.lastname, concat).fetch(); + assertFalse(tuples.isEmpty()); + for (Tuple tuple : tuples) { + String firstName = tuple.get(employee.firstname); + String lastName = tuple.get(employee.lastname); + assertEquals(firstName + lastName, tuple.get(concat)); + } + } + + + @Test + @ExcludeIn({SQLITE}) + public void no_from() { + assertNotNull(firstResult(DateExpression.currentDate())); + } + + @Test + public void nullif() { + query().from(employee).select(employee.firstname.nullif(employee.lastname)).fetch(); + } + + @Test + public void nullif_constant() { + query().from(employee).select(employee.firstname.nullif("xxx")).fetch(); + } + + @Test + public void num_cast() { + query().from(employee).select(employee.id.castToNum(Long.class)).fetch(); + query().from(employee).select(employee.id.castToNum(Float.class)).fetch(); + query().from(employee).select(employee.id.castToNum(Double.class)).fetch(); + } + + @Test + public void num_cast2() { + NumberExpression num = Expressions.numberTemplate(Integer.class, "0"); + firstResult(num.castToNum(Byte.class)); + firstResult(num.castToNum(Short.class)); + firstResult(num.castToNum(Integer.class)); + firstResult(num.castToNum(Long.class)); + firstResult(num.castToNum(Float.class)); + firstResult(num.castToNum(Double.class)); + } + + @Test + public void num_date_operation() { + long result = query() + .select(employee.datefield.year().mod(1)) + .from(employee) + .fetchFirst(); + assertEquals(0, result); + } + + @Test + @ExcludeIn({DERBY, FIREBIRD, POSTGRESQL}) + public void number_as_boolean() { + QNumberTest numberTest = QNumberTest.numberTest; + delete(numberTest).execute(); + insert(numberTest).set(numberTest.col1Boolean, true).execute(); + insert(numberTest).set(numberTest.col1Number, (byte) 1).execute(); + assertEquals(2, query().from(numberTest).select(numberTest.col1Boolean).fetch().size()); + assertEquals(2, query().from(numberTest).select(numberTest.col1Number).fetch().size()); + } + + @Test + public void number_as_boolean_Null() { + QNumberTest numberTest = QNumberTest.numberTest; + delete(numberTest).execute(); + insert(numberTest).setNull(numberTest.col1Boolean).execute(); + insert(numberTest).setNull(numberTest.col1Number).execute(); + assertEquals(2, query().from(numberTest).select(numberTest.col1Boolean).fetch().size()); + assertEquals(2, query().from(numberTest).select(numberTest.col1Number).fetch().size()); + } + + @Test + public void offset_only() { + assertEquals(Arrays.asList(20, 13, 10, 2, 1, 11, 12), query().from(employee) + .orderBy(employee.firstname.asc()) + .offset(3) + .select(employee.id).fetch()); + } + + @Test + public void operation_in_constant_list() { + assertEquals(0, query().from(survey).where(survey.name.charAt(0).in(Collections.singletonList('a'))).fetchCount()); + assertEquals(0, query().from(survey).where(survey.name.charAt(0).in(Arrays.asList('a','b'))).fetchCount()); + assertEquals(0, query().from(survey).where(survey.name.charAt(0).in(Arrays.asList('a','b','c'))).fetchCount()); + } + + @Test + public void order_nullsFirst() { + assertEquals(Collections.singletonList("Hello World"), query().from(survey) + .orderBy(survey.name.asc().nullsFirst()) + .select(survey.name).fetch()); + } + + @Test + public void order_nullsLast() { + assertEquals(Collections.singletonList("Hello World"), query().from(survey) + .orderBy(survey.name.asc().nullsLast()) + .select(survey.name).fetch()); + } + + @Test + public void params() { + Param name = new Param(String.class,"name"); + assertEquals("Mike", query() + .from(employee).where(employee.firstname.eq(name)) + .set(name, "Mike") + .select(employee.firstname).fetchFirst()); + } + + @Test + public void params_anon() { + Param name = new Param(String.class); + assertEquals("Mike", query() + .from(employee).where(employee.firstname.eq(name)) + .set(name, "Mike") + .select(employee.firstname).fetchFirst()); + } + + @Test(expected = ParamNotSetException.class) + public void params_not_set() { + Param name = new Param(String.class,"name"); + assertEquals("Mike", query() + .from(employee).where(employee.firstname.eq(name)) + .select(employee.firstname).fetchFirst()); + } + + @Test + @ExcludeIn({DB2, DERBY, FIREBIRD, HSQLDB, ORACLE, SQLSERVER}) + @SkipForQuoted + public void path_alias() { + expectedQuery = "select e.LASTNAME, sum(e.SALARY) as salarySum " + + "from EMPLOYEE e " + + "group by e.LASTNAME having salarySum > ?"; + + NumberExpression salarySum = employee.salary.sum().as("salarySum"); + query().from(employee) + .groupBy(employee.lastname) + .having(salarySum.gt(10000)) + .select(employee.lastname, salarySum).fetch(); + } + + @Test + public void path_in_constant_list() { + assertEquals(0, query().from(survey).where(survey.name.in(Collections.singletonList("a"))).fetchCount()); + assertEquals(0, query().from(survey).where(survey.name.in(Arrays.asList("a","b"))).fetchCount()); + assertEquals(0, query().from(survey).where(survey.name.in(Arrays.asList("a","b","c"))).fetchCount()); + } + + @Test + public void precedence() { + StringPath fn = employee.firstname; + StringPath ln = employee.lastname; + Predicate where = fn.eq("Mike").and(ln.eq("Smith")).or(fn.eq("Joe").and(ln.eq("Divis"))); + assertEquals(2L, query().from(employee).where(where).fetchCount()); + } + + @Test + public void precedence2() { + StringPath fn = employee.firstname; + StringPath ln = employee.lastname; + Predicate where = fn.eq("Mike").and(ln.eq("Smith").or(fn.eq("Joe")).and(ln.eq("Divis"))); + assertEquals(0L, query().from(employee).where(where).fetchCount()); + } + + @Test + public void projection() throws IOException { + CloseableIterator results = query().from(survey).select(survey.all()).iterate(); + assertTrue(results.hasNext()); + while (results.hasNext()) { + assertEquals(3, results.next().size()); + } + results.close(); + } + + @Test + public void projection_and_twoColumns() { + // projection and two columns + for (Tuple row : query().from(survey) + .select(new QIdName(survey.id, survey.name), survey.id, survey.name).fetch()) { + assertEquals(3, row.size()); + assertEquals(IdName.class, row.get(0, Object.class).getClass()); + assertEquals(Integer.class, row.get(1, Object.class).getClass()); + assertEquals(String.class, row.get(2, Object.class).getClass()); + } + } + + @Test + public void projection2() throws IOException { + CloseableIterator results = query().from(survey).select(survey.id, survey.name).iterate(); + assertTrue(results.hasNext()); + while (results.hasNext()) { + assertEquals(2, results.next().size()); + } + results.close(); + } + + @Test + public void projection3() throws IOException { + CloseableIterator names = query().from(survey).select(survey.name).iterate(); + assertTrue(names.hasNext()); + while (names.hasNext()) { + System.out.println(names.next()); + } + names.close(); + } + + @Test + public void qBeanUsage() { + PathBuilder sq = new PathBuilder(Object[].class, "sq"); + List surveys = + query().from( + query().from(survey).select(survey.all()).as("sq")) + .select(Projections.bean(Survey.class, Collections.singletonMap("name", sq.get(survey.name)))).fetch(); + assertFalse(surveys.isEmpty()); + + } + + @Test + public void query_with_constant() throws Exception { + for (Tuple row : query().from(survey) + .where(survey.id.eq(1)) + .select(survey.id, survey.name).fetch()) { + assertNotNull(row.get(survey.id)); + assertNotNull(row.get(survey.name)); + } + } + + @Test + public void query1() throws Exception { + for (String s : query().from(survey).select(survey.name).fetch()) { + assertNotNull(s); + } + } + + @Test + public void query2() throws Exception { + for (Tuple row : query().from(survey).select(survey.id, survey.name).fetch()) { + assertNotNull(row.get(survey.id)); + assertNotNull(row.get(survey.name)); + } + } + + private double radians(double x) { + return x * Math.PI / 180.0; + } + + @Test + public void random() { + firstResult(MathExpressions.random()); + } + + @Test + @ExcludeIn({FIREBIRD, ORACLE, POSTGRESQL, SQLITE, TERADATA}) + public void random2() { + firstResult(MathExpressions.random(10)); + } + + @Test + public void relationalPath_projection() { + List results = query().from(employee, employee2).where(employee.id.eq(employee2.id)) + .select(employee, employee2).fetch(); + assertFalse(results.isEmpty()); + for (Tuple row : results) { + Employee e1 = row.get(employee); + Employee e2 = row.get(employee2); + assertEquals(e1.getId(), e2.getId()); + } + } + + @Test + public void relationalPath_eq() { + assertEquals(10, query().from(employee, employee2) + .where(employee.eq(employee2)) + .select(employee.id, employee2.id).fetch().size()); + } + + @Test + public void relationalPath_ne() { + assertEquals(90, query().from(employee, employee2) + .where(employee.ne(employee2)) + .select(employee.id, employee2.id).fetch().size()); + } + + @Test + public void relationalPath_eq2() { + assertEquals(1, query().from(survey, survey2) + .where(survey.eq(survey2)) + .select(survey.id, survey2.id).fetch().size()); + } + + @Test + public void relationalPath_ne2() { + assertEquals(0, query().from(survey, survey2) + .where(survey.ne(survey2)) + .select(survey.id, survey2.id).fetch().size()); + } + + @Test + @ExcludeIn(SQLITE) + public void right_join() throws SQLException { + assertEquals(16, query().from(employee).rightJoin(employee2) + .on(employee.superiorIdKey.on(employee2)) + .select(employee.id, employee2.id).fetch().size()); + } + + @Test + @ExcludeIn(DERBY) + public void round() { + Expression expr = Expressions.numberTemplate(Double.class, "1.32"); + + assertEquals(Double.valueOf(1.0), firstResult(MathExpressions.round(expr))); + assertEquals(Double.valueOf(1.3), firstResult(MathExpressions.round(expr, 1))); + } + + @Test + @ExcludeIn({SQLITE, DERBY}) + public void rpad() { + assertEquals("ab ", firstResult(StringExpressions.rpad(ConstantImpl.create("ab"), 4))); + assertEquals("ab!!", firstResult(StringExpressions.rpad(ConstantImpl.create("ab"), 4, '!'))); + } + + @Test + @Ignore + @ExcludeIn({ORACLE, DERBY, SQLSERVER}) + public void select_booleanExpr() throws SQLException { + // TODO : FIXME + System.out.println(query().from(survey).select(survey.id.eq(0)).fetch()); + } + + @Test + @Ignore + @ExcludeIn({ORACLE, DERBY, SQLSERVER}) + public void select_booleanExpr2() throws SQLException { + // TODO : FIXME + System.out.println(query().from(survey).select(survey.id.gt(0)).fetch()); + } + + @Test + public void select_booleanExpr3() { + assertTrue(query().select(Expressions.TRUE).fetchFirst()); + assertFalse(query().select(Expressions.FALSE).fetchFirst()); + } + + @Test + public void select_concat() throws SQLException { + for (Tuple row : query().from(survey).select(survey.name, survey.name.append("Hello World")).fetch()) { + assertEquals( + row.get(survey.name) + "Hello World", + row.get(survey.name.append("Hello World"))); + } + } + + @Test + @ExcludeIn({SQLITE, CUBRID, TERADATA}) + public void select_for_update() { + assertEquals(1, query().from(survey).forUpdate().select(survey.id).fetch().size()); + } + + @Test + @ExcludeIn({SQLITE, CUBRID, TERADATA}) + public void select_for_update_Where() { + assertEquals(1, query().from(survey).forUpdate().where(survey.id.isNotNull()).select(survey.id).fetch().size()); + } + + @Test + @ExcludeIn({SQLITE, CUBRID, TERADATA}) + public void select_for_update_UniqueResult() { + query().from(survey).forUpdate().select(survey.id).fetchOne(); + } + + @Test + public void select_for_share() { + if (configuration.getTemplates().isForShareSupported()) { + assertEquals(1, query().from(survey).forShare().where(survey.id.isNotNull()).select(survey.id).fetch().size()); + } else { + try { + query().from(survey).forShare().where(survey.id.isNotNull()).select(survey.id).fetch().size(); + fail(); + } catch (QueryException e) { + assertTrue(e.getMessage().equals("Using forShare() is not supported")); + } + } + } + + @Test + @SkipForQuoted + public void serialization() { + SQLQuery query = query(); + query.from(survey); + assertEquals("from SURVEY s", query.toString()); + query.from(survey2); + assertEquals("from SURVEY s, SURVEY s2", query.toString()); + } + + @Test + public void serialization2() throws Exception { + List rows = query().from(survey).select(survey.id, survey.name).fetch(); + serialize(rows); + } + + private void serialize(List rows) throws IOException, ClassNotFoundException { + rows = Serialization.serialize(rows); + for (Tuple row : rows) { + row.hashCode(); + } + } + + @Test + public void single() { + assertNotNull(query().from(survey).select(survey.name).fetchFirst()); + } + + @Test + public void single_array() { + assertNotNull(query().from(survey).select(new Expression[]{survey.name}).fetchFirst()); + } + + @Test + public void single_column() { + // single column + for (String s : query().from(survey).select(survey.name).fetch()) { + assertNotNull(s); + } + } + + @Test + public void single_column_via_Object_type() { + for (Object s : query().from(survey) + .select(ExpressionUtils.path(Object.class, survey.name.getMetadata())).fetch()) { + assertEquals(String.class, s.getClass()); + } + } + + @Test + public void specialChars() { + assertEquals(0, query().from(survey).where(survey.name.in("\n", "\r", "\\", "\'", "\"")).fetchCount()); + } + + @Test + public void standardTest() { + standardTest.runBooleanTests(employee.firstname.isNull(), employee2.lastname.isNotNull()); + // datetime + standardTest.runDateTests(employee.datefield, employee2.datefield, date); + + // numeric + standardTest.runNumericCasts(employee.id, employee2.id, 1); + standardTest.runNumericTests(employee.id, employee2.id, 1); + // BigDecimal + standardTest.runNumericTests(employee.salary, employee2.salary, new BigDecimal("30000.00")); + + standardTest.runStringTests(employee.firstname, employee2.firstname, "Jennifer"); + Target target = Connections.getTarget(); + if (target != SQLITE) { + standardTest.runTimeTests(employee.timefield, employee2.timefield, time); + } + + standardTest.report(); + } + + @Test + @IncludeIn(H2) + public void standardTest_turkish() { + Locale defaultLocale = Locale.getDefault(); + Locale.setDefault(new Locale("tr", "TR")); + try { + standardTest(); + } finally { + Locale.setDefault(defaultLocale); + } + } + + @Test + @ExcludeIn(SQLITE) + public void string() { + StringExpression str = Expressions.stringTemplate("' abcd '"); + + assertEquals("abcd ", firstResult(StringExpressions.ltrim(str))); + assertEquals(Integer.valueOf(3), firstResult(str.locate("a"))); + assertEquals(Integer.valueOf(0), firstResult(str.locate("a", 4))); + assertEquals(Integer.valueOf(4), firstResult(str.locate("b", 2))); + assertEquals(" abcd", firstResult(StringExpressions.rtrim(str))); + assertEquals("abc", firstResult(str.substring(2, 5))); + } + + @Test + @ExcludeIn(SQLITE) + public void string_withTemplate() { + StringExpression str = Expressions.stringTemplate("' abcd '"); + + NumberExpression four = Expressions.numberTemplate(Integer.class, "4"); + NumberExpression two = Expressions.numberTemplate(Integer.class, "2"); + NumberExpression five = Expressions.numberTemplate(Integer.class, "5"); + + assertEquals("abcd ", firstResult(StringExpressions.ltrim(str))); + assertEquals(Integer.valueOf(3), firstResult(str.locate("a"))); + assertEquals(Integer.valueOf(0), firstResult(str.locate("a", four))); + assertEquals(Integer.valueOf(4), firstResult(str.locate("b", two))); + assertEquals(" abcd", firstResult(StringExpressions.rtrim(str))); + assertEquals("abc", firstResult(str.substring(two, five))); + } + + @Test + @ExcludeIn({POSTGRESQL, SQLITE}) + public void string_indexOf() { + StringExpression str = Expressions.stringTemplate("' abcd '"); + + assertEquals(Integer.valueOf(2), firstResult(str.indexOf("a"))); + assertEquals(Integer.valueOf(-1), firstResult(str.indexOf("a", 4))); + assertEquals(Integer.valueOf(3), firstResult(str.indexOf("b", 2))); + } + + @Test + public void stringFunctions2() throws SQLException { + for (BooleanExpression where : Arrays.asList( + employee.firstname.startsWith("a"), + employee.firstname.startsWithIgnoreCase("a"), + employee.firstname.endsWith("a"), + employee.firstname.endsWithIgnoreCase("a"))) { + query().from(employee).where(where).select(employee.firstname).fetch(); + } + } + + @Test + @ExcludeIn(SQLITE) + public void string_left() { + assertEquals("John", query().from(employee).where(employee.lastname.eq("Johnson")) + .select(SQLExpressions.left(employee.lastname, 4)).fetchFirst()); + } + + @Test + @ExcludeIn({DERBY, SQLITE}) + public void string_right() { + assertEquals("son", query().from(employee).where(employee.lastname.eq("Johnson")) + .select(SQLExpressions.right(employee.lastname, 3)).fetchFirst()); + } + + @Test + @ExcludeIn({DERBY, SQLITE}) + public void string_left_Right() { + assertEquals("hn", query().from(employee).where(employee.lastname.eq("Johnson")) + .select(SQLExpressions.right(SQLExpressions.left(employee.lastname, 4), 2)).fetchFirst()); + } + + @Test + @ExcludeIn({DERBY, SQLITE}) + public void string_right_Left() { + assertEquals("ns", query().from(employee).where(employee.lastname.eq("Johnson")) + .select(SQLExpressions.left(SQLExpressions.right(employee.lastname, 4), 2)).fetchFirst()); + } + + @Test + @ExcludeIn({DB2, DERBY, FIREBIRD}) + public void substring() { + //SELECT * FROM account where SUBSTRING(name, -x, 1) = SUBSTRING(name, -y, 1) + query().from(employee) + .where(employee.firstname.substring(-3, 1).eq(employee.firstname.substring(-2, 1))) + .select(employee.id).fetch(); + } + + @Test + public void syntax_for_employee() throws SQLException { + assertEquals(3, query().from(employee).groupBy(employee.superiorId) + .orderBy(employee.superiorId.asc()) + .select(employee.salary.avg(), employee.id.max()).fetch().size()); + + assertEquals(2, query().from(employee).groupBy(employee.superiorId) + .having(employee.id.max().gt(5)) + .orderBy(employee.superiorId.asc()) + .select(employee.salary.avg(), employee.id.max()).fetch().size()); + + assertEquals(2, query().from(employee).groupBy(employee.superiorId) + .having(employee.superiorId.isNotNull()) + .orderBy(employee.superiorId.asc()) + .select(employee.salary.avg(), employee.id.max()).fetch().size()); + } + + @Test + public void templateExpression() { + NumberExpression one = Expressions.numberTemplate(Integer.class, "1"); + assertEquals(Collections.singletonList(1), query().from(survey).select(one.as("col1")).fetch()); + } + + @Test + public void transform_groupBy() { + QEmployee employee = new QEmployee("employee"); + QEmployee employee2 = new QEmployee("employee2"); + Map> results = query().from(employee, employee2) + .transform(GroupBy.groupBy(employee.id).as(GroupBy.map(employee2.id, employee2))); + + int count = (int) query().from(employee).fetchCount(); + assertEquals(count, results.size()); + for (Map.Entry> entry : results.entrySet()) { + Map employees = entry.getValue(); + assertEquals(count, employees.size()); + } + + } + + @Test + public void tuple_projection() { + List tuples = query().from(employee) + .select(employee.firstname, employee.lastname).fetch(); + assertFalse(tuples.isEmpty()); + for (Tuple tuple : tuples) { + assertNotNull(tuple.get(employee.firstname)); + assertNotNull(tuple.get(employee.lastname)); + } + } + + @Test + @ExcludeIn({DB2, DERBY}) + public void tuple2() { + assertEquals(10, query().from(employee) + .select(Expressions.as(ConstantImpl.create("1"), "code"), + employee.id).fetch().size()); + } + + @Test + public void twoColumns() { + // two columns + for (Tuple row : query().from(survey).select(survey.id, survey.name).fetch()) { + assertEquals(2, row.size()); + assertEquals(Integer.class, row.get(0, Object.class).getClass()); + assertEquals(String.class, row.get(1, Object.class).getClass()); + } + } + + @Test + public void twoColumns_and_projection() { + // two columns and projection + for (Tuple row : query().from(survey) + .select(survey.id, survey.name, new QIdName(survey.id, survey.name)).fetch()) { + assertEquals(3, row.size()); + assertEquals(Integer.class, row.get(0, Object.class).getClass()); + assertEquals(String.class, row.get(1, Object.class).getClass()); + assertEquals(IdName.class, row.get(2, Object.class).getClass()); + } + } + + @Test + public void unique_Constructor_projection() { + IdName idAndName = query().from(survey).limit(1).select(new QIdName(survey.id, survey.name)).fetchFirst(); + assertNotNull(idAndName); + assertNotNull(idAndName.getId()); + assertNotNull(idAndName.getName()); + } + + @Test + public void unique_single() { + String s = query().from(survey).limit(1).select(survey.name).fetchFirst(); + assertNotNull(s); + } + + @Test + public void unique_wildcard() { + // unique wildcard + Tuple row = query().from(survey).limit(1).select(survey.all()).fetchFirst(); + assertNotNull(row); + assertEquals(3, row.size()); + assertNotNull(row.get(0, Object.class)); + assertNotNull(row.get(0, Object.class) + " is not null", row.get(1, Object.class)); + } + + @Test(expected = NonUniqueResultException.class) + public void uniqueResultContract() { + query().from(employee).select(employee.all()).fetchOne(); + } + + @Test + public void various() throws SQLException { + for (String s : query().from(survey).select(survey.name.lower()).fetch()) { + assertEquals(s, s.toLowerCase()); + } + + for (String s : query().from(survey).select(survey.name.append("abc")).fetch()) { + assertTrue(s.endsWith("abc")); + } + + System.out.println(query().from(survey).select(survey.id.sqrt()).fetch()); + } + + @Test + public void where_exists() throws SQLException { + SQLQuery sq1 = query().from(employee).select(employee.id.max()); + assertEquals(10, query().from(employee).where(sq1.exists()).fetchCount()); + } + + @Test + public void where_exists_Not() throws SQLException { + SQLQuery sq1 = query().from(employee).select(employee.id.max()); + assertEquals(0, query().from(employee).where(sq1.exists().not()).fetchCount()); + } + + @Test + @IncludeIn({HSQLDB, ORACLE, POSTGRESQL}) + public void with() { + assertEquals(10, query().with(employee2, query().from(employee) + .where(employee.firstname.eq("Jim")) + .select(Wildcard.all)) + .from(employee, employee2) + .select(employee.id, employee2.id).fetch().size()); + } + + @Test + @IncludeIn({HSQLDB, ORACLE, POSTGRESQL}) + public void with2() { + QEmployee employee3 = new QEmployee("e3"); + assertEquals(100, query().with(employee2, query().from(employee) + .where(employee.firstname.eq("Jim")) + .select(Wildcard.all)) + .with(employee2, query().from(employee) + .where(employee.firstname.eq("Jim")) + .select(Wildcard.all)) + .from(employee, employee2, employee3) + .select(employee.id, employee2.id, employee3.id).fetch().size()); + } + + @Test + @IncludeIn({HSQLDB, ORACLE, POSTGRESQL}) + public void with3() { + assertEquals(10, query().with(employee2, employee2.all()).as( + query().from(employee) + .where(employee.firstname.eq("Jim")) + .select(Wildcard.all)) + .from(employee, employee2) + .select(employee.id, employee2.id).fetch().size()); + } + + @Test + @IncludeIn({HSQLDB, ORACLE, POSTGRESQL}) + public void with_limit() { + assertEquals(5, query().with(employee2, employee2.all()).as( + query().from(employee) + .where(employee.firstname.eq("Jim")) + .select(Wildcard.all)) + .from(employee, employee2) + .limit(5) + .orderBy(employee.id.asc(), employee2.id.asc()) + .select(employee.id, employee2.id).fetch().size()); + } + + @Test + @IncludeIn({HSQLDB, ORACLE, POSTGRESQL}) + public void with_limitOffset() { + assertEquals(5, query().with(employee2, employee2.all()).as( + query().from(employee) + .where(employee.firstname.eq("Jim")) + .select(Wildcard.all)) + .from(employee, employee2) + .limit(10) + .offset(5) + .orderBy(employee.id.asc(), employee2.id.asc()) + .select(employee.id, employee2.id).fetch().size()); + } + + @Test + @IncludeIn({ORACLE, POSTGRESQL}) + public void with_recursive() { + assertEquals(10, query().withRecursive(employee2, query().from(employee) + .where(employee.firstname.eq("Jim")) + .select(Wildcard.all)) + .from(employee, employee2) + .select(employee.id, employee2.id).fetch().size()); + } + + + @Test + @IncludeIn({ORACLE, POSTGRESQL}) + public void with_recursive2() { + assertEquals(10, query().withRecursive(employee2, employee2.all()).as( + query().from(employee) + .where(employee.firstname.eq("Jim")) + .select(Wildcard.all)) + .from(employee, employee2) + .select(employee.id, employee2.id).fetch().size()); + } + + @Test + public void wildcard() { + // wildcard + for (Tuple row : query().from(survey).select(survey.all()).fetch()) { + assertNotNull(row); + assertEquals(3, row.size()); + assertNotNull(row.get(0, Object.class)); + assertNotNull(row.get(0, Object.class) + " is not null", row.get(1, Object.class)); + } + } + + @Test + @SkipForQuoted + public void wildcard_all() { + expectedQuery = "select * from EMPLOYEE e"; + query().from(employee).select(Wildcard.all).fetch(); + } + + @Test + public void wildcard_all2() { + assertEquals(10, query().from(new RelationalPathBase(Object.class, "employee", "public", "EMPLOYEE")) + .select(Wildcard.all).fetch().size()); + } + + @Test + public void wildcard_and_qTuple() { + // wildcard and QTuple + for (Tuple tuple : query().from(survey).select(survey.all()).fetch()) { + assertNotNull(tuple.get(survey.id)); + assertNotNull(tuple.get(survey.name)); + } + } + + @Test + @IncludeIn(ORACLE) + public void withinGroup() { + List> exprs = new ArrayList>(); + NumberPath path = survey.id; + + // two args + add(exprs, SQLExpressions.cumeDist(2, 3)); + add(exprs, SQLExpressions.denseRank(4, 5)); + add(exprs, SQLExpressions.listagg(path, ",")); + add(exprs, SQLExpressions.percentRank(6, 7)); + add(exprs, SQLExpressions.rank(8, 9)); + + for (WithinGroup wg : exprs) { + query().from(survey).select(wg.withinGroup().orderBy(survey.id, survey.id)).fetch(); + query().from(survey).select(wg.withinGroup().orderBy(survey.id.asc(), survey.id.asc())).fetch(); + } + + // one arg + exprs.clear(); + add(exprs, SQLExpressions.percentileCont(0.1)); + add(exprs, SQLExpressions.percentileDisc(0.9)); + + for (WithinGroup wg : exprs) { + query().from(survey).select(wg.withinGroup().orderBy(survey.id)).fetch(); + query().from(survey).select(wg.withinGroup().orderBy(survey.id.asc())).fetch(); + } + } + + @Test + @ExcludeIn({DB2, DERBY, H2}) + public void yearWeek() { + SQLQuery query = query().from(employee).orderBy(employee.id.asc()); + assertEquals(Integer.valueOf(200006), query.select(employee.datefield.yearWeek()).fetchFirst()); + } + + @Test + @IncludeIn({H2}) + public void yearWeek_h2() { + SQLQuery query = query().from(employee).orderBy(employee.id.asc()); + assertEquals(Integer.valueOf(200007), query.select(employee.datefield.yearWeek()).fetchFirst()); + } + + @Test + public void statementOptions() { + StatementOptions options = StatementOptions.builder().setFetchSize(15).setMaxRows(150).build(); + SQLQuery query = query().from(employee).orderBy(employee.id.asc()); + query.setStatementOptions(options); + query.addListener(new SQLBaseListener() { + public void preExecute(SQLListenerContext context) { + try { + assertEquals(15, context.getPreparedStatement().getFetchSize()); + assertEquals(150, context.getPreparedStatement().getMaxRows()); + } catch (SQLException e) { + throw new RuntimeException(e); + } + } + }); + query.select(employee.id).fetch(); + } + + @Test + public void getResults() throws SQLException, InterruptedException { + final AtomicLong endCalled = new AtomicLong(0); + SQLQuery query = query().select(employee.id).from(employee); + query.addListener(new SQLBaseListener() { + @Override + public void end(SQLListenerContext context) { + endCalled.set(System.currentTimeMillis()); + } + }); + ResultSet results = query.getResults(employee.id); + long getResultsCalled = System.currentTimeMillis(); + Thread.sleep(100); + results.close(); + assertTrue(endCalled.get() - getResultsCalled >= 100); + } + + @Test + @ExcludeIn({DB2, DERBY, ORACLE, SQLSERVER}) + public void groupConcat() { + List expected = Arrays.asList("Mike,Mary", "Joe,Peter,Steve,Jim", "Jennifer,Helen,Daisy,Barbara"); + if (Connections.getTarget() == POSTGRESQL) { + expected = Arrays.asList("Steve,Jim,Joe,Peter", "Barbara,Helen,Daisy,Jennifer", "Mary,Mike"); + } + assertEquals( + expected, + query().select(SQLExpressions.groupConcat(employee.firstname)) + .from(employee) + .groupBy(employee.superiorId).fetch()); + } + + @Test + @ExcludeIn({DB2, DERBY, ORACLE, SQLSERVER}) + public void groupConcat2() { + List expected = Arrays.asList("Mike-Mary", "Joe-Peter-Steve-Jim", "Jennifer-Helen-Daisy-Barbara"); + if (Connections.getTarget() == POSTGRESQL) { + expected = Arrays.asList("Steve-Jim-Joe-Peter", "Barbara-Helen-Daisy-Jennifer", "Mary-Mike"); + } + assertEquals( + expected, + query().select(SQLExpressions.groupConcat(employee.firstname, "-")) + .from(employee) + .groupBy(employee.superiorId).fetch()); + } + +} +//CHECKSTYLERULE:ON: FileLength diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/SelectMySQLBase.java b/querydsl-sql/src/test/java/com/querydsl/sql/SelectMySQLBase.java new file mode 100644 index 0000000000..4abc9b6231 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/SelectMySQLBase.java @@ -0,0 +1,33 @@ +package com.querydsl.sql; + +import static com.querydsl.core.Target.MYSQL; +import static com.querydsl.sql.Constants.survey; + +import org.junit.Test; + +import com.querydsl.core.testutil.IncludeIn; +import com.querydsl.sql.mysql.MySQLQuery; + + +public class SelectMySQLBase extends AbstractBaseTest { + + protected MySQLQuery mysqlQuery() { + return new MySQLQuery(connection, configuration); + } + + @Test + @IncludeIn(MYSQL) + public void mysql_extensions() { + mysqlQuery().from(survey).bigResult().select(survey.id).fetch(); + mysqlQuery().from(survey).bufferResult().select(survey.id).fetch(); + mysqlQuery().from(survey).cache().select(survey.id).fetch(); + mysqlQuery().from(survey).calcFoundRows().select(survey.id).fetch(); + mysqlQuery().from(survey).noCache().select(survey.id).fetch(); + + mysqlQuery().from(survey).highPriority().select(survey.id).fetch(); + mysqlQuery().from(survey).lockInShareMode().select(survey.id).fetch(); + mysqlQuery().from(survey).smallResult().select(survey.id).fetch(); + mysqlQuery().from(survey).straightJoin().select(survey.id).fetch(); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/SelectOracleBase.java b/querydsl-sql/src/test/java/com/querydsl/sql/SelectOracleBase.java new file mode 100644 index 0000000000..27990c6697 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/SelectOracleBase.java @@ -0,0 +1,155 @@ +package com.querydsl.sql; + +import static com.querydsl.core.Target.ORACLE; +import static com.querydsl.sql.Constants.employee; +import static com.querydsl.sql.oracle.OracleGrammar.level; + +import java.sql.SQLException; +import java.util.logging.Logger; + +import org.junit.Assert; +import org.junit.Ignore; +import org.junit.Test; + +import com.querydsl.core.testutil.IncludeIn; +import com.querydsl.sql.domain.QEmployee; +import com.querydsl.sql.oracle.OracleQuery; + +public class SelectOracleBase extends AbstractBaseTest { + + private static final Logger logger = Logger.getLogger(AbstractSQLQuery.class.getName()); + + protected OracleQuery oracleQuery() { + return new OracleQuery(connection, configuration) { + @Override + protected SQLSerializer serialize(boolean forCountRow) { + SQLSerializer serializer = super.serialize(forCountRow); + String rv = serializer.toString(); + if (expectedQuery != null) { + Assert.assertEquals(expectedQuery, rv.replace('\n', ' ')); + expectedQuery = null; + } + logger.fine(rv); + return serializer; + } + }; + } + + @Test + @Ignore + public void connectBy() throws SQLException { + // TODO : come up with a legal case + oracleQuery().from(employee) + .where(level.eq(-1)) + .connectBy(level.lt(1000)) + .select(employee.id).fetch(); + } + + @Test + @IncludeIn(ORACLE) + @SkipForQuoted + public void connectByPrior() throws SQLException { + expectedQuery = "select e.ID, e.LASTNAME, e.SUPERIOR_ID " + + "from EMPLOYEE e " + + "connect by prior e.ID = e.SUPERIOR_ID"; + oracleQuery().from(employee) + .connectByPrior(employee.id.eq(employee.superiorId)) + .select(employee.id, employee.lastname, employee.superiorId).fetch(); + } + + @Test + @IncludeIn(ORACLE) + @SkipForQuoted + public void connectByPrior2() throws SQLException { + if (configuration.getUseLiterals()) { + return; + } + + expectedQuery = + "select e.ID, e.LASTNAME, e.SUPERIOR_ID " + + "from EMPLOYEE e " + + "start with e.ID = ? " + + "connect by prior e.ID = e.SUPERIOR_ID"; + oracleQuery().from(employee) + .startWith(employee.id.eq(1)) + .connectByPrior(employee.id.eq(employee.superiorId)) + .select(employee.id, employee.lastname, employee.superiorId).fetch(); + } + + @Test + @IncludeIn(ORACLE) + @SkipForQuoted + public void connectByPrior3() throws SQLException { + if (configuration.getUseLiterals()) { + return; + } + + expectedQuery = + "select e.ID, e.LASTNAME, e.SUPERIOR_ID " + + "from EMPLOYEE e " + + "start with e.ID = ? " + + "connect by prior e.ID = e.SUPERIOR_ID " + + "order siblings by e.LASTNAME"; + oracleQuery().from(employee) + .startWith(employee.id.eq(1)) + .connectByPrior(employee.id.eq(employee.superiorId)) + .orderSiblingsBy(employee.lastname) + .select(employee.id, employee.lastname, employee.superiorId).fetch(); + } + + @Test + @IncludeIn(ORACLE) + @SkipForQuoted + public void connectByPrior4() throws SQLException { + if (configuration.getUseLiterals()) { + return; + } + + expectedQuery = + "select e.ID, e.LASTNAME, e.SUPERIOR_ID " + + "from EMPLOYEE e " + + "connect by nocycle prior e.ID = e.SUPERIOR_ID"; + oracleQuery().from(employee) + .connectByNocyclePrior(employee.id.eq(employee.superiorId)) + .select(employee.id, employee.lastname, employee.superiorId).fetch(); + } + + @Test + @IncludeIn(ORACLE) + @SkipForQuoted + public void sumOver() throws SQLException { +// SQL> select deptno, +// 2 ename, +// 3 sal, +// 4 sum(sal) over (partition by deptno +// 5 order by sal,ename) CumDeptTot, +// 6 sum(sal) over (partition by deptno) SalByDept, +// 7 sum(sal) over (order by deptno, sal) CumTot, +// 8 sum(sal) over () TotSal +// 9 from emp +// 10 order by deptno, sal; + expectedQuery = "select e.LASTNAME, e.SALARY, " + + "sum(e.SALARY) over (partition by e.SUPERIOR_ID order by e.LASTNAME asc, e.SALARY asc), " + + "sum(e.SALARY) over (order by e.SUPERIOR_ID asc, e.SALARY asc), " + + "sum(e.SALARY) over () from EMPLOYEE e order by e.SALARY asc, e.SUPERIOR_ID asc"; + + oracleQuery().from(employee) + .orderBy(employee.salary.asc(), employee.superiorId.asc()) + .select( + employee.lastname, + employee.salary, + SQLExpressions.sum(employee.salary).over().partitionBy(employee.superiorId).orderBy(employee.lastname, employee.salary), + SQLExpressions.sum(employee.salary).over().orderBy(employee.superiorId, employee.salary), + SQLExpressions.sum(employee.salary).over()).fetch(); + + // shorter version + QEmployee e = employee; + oracleQuery().from(e) + .orderBy(e.salary.asc(), e.superiorId.asc()) + .select(e.lastname, e.salary, + SQLExpressions.sum(e.salary).over().partitionBy(e.superiorId).orderBy(e.lastname, e.salary), + SQLExpressions.sum(e.salary).over().orderBy(e.superiorId, e.salary), + SQLExpressions.sum(e.salary).over()).fetch(); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/SelectTeradataBase.java b/querydsl-sql/src/test/java/com/querydsl/sql/SelectTeradataBase.java new file mode 100644 index 0000000000..3d5b75ed45 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/SelectTeradataBase.java @@ -0,0 +1,31 @@ +package com.querydsl.sql; + +import static com.querydsl.core.Target.TERADATA; +import static com.querydsl.sql.Constants.survey; + +import org.junit.Test; + +import com.querydsl.core.testutil.IncludeIn; +import com.querydsl.sql.teradata.SetQueryBandClause; + +public class SelectTeradataBase extends AbstractBaseTest { + + protected SetQueryBandClause setQueryBand() { + return new SetQueryBandClause(connection, configuration); + } + + @Test + @IncludeIn(TERADATA) + public void setQueryBand_forSession() { + setQueryBand().set("a", "bb").forSession().execute(); + query().from(survey).select(survey.id).fetch(); + } + + @Test + @IncludeIn(TERADATA) + public void setQueryBand_forTransaction() { + setQueryBand().set("a", "bb").forTransaction().execute(); + query().from(survey).select(survey.id).fetch(); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/SelectWindowFunctionsBase.java b/querydsl-sql/src/test/java/com/querydsl/sql/SelectWindowFunctionsBase.java new file mode 100644 index 0000000000..2f36f9e199 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/SelectWindowFunctionsBase.java @@ -0,0 +1,223 @@ +package com.querydsl.sql; + +import static com.querydsl.core.Target.*; +import static com.querydsl.sql.Constants.*; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.junit.Test; + +import com.querydsl.core.Tuple; +import com.querydsl.core.testutil.ExcludeIn; +import com.querydsl.core.testutil.IncludeIn; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.SimplePath; +import com.querydsl.core.types.dsl.Wildcard; + +public class SelectWindowFunctionsBase extends AbstractBaseTest { + + @Test + @ExcludeIn(SQLSERVER) // FIXME + public void windowFunctions() { + NumberPath path = survey.id; + NumberPath path2 = survey.id; + + List> exprs = new ArrayList>(); + add(exprs, SQLExpressions.avg(path)); + add(exprs, SQLExpressions.count(path)); + add(exprs, SQLExpressions.corr(path, path2)); + add(exprs, SQLExpressions.covarPop(path, path2), DB2); + add(exprs, SQLExpressions.covarSamp(path, path2), DB2); + add(exprs, SQLExpressions.cumeDist(), DB2, TERADATA); + add(exprs, SQLExpressions.denseRank(), TERADATA); + add(exprs, SQLExpressions.firstValue(path), TERADATA); + add(exprs, SQLExpressions.lag(path), TERADATA); + add(exprs, SQLExpressions.lastValue(path), TERADATA); + add(exprs, SQLExpressions.lead(path), TERADATA); + add(exprs, SQLExpressions.max(path)); + add(exprs, SQLExpressions.min(path)); + add(exprs, SQLExpressions.nthValue(path, 2), DB2, TERADATA); + add(exprs, SQLExpressions.ntile(3), DB2, TERADATA); + add(exprs, SQLExpressions.percentRank(), DB2); + add(exprs, SQLExpressions.rank()); + add(exprs, SQLExpressions.rowNumber()); + add(exprs, SQLExpressions.stddev(path), TERADATA); + add(exprs, SQLExpressions.stddevPop(path), DB2, TERADATA); + add(exprs, SQLExpressions.stddevSamp(path), DB2, TERADATA); + add(exprs, SQLExpressions.sum(path)); + add(exprs, SQLExpressions.variance(path), TERADATA); + add(exprs, SQLExpressions.varPop(path), DB2, TERADATA); + add(exprs, SQLExpressions.varSamp(path), DB2, TERADATA); + + for (WindowOver wo : exprs) { + query().from(survey).select(wo.over().partitionBy(survey.name).orderBy(survey.id)).fetch(); + } + } + + @Test + public void windowFunctions_manual_paging() { + Expression rowNumber = SQLExpressions.rowNumber().over().orderBy(employee.lastname.asc()).as("rn"); + Expression all = Wildcard.all; + + // simple + System.out.println("#1"); + for (Tuple row : query().from(employee).select(employee.firstname, employee.lastname, rowNumber).fetch()) { + System.out.println(row); + } + System.out.println(); + + // with subquery, generic alias + System.out.println("#2"); + SQLQuery sub = query().from(employee).select(employee.firstname, employee.lastname, rowNumber); + SimplePath subAlias = Expressions.path(Tuple.class, "s"); + for (Object[] row : query().from(sub.as(subAlias)).select(all).fetch()) { + System.out.println(Arrays.asList(row)); + } + System.out.println(); + + // with subquery, only row number + System.out.println("#3"); + SQLQuery sub2 = query().from(employee).select(rowNumber); + SimplePath subAlias2 = Expressions.path(Long.class, "s"); + for (Object[] row : query().from(sub2.as(subAlias2)).select(all).fetch()) { + System.out.println(Arrays.asList(row)); + } + System.out.println(); + + // with subquery, specific alias + System.out.println("#4"); + SQLQuery sub3 = query().from(employee).select(employee.firstname, employee.lastname, rowNumber); + for (Tuple row : query().from(sub3.as(employee2)).select(employee2.firstname, employee2.lastname).fetch()) { + System.out.println(Collections.singletonList(row)); + } + } + + @Test + @IncludeIn(ORACLE) + public void windowFunctions_keep() { + List> exprs = new ArrayList>(); + NumberPath path = survey.id; + + add(exprs, SQLExpressions.avg(path)); + add(exprs, SQLExpressions.count(path)); + add(exprs, SQLExpressions.max(path)); + add(exprs, SQLExpressions.min(path)); + add(exprs, SQLExpressions.stddev(path)); + add(exprs, SQLExpressions.variance(path)); + + for (WindowOver wo : exprs) { + query().from(survey).select(wo.keepFirst().orderBy(survey.id)).fetch(); + } + } + + @Test + @ExcludeIn({DB2, SQLSERVER}) + public void windowFunctions_regr() { + List> exprs = new ArrayList>(); + NumberPath path = survey.id; + NumberPath path2 = survey.id; + + add(exprs, SQLExpressions.regrSlope(path, path2), SQLSERVER); + add(exprs, SQLExpressions.regrIntercept(path, path2)); + add(exprs, SQLExpressions.regrCount(path, path2)); + add(exprs, SQLExpressions.regrR2(path, path2)); + add(exprs, SQLExpressions.regrAvgx(path, path2)); + add(exprs, SQLExpressions.regrSxx(path, path2)); + add(exprs, SQLExpressions.regrSyy(path, path2)); + add(exprs, SQLExpressions.regrSxy(path, path2)); + + for (WindowOver wo : exprs) { + query().from(survey).select(wo.over().partitionBy(survey.name).orderBy(survey.id)).fetch(); + } + } + + @Test + @IncludeIn(ORACLE) + public void windowFunctions_oracle() { + List> exprs = new ArrayList>(); + NumberPath path = survey.id; + add(exprs, SQLExpressions.countDistinct(path)); + add(exprs, SQLExpressions.ratioToReport(path)); + add(exprs, SQLExpressions.stddevDistinct(path)); + + for (WindowOver wo : exprs) { + query().from(survey).select(wo.over().partitionBy(survey.name)).fetch(); + } + } + + @Test + public void windowFunctions_over() { + //SELECT Shipment_id,Ship_date, SUM(Qty) OVER () AS Total_Qty + //FROM TestDB.Shipment + + query().from(employee).select( + employee.id, + SQLExpressions.sum(employee.salary).over()).fetch(); + } + + @Test + public void windowFunctions_partitionBy() { + //SELECT Shipment_id,Ship_date,Ship_Type, + //SUM(Qty) OVER (PARTITION BY Ship_Type ) AS Total_Qty + //FROM TestDB.Shipment + + query().from(employee).select( + employee.id, + employee.superiorId, + SQLExpressions.sum(employee.salary).over() + .partitionBy(employee.superiorId)).fetch(); + } + + @Test + @ExcludeIn(SQLSERVER) + public void windowFunctions_orderBy() { + //SELECT Shipment_id,Ship_date,Ship_Type, + //SUM(Qty) OVER (PARTITION BY Ship_Type ORDER BY Ship_Dt ) AS Total_Qty + //FROM TestDB.Shipment + + query().from(employee).select( + employee.id, + SQLExpressions.sum(employee.salary).over() + .partitionBy(employee.superiorId) + .orderBy(employee.datefield)).fetch(); + } + + @Test + @ExcludeIn(SQLSERVER) + public void windowFunctions_unboundedRows() { + //SELECT Shipment_id,Ship_date,Ship_Type, + //SUM(Qty) OVER (PARTITION BY Ship_Type ORDER BY Ship_Dt + //ROWS BETWEEN UNBOUNDED PRECEDING + //AND CURRENT ROW) AS Total_Qty + //FROM TestDB.Shipment + + query().from(employee).select( + employee.id, + SQLExpressions.sum(employee.salary).over() + .partitionBy(employee.superiorId) + .orderBy(employee.datefield) + .rows().between().unboundedPreceding().currentRow()).fetch(); + } + + @Test + @IncludeIn({TERADATA}) + public void windowFunctions_qualify() { + //SELECT Shipment_id,Ship_date,Ship_Type, + //Rank() OVER (PARTITION BY Ship_Type ORDER BY Ship_Dt ) AS rnk + //FROM TestDB.Shipment + //QUALIFY (Rank() OVER (PARTITION BY Ship_Type ORDER BY Ship_Dt )) =1 + + teradataQuery().from(employee) + .qualify(SQLExpressions.rank().over() + .partitionBy(employee.superiorId) + .orderBy(employee.datefield).eq(1L)) + .select(employee.id,SQLExpressions.sum(employee.salary).over()).fetch(); + + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/SerializationTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/SerializationTest.java new file mode 100644 index 0000000000..2b582ce317 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/SerializationTest.java @@ -0,0 +1,265 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import static com.querydsl.sql.SQLExpressions.*; +import static org.junit.Assert.assertEquals; + +import java.sql.Connection; + +import org.easymock.EasyMock; +import org.junit.Test; + +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.SubQueryExpression; +import com.querydsl.core.types.dsl.PathBuilder; +import com.querydsl.sql.dml.SQLDeleteClause; +import com.querydsl.sql.dml.SQLInsertClause; +import com.querydsl.sql.dml.SQLUpdateClause; +import com.querydsl.sql.domain.QEmployee; +import com.querydsl.sql.domain.QSurvey; + +public class SerializationTest { + + private static final QSurvey survey = QSurvey.survey; + + private final Connection connection = EasyMock.createMock(Connection.class); + + @Test + public void innerJoin() { + SQLQuery query = new SQLQuery(connection,SQLTemplates.DEFAULT); + query.from(new QSurvey("s1")).innerJoin(new QSurvey("s2")); + assertEquals("from SURVEY s1\ninner join SURVEY s2", query.toString()); + } + + @Test + public void leftJoin() { + SQLQuery query = new SQLQuery(connection,SQLTemplates.DEFAULT); + query.from(new QSurvey("s1")).leftJoin(new QSurvey("s2")); + assertEquals("from SURVEY s1\nleft join SURVEY s2", query.toString()); + } + + @Test + public void rightJoin() { + SQLQuery query = new SQLQuery(connection,SQLTemplates.DEFAULT); + query.from(new QSurvey("s1")).rightJoin(new QSurvey("s2")); + assertEquals("from SURVEY s1\nright join SURVEY s2", query.toString()); + } + + @Test + public void fullJoin() { + SQLQuery query = new SQLQuery(connection,SQLTemplates.DEFAULT); + query.from(new QSurvey("s1")).fullJoin(new QSurvey("s2")); + assertEquals("from SURVEY s1\nfull join SURVEY s2", query.toString()); + } + + @Test + public void update() { + SQLUpdateClause updateClause = new SQLUpdateClause(connection,SQLTemplates.DEFAULT,survey); + updateClause.set(survey.id, 1); + updateClause.set(survey.name, (String) null); + assertEquals("update SURVEY\nset ID = ?, NAME = ?", updateClause.toString()); + } + + @Test + public void update_where() { + SQLUpdateClause updateClause = new SQLUpdateClause(connection,SQLTemplates.DEFAULT,survey); + updateClause.set(survey.id, 1); + updateClause.set(survey.name, (String) null); + updateClause.where(survey.name.eq("XXX")); + assertEquals("update SURVEY\nset ID = ?, NAME = ?\nwhere SURVEY.NAME = ?", updateClause.toString()); + } + + @Test + public void insert() { + SQLInsertClause insertClause = new SQLInsertClause(connection,SQLTemplates.DEFAULT,survey); + insertClause.set(survey.id, 1); + insertClause.set(survey.name, (String) null); + assertEquals("insert into SURVEY (ID, NAME)\nvalues (?, ?)", insertClause.toString()); + } + + @Test + public void delete_with_subQuery_exists() { + QSurvey survey1 = new QSurvey("s1"); + QEmployee employee = new QEmployee("e"); + SQLDeleteClause delete = new SQLDeleteClause(connection, SQLTemplates.DEFAULT,survey1); + delete.where(survey1.name.eq("XXX"), selectOne().from(employee).where(survey1.id.eq(employee.id)).exists()); + assertEquals("delete from SURVEY\n" + + "where SURVEY.NAME = ? and exists (select 1\n" + + "from EMPLOYEE e\n" + + "where SURVEY.ID = e.ID)", delete.toString()); + } + + @Test + public void nextval() { + SubQueryExpression sq = select(SQLExpressions.nextval("myseq")).from(QSurvey.survey); + SQLSerializer serializer = new SQLSerializer(Configuration.DEFAULT); + serializer.serialize(sq.getMetadata(), false); + assertEquals("select nextval('myseq')\nfrom SURVEY SURVEY", serializer.toString()); + } + + @Test + public void functionCall() { + RelationalFunctionCall func = SQLExpressions.relationalFunctionCall(String.class, "TableValuedFunction", "parameter"); + PathBuilder funcAlias = new PathBuilder(String.class, "tokFunc"); + SubQueryExpression expr = select(survey.name).from(survey) + .join(func, funcAlias).on(survey.name.like(funcAlias.getString("prop")).not()); + + SQLSerializer serializer = new SQLSerializer(new Configuration(new SQLServerTemplates())); + serializer.serialize(expr.getMetadata(), false); + assertEquals("select SURVEY.NAME\n" + + "from SURVEY SURVEY\n" + + "join TableValuedFunction(?) as tokFunc\n" + + "on not (SURVEY.NAME like tokFunc.prop escape '\\')", serializer.toString()); + + } + + @Test + public void functionCall2() { + RelationalFunctionCall func = SQLExpressions.relationalFunctionCall(String.class, "TableValuedFunction", "parameter"); + PathBuilder funcAlias = new PathBuilder(String.class, "tokFunc"); + SQLQuery q = new SQLQuery(SQLServerTemplates.DEFAULT); + q.from(survey) + .join(func, funcAlias).on(survey.name.like(funcAlias.getString("prop")).not()); + + assertEquals("from SURVEY SURVEY\n" + + "join TableValuedFunction(?) as tokFunc\n" + + "on not (SURVEY.NAME like tokFunc.prop escape '\\')", q.toString()); + } + + @Test + public void functionCall3() { + RelationalFunctionCall func = SQLExpressions.relationalFunctionCall(String.class, "TableValuedFunction", "parameter"); + PathBuilder funcAlias = new PathBuilder(String.class, "tokFunc"); + SQLQuery q = new SQLQuery(HSQLDBTemplates.DEFAULT); + q.from(survey) + .join(func, funcAlias).on(survey.name.like(funcAlias.getString("prop")).not()); + + assertEquals("from SURVEY SURVEY\n" + + "join table(TableValuedFunction(?)) as tokFunc\n" + + "on not (SURVEY.NAME like tokFunc.prop escape '\\')", q.toString()); + } + + @SuppressWarnings("unchecked") + @Test + public void union1() { + Expression q = union(select(survey.all()).from(survey), + select(survey.all()).from(survey)); + + assertEquals("(select SURVEY.NAME, SURVEY.NAME2, SURVEY.ID\n" + + "from SURVEY SURVEY)\n" + + "union\n" + + "(select SURVEY.NAME, SURVEY.NAME2, SURVEY.ID\n" + + "from SURVEY SURVEY)", q.toString()); + + } + + @SuppressWarnings("unchecked") + @Test + public void union1_groupBy() { + Expression q = union(select(survey.all()).from(survey), + select(survey.all()).from(survey)) + .groupBy(survey.id); + + assertEquals("(select SURVEY.NAME, SURVEY.NAME2, SURVEY.ID\n" + + "from SURVEY SURVEY)\n" + + "union\n" + + "(select SURVEY.NAME, SURVEY.NAME2, SURVEY.ID\n" + + "from SURVEY SURVEY)\n" + + "group by SURVEY.ID", q.toString()); + + } + + @SuppressWarnings("unchecked") + @Test + public void union2() { + Expression q = new SQLQuery().union(survey, + select(survey.all()).from(survey), + select(survey.all()).from(survey)); + + assertEquals("from ((select SURVEY.NAME, SURVEY.NAME2, SURVEY.ID\n" + + "from SURVEY SURVEY)\n" + + "union\n" + + "(select SURVEY.NAME, SURVEY.NAME2, SURVEY.ID\n" + + "from SURVEY SURVEY)) as SURVEY", q.toString()); + + } + + @Test + public void with() { + QSurvey survey2 = new QSurvey("survey2"); + SQLQuery q = new SQLQuery(); + q.with(survey, survey.id, survey.name).as( + select(survey2.id, survey2.name).from(survey2)); + + assertEquals("with SURVEY (ID, NAME) as (select survey2.ID, survey2.NAME\n" + + "from SURVEY survey2)\n\n" + + "from dual", q.toString()); + } + + @Test + public void with_complex() { + QSurvey s = new QSurvey("s"); + SQLQuery q = new SQLQuery(); + q.with(s, s.id, s.name).as( + select(survey.id, survey.name).from(survey)) + .select(s.id, s.name, survey.id, survey.name).from(s, survey); + + assertEquals("with s (ID, NAME) as (select SURVEY.ID, SURVEY.NAME\n" + + "from SURVEY SURVEY)\n" + + "select s.ID, s.NAME, SURVEY.ID, SURVEY.NAME\n" + + "from s s, SURVEY SURVEY", q.toString()); + } + + @Test + public void with_tuple() { + PathBuilder survey = new PathBuilder(Survey.class, "SURVEY"); + QSurvey survey2 = new QSurvey("survey2"); + SQLQuery q = new SQLQuery(); + q.with(survey, survey.get(survey2.id), survey.get(survey2.name)).as( + select(survey2.id, survey2.name).from(survey2)); + + assertEquals("with SURVEY (ID, NAME) as (select survey2.ID, survey2.NAME\n" + + "from SURVEY survey2)\n\n" + + "from dual", q.toString()); + } + + @Test + public void with_tuple2() { + QSurvey survey2 = new QSurvey("survey2"); + SQLQuery q = new SQLQuery(); + q.with(survey, survey.id, survey.name).as( + select(survey2.id, survey2.name).from(survey2)); + + assertEquals("with SURVEY (ID, NAME) as (select survey2.ID, survey2.NAME\n" + + "from SURVEY survey2)\n\n" + + "from dual", q.toString()); + } + + @Test + public void with_singleColumn() { + QSurvey survey2 = new QSurvey("survey2"); + SQLQuery q = new SQLQuery(); + q.with(survey, new Path[]{survey.id}).as( + select(survey2.id).from(survey2)); + + assertEquals("with SURVEY (ID) as (select survey2.ID\n" + + "from SURVEY survey2)\n\n" + + "from dual", q.toString()); + } + + + +} diff --git a/querydsl-sql/src/test/java/com/mysema/query/SimpleProjection.java b/querydsl-sql/src/test/java/com/querydsl/sql/SimpleProjection.java similarity index 78% rename from querydsl-sql/src/test/java/com/mysema/query/SimpleProjection.java rename to querydsl-sql/src/test/java/com/querydsl/sql/SimpleProjection.java index af38f02b22..7d0a4d8201 100644 --- a/querydsl-sql/src/test/java/com/mysema/query/SimpleProjection.java +++ b/querydsl-sql/src/test/java/com/querydsl/sql/SimpleProjection.java @@ -1,4 +1,4 @@ -package com.mysema.query; +package com.querydsl.sql; public class SimpleProjection { diff --git a/querydsl-sql/src/test/java/com/mysema/query/SkipForQuoted.java b/querydsl-sql/src/test/java/com/querydsl/sql/SkipForQuoted.java similarity index 90% rename from querydsl-sql/src/test/java/com/mysema/query/SkipForQuoted.java rename to querydsl-sql/src/test/java/com/querydsl/sql/SkipForQuoted.java index 4dc2473706..f8e1bd00a3 100644 --- a/querydsl-sql/src/test/java/com/mysema/query/SkipForQuoted.java +++ b/querydsl-sql/src/test/java/com/querydsl/sql/SkipForQuoted.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query; +package com.querydsl.sql; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.TYPE; diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/SkipForQuotedRule.java b/querydsl-sql/src/test/java/com/querydsl/sql/SkipForQuotedRule.java new file mode 100644 index 0000000000..04a8b4356f --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/SkipForQuotedRule.java @@ -0,0 +1,28 @@ +package com.querydsl.sql; + +import org.junit.rules.MethodRule; +import org.junit.runners.model.FrameworkMethod; +import org.junit.runners.model.Statement; + +import com.querydsl.core.testutil.EmptyStatement; + +public class SkipForQuotedRule implements MethodRule { + + private final Configuration configuration; + + public SkipForQuotedRule(Configuration conf) { + this.configuration = conf; + } + + @Override + public Statement apply(Statement base, FrameworkMethod method, Object target) { + SQLTemplates templates = configuration.getTemplates(); + if (templates.isUseQuotes() || templates.isPrintSchema() || configuration.getUseLiterals()) { + boolean skip = method.getMethod().isAnnotationPresent(SkipForQuoted.class); + return skip ? EmptyStatement.DEFAULT : base; + } else { + return base; + } + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/StoredProcedures.java b/querydsl-sql/src/test/java/com/querydsl/sql/StoredProcedures.java new file mode 100644 index 0000000000..a3e840bc34 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/StoredProcedures.java @@ -0,0 +1,54 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import java.sql.*; + +public final class StoredProcedures { + + private StoredProcedures() { } + + public static void main(String[] args) throws ClassNotFoundException, SQLException { + Class.forName("org.apache.derby.jdbc.EmbeddedDriver"); + String url = "jdbc:derby:target/procedure_test;create=true"; + + try (Connection connection = DriverManager.getConnection(url, "", "")) { + DatabaseMetaData md = connection.getMetaData(); + try (ResultSet procedures = md.getProcedures(null, null, null)) { + while (procedures.next()) { + String cat = procedures.getString(1); + String schema = procedures.getString(2); + String name = procedures.getString(3); + String remarks = procedures.getString(7); + String type = procedures.getString(8); + String specificName = procedures.getString(9); + System.out.println(name + "\n" + remarks + "\n" + type + "\n" + specificName); + + try (ResultSet procedureColumns = md.getProcedureColumns(cat, schema, name, null)) { + while (procedureColumns.next()) { + String columnName = procedureColumns.getString(4); + int columnType = procedureColumns.getInt(5); + int dataType = procedureColumns.getInt(6); + String typeName = procedureColumns.getString(7); + short nullable = procedureColumns.getShort(12); + System.out.println(" " + columnName + " " + columnType + " " + dataType + " " + typeName + " " + nullable); + } + System.out.println(); + } + } + } + } + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/SubqueriesBase.java b/querydsl-sql/src/test/java/com/querydsl/sql/SubqueriesBase.java new file mode 100644 index 0000000000..c2ba367081 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/SubqueriesBase.java @@ -0,0 +1,207 @@ +package com.querydsl.sql; + +import static com.querydsl.core.Target.*; +import static com.querydsl.sql.Constants.*; +import static com.querydsl.sql.SQLExpressions.select; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; + +import java.math.BigDecimal; +import java.sql.SQLException; +import java.util.Arrays; +import java.util.List; + +import org.junit.Test; + +import com.querydsl.core.testutil.ExcludeIn; +import com.querydsl.core.types.SubQueryExpression; +import com.querydsl.core.types.dsl.*; +import com.querydsl.sql.domain.Employee; +import com.querydsl.sql.domain.QEmployee; + +public class SubqueriesBase extends AbstractBaseTest { + + @Test + @ExcludeIn({CUBRID, DERBY, FIREBIRD, H2, HSQLDB, SQLITE, SQLSERVER}) + public void keys() { + QEmployee employee2 = new QEmployee("employee2"); + ForeignKey nameKey1 = new ForeignKey(employee, + Arrays.asList(employee.firstname, employee.lastname), + Arrays.asList("a", "b")); + ForeignKey nameKey2 = new ForeignKey(employee, + Arrays.asList(employee.firstname, employee.lastname), + Arrays.asList("a", "b")); + + query().from(employee) + .where(nameKey1.in(query().from(employee2).select(nameKey2.getProjection()))) + .select(employee.id).fetch(); + } + + @Test + @ExcludeIn({CUBRID, DERBY, FIREBIRD, H2, HSQLDB, SQLITE, SQLSERVER}) + public void list_in_query() { + QEmployee employee2 = new QEmployee("employee2"); + query().from(employee) + .where(Expressions.list(employee.id, employee.lastname) + .in(query().from(employee2).select(employee2.id, employee2.lastname))) + .select(employee.id).fetch(); + } + + @Test + @SkipForQuoted + @ExcludeIn(DB2) // ID is reserved IN DB2 + public void subQueries() throws SQLException { + // subquery in where block + expectedQuery = "select e.ID from EMPLOYEE e " + + "where e.ID = (select max(e.ID) " + + "from EMPLOYEE e)"; + List list = query().from(employee) + .where(employee.id.eq(query().from(employee).select(employee.id.max()))) + .select(employee.id).fetch(); + assertFalse(list.isEmpty()); + } + + @Test + public void subQuery_alias() { + query().from(query().from(employee).select(employee.all()).as(employee2)).select(employee2.all()).fetch(); + } + + @Test + @ExcludeIn(SQLITE) + public void subQuery_all() { + query().from(employee).where(employee.id.gtAll( + query().from(employee2).select(employee2.id))).fetchCount(); + } + + @Test + @ExcludeIn(SQLITE) + public void subQuery_any() { + query().from(employee).where(employee.id.gtAny( + query().from(employee2).select(employee2.id))).fetchCount(); + } + + @Test + public void subQuery_innerJoin() { + SubQueryExpression sq = query().from(employee2).select(employee2.id); + QEmployee sqEmp = new QEmployee("sq"); + query().from(employee).innerJoin(sq, sqEmp).on(sqEmp.id.eq(employee.id)).select(employee.id).fetch(); + + } + + @Test + public void subQuery_leftJoin() { + SubQueryExpression sq = query().from(employee2).select(employee2.id); + QEmployee sqEmp = new QEmployee("sq"); + query().from(employee).leftJoin(sq, sqEmp).on(sqEmp.id.eq(employee.id)).select(employee.id).fetch(); + + } + + @Test + @ExcludeIn({MYSQL, POSTGRESQL, DERBY, SQLSERVER, TERADATA}) + public void subQuery_params() { + Param aParam = new Param(String.class, "param"); + SQLQuery subQuery = select(Wildcard.all).from(employee).where(employee.firstname.eq(aParam)); + subQuery.set(aParam, "Mike"); + + assertEquals(1, query().from(subQuery).fetchCount()); + } + + @Test + @ExcludeIn(SQLITE) + public void subQuery_rightJoin() { + SubQueryExpression sq = query().from(employee2).select(employee2.id); + QEmployee sqEmp = new QEmployee("sq"); + query().from(employee).rightJoin(sq, sqEmp).on(sqEmp.id.eq(employee.id)).select(employee.id).fetch(); + } + + @Test + public void subQuery_with_alias() { + List ids1 = query().from(employee).select(employee.id).fetch(); + List ids2 = query().from(query().from(employee).select(employee.id), employee).select(employee.id).fetch(); + assertEquals(ids1, ids2); + } + + @Test + public void subQuery_with_alias2() { + List ids1 = query().from(employee).select(employee.id).fetch(); + List ids2 = query().from(query().from(employee).select(employee.id).as(employee)).select(employee.id).fetch(); + assertEquals(ids1, ids2); + } + + @Test + @SkipForQuoted + public void subQuerySerialization() { + SQLQuery query = query(); + query.from(survey); + assertEquals("from SURVEY s", query.toString()); + + query.from(survey2); + assertEquals("from SURVEY s, SURVEY s2", query.toString()); + } + + @Test + public void subQuerySerialization2() { + NumberPath sal = Expressions.numberPath(BigDecimal.class, "sal"); + PathBuilder sq = new PathBuilder(Object[].class, "sq"); + SQLSerializer serializer = new SQLSerializer(Configuration.DEFAULT); + + serializer.handle( + query() + .from(employee) + .select(employee.salary.add(employee.salary).add(employee.salary).as(sal)) + .as(sq)); + assertEquals( + "(select (e.SALARY + e.SALARY + e.SALARY) as sal\nfrom EMPLOYEE e) as sq", + serializer.toString()); + } + + @Test + public void scalarSubQueryInClause() { + SQLSerializer serializer = new SQLSerializer(Configuration.DEFAULT); + + serializer.handle( + this.query() + .from(employee) + .where( + SQLExpressions + .select(employee.firstname) + .from(employee) + .orderBy(employee.salary.asc()) + .limit(1) + .in(Arrays.asList("Mike", "Mary")) + )); + + expectedQuery = "(\nfrom EMPLOYEE e\n" + + "where (select e.FIRSTNAME\n" + + "from EMPLOYEE e\n" + + "order by e.SALARY asc\n" + + "limit ?) in (?, ?))"; + + assertEquals(expectedQuery, serializer.toString()); + } + + @Test + public void scalarSubQueryInClause2() { + SQLSerializer serializer = new SQLSerializer(Configuration.DEFAULT); + + serializer.handle( + this.query() + .from(employee) + .where( + SQLExpressions + .select(employee.firstname) + .from(employee) + .orderBy(employee.salary.asc()) + .limit(1) + .in("Mike", "Mary") + )); + + expectedQuery = "(\nfrom EMPLOYEE e\n" + + "where (select e.FIRSTNAME\n" + + "from EMPLOYEE e\n" + + "order by e.SALARY asc\n" + + "limit ?) in (?, ?))"; + + assertEquals(expectedQuery, serializer.toString()); + } +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/Survey.java b/querydsl-sql/src/test/java/com/querydsl/sql/Survey.java new file mode 100644 index 0000000000..4686e14c9a --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/Survey.java @@ -0,0 +1,16 @@ +package com.querydsl.sql; + +public class Survey { + + @Column("NAME") + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + +} \ No newline at end of file diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/TargetRule.java b/querydsl-sql/src/test/java/com/querydsl/sql/TargetRule.java new file mode 100644 index 0000000000..f0098fb548 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/TargetRule.java @@ -0,0 +1,37 @@ +package com.querydsl.sql; + +import java.util.Arrays; + +import org.junit.rules.TestRule; +import org.junit.runner.Description; +import org.junit.runners.model.Statement; + +import com.querydsl.core.Target; +import com.querydsl.core.testutil.EmptyStatement; +import com.querydsl.core.testutil.ExcludeIn; +import com.querydsl.core.testutil.IncludeIn; + +public class TargetRule implements TestRule { + + @Override + public Statement apply(Statement base, Description description) { + Target target = Connections.getTarget(); + boolean run = target == null || isExecuted(description, target); + return run ? base : EmptyStatement.DEFAULT; + } + + private boolean isExecuted(Description description, Target target) { + ExcludeIn ex = description.getAnnotation(ExcludeIn.class); + // excluded in given targets + if (ex != null && Arrays.asList(ex.value()).contains(target)) { + return false; + } + // included only in given targets + IncludeIn in = description.getAnnotation(IncludeIn.class); + if (in != null && !Arrays.asList(in.value()).contains(target)) { + return false; + } + return true; + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/TemplateTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/TemplateTest.java new file mode 100644 index 0000000000..e930df5849 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/TemplateTest.java @@ -0,0 +1,50 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import static org.junit.Assert.assertEquals; + +import java.util.Date; + +import org.junit.Test; + +import com.querydsl.core.types.ConstantImpl; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.dsl.DateExpression; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.StringExpression; + +public class TemplateTest { + + @Test + public void toDate() { + StringExpression str = Expressions.stringPath("str"); + assertEquals("to_date(str,'DD-MON-YYYY')", to_date(str, "DD-MON-YYYY").toString()); + } + + @Test + public void toChar() { + DateExpression date = Expressions.datePath(Date.class,"date"); + assertEquals("to_char(date,'DD-MON-YYYY')", to_char(date, "DD-MON-YYYY").toString()); + } + + private DateExpression to_date(Expression expr, String pattern) { + return Expressions.dateTemplate(Date.class, "to_date({0},'{1s}')", expr, ConstantImpl.create(pattern)); + } + + private StringExpression to_char(Expression expr, String pattern) { + return Expressions.stringTemplate("to_char({0},'{1s}')", expr, ConstantImpl.create(pattern)); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/TemplatesTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/TemplatesTest.java new file mode 100644 index 0000000000..be92198f27 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/TemplatesTest.java @@ -0,0 +1,34 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import org.junit.Test; + +import com.querydsl.core.TemplatesTestBase; + +public class TemplatesTest extends TemplatesTestBase { + + @Test + public void test() { + new DerbyTemplates(); + new H2Templates(); + new HSQLDBTemplates(); + new MySQLTemplates(); + new OracleTemplates(); + new PostgreSQLTemplates(); + new SQLTemplates("\"",'\\',false); + new SQLServerTemplates(); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/TeradataTemplatesTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/TeradataTemplatesTest.java new file mode 100644 index 0000000000..c8ef55ec78 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/TeradataTemplatesTest.java @@ -0,0 +1,76 @@ +package com.querydsl.sql; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +import com.querydsl.core.types.Ops; + +public class TeradataTemplatesTest extends AbstractSQLTemplatesTest { + + @Override + protected SQLTemplates createTemplates() { + return new TeradataTemplates(); + } + + @Test + public void limit() { + query.from(survey1).limit(5); + assertEquals("from SURVEY survey1 " + + "qualify row_number() over (order by 1) <= ?", query.toString()); + } + + @Test + public void offset() { + query.from(survey1).offset(5); + assertEquals("from SURVEY survey1 " + + "qualify row_number() over (order by 1) > ?", query.toString()); + } + + @Test + public void limit_offset() { + query.from(survey1).limit(5).offset(10); + assertEquals("from SURVEY survey1 " + + "qualify row_number() over (order by 1) between ? and ?", query.toString()); + } + + @Test + public void orderBy_limit() { + query.from(survey1).orderBy(survey1.name.asc()).limit(5); + assertEquals("from SURVEY survey1 " + + "order by survey1.NAME asc " + + "qualify row_number() over (order by survey1.NAME asc) <= ?", query.toString()); + } + + @Test + public void precedence() { + // +, - (unary) + int p1 = getPrecedence(Ops.NEGATE); + // ** (exponentation) + // * / MOD + int p2 = getPrecedence(Ops.MULT, Ops.DIV, Ops.MOD); + // +, - (binary) + int p3 = getPrecedence(Ops.ADD, Ops.SUB); + // concat + int p4 = getPrecedence(Ops.CONCAT); + // EQ, NE, GT, LE, LT, GE, IN, NOT IN, BEWEEN, LIKE + int p5 = getPrecedence(Ops.EQ, Ops.NE, Ops.GT, Ops.LT, Ops.GOE, Ops.LOE, Ops.IN, Ops.NOT_IN, + Ops.BETWEEN, Ops.LIKE, Ops.LIKE_ESCAPE); + // NOT + int p6 = getPrecedence(Ops.NOT); + // AND + int p7 = getPrecedence(Ops.AND); + // OR + int p8 = getPrecedence(Ops.OR); + + assertTrue(p1 < p2); + assertTrue(p2 < p3); + assertTrue(p3 < p4); + assertTrue(p4 < p5); + assertTrue(p5 < p6); + assertTrue(p6 < p7); + assertTrue(p7 < p8); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/TestLoggingListener.java b/querydsl-sql/src/test/java/com/querydsl/sql/TestLoggingListener.java new file mode 100644 index 0000000000..c462f8a10a --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/TestLoggingListener.java @@ -0,0 +1,160 @@ +package com.querydsl.sql; + +import static java.lang.String.format; + +import java.util.List; +import java.util.Map; + +import com.querydsl.core.QueryMetadata; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.SubQueryExpression; +import com.querydsl.sql.dml.SQLInsertBatch; +import com.querydsl.sql.dml.SQLMergeBatch; +import com.querydsl.sql.dml.SQLUpdateBatch; + +/** + */ +public class TestLoggingListener implements SQLDetailedListener { + private static boolean enabled = false; + + /** + * Called to enable logging in tests + */ + public static void enable() { + enabled = true; + } + + /** + * Called to disable logging in tests + */ + public static void disable() { + enabled = false; + } + + @Override + public void start(SQLListenerContext context) { + if (enabled) { + System.out.println(format("\n\tstart %s", context)); + } + } + + @Override + public void preRender(SQLListenerContext context) { + if (enabled) { + System.out.println(format("\t\tpreRender %s", context)); + } + } + + @Override + public void rendered(SQLListenerContext context) { + if (enabled) { + System.out.println(format("\t\t\trendered %s", context)); + } + } + + @Override + public void prePrepare(SQLListenerContext context) { + if (enabled) { + System.out.println(format("\t\tprePrepare %s", context)); + } + } + + @Override + public void prepared(SQLListenerContext context) { + if (enabled) { + System.out.println(format("\t\t\tprepared %s", context)); + } + } + + @Override + public void preExecute(SQLListenerContext context) { + if (enabled) { + System.out.println(format("\t\tpreExecute %s", context)); + } + } + + @Override + public void executed(SQLListenerContext context) { + if (enabled) { + System.out.println(format("\t\t\texecuted %s", context)); + } + } + + @Override + public void exception(SQLListenerContext context) { + if (enabled) { + System.out.println(format("\t\texception %s", context)); + } + } + + @Override + public void end(SQLListenerContext context) { + if (enabled) { + System.out.println(format("\tend %s\n\n", context)); + } + } + + @Override + public void notifyQuery(QueryMetadata md) { + if (enabled) { + System.out.println(format("\t\t\tnotifyQuery %s", md)); + } + } + + @Override + public void notifyDelete(RelationalPath entity, QueryMetadata md) { + if (enabled) { + System.out.println(format("\t\t\tnotifyDelete %s", entity)); + } + } + + @Override + public void notifyDeletes(RelationalPath entity, List batches) { + if (enabled) { + System.out.println(format("\t\t\tnotifyDeletes %s", entity)); + } + } + + @Override + public void notifyMerge(RelationalPath entity, QueryMetadata md, List> keys, List> columns, List> values, SubQueryExpression subQuery) { + if (enabled) { + System.out.println(format("\t\t\tnotifyMerge %s", entity)); + } + } + + @Override + public void notifyMerges(RelationalPath entity, QueryMetadata md, List batches) { + if (enabled) { + System.out.println(format("\t\t\tnotifyMerges %s", entity)); + } + } + + @Override + public void notifyInsert(RelationalPath entity, QueryMetadata md, List> columns, List> values, SubQueryExpression subQuery) { + if (enabled) { + System.out.println(format("\t\t\tnotifyInsert %s", entity)); + } + } + + @Override + public void notifyInserts(RelationalPath entity, QueryMetadata md, List batches) { + if (enabled) { + System.out.println(format("\t\t\tnotifyInserts %s", entity)); + } + } + + @Override + public void notifyUpdate(RelationalPath entity, QueryMetadata md, Map, Expression> updates) { + if (enabled) { + System.out.println(format("\t\t\tnotifyUpdate %s", entity)); + } + } + + @Override + public void notifyUpdates(RelationalPath entity, List batches) { + if (enabled) { + System.out.println(format("\t\t\tnotifyUpdates %s", entity)); + } + } +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/TypesBase.java b/querydsl-sql/src/test/java/com/querydsl/sql/TypesBase.java new file mode 100644 index 0000000000..39c3cf525d --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/TypesBase.java @@ -0,0 +1,97 @@ +package com.querydsl.sql; + +import static com.querydsl.core.Target.*; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.LinkedHashMap; +import java.util.Map; + +import org.junit.Test; + +import com.querydsl.core.testutil.ExcludeIn; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.sql.ddl.CreateTableClause; +import com.querydsl.sql.ddl.DropTableClause; + +public class TypesBase extends AbstractBaseTest { + + @Test + public void create_tables() { + Map, Object> instances = new LinkedHashMap<>(); + instances.put(BigInteger.class, BigInteger.valueOf(1)); + instances.put(Long.class, 1L); + instances.put(Integer.class, 1); + instances.put(Short.class, (short) 1); + instances.put(Byte.class, (byte) 1); + instances.put(BigDecimal.class, BigDecimal.valueOf(1.0)); + instances.put(Double.class, 1.0); + instances.put(Float.class, 1.0f); + instances.put(Boolean.class, Boolean.TRUE); + instances.put(Character.class, 'a'); + instances.put(String.class, "ABC"); + + for (Map.Entry, Object> entry : instances.entrySet()) { + String tableName = "test_" + entry.getKey().getSimpleName(); + new DropTableClause(connection, configuration, tableName).execute(); + CreateTableClause c = new CreateTableClause(connection, configuration, tableName) + .column("col", entry.getKey()); + if (entry.getKey().equals(String.class)) { + c.size(256); + } + c.execute(); + RelationalPath entityPath = new RelationalPathBase(Object.class, tableName, "PUBLIC", tableName); + Path columnPath = Expressions.path(entry.getKey(), entityPath, "col"); + insert(entityPath).set((Path) columnPath, entry.getValue()).execute(); + new DropTableClause(connection, configuration, tableName).execute(); + } + + } + + @Test + @ExcludeIn({CUBRID, POSTGRESQL, TERADATA}) + public void dump_types() throws SQLException { + Connection conn = Connections.getConnection(); + DatabaseMetaData md = conn.getMetaData(); + + // types + try (ResultSet rs = md.getUDTs(null, null, null, null)) { + while (rs.next()) { + // cat, schema, name, classname, datatype, remarks, base_type + String cat = rs.getString(1); + String schema = rs.getString(2); + String name = rs.getString(3); + String classname = rs.getString(4); + String datatype = rs.getString(5); + String remarks = rs.getString(6); + String baseType = rs.getString(7); + System.out.println(name + " " + classname + " " + datatype + " " + + remarks + " " + baseType); + + // attributes + try (ResultSet rs2 = md.getAttributes(cat, schema, name, null)) { + while (rs2.next()) { + // cat, schema, name, attr_name, data_type, attr_type_name, attr_size + // decimal_digits, num_prec_radix, nullable, remarks, attr_def, sql_data_type, ordinal_position + // ... + String cat2 = rs2.getString(1); + String schema2 = rs2.getString(2); + String name2 = rs2.getString(3); + String attrName2 = rs2.getString(4); + String dataType2 = rs2.getString(5); + String attrTypeName2 = rs2.getString(6); + String attrSize2 = rs2.getString(7); + + System.out.println(" " + attrName2 + " " + dataType2 + " " + attrTypeName2 + " " + attrSize2); + } + } + } + } + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/TypesDump.java b/querydsl-sql/src/test/java/com/querydsl/sql/TypesDump.java new file mode 100644 index 0000000000..e44442c31f --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/TypesDump.java @@ -0,0 +1,47 @@ +package com.querydsl.sql; + +import java.lang.reflect.Field; +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.ResultSet; +import java.util.HashMap; +import java.util.Map; + +public final class TypesDump { + + private TypesDump() { } + + public static void main(String[] args) throws Exception { + Map typeConstants = new HashMap<>(); + for (Field field : java.sql.Types.class.getDeclaredFields()) { + if (field.getType().equals(Integer.TYPE)) { + typeConstants.put(field.getInt(null), field.getName()); + } + } + + Connections.initOracle(); + try { + Connection c = Connections.getConnection(); + DatabaseMetaData m = c.getMetaData(); + System.out.println(m.getDatabaseProductName()); + try (ResultSet rs = m.getTypeInfo()) { + while (rs.next()) { + String name = rs.getString("TYPE_NAME"); + int jdbcType = rs.getInt("DATA_TYPE"); + String jdbcTypeField = typeConstants.get(jdbcType); + if (jdbcTypeField == null || !jdbcTypeField.equalsIgnoreCase(name)) { + String prefix = rs.getString("LITERAL_PREFIX"); + String suffix = rs.getString("LITERAL_SUFFIX"); + String jdbcTypeStr = jdbcTypeField != null ? ("Types." + jdbcTypeField) : String.valueOf(jdbcType); + System.out.println("addTypeNameToCode(\"" + name.toLowerCase() + "\", " + jdbcTypeStr + ");"); + //System.out.println(rs.getInt("PRECISION")); + } + } + } + } finally { + Connections.close(); + } + + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/UnionBase.java b/querydsl-sql/src/test/java/com/querydsl/sql/UnionBase.java new file mode 100644 index 0000000000..3102057795 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/UnionBase.java @@ -0,0 +1,268 @@ +package com.querydsl.sql; + +import static com.querydsl.core.Target.*; +import static com.querydsl.sql.Constants.employee; +import static org.junit.Assert.*; + +import java.io.IOException; +import java.sql.SQLException; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.junit.Ignore; +import org.junit.Test; + +import com.mysema.commons.lang.CloseableIterator; +import com.querydsl.core.Tuple; +import com.querydsl.core.testutil.ExcludeIn; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.Projections; +import com.querydsl.core.types.SubQueryExpression; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.sql.domain.Employee; +import com.querydsl.sql.domain.QEmployee; + +public class UnionBase extends AbstractBaseTest { + + @SuppressWarnings("unchecked") + @Test + @ExcludeIn({MYSQL, TERADATA}) + public void in_union() { + assertNotNull(query().from(employee) + .where(employee.id.in( + query().union(query().select(Expressions.ONE), + query().select(Expressions.TWO)))) + .select(Expressions.ONE).fetchFirst()); + } + + @Test + @SuppressWarnings("unchecked") + @ExcludeIn(FIREBIRD) // order is not properly supported + public void union() throws SQLException { + SubQueryExpression sq1 = query().from(employee).select(employee.id.max().as("ID")); + SubQueryExpression sq2 = query().from(employee).select(employee.id.min().as("ID")); + assertEquals( + Arrays.asList(query().select(employee.id.min()).from(employee).fetchFirst(), + query().select(employee.id.max()).from(employee).fetchFirst()), + query().union(sq1, sq2).orderBy(employee.id.asc()).fetch()); + } + + @Test + @SuppressWarnings("unchecked") + public void union_list() throws SQLException { + SubQueryExpression sq1 = query().from(employee).select(employee.id.max()); + SubQueryExpression sq2 = query().from(employee).select(employee.id.min()); + assertEquals( + query().union(sq1, sq2).fetch(), + query().union(sq1, sq2).list()); + } + + @Test + @SuppressWarnings("unchecked") + public void union_all() { + SubQueryExpression sq1 = query().from(employee).select(employee.id.max()); + SubQueryExpression sq2 = query().from(employee).select(employee.id.min()); + List list = query().unionAll(sq1, sq2).fetch(); + assertFalse(list.isEmpty()); + } + + @SuppressWarnings("unchecked") + @Test + public void union_multiple_columns() throws SQLException { + SubQueryExpression sq1 = query().from(employee).select(employee.firstname, employee.lastname); + SubQueryExpression sq2 = query().from(employee).select(employee.lastname, employee.firstname); + List list = query().union(sq1, sq2).fetch(); + assertFalse(list.isEmpty()); + for (Tuple row : list) { + assertNotNull(row.get(0, Object.class)); + assertNotNull(row.get(1, Object.class)); + } + } + + @SuppressWarnings("unchecked") + @Test + @ExcludeIn(DERBY) + public void union_multiple_columns2() throws SQLException { + SubQueryExpression sq1 = query().from(employee).select(employee.firstname, employee.lastname); + SubQueryExpression sq2 = query().from(employee).select(employee.firstname, employee.lastname); + SQLQuery query = query(); + query.union(sq1, sq2); + List list = query.select(employee.firstname).fetch(); + assertFalse(list.isEmpty()); + for (String row : list) { + assertNotNull(row); + } + } + + @SuppressWarnings("unchecked") + @Test + @ExcludeIn(DERBY) + public void union_multiple_columns3() throws SQLException { + SubQueryExpression sq1 = query().from(employee).select(employee.firstname, employee.lastname); + SubQueryExpression sq2 = query().from(employee).select(employee.firstname, employee.lastname); + SQLQuery query = query(); + query.union(sq1, sq2); + List list = query.select(employee.lastname, employee.firstname).fetch(); + assertFalse(list.isEmpty()); + for (Tuple row : list) { + System.out.println(row.get(0, String.class) + " " + row.get(1, String.class)); + } + } + + @Test + @SuppressWarnings("unchecked") + public void union_empty_result() throws SQLException { + SubQueryExpression sq1 = query().from(employee).where(employee.firstname.eq("XXX")).select(employee.id); + SubQueryExpression sq2 = query().from(employee).where(employee.firstname.eq("YYY")).select(employee.id); + List list = query().union(sq1, sq2).fetch(); + assertTrue(list.isEmpty()); + } + + @Test + @SuppressWarnings("unchecked") + public void union2() throws SQLException { + List list = query().union( + query().from(employee).select(employee.id.max()), + query().from(employee).select(employee.id.min())).fetch(); + assertFalse(list.isEmpty()); + + } + + @Test + @SuppressWarnings("unchecked") + public void union3() throws SQLException { + SubQueryExpression sq3 = query().from(employee).select(new Expression[]{employee.id.max()}); + SubQueryExpression sq4 = query().from(employee).select(new Expression[]{employee.id.min()}); + List list2 = query().union(sq3, sq4).fetch(); + assertFalse(list2.isEmpty()); + } + + @SuppressWarnings("unchecked") + @Test + @ExcludeIn({DERBY}) + public void union4() { + SubQueryExpression sq1 = query().from(employee).select(employee.id, employee.firstname); + SubQueryExpression sq2 = query().from(employee).select(employee.id, employee.firstname); + assertEquals(1, query().union(employee, sq1, sq2).select(employee.id.count()).fetch().size()); + } + + // FIXME for CUBRID + // Teradata: The ORDER BY clause must contain only integer constants. + @SuppressWarnings("unchecked") + @Test + @ExcludeIn({DERBY, CUBRID, FIREBIRD, TERADATA}) + @Ignore // FIXME + public void union5() { + /* (select e.ID, e.FIRSTNAME, superior.ID as sup_id, superior.FIRSTNAME as sup_name + * from EMPLOYEE e join EMPLOYEE superior on e.SUPERIOR_ID = superior.ID) + * union + * (select e.ID, e.FIRSTNAME, null, null from EMPLOYEE e) + * order by ID asc + */ + QEmployee superior = new QEmployee("superior"); + SubQueryExpression sq1 = query().from(employee) + .join(employee.superiorIdKey, superior) + .select(employee.id, employee.firstname, superior.id.as("sup_id"), superior.firstname.as("sup_name")); + SubQueryExpression sq2 = query().from(employee) + .select(employee.id, employee.firstname, null, null); + List results = query().union(sq1, sq2).orderBy(employee.id.asc()).fetch(); + for (Tuple result : results) { + System.err.println(Collections.singletonList(result)); + } + } + + @Test + @ExcludeIn({FIREBIRD, TERADATA}) // The ORDER BY clause must contain only integer constants. + @SuppressWarnings("unchecked") + public void union_with_order() throws SQLException { + SubQueryExpression sq1 = query().from(employee).select(employee.id); + SubQueryExpression sq2 = query().from(employee).select(employee.id); + List list = query().union(sq1, sq2).orderBy(employee.id.asc()).fetch(); + assertFalse(list.isEmpty()); + } + + @SuppressWarnings("unchecked") + @Test + @ExcludeIn(FIREBIRD) + public void union_multi_column_projection_list() throws IOException { + SubQueryExpression sq1 = query().from(employee).select(employee.id.max(), employee.id.max().subtract(1)); + SubQueryExpression sq2 = query().from(employee).select(employee.id.min(), employee.id.min().subtract(1)); + + List list = query().union(sq1, sq2).list(); + assertEquals(2, list.size()); + assertTrue(list.get(0) != null); + assertTrue(list.get(1) != null); + } + + @SuppressWarnings("unchecked") + @Test + @ExcludeIn(FIREBIRD) + public void union_multi_column_projection_iterate() throws IOException { + SubQueryExpression sq1 = query().from(employee).select(employee.id.max(), employee.id.max().subtract(1)); + SubQueryExpression sq2 = query().from(employee).select(employee.id.min(), employee.id.min().subtract(1)); + + try (CloseableIterator iterator = query().union(sq1, sq2).iterate()) { + assertTrue(iterator.hasNext()); + assertTrue(iterator.next() != null); + assertTrue(iterator.next() != null); + assertFalse(iterator.hasNext()); + } + } + + @SuppressWarnings("unchecked") + @Test + public void union_single_column_projections_list() throws IOException { + SubQueryExpression sq1 = query().from(employee).select(employee.id.max()); + SubQueryExpression sq2 = query().from(employee).select(employee.id.min()); + + List list = query().union(sq1, sq2).list(); + assertEquals(2, list.size()); + assertTrue(list.get(0) != null); + assertTrue(list.get(1) != null); + } + + @SuppressWarnings("unchecked") + @Test + public void union_single_column_projections_iterate() throws IOException { + SubQueryExpression sq1 = query().from(employee).select(employee.id.max()); + SubQueryExpression sq2 = query().from(employee).select(employee.id.min()); + + try (CloseableIterator iterator = query().union(sq1, sq2).iterate()) { + assertTrue(iterator.hasNext()); + assertTrue(iterator.next() != null); + assertTrue(iterator.next() != null); + assertFalse(iterator.hasNext()); + } + } + + @SuppressWarnings("unchecked") + @Test + public void union_factoryExpression() { + SubQueryExpression sq1 = query().from(employee) + .select(Projections.constructor(Employee.class, employee.id)); + SubQueryExpression sq2 = query().from(employee) + .select(Projections.constructor(Employee.class, employee.id)); + List employees = query().union(sq1, sq2).list(); + for (Employee employee : employees) { + assertNotNull(employee); + } + } + + @SuppressWarnings("unchecked") + @Test + @ExcludeIn({DERBY, CUBRID}) + public void union_clone() { + NumberPath idAlias = Expressions.numberPath(Integer.class, "id"); + SubQueryExpression sq1 = query().from(employee) + .select(Projections.constructor(Employee.class, employee.id.as(idAlias))); + SubQueryExpression sq2 = query().from(employee) + .select(Projections.constructor(Employee.class, employee.id.as(idAlias))); + + SQLQuery query = query(); + query.union(sq1, sq2); + assertEquals(10, query.clone().select(idAlias).fetch().size()); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/UnionSubQueryTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/UnionSubQueryTest.java new file mode 100644 index 0000000000..dc4a4f7d50 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/UnionSubQueryTest.java @@ -0,0 +1,90 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import static com.querydsl.sql.SQLExpressions.*; +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.SimpleExpression; +import com.querydsl.core.types.dsl.SimplePath; + +public class UnionSubQueryTest { + + private static final SimpleExpression one = Expressions.numberTemplate(Integer.class, "1"); + + private static final SimpleExpression two = Expressions.numberTemplate(Integer.class, "2"); + + private static final SimpleExpression three = Expressions.numberTemplate(Integer.class,"3"); + + private SQLTemplates templates = H2Templates.builder().newLineToSingleSpace().build(); + + private SQLSerializer serializer = new SQLSerializer(new Configuration(templates)); + + @SuppressWarnings("unchecked") + @Test + public void in_union() { + NumberPath intPath = Expressions.numberPath(Integer.class, "intPath"); + Expression expr = intPath.in(union( + select(one), + select(two))); + + serializer.handle(expr); + assertEquals( + "intPath in ((select 1 from dual)\n" + + "union\n" + + "(select 2 from dual))", serializer.toString()); + } + + @SuppressWarnings("unchecked") + @Test + public void union_subQuery() { + SimplePath col1 = Expressions.path(Integer.class, "col1"); + Expression union = union( + select(one.as(col1)), + select(two), + select(three)); + + serializer.handle(union); + assertEquals( + "(select 1 as col1 from dual)\n" + + "union\n" + + "(select 2 from dual)\n" + + "union\n" + + "(select 3 from dual)", serializer.toString()); + } + + @SuppressWarnings("unchecked") + @Test + public void unionAll_subQuery() { + SimplePath col1 = Expressions.path(Integer.class,"col1"); + Expression union = unionAll( + select(one.as(col1)), + select(two), + select(three)); + + serializer.handle(union); + assertEquals( + "(select 1 as col1 from dual)\n" + + "union all\n" + + "(select 2 from dual)\n" + + "union all\n" + + "(select 3 from dual)", serializer.toString()); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/UpdateBase.java b/querydsl-sql/src/test/java/com/querydsl/sql/UpdateBase.java new file mode 100644 index 0000000000..f0e883697e --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/UpdateBase.java @@ -0,0 +1,218 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql; + +import static com.querydsl.core.Target.*; +import static com.querydsl.sql.Constants.survey; +import static com.querydsl.sql.SQLExpressions.selectOne; +import static org.junit.Assert.assertEquals; + +import java.sql.SQLException; +import java.util.Collections; +import java.util.List; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.querydsl.core.testutil.ExcludeIn; +import com.querydsl.core.testutil.IncludeIn; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.Param; +import com.querydsl.core.types.dsl.StringPath; +import com.querydsl.sql.dml.SQLUpdateClause; +import com.querydsl.sql.domain.QEmployee; +import com.querydsl.sql.domain.QSurvey; + +public class UpdateBase extends AbstractBaseTest { + + protected void reset() throws SQLException { + delete(survey).execute(); + insert(survey).values(1, "Hello World", "Hello").execute(); + } + + @Before + public void setUp() throws SQLException { + reset(); + } + + @After + public void tearDown() throws SQLException { + reset(); + } + + @Test + public void update() throws SQLException { + // original state + long count = query().from(survey).fetchCount(); + assertEquals(0, query().from(survey).where(survey.name.eq("S")).fetchCount()); + + // update call with 0 update count + assertEquals(0, update(survey).where(survey.name.eq("XXX")).set(survey.name, "S").execute()); + assertEquals(0, query().from(survey).where(survey.name.eq("S")).fetchCount()); + + // update call with full update count + assertEquals(count, update(survey).set(survey.name, "S").execute()); + assertEquals(count, query().from(survey).where(survey.name.eq("S")).fetchCount()); + } + + @Test + @IncludeIn({CUBRID, H2, MYSQL, ORACLE, SQLSERVER}) + public void update_limit() { + assertEquals(1, insert(survey).values(2, "A","B").execute()); + assertEquals(1, insert(survey).values(3, "B","C").execute()); + + assertEquals(2, update(survey).set(survey.name, "S").limit(2).execute()); + } + + @Test + public void update2() throws SQLException { + List> paths = Collections.>singletonList(survey.name); + List values = Collections.singletonList("S"); + + // original state + long count = query().from(survey).fetchCount(); + assertEquals(0, query().from(survey).where(survey.name.eq("S")).fetchCount()); + + // update call with 0 update count + assertEquals(0, update(survey).where(survey.name.eq("XXX")).set(paths, values).execute()); + assertEquals(0, query().from(survey).where(survey.name.eq("S")).fetchCount()); + + // update call with full update count + assertEquals(count, update(survey).set(paths, values).execute()); + assertEquals(count, query().from(survey).where(survey.name.eq("S")).fetchCount()); + + } + + @Test + public void update3() { + assertEquals(1, update(survey).set(survey.name, survey.name.append("X")).execute()); + } + + @Test + public void update4() { + assertEquals(1, insert(survey).values(2, "A","B").execute()); + assertEquals(1, update(survey).set(survey.name, "AA").where(survey.name.eq("A")).execute()); + } + + @Test + public void update5() { + assertEquals(1, insert(survey).values(3, "B","C").execute()); + assertEquals(1, update(survey).set(survey.name, "BB").where(survey.name.eq("B")).execute()); + } + + @Test + public void setNull() { + List> paths = Collections.>singletonList(survey.name); + List values = Collections.singletonList(null); + long count = query().from(survey).fetchCount(); + assertEquals(count, update(survey).set(paths, values).execute()); + } + + @Test + public void setNull2() { + long count = query().from(survey).fetchCount(); + assertEquals(count, update(survey).set(survey.name, (String) null).execute()); + } + + @Test + @SkipForQuoted + @ExcludeIn({DB2, DERBY}) + public void setNullEmptyRootPath() { + StringPath name = Expressions.stringPath("name"); + long count = query().from(survey).fetchCount(); + assertEquals(count, execute(update(survey).setNull(name))); + } + + @Test + public void batch() throws SQLException { + assertEquals(1, insert(survey).values(2, "A","B").execute()); + assertEquals(1, insert(survey).values(3, "B","C").execute()); + + SQLUpdateClause update = update(survey); + update.set(survey.name, "AA").where(survey.name.eq("A")).addBatch(); + assertEquals(1, update.getBatchCount()); + update.set(survey.name, "BB").where(survey.name.eq("B")).addBatch(); + assertEquals(2, update.getBatchCount()); + assertEquals(2, update.execute()); + } + + @Test + public void batch_templates() throws SQLException { + assertEquals(1, insert(survey).values(2, "A","B").execute()); + assertEquals(1, insert(survey).values(3, "B","C").execute()); + + SQLUpdateClause update = update(survey); + update.set(survey.name, "AA").where(survey.name.eq(Expressions.stringTemplate("'A'"))).addBatch(); + update.set(survey.name, "BB").where(survey.name.eq(Expressions.stringTemplate("'B'"))).addBatch(); + assertEquals(2, update.execute()); + } + + @Test + public void update_with_subQuery_exists() { + QSurvey survey1 = new QSurvey("s1"); + QEmployee employee = new QEmployee("e"); + SQLUpdateClause update = update(survey1); + update.set(survey1.name, "AA"); + update.where(selectOne().from(employee).where(survey1.id.eq(employee.id)).exists()); + assertEquals(1, update.execute()); + } + + @Test + public void update_with_subQuery_exists_Params() { + QSurvey survey1 = new QSurvey("s1"); + QEmployee employee = new QEmployee("e"); + + Param param = new Param(Integer.class, "param"); + SQLQuery sq = query().from(employee).where(employee.id.eq(param)); + sq.set(param, -12478923); + + SQLUpdateClause update = update(survey1); + update.set(survey1.name, "AA"); + update.where(sq.exists()); + assertEquals(0, update.execute()); + } + + @Test + public void update_with_subQuery_exists2() { + QSurvey survey1 = new QSurvey("s1"); + QEmployee employee = new QEmployee("e"); + SQLUpdateClause update = update(survey1); + update.set(survey1.name, "AA"); + update.where(selectOne().from(employee).where(survey1.name.eq(employee.lastname)).exists()); + assertEquals(0, update.execute()); + } + + @Test + public void update_with_subQuery_notExists() { + QSurvey survey1 = new QSurvey("s1"); + QEmployee employee = new QEmployee("e"); + SQLUpdateClause update = update(survey1); + update.set(survey1.name, "AA"); + update.where(query().from(employee).where(survey1.id.eq(employee.id)).notExists()); + assertEquals(0, update.execute()); + } + + @Test + @ExcludeIn(TERADATA) + public void update_with_templateExpression_in_batch() { + assertEquals(1, update(survey) + .set(survey.id, 3) + .set(survey.name, Expressions.stringTemplate("'Hello'")) + .addBatch() + .execute()); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/WindowFunctionTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/WindowFunctionTest.java new file mode 100644 index 0000000000..7ed52053d6 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/WindowFunctionTest.java @@ -0,0 +1,155 @@ +package com.querydsl.sql; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberPath; + +public class WindowFunctionTest { + + private static String toString(Expression e) { + return new SQLSerializer(Configuration.DEFAULT).handle(e).toString(); + } + + @Test + public void complex() { + NumberPath path = Expressions.numberPath(Long.class, "path"); + NumberPath path2 = Expressions.numberPath(Long.class, "path2"); + Expression wf = SQLExpressions.sum(path).over().partitionBy(path2).orderBy(path); + assertEquals("sum(path) over (partition by path2 order by path asc)", toString(wf)); + } + + @Test + public void complex_nullsFirst() { + NumberPath path = Expressions.numberPath(Long.class, "path"); + NumberPath path2 = Expressions.numberPath(Long.class, "path2"); + Expression wf = SQLExpressions.sum(path).over().partitionBy(path2).orderBy(path.desc().nullsFirst()); + assertEquals("sum(path) over (partition by path2 order by path desc nulls first)", toString(wf)); + } + + @Test + public void all() { + NumberPath path = Expressions.numberPath(Long.class, "path"); + NumberPath path2 = Expressions.numberPath(Long.class, "path2"); + assertEquals("avg(path)", toString(SQLExpressions.avg(path))); + assertEquals("count(path)", toString(SQLExpressions.count(path))); + assertEquals("corr(path,path2)", toString(SQLExpressions.corr(path, path2))); + assertEquals("covar_pop(path,path2)", toString(SQLExpressions.covarPop(path, path2))); + assertEquals("covar_samp(path,path2)", toString(SQLExpressions.covarSamp(path, path2))); + assertEquals("cume_dist()", toString(SQLExpressions.cumeDist())); + assertEquals("dense_rank()", toString(SQLExpressions.denseRank())); + assertEquals("first_value(path)", toString(SQLExpressions.firstValue(path))); + assertEquals("lag(path)", toString(SQLExpressions.lag(path))); + assertEquals("last_value(path)", toString(SQLExpressions.lastValue(path))); + assertEquals("lead(path)", toString(SQLExpressions.lead(path))); + assertEquals("max(path)", toString(SQLExpressions.max(path))); + assertEquals("min(path)", toString(SQLExpressions.min(path))); + assertEquals("nth_value(path, ?)", toString(SQLExpressions.nthValue(path, 3))); + assertEquals("ntile(?)", toString(SQLExpressions.ntile(4))); + assertEquals("percent_rank()", toString(SQLExpressions.percentRank())); + assertEquals("rank()", toString(SQLExpressions.rank())); + assertEquals("ratio_to_report(path)", toString(SQLExpressions.ratioToReport(path))); + assertEquals("row_number()", toString(SQLExpressions.rowNumber())); + assertEquals("stddev(path)", toString(SQLExpressions.stddev(path))); + assertEquals("stddev(distinct path)", toString(SQLExpressions.stddevDistinct(path))); + assertEquals("stddev_pop(path)", toString(SQLExpressions.stddevPop(path))); + assertEquals("stddev_samp(path)", toString(SQLExpressions.stddevSamp(path))); + assertEquals("sum(path)", toString(SQLExpressions.sum(path))); + assertEquals("variance(path)", toString(SQLExpressions.variance(path))); + assertEquals("var_pop(path)", toString(SQLExpressions.varPop(path))); + assertEquals("var_samp(path)", toString(SQLExpressions.varSamp(path))); + + // TODO FIRST + // TODO LAST + // TODO NTH_VALUE ... FROM (FIRST|LAST) (RESPECT|IGNORE) NULLS + } + + @Test + public void regr() { + NumberPath path = Expressions.numberPath(Long.class, "path"); + NumberPath path2 = Expressions.numberPath(Long.class, "path2"); + assertEquals("regr_slope(path, path2)", toString(SQLExpressions.regrSlope(path, path2))); + assertEquals("regr_intercept(path, path2)", toString(SQLExpressions.regrIntercept(path, path2))); + assertEquals("regr_count(path, path2)", toString(SQLExpressions.regrCount(path, path2))); + assertEquals("regr_r2(path, path2)", toString(SQLExpressions.regrR2(path, path2))); + assertEquals("regr_avgx(path, path2)", toString(SQLExpressions.regrAvgx(path, path2))); + assertEquals("regr_avgy(path, path2)", toString(SQLExpressions.regrAvgy(path, path2))); + assertEquals("regr_sxx(path, path2)", toString(SQLExpressions.regrSxx(path, path2))); + assertEquals("regr_syy(path, path2)", toString(SQLExpressions.regrSyy(path, path2))); + assertEquals("regr_sxy(path, path2)", toString(SQLExpressions.regrSxy(path, path2))); + } + + @Test + public void rows_between() { + NumberPath path = Expressions.numberPath(Long.class, "path"); + NumberPath intPath = Expressions.numberPath(Integer.class, "intPath"); + WindowFunction wf = SQLExpressions.sum(path).over().orderBy(path); + + assertEquals("sum(path) over (order by path asc rows between current row and unbounded following)", + toString(wf.rows().between().currentRow().unboundedFollowing())); + assertEquals("sum(path) over (order by path asc rows between preceding intPath and following intPath)", + toString(wf.rows().between().preceding(intPath).following(intPath))); + assertEquals("sum(path) over (order by path asc rows between preceding ? and following ?)", + toString(wf.rows().between().preceding(1).following(3))); + } + + @Test + public void rows_unboundedPreceding() { + NumberPath path = Expressions.numberPath(Long.class, "path"); + WindowFunction wf = SQLExpressions.sum(path).over().orderBy(path); + + assertEquals("sum(path) over (order by path asc rows unbounded preceding)", + toString(wf.rows().unboundedPreceding())); + } + + @Test + public void rows_currentRow() { + NumberPath path = Expressions.numberPath(Long.class, "path"); + WindowFunction wf = SQLExpressions.sum(path).over().orderBy(path); + + assertEquals("sum(path) over (order by path asc rows current row)", + toString(wf.rows().currentRow())); + } + + @Test + public void rows_precedingRow() { + NumberPath path = Expressions.numberPath(Long.class, "path"); + NumberPath intPath = Expressions.numberPath(Integer.class, "intPath"); + WindowFunction wf = SQLExpressions.sum(path).over().orderBy(path); + + assertEquals("sum(path) over (order by path asc rows preceding intPath)", + toString(wf.rows().preceding(intPath))); + assertEquals("sum(path) over (order by path asc rows preceding ?)", + toString(wf.rows().preceding(3))); + } + + @Test + public void keep_first() { + //MIN(salary) KEEP (DENSE_RANK FIRST ORDER BY commission_pct) OVER (PARTITION BY department_id) + NumberPath path = Expressions.numberPath(Long.class, "path"); + NumberPath path2 = Expressions.numberPath(Long.class, "path2"); + NumberPath path3 = Expressions.numberPath(Long.class, "path3"); + assertEquals( + "min(path) keep (dense_rank first order by path2 asc)", + toString(SQLExpressions.min(path).keepFirst().orderBy(path2))); + assertEquals( + "min(path) keep (dense_rank first order by path2 asc) over (partition by path3)", + toString(SQLExpressions.min(path).keepFirst().orderBy(path2).over().partitionBy(path3))); + } + + @Test + public void keep_last() { + //MIN(salary) KEEP (DENSE_RANK FIRST ORDER BY commission_pct) OVER (PARTITION BY department_id) + NumberPath path = Expressions.numberPath(Long.class, "path"); + NumberPath path2 = Expressions.numberPath(Long.class, "path2"); + NumberPath path3 = Expressions.numberPath(Long.class, "path3"); + assertEquals( + "min(path) keep (dense_rank last order by path2 asc) over (partition by path3)", + toString(SQLExpressions.min(path).keepLast().orderBy(path2).over().partitionBy(path3))); + } + + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/WithinGroupTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/WithinGroupTest.java new file mode 100644 index 0000000000..18d837c96f --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/WithinGroupTest.java @@ -0,0 +1,82 @@ +package com.querydsl.sql; + +import static org.junit.Assert.assertEquals; + +import org.junit.Before; +import org.junit.Test; + +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberPath; + +public class WithinGroupTest { + NumberPath path = null; + NumberPath path2 = null; + + private static String toString(Expression e) { + return new SQLSerializer(Configuration.DEFAULT).handle(e).toString(); + } + @Before + public void setPaths() { + this.path = Expressions.numberPath(Long.class, "path"); + this.path2 = Expressions.numberPath(Long.class, "path2"); + } + + @Test + public void cume_Dist() { + assertEquals("cume_dist(path)", toString(SQLExpressions.cumeDist(path))); + assertEquals("cume_dist(path, path2)", toString(SQLExpressions.cumeDist(path, path2))); + } + + @Test + public void dense_Rank() { + assertEquals("dense_rank(path, path2)", toString(SQLExpressions.denseRank(path, path2))); + } + + @Test + public void perfect_Rank() { + assertEquals("percent_rank(path, path2)", toString(SQLExpressions.percentRank(path, path2))); + } + + @Test + public void percentile() { + assertEquals("percentile_cont(path)", toString(SQLExpressions.percentileCont(path))); + assertEquals("percentile_disc(path)", toString(SQLExpressions.percentileDisc(path))); + } + + @Test + public void rank() { + assertEquals("rank(path, path2)", toString(SQLExpressions.rank(path, path2))); + } + + @Test + public void listaggComma() { + assertEquals("listagg(path,',')", toString(SQLExpressions.listagg(path, ","))); + } + + @Test + public void listaggEmpty() { + assertEquals("listagg(path,'')", toString(SQLExpressions.listagg(path, ""))); + } + + @Test + public void listaggSpace() { + assertEquals("listagg(path,' ')", toString(SQLExpressions.listagg(path, " "))); + } + + @Test + public void listaggDelimiter() { + assertEquals("listagg(path,'|')", toString(SQLExpressions.listagg(path, "|"))); + } + + @Test + public void listaggCommaWithSpace() { + assertEquals("listagg(path,', ')", toString(SQLExpressions.listagg(path, ", "))); + } + + @Test + public void listaggIntString() { + assertEquals("listagg(path,'1')", toString(SQLExpressions.listagg(path, "1"))); + } + +} \ No newline at end of file diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/ddl/ColumnData.java b/querydsl-sql/src/test/java/com/querydsl/sql/ddl/ColumnData.java new file mode 100644 index 0000000000..b7e56a18ff --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/ddl/ColumnData.java @@ -0,0 +1,61 @@ +/* +* Copyright (c) 2010 Mysema Ltd. +* All rights reserved. +* +*/ +package com.querydsl.sql.ddl; + +/** +* @author tiwe +* +*/ +public class ColumnData { + + private final String name; + + private final String type; + + private boolean nullAllowed = true; + + private boolean autoIncrement; + + private Integer size; + + public ColumnData(String name, String type) { + this.name = name; + this.type = type; + } + + public String getName() { + return name; + } + + public String getType() { + return type; + } + + public boolean isNullAllowed() { + return nullAllowed; + } + + public void setNullAllowed(boolean nullAllowed) { + this.nullAllowed = nullAllowed; + } + + public void setSize(Integer size) { + this.size = size; + } + + public Integer getSize() { + return size; + } + + public boolean isAutoIncrement() { + return autoIncrement; + } + + public void setAutoIncrement(boolean autoIncrement) { + this.autoIncrement = autoIncrement; + } + +} \ No newline at end of file diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/ddl/CreateTableClause.java b/querydsl-sql/src/test/java/com/querydsl/sql/ddl/CreateTableClause.java new file mode 100644 index 0000000000..973f480307 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/ddl/CreateTableClause.java @@ -0,0 +1,212 @@ +/* + * Copyright (c) 2010 Mysema Ltd. + * All rights reserved. + * + */ +package com.querydsl.sql.ddl; + +import java.sql.Connection; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Logger; + +import com.querydsl.core.QueryException; +import com.querydsl.sql.Configuration; +import com.querydsl.sql.SQLTemplates; + +/** + * CreateTableClause defines a CREATE TABLE clause + * + * @author tiwe + * + */ +public class CreateTableClause { + + private static final Logger logger = Logger.getLogger(CreateTableClause.class.getName()); + + private final Connection connection; + + private final Configuration configuration; + + private final SQLTemplates templates; + + private final String table; + + private final List columns = new ArrayList(); + + private final List indexes = new ArrayList(); + + private PrimaryKeyData primaryKey; + + private final List foreignKeys = new ArrayList(); + + public CreateTableClause(Connection conn, Configuration c, String table) { + this.connection = conn; + this.configuration = c; + this.templates = c.getTemplates(); + this.table = templates.quoteIdentifier(table); + } + + /** + * Add a new column definition + * + * @param name + * @param type + * @return + */ + public CreateTableClause column(String name, Class type) { + String typeName = configuration.getTypeName(type); + columns.add(new ColumnData(templates.quoteIdentifier(name), typeName)); + return this; + } + + private ColumnData lastColumn() { + return columns.get(columns.size() - 1); + } + + /** + * Set the last added column to not null + * + * @return + */ + public CreateTableClause notNull() { + lastColumn().setNullAllowed(false); + return this; + } + + /** + * Set the size of the last column's type + * + * @param size + * @return + */ + public CreateTableClause size(int size) { + lastColumn().setSize(size); + return this; + } + + /** + * Set the last column to auto increment + * + * @return + */ + public CreateTableClause autoIncrement() { + lastColumn().setAutoIncrement(true); + return this; + } + + /** + * Set the primary key + * + * @param name + * @param columns + * @return + */ + public CreateTableClause primaryKey(String name, String... columns) { + for (int i = 0; i < columns.length; i++) { + columns[i] = templates.quoteIdentifier(columns[i]); + } + primaryKey = new PrimaryKeyData(templates.quoteIdentifier(name), columns); + return this; + } + + /** + * Add an index + * + * @param name + * @param columns + * @return + */ + public CreateTableClause index(String name, String... columns) { + indexes.add(new IndexData(name, columns)); + return this; + } + + /** + * Set the last added index to unique + * + * @return + */ + public CreateTableClause unique() { + indexes.get(indexes.size() - 1).setUnique(true); + return this; + } + + /** + * Add a foreign key + * + * @param name + * @param columns + * @return + */ + public ForeignKeyBuilder foreignKey(String name, String... columns) { + return new ForeignKeyBuilder(this, templates, foreignKeys, templates.quoteIdentifier(name), columns); + } + + /** + * Execute the clause + */ + @SuppressWarnings("SQL_NONCONSTANT_STRING_PASSED_TO_EXECUTE") + public void execute() { + StringBuilder builder = new StringBuilder(); + builder.append(templates.getCreateTable()).append(table).append(" (\n"); + List lines = new ArrayList(columns.size() + foreignKeys.size() + 1); + // columns + for (ColumnData column : columns) { + StringBuilder line = new StringBuilder(); + line.append(column.getName()).append(" ").append(column.getType().toUpperCase()); + if (column.getSize() != null) { + line.append("(").append(column.getSize()).append(")"); + } + if (!column.isNullAllowed()) { + line.append(templates.getNotNull().toUpperCase()); + } + if (column.isAutoIncrement()) { + line.append(templates.getAutoIncrement().toUpperCase()); + } + lines.add(line.toString()); + } + + // primary key + if (primaryKey != null) { + StringBuilder line = new StringBuilder(); + line.append("CONSTRAINT ").append(primaryKey.getName()).append(" "); + line.append("PRIMARY KEY(").append(String.join(", ", primaryKey.getColumns())).append(")"); + lines.add(line.toString()); + } + + // foreign keys + for (ForeignKeyData foreignKey : foreignKeys) { + StringBuilder line = new StringBuilder(); + line.append("CONSTRAINT ").append(foreignKey.getName()).append(" "); + line.append("FOREIGN KEY(").append(String.join(", ", foreignKey.getForeignColumns())).append(") "); + line.append("REFERENCES ").append(foreignKey.getTable()).append("(").append(String.join(", ", foreignKey.getParentColumns())).append(")"); + lines.add(line.toString()); + } + builder.append(" ").append(String.join(",\n ", lines)); + builder.append("\n)\n"); + logger.info(builder.toString()); + + try (Statement stmt = connection.createStatement()) { + stmt.execute(builder.toString()); + + // indexes + for (IndexData index : indexes) { + String indexColumns = String.join(", ", index.getColumns()); + String prefix = templates.getCreateIndex(); + if (index.isUnique()) { + prefix = templates.getCreateUniqueIndex(); + } + String sql = prefix + index.getName() + templates.getOn() + table + "(" + indexColumns + ")"; + logger.info(sql); + stmt.execute(sql); + } + } catch (SQLException e) { + System.err.println(builder.toString()); + throw new QueryException(e.getMessage(), e); + } + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/ddl/DropTableClause.java b/querydsl-sql/src/test/java/com/querydsl/sql/ddl/DropTableClause.java new file mode 100644 index 0000000000..c3da8ba83c --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/ddl/DropTableClause.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2010 Mysema Ltd. + * All rights reserved. + * + */ +package com.querydsl.sql.ddl; + +import java.sql.Connection; +import java.sql.SQLException; +import java.sql.Statement; + +import com.querydsl.core.QueryException; +import com.querydsl.sql.Configuration; + +/** + * DropTableClause defines a DROP TABLE clause + * + * @author tiwe + * + */ +public class DropTableClause { + + private final Connection connection; + + private final String table; + + public DropTableClause(Connection conn, Configuration c, String table) { + this.connection = conn; + this.table = c.getTemplates().quoteIdentifier(table); + } + + @SuppressWarnings("SQL_NONCONSTANT_STRING_PASSED_TO_EXECUTE") + public void execute() { + Statement stmt = null; + try { + stmt = connection.createStatement(); + stmt.execute("DROP TABLE " + table); + } catch (SQLException e) { + // do not rethrow + } finally { + if (stmt != null) { + try { + stmt.close(); + } catch (SQLException e) { + throw new QueryException(e); + } + } + } + } + +} diff --git a/querydsl-sql/src/test/java/com/mysema/query/ddl/ForeignKeyBuilder.java b/querydsl-sql/src/test/java/com/querydsl/sql/ddl/ForeignKeyBuilder.java similarity index 88% rename from querydsl-sql/src/test/java/com/mysema/query/ddl/ForeignKeyBuilder.java rename to querydsl-sql/src/test/java/com/querydsl/sql/ddl/ForeignKeyBuilder.java index b6f92e37cc..313235f8f7 100644 --- a/querydsl-sql/src/test/java/com/mysema/query/ddl/ForeignKeyBuilder.java +++ b/querydsl-sql/src/test/java/com/querydsl/sql/ddl/ForeignKeyBuilder.java @@ -3,30 +3,30 @@ * All rights reserved. * */ -package com.mysema.query.ddl; +package com.querydsl.sql.ddl; import java.util.List; -import com.mysema.query.sql.SQLTemplates; +import com.querydsl.sql.SQLTemplates; /** * ForeignKeyBuilder is part of the fluent interface of CreateTableClause - * + * * @author tiwe * */ public class ForeignKeyBuilder { private final List foreignKeys; - + private final CreateTableClause clause; - + private final String name; - + private final String[] foreignColumns; private final SQLTemplates templates; - + public ForeignKeyBuilder(CreateTableClause clause, SQLTemplates templates, List foreignKeys, String name, String[] columns) { this.clause = clause; this.templates = templates; @@ -39,7 +39,7 @@ public CreateTableClause references(String table, String... parentColumns) { ForeignKeyData foreignKey = new ForeignKeyData(name, templates.quoteIdentifier(table)); for (int i = 0; i < parentColumns.length; i++) { foreignKey.add( - templates.quoteIdentifier(foreignColumns[i]), + templates.quoteIdentifier(foreignColumns[i]), templates.quoteIdentifier(parentColumns[i])); } foreignKeys.add(foreignKey); diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/ddl/ForeignKeyData.java b/querydsl-sql/src/test/java/com/querydsl/sql/ddl/ForeignKeyData.java new file mode 100644 index 0000000000..5d46f58357 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/ddl/ForeignKeyData.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2010 Mysema Ltd. + * All rights reserved. + * + */ +package com.querydsl.sql.ddl; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author tiwe + * + */ +public class ForeignKeyData implements KeyData { + + private final String name; + + private final String table; + + private final List foreignColumns = new ArrayList(); + + private final List parentColumns = new ArrayList(); + + public ForeignKeyData(String name, String parentTable) { + this.name = name; + this.table = parentTable; + } + + public void add(String foreignColumn, String parentColumn) { + foreignColumns.add(foreignColumn); + parentColumns.add(parentColumn); + } + + public String getName() { + return name; + } + + public String getTable() { + return table; + } + + public List getForeignColumns() { + return foreignColumns; + } + + public List getParentColumns() { + return parentColumns; + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/ddl/IndexData.java b/querydsl-sql/src/test/java/com/querydsl/sql/ddl/IndexData.java new file mode 100644 index 0000000000..e30d2eedf6 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/ddl/IndexData.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2010 Mysema Ltd. + * All rights reserved. + * + */ +package com.querydsl.sql.ddl; + +/** + * @author tiwe + * + */ +public class IndexData { + + private final String name; + + private final String[] columns; + + private boolean unique; + + public IndexData(String name, String[] columns) { + this.name = name; + this.columns = columns.clone(); + } + + public String getName() { + return name; + } + + public String[] getColumns() { + return columns.clone(); + } + + public boolean isUnique() { + return unique; + } + + public void setUnique(boolean unique) { + this.unique = unique; + } + + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/ddl/KeyData.java b/querydsl-sql/src/test/java/com/querydsl/sql/ddl/KeyData.java new file mode 100644 index 0000000000..a8e411b938 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/ddl/KeyData.java @@ -0,0 +1,24 @@ +/* + * + */ +package com.querydsl.sql.ddl; + +import java.util.List; + +/** + * Common interface for ForeignKeyData and InverseForeignKeyData + * + * @author tiwe + * + */ +public interface KeyData { + + String getName(); + + String getTable(); + + List getForeignColumns(); + + List getParentColumns(); + +} \ No newline at end of file diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/ddl/PrimaryKeyData.java b/querydsl-sql/src/test/java/com/querydsl/sql/ddl/PrimaryKeyData.java new file mode 100644 index 0000000000..36f22c5b55 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/ddl/PrimaryKeyData.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2010 Mysema Ltd. + * All rights reserved. + * + */ +package com.querydsl.sql.ddl; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * @author tiwe + * + */ +public class PrimaryKeyData { + + private final String name; + + private final List columns = new ArrayList(); + + public PrimaryKeyData(String name) { + this.name = name; + } + + public PrimaryKeyData(String name, String[] c) { + this.name = name; + columns.addAll(Arrays.asList(c)); + } + + public void add(String column) { + columns.add(column); + } + + public String getName() { + return name; + } + + public List getColumns() { + return columns; + } + +} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/dml/AbstractMapperTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/dml/AbstractMapperTest.java similarity index 85% rename from querydsl-sql/src/test/java/com/mysema/query/sql/dml/AbstractMapperTest.java rename to querydsl-sql/src/test/java/com/querydsl/sql/dml/AbstractMapperTest.java index c672051f4d..bd1d4620bd 100644 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/dml/AbstractMapperTest.java +++ b/querydsl-sql/src/test/java/com/querydsl/sql/dml/AbstractMapperTest.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql.dml; +package com.querydsl.sql.dml; import java.math.BigDecimal; import java.sql.Date; @@ -19,38 +19,38 @@ import org.junit.Before; -import com.mysema.query.sql.Column; -import com.mysema.query.sql.domain.Employee; +import com.querydsl.sql.Column; +import com.querydsl.sql.domain.Employee; public abstract class AbstractMapperTest { - + public static class EmployeeX { - + private String property; - + public String getProperty() { return property; } - + public void setProperty(String property) { this.property = property; } } - + public static class EmployeeNames { @Column("ID") Integer _id; - + @Column("FIRSTNAME") String _firstname; - + @Column("LASTNAME") - String _lastname; + String _lastname; } protected Employee employee; - + @Before public void setUp() { employee = new Employee(); @@ -61,6 +61,6 @@ public void setUp() { employee.setSuperiorId(2); employee.setTimefield(new Time(0)); } - + } diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/dml/AnnotationMapperTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/dml/AnnotationMapperTest.java similarity index 79% rename from querydsl-sql/src/test/java/com/mysema/query/sql/dml/AnnotationMapperTest.java rename to querydsl-sql/src/test/java/com/querydsl/sql/dml/AnnotationMapperTest.java index 8a8ff49b63..26a849f31e 100644 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/dml/AnnotationMapperTest.java +++ b/querydsl-sql/src/test/java/com/querydsl/sql/dml/AnnotationMapperTest.java @@ -1,4 +1,4 @@ -package com.mysema.query.sql.dml; +package com.querydsl.sql.dml; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -7,35 +7,35 @@ import org.junit.Test; -import com.mysema.query.sql.domain.QEmployee; -import com.mysema.query.types.Path; +import com.querydsl.core.types.Path; +import com.querydsl.sql.domain.QEmployee; public class AnnotationMapperTest extends AbstractMapperTest { - + private static final QEmployee emp = QEmployee.employee; - + @Test - public void Extract_Success() { + public void extract_success() { EmployeeNames names = new EmployeeNames(); names._id = 9; names._firstname = "A"; names._lastname = "B"; - + Map, Object> values = AnnotationMapper.DEFAULT.createMap(emp, names); assertEquals(3, values.size()); assertEquals(names._id, values.get(emp.id)); assertEquals(names._firstname, values.get(emp.firstname)); - assertEquals(names._lastname, values.get(emp.lastname)); + assertEquals(names._lastname, values.get(emp.lastname)); } - + @Test - public void Extract_Failure() { + public void extract_failure() { Map, Object> values = AnnotationMapper.DEFAULT.createMap(emp, employee); assertTrue(values.isEmpty()); } - + @Test - public void Extract2() { + public void extract2() { Map, Object> values = AnnotationMapper.DEFAULT.createMap(emp, new EmployeeX()); assertTrue(values.isEmpty()); } diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/dml/BeanMapperTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/dml/BeanMapperTest.java similarity index 81% rename from querydsl-sql/src/test/java/com/mysema/query/sql/dml/BeanMapperTest.java rename to querydsl-sql/src/test/java/com/querydsl/sql/dml/BeanMapperTest.java index bf5b60b991..1adbde38af 100644 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/dml/BeanMapperTest.java +++ b/querydsl-sql/src/test/java/com/querydsl/sql/dml/BeanMapperTest.java @@ -1,4 +1,4 @@ -package com.mysema.query.sql.dml; +package com.querydsl.sql.dml; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -7,16 +7,16 @@ import org.junit.Test; -import com.mysema.query.sql.domain.QEmployee; -import com.mysema.query.types.Path; +import com.querydsl.core.types.Path; +import com.querydsl.sql.domain.QEmployee; public class BeanMapperTest extends AbstractMapperTest { - + private static final QEmployee emp = QEmployee.employee; - + @Test - public void Extract() { - Map, Object> values = BeanMapper.DEFAULT.createMap(emp, employee); + public void extract() { + Map, Object> values = BeanMapper.DEFAULT.createMap(emp, employee); assertEquals(employee.getDatefield(), values.get(emp.datefield)); assertEquals(employee.getFirstname(), values.get(emp.firstname)); assertEquals(employee.getLastname(), values.get(emp.lastname)); @@ -24,9 +24,9 @@ public void Extract() { assertEquals(employee.getSuperiorId(), values.get(emp.superiorId)); assertEquals(employee.getTimefield(), values.get(emp.timefield)); } - + @Test - public void Extract2() { + public void extract2() { Map, Object> values = BeanMapper.DEFAULT.createMap(emp, new EmployeeX()); assertTrue(values.isEmpty()); } diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/dml/DefaultMapperTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/dml/DefaultMapperTest.java new file mode 100644 index 0000000000..e0b838c370 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/dml/DefaultMapperTest.java @@ -0,0 +1,42 @@ +package com.querydsl.sql.dml; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.util.*; + +import org.junit.Test; + +import com.querydsl.core.types.Path; +import com.querydsl.sql.domain.QEmployee; + +public class DefaultMapperTest extends AbstractMapperTest { + + private static final QEmployee emp = QEmployee.employee; + + @Test + public void extract() { + Map, Object> values = DefaultMapper.DEFAULT.createMap(emp, employee); + assertEquals(employee.getDatefield(), values.get(emp.datefield)); + assertEquals(employee.getFirstname(), values.get(emp.firstname)); + assertEquals(employee.getLastname(), values.get(emp.lastname)); + assertEquals(employee.getSalary(), values.get(emp.salary)); + assertEquals(employee.getSuperiorId(), values.get(emp.superiorId)); + assertEquals(employee.getTimefield(), values.get(emp.timefield)); + } + + @Test + public void extract2() { + Map, Object> values = DefaultMapper.DEFAULT.createMap(emp, new EmployeeX()); + assertTrue(values.isEmpty()); + } + + @Test + public void preservedColumnOrder() { + final Map> columns = DefaultMapper.DEFAULT.getColumns(emp); + final List expectedKeySet = Arrays.asList("id", "firstname", "lastname", + "salary", "datefield", "timefield", "superiorId"); + assertEquals(expectedKeySet, new ArrayList(columns.keySet())); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/dml/SQLDeleteClauseTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/dml/SQLDeleteClauseTest.java new file mode 100644 index 0000000000..c8160b89fc --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/dml/SQLDeleteClauseTest.java @@ -0,0 +1,55 @@ +package com.querydsl.sql.dml; + +import static org.junit.Assert.assertEquals; + +import org.junit.Ignore; +import org.junit.Test; + +import com.querydsl.sql.KeyAccessorsTest.QEmployee; +import com.querydsl.sql.SQLBindings; +import com.querydsl.sql.SQLTemplates; + +import java.util.Collections; + +public class SQLDeleteClauseTest { + + @Test(expected = IllegalStateException.class) + public void noConnection() { + QEmployee emp1 = new QEmployee("emp1"); + SQLDeleteClause delete = new SQLDeleteClause(null, SQLTemplates.DEFAULT, emp1); + delete.where(emp1.id.eq(1)); + delete.execute(); + } + + @Test(expected = IllegalArgumentException.class) + @Ignore + public void error() { + QEmployee emp1 = new QEmployee("emp1"); + QEmployee emp2 = new QEmployee("emp2"); + SQLDeleteClause delete = new SQLDeleteClause(null, SQLTemplates.DEFAULT, emp1); + delete.where(emp2.id.eq(1)); + } + + @Test + public void getSQL() { + QEmployee emp1 = new QEmployee("emp1"); + SQLDeleteClause delete = new SQLDeleteClause(null, SQLTemplates.DEFAULT, emp1); + delete.where(emp1.id.eq(1)); + + SQLBindings sql = delete.getSQL().get(0); + assertEquals("delete from EMPLOYEE\nwhere EMPLOYEE.ID = ?", sql.getSQL()); + assertEquals(Collections.singletonList(1), sql.getNullFriendlyBindings()); + } + + @Test + public void clear() { + QEmployee emp1 = new QEmployee("emp1"); + SQLDeleteClause delete = new SQLDeleteClause(null, SQLTemplates.DEFAULT, emp1); + delete.where(emp1.id.eq(1)); + delete.addBatch(); + assertEquals(1, delete.getBatchCount()); + delete.clear(); + assertEquals(0, delete.getBatchCount()); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/dml/SQLInsertClauseTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/dml/SQLInsertClauseTest.java new file mode 100644 index 0000000000..9e838eeeb1 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/dml/SQLInsertClauseTest.java @@ -0,0 +1,73 @@ +package com.querydsl.sql.dml; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import com.querydsl.core.QueryFlag; +import com.querydsl.sql.KeyAccessorsTest.QEmployee; +import com.querydsl.sql.SQLBindings; +import com.querydsl.sql.SQLTemplates; + +import java.util.Collections; + +public class SQLInsertClauseTest { + + @Test(expected = IllegalStateException.class) + public void noConnection() { + QEmployee emp1 = new QEmployee("emp1"); + SQLInsertClause insert = new SQLInsertClause(null, SQLTemplates.DEFAULT, emp1); + insert.set(emp1.id, 1); + insert.execute(); + } + + @Test + public void getSQL() { + QEmployee emp1 = new QEmployee("emp1"); + SQLInsertClause insert = new SQLInsertClause(null, SQLTemplates.DEFAULT, emp1); + insert.set(emp1.id, 1); + + SQLBindings sql = insert.getSQL().get(0); + assertEquals("insert into EMPLOYEE (ID)\nvalues (?)", sql.getSQL()); + assertEquals(Collections.singletonList(1), sql.getNullFriendlyBindings()); + } + + @Test + public void bulk() { + QEmployee emp1 = new QEmployee("emp1"); + SQLInsertClause insert = new SQLInsertClause(null, SQLTemplates.DEFAULT, emp1); + insert.set(emp1.id, 1); + insert.addBatch(); + insert.set(emp1.id, 2); + insert.addBatch(); + insert.addFlag(QueryFlag.Position.END, " on duplicate key ignore"); + insert.setBatchToBulk(true); + assertEquals("insert into EMPLOYEE (ID)\n" + + "values (?), (?) on duplicate key ignore", insert.getSQL().get(0).getSQL()); + + } + + @Test + public void getSQLWithPreservedColumnOrder() { + com.querydsl.sql.domain.QEmployee emp1 = new com.querydsl.sql.domain.QEmployee("emp1"); + SQLInsertClause insert = new SQLInsertClause(null, SQLTemplates.DEFAULT, emp1); + insert.populate(emp1); + + SQLBindings sql = insert.getSQL().get(0); + assertEquals("The order of columns in generated sql should be predictable", + "insert into EMPLOYEE (ID, FIRSTNAME, LASTNAME, SALARY, DATEFIELD, TIMEFIELD, SUPERIOR_ID)\n" + + "values (EMPLOYEE.ID, EMPLOYEE.FIRSTNAME, EMPLOYEE.LASTNAME, EMPLOYEE.SALARY, EMPLOYEE.DATEFIELD, EMPLOYEE.TIMEFIELD, EMPLOYEE.SUPERIOR_ID)", sql.getSQL()); + } + + @Test + public void clear() { + QEmployee emp1 = new QEmployee("emp1"); + SQLInsertClause insert = new SQLInsertClause(null, SQLTemplates.DEFAULT, emp1); + insert.set(emp1.id, 1); + insert.addBatch(); + assertEquals(1, insert.getBatchCount()); + insert.clear(); + assertEquals(0, insert.getBatchCount()); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/dml/SQLMergeClauseTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/dml/SQLMergeClauseTest.java new file mode 100644 index 0000000000..97a7b1ce16 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/dml/SQLMergeClauseTest.java @@ -0,0 +1,22 @@ +package com.querydsl.sql.dml; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import com.querydsl.sql.H2Templates; +import com.querydsl.sql.KeyAccessorsTest; + +public class SQLMergeClauseTest { + + @Test + public void clear() { + KeyAccessorsTest.QEmployee emp1 = new KeyAccessorsTest.QEmployee("emp1"); + SQLMergeClause merge = new SQLMergeClause(null, new H2Templates(), emp1); + merge.set(emp1.id, 1); + merge.addBatch(); + assertEquals(1, merge.getBatchCount()); + merge.clear(); + assertEquals(0, merge.getBatchCount()); + } +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/dml/SQLUpdateClauseTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/dml/SQLUpdateClauseTest.java new file mode 100644 index 0000000000..0864e0aa99 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/dml/SQLUpdateClauseTest.java @@ -0,0 +1,120 @@ +package com.querydsl.sql.dml; + +import static com.querydsl.sql.SQLExpressions.select; +import static org.junit.Assert.assertEquals; + +import com.querydsl.core.QueryFlag.Position; +import org.junit.Test; + +import com.querydsl.sql.KeyAccessorsTest.QEmployee; +import com.querydsl.sql.SQLBindings; +import com.querydsl.sql.SQLTemplates; + +import java.util.Collections; + +public class SQLUpdateClauseTest { + + @Test(expected = IllegalStateException.class) + public void noConnection() { + QEmployee emp1 = new QEmployee("emp1"); + SQLUpdateClause update = new SQLUpdateClause(null, SQLTemplates.DEFAULT, emp1); + update.set(emp1.id, 1); + update.execute(); + } + + @Test + public void getSQL() { + QEmployee emp1 = new QEmployee("emp1"); + SQLUpdateClause update = new SQLUpdateClause(null, SQLTemplates.DEFAULT, emp1); + update.set(emp1.id, 1); + + SQLBindings sql = update.getSQL().get(0); + assertEquals("update EMPLOYEE\nset ID = ?", sql.getSQL()); + assertEquals(Collections.singletonList(1), sql.getNullFriendlyBindings()); + } + + @Test + public void intertable() { + QEmployee emp1 = new QEmployee("emp1"); + QEmployee emp2 = new QEmployee("emp2"); + SQLUpdateClause update = new SQLUpdateClause(null, SQLTemplates.DEFAULT, emp1); + update.set(emp1.id, 1) + .where(emp1.id.eq(select(emp2.id).from(emp2) + .where(emp2.superiorId.isNotNull()))); + + SQLBindings sql = update.getSQL().get(0); + assertEquals("update EMPLOYEE\n" + + "set ID = ?\n" + + "where EMPLOYEE.ID = (select emp2.ID\n" + + "from EMPLOYEE emp2\n" + + "where emp2.SUPERIOR_ID is not null)", sql.getSQL()); + } + + @Test + public void intertable2() { + QEmployee emp1 = new QEmployee("emp1"); + QEmployee emp2 = new QEmployee("emp2"); + SQLUpdateClause update = new SQLUpdateClause(null, SQLTemplates.DEFAULT, emp1); + update.set(emp1.id, select(emp2.id).from(emp2) + .where(emp2.superiorId.isNotNull())); + + SQLBindings sql = update.getSQL().get(0); + assertEquals("update EMPLOYEE\n" + + "set ID = (select emp2.ID\n" + + "from EMPLOYEE emp2\n" + + "where emp2.SUPERIOR_ID is not null)", sql.getSQL()); + } + + @Test + public void intertable3() { + QEmployee emp1 = new QEmployee("emp1"); + QEmployee emp2 = new QEmployee("emp2"); + SQLUpdateClause update = new SQLUpdateClause(null, SQLTemplates.DEFAULT, emp1); + update.set(emp1.superiorId, select(emp2.id).from(emp2) + .where(emp2.id.eq(emp1.id))); + + SQLBindings sql = update.getSQL().get(0); + assertEquals("update EMPLOYEE\n" + + "set SUPERIOR_ID = (select emp2.ID\n" + + "from EMPLOYEE emp2\n" + + "where emp2.ID = EMPLOYEE.ID)", sql.getSQL()); + } + + @Test + public void testBeforeFiltersFlag() { + QEmployee emp1 = new QEmployee("emp1"); + QEmployee emp2 = new QEmployee("emp2"); + SQLUpdateClause update = new SQLUpdateClause(null, SQLTemplates.DEFAULT, emp1) + .set(emp1.superiorId, emp2.id) + .addFlag(Position.BEFORE_FILTERS, String.format("\nfrom %s %s", emp2.getTableName(), emp2)) + .where(emp2.id.eq(emp1.id)); + + SQLBindings sql = update.getSQL().get(0); + assertEquals("update EMPLOYEE\n" + + "set SUPERIOR_ID = emp2.ID\n" + + "from EMPLOYEE emp2\n" + + "where emp2.ID = EMPLOYEE.ID", sql.getSQL()); + + update = new SQLUpdateClause(null, SQLTemplates.DEFAULT, emp1) + .set(emp1.superiorId, emp2.id) + .addFlag(Position.BEFORE_FILTERS, " THE_FLAG") + .where(emp2.id.eq(emp1.id)); + + sql = update.getSQL().get(0); + assertEquals("update EMPLOYEE\n" + + "set SUPERIOR_ID = emp2.ID THE_FLAG\n" + + "where emp2.ID = EMPLOYEE.ID", sql.getSQL()); + } + + @Test + public void clear() { + QEmployee emp1 = new QEmployee("emp1"); + SQLUpdateClause update = new SQLUpdateClause(null, SQLTemplates.DEFAULT, emp1); + update.set(emp1.id, 1); + update.addBatch(); + assertEquals(1, update.getBatchCount()); + update.clear(); + assertEquals(0, update.getBatchCount()); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/domain/Employee.java b/querydsl-sql/src/test/java/com/querydsl/sql/domain/Employee.java new file mode 100644 index 0000000000..a012302d83 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/domain/Employee.java @@ -0,0 +1,109 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.domain; + +import java.math.BigDecimal; +import java.sql.Date; +import java.sql.Time; + +//@Schema("PUBLIC") +//@Table("EMPLOYEE") +public class Employee { + + //@Column("ID") + private Integer id; + + //@Column("FIRSTNAME") + private String firstname; + + //@Column("LASTNAME") + private String lastname; + + //@Column("SALARY") + private BigDecimal salary; + + //@Column("DATEFIELD") + private Date datefield; + + //@Column("TIMEFIELD") + private Time timefield; + + //@Column("SUPERIOR_ID") + private Integer superiorId; + + public Employee() { } + + public Employee(int id) { + this.id = id; + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getFirstname() { + return firstname; + } + + public void setFirstname(String firstname) { + this.firstname = firstname; + } + + public String getLastname() { + return lastname; + } + + public void setLastname(String lastname) { + this.lastname = lastname; + } + + public BigDecimal getSalary() { + return salary; + } + + public void setSalary(BigDecimal salary) { + this.salary = salary; + } + + public Date getDatefield() { + return new Date(datefield.getTime()); + } + + public void setDatefield(Date datefield) { + this.datefield = new Date(datefield.getTime()); + } + + public Time getTimefield() { + return timefield; + } + + public void setTimefield(Time timefield) { + this.timefield = timefield; + } + + public Integer getSuperiorId() { + return superiorId; + } + + public void setSuperiorId(Integer superiorId) { + this.superiorId = superiorId; + } + + + +} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/domain/IdName.java b/querydsl-sql/src/test/java/com/querydsl/sql/domain/IdName.java similarity index 84% rename from querydsl-sql/src/test/java/com/mysema/query/sql/domain/IdName.java rename to querydsl-sql/src/test/java/com/querydsl/sql/domain/IdName.java index 62464cf50c..c67a059766 100644 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/domain/IdName.java +++ b/querydsl-sql/src/test/java/com/querydsl/sql/domain/IdName.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,9 +11,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql.domain; +package com.querydsl.sql.domain; -import com.mysema.query.annotations.QueryProjection; +import com.querydsl.core.annotations.QueryProjection; public class IdName { diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/domain/QDateTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/domain/QDateTest.java new file mode 100644 index 0000000000..4c3d815c81 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/domain/QDateTest.java @@ -0,0 +1,33 @@ +package com.querydsl.sql.domain; + +import java.sql.Date; + +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.PathMetadataFactory; +import com.querydsl.core.types.dsl.DatePath; +import com.querydsl.sql.ColumnMetadata; +import com.querydsl.sql.RelationalPathBase; + +public class QDateTest extends RelationalPathBase { + + private static final long serialVersionUID = 1394463749655231079L; + + public static final QDateTest qDateTest = new QDateTest("DATE_TEST"); + + public final DatePath dateTest = createDate("dateTest", java.sql.Date.class); + + public QDateTest(String path) { + super(QDateTest.class, PathMetadataFactory.forVariable(path), "PUBLIC", "DATE_TEST"); + addMetadata(); + } + + public QDateTest(PathMetadata metadata) { + super(QDateTest.class, metadata, "PUBLIC", "DATE_TEST"); + addMetadata(); + } + + protected void addMetadata() { + addMetadata(dateTest, ColumnMetadata.named("DATE_TEST")); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/domain/QEmployee.java b/querydsl-sql/src/test/java/com/querydsl/sql/domain/QEmployee.java new file mode 100644 index 0000000000..ef204aab9a --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/domain/QEmployee.java @@ -0,0 +1,78 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.domain; + +import java.math.BigDecimal; +import java.sql.Types; + +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.PathMetadataFactory; +import com.querydsl.core.types.dsl.DatePath; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.StringPath; +import com.querydsl.core.types.dsl.TimePath; +import com.querydsl.sql.ColumnMetadata; +import com.querydsl.sql.ForeignKey; +import com.querydsl.sql.PrimaryKey; +import com.querydsl.sql.RelationalPathBase; + +//@Schema("PUBLIC") +//@Table("EMPLOYEE") +public class QEmployee extends RelationalPathBase { + + private static final long serialVersionUID = 1394463749655231079L; + + public static final QEmployee employee = new QEmployee("EMPLOYEE"); + + public final NumberPath id = createNumber("id", Integer.class); + + public final StringPath firstname = createString("firstname"); + + public final StringPath lastname = createString("lastname"); + + public final NumberPath salary = createNumber("salary", BigDecimal.class); + + public final DatePath datefield = createDate("datefield", java.sql.Date.class); + + public final TimePath timefield = createTime("timefield", java.sql.Time.class); + + public final NumberPath superiorId = createNumber("superiorId", Integer.class); + + public final PrimaryKey idKey = createPrimaryKey(id); + + public final ForeignKey superiorIdKey = createForeignKey(superiorId, "ID"); + + public final ForeignKey _superiorIdKey = createInvForeignKey(id, "SUPERIOR_ID"); + + public QEmployee(String path) { + super(Employee.class, PathMetadataFactory.forVariable(path), "PUBLIC", "EMPLOYEE"); + addMetadata(); + } + + public QEmployee(PathMetadata metadata) { + super(Employee.class, metadata, "PUBLIC", "EMPLOYEE"); + addMetadata(); + } + + protected void addMetadata() { + addMetadata(id, ColumnMetadata.named("ID").ofType(Types.INTEGER)); + addMetadata(firstname, ColumnMetadata.named("FIRSTNAME").ofType(Types.VARCHAR)); + addMetadata(lastname, ColumnMetadata.named("LASTNAME").ofType(Types.VARCHAR)); + addMetadata(salary, ColumnMetadata.named("SALARY").ofType(Types.DECIMAL)); + addMetadata(datefield, ColumnMetadata.named("DATEFIELD").ofType(Types.DATE)); + addMetadata(timefield, ColumnMetadata.named("TIMEFIELD").ofType(Types.TIME)); + addMetadata(superiorId, ColumnMetadata.named("SUPERIOR_ID").ofType(Types.INTEGER)); + } + +} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/domain/QEmployeeNoPK.java b/querydsl-sql/src/test/java/com/querydsl/sql/domain/QEmployeeNoPK.java similarity index 81% rename from querydsl-sql/src/test/java/com/mysema/query/sql/domain/QEmployeeNoPK.java rename to querydsl-sql/src/test/java/com/querydsl/sql/domain/QEmployeeNoPK.java index 0474dd64a6..dffc72914f 100644 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/domain/QEmployeeNoPK.java +++ b/querydsl-sql/src/test/java/com/querydsl/sql/domain/QEmployeeNoPK.java @@ -1,5 +1,5 @@ /* - * Copyright 2011, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,19 +11,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql.domain; +package com.querydsl.sql.domain; import java.math.BigDecimal; -import com.mysema.query.sql.ColumnMetadata; -import com.mysema.query.sql.ForeignKey; -import com.mysema.query.sql.RelationalPathBase; -import com.mysema.query.types.PathMetadata; -import com.mysema.query.types.PathMetadataFactory; -import com.mysema.query.types.path.DatePath; -import com.mysema.query.types.path.NumberPath; -import com.mysema.query.types.path.StringPath; -import com.mysema.query.types.path.TimePath; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.PathMetadataFactory; +import com.querydsl.core.types.dsl.DatePath; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.StringPath; +import com.querydsl.core.types.dsl.TimePath; +import com.querydsl.sql.ColumnMetadata; +import com.querydsl.sql.ForeignKey; +import com.querydsl.sql.RelationalPathBase; //@Schema("PUBLIC") //@Table("EMPLOYEE") @@ -56,7 +56,7 @@ public QEmployeeNoPK(String path) { addMetadata(); } - public QEmployeeNoPK(PathMetadata metadata) { + public QEmployeeNoPK(PathMetadata metadata) { super(Employee.class, metadata, "PUBLIC", "EMPLOYEE"); addMetadata(); } diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/domain/QIdName.java b/querydsl-sql/src/test/java/com/querydsl/sql/domain/QIdName.java new file mode 100644 index 0000000000..e34bef479a --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/domain/QIdName.java @@ -0,0 +1,27 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.domain; + +import com.querydsl.core.types.ConstructorExpression; +import com.querydsl.core.types.Expression; + +public class QIdName extends ConstructorExpression { + + private static final long serialVersionUID = 5770565824515003611L; + + public QIdName(Expression id, Expression name) { + super(IdName.class, new Class[]{int.class, String.class}, id, name); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/domain/QNumberTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/domain/QNumberTest.java new file mode 100644 index 0000000000..225b806b5c --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/domain/QNumberTest.java @@ -0,0 +1,57 @@ +package com.querydsl.sql.domain; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import java.sql.Types; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.BooleanPath; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.sql.ColumnMetadata; +import com.querydsl.sql.RelationalPathBase; + + + +/** + * QNumberTest is a Querydsl query type for QNumberTest + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class QNumberTest extends RelationalPathBase { + + private static final long serialVersionUID = 291758928; + + public static final QNumberTest numberTest = new QNumberTest("NUMBER_TEST"); + + public final BooleanPath col1Boolean = createBoolean("col1"); + + public final NumberPath col1Number = createNumber("col2", Byte.class); + + public QNumberTest(String variable) { + super(QNumberTest.class, forVariable(variable), "PUBLIC", "NUMBER_TEST"); + addMetadata(); + } + + public QNumberTest(String variable, String schema, String table) { + super(QNumberTest.class, forVariable(variable), schema, table); + addMetadata(); + } + + public QNumberTest(Path path) { + super(path.getType(), path.getMetadata(), "PUBLIC", "NUMBER_TEST"); + addMetadata(); + } + + public QNumberTest(PathMetadata metadata) { + super(QNumberTest.class, metadata, "PUBLIC", "NUMBER_TEST"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(col1Boolean, ColumnMetadata.named("COL1").withIndex(1).ofType(Types.BIT)); + addMetadata(col1Number, ColumnMetadata.named("COL1").withIndex(1).ofType(Types.BIT)); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/domain/QSurvey.java b/querydsl-sql/src/test/java/com/querydsl/sql/domain/QSurvey.java new file mode 100644 index 0000000000..7fb419ac20 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/domain/QSurvey.java @@ -0,0 +1,58 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.domain; + +import java.sql.Types; + +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.PathMetadataFactory; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.StringPath; +import com.querydsl.sql.ColumnMetadata; +import com.querydsl.sql.PrimaryKey; +import com.querydsl.sql.RelationalPathBase; + +//@Schema("PUBLIC") +//@Table("SURVEY") +public class QSurvey extends RelationalPathBase { + + private static final long serialVersionUID = -7427577079709192842L; + + public static final QSurvey survey = new QSurvey("SURVEY"); + + public final StringPath name = createString("name"); + + public final StringPath name2 = createString("name2"); + + public final NumberPath id = createNumber("id", Integer.class); + + public final PrimaryKey idKey = createPrimaryKey(id); + + public QSurvey(String path) { + super(QSurvey.class, PathMetadataFactory.forVariable(path), "PUBLIC", "SURVEY"); + addMetadata(); + } + + public QSurvey(PathMetadata metadata) { + super(QSurvey.class, metadata, "PUBLIC", "SURVEY"); + addMetadata(); + } + + protected void addMetadata() { + addMetadata(name, ColumnMetadata.named("NAME").ofType(Types.VARCHAR)); + addMetadata(name2, ColumnMetadata.named("NAME2").ofType(Types.VARCHAR)); + addMetadata(id, ColumnMetadata.named("ID").ofType(Types.INTEGER)); + } + +} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/domain/QSurveyNoPK.java b/querydsl-sql/src/test/java/com/querydsl/sql/domain/QSurveyNoPK.java similarity index 77% rename from querydsl-sql/src/test/java/com/mysema/query/sql/domain/QSurveyNoPK.java rename to querydsl-sql/src/test/java/com/querydsl/sql/domain/QSurveyNoPK.java index 0f3d51ab9c..b70d3fda0a 100644 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/domain/QSurveyNoPK.java +++ b/querydsl-sql/src/test/java/com/querydsl/sql/domain/QSurveyNoPK.java @@ -1,5 +1,5 @@ /* - * Copyright 2011, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,18 +11,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql.domain; +package com.querydsl.sql.domain; -import com.mysema.query.sql.ColumnMetadata; -import com.mysema.query.sql.RelationalPathBase; -import com.mysema.query.types.PathMetadata; -import com.mysema.query.types.PathMetadataFactory; -import com.mysema.query.types.path.NumberPath; -import com.mysema.query.types.path.StringPath; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.PathMetadataFactory; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.StringPath; +import com.querydsl.sql.ColumnMetadata; +import com.querydsl.sql.RelationalPathBase; //@Schema("PUBLIC") //@Table("SURVEY") -public class QSurveyNoPK extends RelationalPathBase{ +public class QSurveyNoPK extends RelationalPathBase { private static final long serialVersionUID = -7427577079709192842L; @@ -39,7 +39,7 @@ public QSurveyNoPK(String path) { addMetadata(); } - public QSurveyNoPK(PathMetadata metadata) { + public QSurveyNoPK(PathMetadata metadata) { super(QSurveyNoPK.class, metadata, "PUBLIC", "SURVEY"); addMetadata(); } diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/domain/QTestX.java b/querydsl-sql/src/test/java/com/querydsl/sql/domain/QTestX.java new file mode 100644 index 0000000000..97ba8bf46a --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/domain/QTestX.java @@ -0,0 +1,36 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.domain; + +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.PathMetadataFactory; +import com.querydsl.core.types.dsl.EntityPathBase; +import com.querydsl.core.types.dsl.StringPath; + +//@Table("TEST") +public class QTestX extends EntityPathBase { + + private static final long serialVersionUID = -8421112749591552595L; + + public final StringPath name = createString("NAME"); + + public QTestX(String path) { + super(Object.class, PathMetadataFactory.forVariable(path)); + } + + public QTestX(PathMetadata metadata) { + super(Object.class, metadata); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/domain/QUuids.java b/querydsl-sql/src/test/java/com/querydsl/sql/domain/QUuids.java new file mode 100644 index 0000000000..7d9d8b7d07 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/domain/QUuids.java @@ -0,0 +1,54 @@ +package com.querydsl.sql.domain; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import java.sql.Types; +import java.util.UUID; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.SimplePath; +import com.querydsl.sql.ColumnMetadata; +import com.querydsl.sql.RelationalPathBase; + + + +/** + * QUuids is a Querydsl query type for QUuids + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class QUuids extends RelationalPathBase { + + private static final long serialVersionUID = -1780705501; + + public static final QUuids uuids = new QUuids("UUIDS"); + + public final SimplePath field = createSimple("field", UUID.class); + + public QUuids(String variable) { + super(QUuids.class, forVariable(variable), "public", "UUIDS"); + addMetadata(); + } + + public QUuids(String variable, String schema, String table) { + super(QUuids.class, forVariable(variable), schema, table); + addMetadata(); + } + + public QUuids(Path path) { + super(path.getType(), path.getMetadata(), "public", "UUIDS"); + addMetadata(); + } + + public QUuids(PathMetadata metadata) { + super(QUuids.class, metadata, "public", "UUIDS"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(field, ColumnMetadata.named("FIELD").withIndex(1).ofType(Types.OTHER).withSize(2147483647)); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/domain/QXmlTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/domain/QXmlTest.java new file mode 100644 index 0000000000..f6a32f43c8 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/domain/QXmlTest.java @@ -0,0 +1,53 @@ +package com.querydsl.sql.domain; + +import static com.querydsl.core.types.PathMetadataFactory.forVariable; + +import java.sql.Types; + +import javax.annotation.Generated; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.dsl.StringPath; +import com.querydsl.sql.ColumnMetadata; +import com.querydsl.sql.RelationalPathBase; + + + +/** + * QXmlTest is a Querydsl query type for QXmlTest + */ +@Generated("com.querydsl.sql.codegen.MetaDataSerializer") +public class QXmlTest extends RelationalPathBase { + + private static final long serialVersionUID = 574759316; + + public static final QXmlTest xmlTest = new QXmlTest("XML_TEST"); + + public final StringPath col = createString("COL"); + + public QXmlTest(String variable) { + super(QXmlTest.class, forVariable(variable), "PUBLIC", "XML_TEST"); + addMetadata(); + } + + public QXmlTest(String variable, String schema, String table) { + super(QXmlTest.class, forVariable(variable), schema, table); + addMetadata(); + } + + public QXmlTest(Path path) { + super(path.getType(), path.getMetadata(), "PUBLIC", "XML_TEST"); + addMetadata(); + } + + public QXmlTest(PathMetadata metadata) { + super(QXmlTest.class, metadata, "PUBLIC", "XML_TEST"); + addMetadata(); + } + + public void addMetadata() { + addMetadata(col, ColumnMetadata.named("COL").withIndex(1).ofType(Types.SQLXML).withSize(2147483647)); + } + +} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/h2/GeneratedKeysH2Test.java b/querydsl-sql/src/test/java/com/querydsl/sql/h2/GeneratedKeysH2Test.java similarity index 85% rename from querydsl-sql/src/test/java/com/mysema/query/sql/h2/GeneratedKeysH2Test.java rename to querydsl-sql/src/test/java/com/querydsl/sql/h2/GeneratedKeysH2Test.java index 03ee033967..f4fbb04d2b 100644 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/h2/GeneratedKeysH2Test.java +++ b/querydsl-sql/src/test/java/com/querydsl/sql/h2/GeneratedKeysH2Test.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,18 +11,20 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql.h2; +package com.querydsl.sql.h2; + +import static org.junit.Assert.*; import java.sql.*; import java.util.Collections; -import com.mysema.query.QGeneratedKeysEntity; -import com.mysema.query.sql.H2Templates; -import com.mysema.query.sql.dml.SQLInsertClause; import org.junit.After; import org.junit.Before; import org.junit.Test; -import static org.junit.Assert.*; + +import com.querydsl.sql.H2Templates; +import com.querydsl.sql.QGeneratedKeysEntity; +import com.querydsl.sql.dml.SQLInsertClause; public class GeneratedKeysH2Test { @@ -31,24 +33,24 @@ public class GeneratedKeysH2Test { private Statement stmt; @Before - public void setUp() throws ClassNotFoundException, SQLException{ + public void setUp() throws ClassNotFoundException, SQLException { Class.forName("org.h2.Driver"); - String url = "jdbc:h2:~/dbs/h2-gen"; + String url = "jdbc:h2:./target/h2-gen"; conn = DriverManager.getConnection(url, "sa", ""); stmt = conn.createStatement(); } @After - public void tearDown() throws SQLException{ - try{ + public void tearDown() throws SQLException { + try { stmt.close(); - }finally{ + } finally { conn.close(); } } @Test - public void test() throws SQLException{ + public void test() throws SQLException { stmt.execute("drop table GENERATED_KEYS if exists"); stmt.execute("create table GENERATED_KEYS(" + "ID int AUTO_INCREMENT PRIMARY KEY, " + @@ -59,7 +61,7 @@ public void test() throws SQLException{ ResultSet rs = insertClause.set(entity.name, "Hello").executeWithKeys(); ResultSetMetaData md = rs.getMetaData(); System.out.println(md.getColumnName(1)); - + assertTrue(rs.next()); assertEquals(1, rs.getInt(1)); assertFalse(rs.next()); @@ -72,7 +74,7 @@ public void test() throws SQLException{ insertClause = new SQLInsertClause(conn, new H2Templates(), entity); assertEquals(3, insertClause.set(entity.name, "World").executeWithKey(entity.id).intValue()); - + insertClause = new SQLInsertClause(conn, new H2Templates(), entity); assertEquals(Collections.singletonList(4), insertClause.set(entity.name, "World").executeWithKeys(entity.id)); } diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/h2/H2QueryTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/h2/H2QueryTest.java new file mode 100644 index 0000000000..dd45c2b213 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/h2/H2QueryTest.java @@ -0,0 +1,48 @@ +package com.querydsl.sql.h2; + +import org.junit.Before; +import org.junit.Test; + +import com.querydsl.sql.H2Templates; +import com.querydsl.sql.SQLQuery; +import com.querydsl.sql.domain.QSurvey; + +public class H2QueryTest { + + private SQLQuery query; + + private QSurvey survey = new QSurvey("survey"); + + @Before + public void setUp() { + query = new SQLQuery(H2Templates.builder().newLineToSingleSpace().build()); + } + + @Test + public void syntax() { +// SELECT TOP? [DISTINCT | All]? selectExpression +// FROM tableExpression+ + query.from(survey); +// WHERE expression+ + query.where(survey.name.isNotNull()); +// GROUP BY expression+ + query.groupBy(survey.name); +// HAVING expression + query.having(survey.name.lt("")); +// [ +// UNION ALL? select ORDER BY order +// MINUS +// EXCEPT +// INTERSECT +// ] +// LIMIT expression + query.limit(2); +// OFFSET expression + query.offset(3); +// SAMPLE_SIZE rowCountInt + // TODO +// FOR UPDATE + query.forUpdate(); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/hsqldb/HsqldbQueryTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/hsqldb/HsqldbQueryTest.java new file mode 100644 index 0000000000..de297124db --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/hsqldb/HsqldbQueryTest.java @@ -0,0 +1,47 @@ +package com.querydsl.sql.hsqldb; + +import org.junit.Before; +import org.junit.Test; + +import com.querydsl.sql.HSQLDBTemplates; +import com.querydsl.sql.SQLQuery; +import com.querydsl.sql.domain.QSurvey; + +public class HsqldbQueryTest { + + private SQLQuery query; + + private QSurvey survey = new QSurvey("survey"); + + @Before + public void setUp() { + query = new SQLQuery(HSQLDBTemplates.builder().newLineToSingleSpace().build()); + } + + @Test + public void syntax() { +// SELECT [{LIMIT | TOP }[2]][ALL | DISTINCT] +// { selectExpression | table.* | * } [, ...] +// [INTO [CACHED | TEMP | TEXT][2] newTable] +// FROM tableList + query.from(survey); +// [WHERE Expression] + query.where(survey.id.isNotNull()); +// [GROUP BY Expression [, ...]] + query.groupBy(survey.name); +// [HAVING Expression] + query.having(survey.id.isNotNull()); +// [{ UNION [ALL | DISTINCT] | {MINUS [DISTINCT] | EXCEPT [DISTINCT] } | + // TODO MINUS + // TODO EXCEPT +// INTERSECT [DISTINCT] } selectStatement] + // TODO INTERSECT +// [ORDER BY orderExpression [, ...]] + query.orderBy(survey.name.asc()); +// [LIMIT [OFFSET ]]; + query.limit(4); + query.offset(4); + + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/mssql/SQLServerQueryTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/mssql/SQLServerQueryTest.java new file mode 100644 index 0000000000..3ce8a9c59a --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/mssql/SQLServerQueryTest.java @@ -0,0 +1,75 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.mssql; + +import static org.junit.Assert.assertEquals; + +import com.querydsl.sql.domain.QEmployee; +import org.junit.Test; + +import com.querydsl.sql.SQLServerTemplates; +import com.querydsl.sql.domain.QSurvey; + +public class SQLServerQueryTest { + + private static final QSurvey survey = QSurvey.survey; + + @Test + public void tableHints_single() { + SQLServerQuery query = new SQLServerQuery(null, new SQLServerTemplates()); + query.from(survey).tableHints(SQLServerTableHints.NOWAIT).where(survey.name.isNull()); + assertEquals("from SURVEY SURVEY with (NOWAIT)\nwhere SURVEY.NAME is null", query.toString()); + } + + @Test + public void tableHints_multiple() { + SQLServerQuery query = new SQLServerQuery(null, new SQLServerTemplates()); + query.from(survey).tableHints(SQLServerTableHints.NOWAIT, SQLServerTableHints.NOLOCK).where(survey.name.isNull()); + assertEquals("from SURVEY SURVEY with (NOWAIT, NOLOCK)\nwhere SURVEY.NAME is null", query.toString()); + } + + @Test + public void tableHints_multiple2() { + QSurvey survey2 = new QSurvey("survey2"); + SQLServerQuery query = new SQLServerQuery(null, new SQLServerTemplates()); + query.from(survey).tableHints(SQLServerTableHints.NOWAIT) + .from(survey2).tableHints(SQLServerTableHints.NOLOCK) + .where(survey.name.isNull()); + assertEquals("from SURVEY SURVEY with (NOWAIT), SURVEY survey2 with (NOLOCK)\nwhere SURVEY.NAME is null", query.toString()); + } + + + @Test + public void join_tableHints_single() { + QEmployee employee1 = QEmployee.employee; + QEmployee employee2 = new QEmployee("employee2"); + SQLServerQuery query = new SQLServerQuery(null, new SQLServerTemplates()); + query.from(employee1).tableHints(SQLServerTableHints.NOLOCK) + .join(employee2).tableHints(SQLServerTableHints.NOLOCK) + .on(employee1.superiorId.eq(employee2.id)); + assertEquals("from EMPLOYEE EMPLOYEE with (NOLOCK)\njoin EMPLOYEE employee2 with (NOLOCK)\non EMPLOYEE.SUPERIOR_ID = employee2.ID", query.toString()); + } + + @Test + public void join_tableHints_multiple() { + QEmployee employee1 = QEmployee.employee; + QEmployee employee2 = new QEmployee("employee2"); + SQLServerQuery query = new SQLServerQuery(null, new SQLServerTemplates()); + query.from(employee1).tableHints(SQLServerTableHints.NOLOCK,SQLServerTableHints.READUNCOMMITTED) + .join(employee2).tableHints(SQLServerTableHints.NOLOCK,SQLServerTableHints.READUNCOMMITTED) + .on(employee1.superiorId.eq(employee2.id)); + assertEquals("from EMPLOYEE EMPLOYEE with (NOLOCK, READUNCOMMITTED)\njoin EMPLOYEE employee2 with (NOLOCK, READUNCOMMITTED)\non EMPLOYEE.SUPERIOR_ID = employee2.ID", query.toString()); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/mssql/WindowFunctionTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/mssql/WindowFunctionTest.java new file mode 100644 index 0000000000..0769202f2a --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/mssql/WindowFunctionTest.java @@ -0,0 +1,72 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.mssql; + +import static com.querydsl.sql.Constants.employee; +import static com.querydsl.sql.SQLExpressions.rowNumber; +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import com.querydsl.core.types.Expression; +import com.querydsl.sql.Configuration; +import com.querydsl.sql.SQLSerializer; +import com.querydsl.sql.SQLTemplates; +import com.querydsl.sql.WindowFunction; + +public class WindowFunctionTest { + + private static final Configuration configuration = new Configuration(SQLTemplates.DEFAULT); + + private static String toString(Expression e) { + return new SQLSerializer(configuration).handle(e).toString(); + } + +// ROW_NUMBER() OVER (ORDER BY OrderDate) AS 'RowNumber' + +// ROW_NUMBER() OVER (PARTITION BY PostalCode ORDER BY SalesYTD DESC) + + @Test + public void mutable() { + WindowFunction rn = rowNumber().over().orderBy(employee.firstname); + assertEquals("row_number() over (order by e.FIRSTNAME asc)", toString(rn)); + assertEquals("row_number() over (order by e.FIRSTNAME asc, e.LASTNAME asc)", toString(rn.orderBy(employee.lastname))); + } + + @Test + public void orderBy() { + assertEquals("row_number() over (order by e.FIRSTNAME asc)", + toString(rowNumber().over().orderBy(employee.firstname.asc()))); + + assertEquals("row_number() over (order by e.FIRSTNAME asc)", + toString(rowNumber().over().orderBy(employee.firstname))); + + assertEquals("row_number() over (order by e.FIRSTNAME asc) as rn", + toString(rowNumber().over().orderBy(employee.firstname.asc()).as("rn"))); + + assertEquals("row_number() over (order by e.FIRSTNAME desc)", + toString(rowNumber().over().orderBy(employee.firstname.desc()))); + } + + @Test + public void partitionBy() { + assertEquals("row_number() over (partition by e.LASTNAME order by e.FIRSTNAME asc)", + toString(rowNumber().over().partitionBy(employee.lastname).orderBy(employee.firstname.asc()))); + + assertEquals("row_number() over (partition by e.LASTNAME, e.FIRSTNAME order by e.FIRSTNAME asc)", + toString(rowNumber().over().partitionBy(employee.lastname, employee.firstname).orderBy(employee.firstname.asc()))); + } + + +} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/mysql/GeneratedKeysMySQLTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/mysql/GeneratedKeysMySQLTest.java similarity index 83% rename from querydsl-sql/src/test/java/com/mysema/query/sql/mysql/GeneratedKeysMySQLTest.java rename to querydsl-sql/src/test/java/com/querydsl/sql/mysql/GeneratedKeysMySQLTest.java index f056d55c8a..989816306c 100644 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/mysql/GeneratedKeysMySQLTest.java +++ b/querydsl-sql/src/test/java/com/querydsl/sql/mysql/GeneratedKeysMySQLTest.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,21 +11,23 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql.mysql; +package com.querydsl.sql.mysql; + +import static org.junit.Assert.*; import java.sql.*; -import com.mysema.query.QGeneratedKeysEntity; -import com.mysema.query.sql.H2Templates; -import com.mysema.query.sql.dml.SQLInsertClause; -import com.mysema.testutil.ExternalDB; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.experimental.categories.Category; -import static org.junit.Assert.*; -@Category(ExternalDB.class) +import com.querydsl.core.testutil.MySQL; +import com.querydsl.sql.H2Templates; +import com.querydsl.sql.QGeneratedKeysEntity; +import com.querydsl.sql.dml.SQLInsertClause; + +@Category(MySQL.class) public class GeneratedKeysMySQLTest { private Connection conn; @@ -33,7 +35,7 @@ public class GeneratedKeysMySQLTest { private Statement stmt; @Before - public void setUp() throws ClassNotFoundException, SQLException{ + public void setUp() throws ClassNotFoundException, SQLException { Class.forName("com.mysql.jdbc.Driver"); String url = "jdbc:mysql://localhost:3306/querydsl"; conn = DriverManager.getConnection(url, "querydsl", "querydsl"); @@ -41,16 +43,16 @@ public void setUp() throws ClassNotFoundException, SQLException{ } @After - public void tearDown() throws SQLException{ - try{ + public void tearDown() throws SQLException { + try { stmt.close(); - }finally{ + } finally { conn.close(); } } @Test - public void test() throws SQLException{ + public void test() throws SQLException { stmt.execute("drop table if exists GENERATED_KEYS"); stmt.execute("create table GENERATED_KEYS(" + "ID int AUTO_INCREMENT PRIMARY KEY, " + @@ -61,7 +63,7 @@ public void test() throws SQLException{ ResultSet rs = insertClause.set(entity.name, "Hello").executeWithKeys(); ResultSetMetaData md = rs.getMetaData(); System.out.println(md.getColumnName(1)); - + assertTrue(rs.next()); assertEquals(1, rs.getInt(1)); assertFalse(rs.next()); diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/mysql/MySQLQueryFactoryTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/mysql/MySQLQueryFactoryTest.java new file mode 100644 index 0000000000..aaf729d589 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/mysql/MySQLQueryFactoryTest.java @@ -0,0 +1,120 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.mysql; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.sql.Connection; +import java.util.function.Supplier; + +import org.easymock.EasyMock; +import org.junit.Before; +import org.junit.Test; + +import com.querydsl.sql.SQLExpressions; +import com.querydsl.sql.SQLTemplates; +import com.querydsl.sql.dml.SQLInsertClause; +import com.querydsl.sql.domain.QSurvey; + +public class MySQLQueryFactoryTest { + + private MySQLQueryFactory queryFactory; + + @Before + public void setUp() { + Supplier provider = () -> EasyMock. createNiceMock(Connection.class); + queryFactory = new MySQLQueryFactory(SQLTemplates.DEFAULT, provider); + } + + @Test + public void query() { + assertNotNull(queryFactory.query()); + } + + @Test + public void from() { + assertNotNull(queryFactory.from(QSurvey.survey)); + } + + @Test + public void delete() { + assertNotNull(queryFactory.delete(QSurvey.survey)); + } + + @Test + public void insert() { + assertNotNull(queryFactory.insert(QSurvey.survey)); + } + + @Test + public void insertIgnore() { + SQLInsertClause clause = queryFactory.insertIgnore(QSurvey.survey); + assertEquals("insert ignore into SURVEY\nvalues ()", clause.toString()); + } + + @Test + public void insertOnDuplicateKeyUpdate() { + SQLInsertClause clause = queryFactory.insertOnDuplicateKeyUpdate(QSurvey.survey, "c = c+1"); + assertEquals("insert into SURVEY\nvalues () on duplicate key update c = c+1", clause.toString()); + } + + @Test + public void insertOnDuplicateKeyUpdate2() { + SQLInsertClause clause = queryFactory.insertOnDuplicateKeyUpdate(QSurvey.survey, QSurvey.survey.id.eq(2)); + assertEquals("insert into SURVEY\nvalues () on duplicate key update SURVEY.ID = ?", clause.toString()); + } + + @Test + public void insertOnDuplicateKeyUpdate_multiple() { + SQLInsertClause clause = queryFactory.insertOnDuplicateKeyUpdate(QSurvey.survey, + SQLExpressions.set(QSurvey.survey.id, 2), + SQLExpressions.set(QSurvey.survey.name, "B")); + assertEquals("insert into SURVEY\n" + + "values () on duplicate key update SURVEY.ID = ?, SURVEY.NAME = ?", clause.toString()); + } + + @Test + public void insertOnDuplicateKeyUpdate_values() { + SQLInsertClause clause = queryFactory.insertOnDuplicateKeyUpdate(QSurvey.survey, + SQLExpressions.set(QSurvey.survey.name, QSurvey.survey.name)); + assertEquals("insert into SURVEY\n" + + "values () on duplicate key update SURVEY.NAME = values(SURVEY.NAME)", clause.toString()); + } + + @Test + public void insertOnDuplicateKeyUpdate_null() { + SQLInsertClause clause = queryFactory.insertOnDuplicateKeyUpdate(QSurvey.survey, + SQLExpressions.set(QSurvey.survey.name, (String) null)); + assertEquals("insert into SURVEY\n" + + "values () on duplicate key update SURVEY.NAME = null", clause.toString()); + } + + + @Test + public void replace() { + assertNotNull(queryFactory.replace(QSurvey.survey)); + } + + @Test + public void update() { + assertNotNull(queryFactory.update(QSurvey.survey)); + } + + @Test + public void merge() { + assertNotNull(queryFactory.merge(QSurvey.survey)); + } + +} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/mysql/MySQLQueryTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/mysql/MySQLQueryTest.java similarity index 79% rename from querydsl-sql/src/test/java/com/mysema/query/sql/mysql/MySQLQueryTest.java rename to querydsl-sql/src/test/java/com/querydsl/sql/mysql/MySQLQueryTest.java index 9a036da342..e3833623ed 100644 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/mysql/MySQLQueryTest.java +++ b/querydsl-sql/src/test/java/com/querydsl/sql/mysql/MySQLQueryTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2011, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql.mysql; +package com.querydsl.sql.mysql; import static org.junit.Assert.assertEquals; @@ -20,26 +20,24 @@ import org.junit.Before; import org.junit.Test; -import com.mysema.query.sql.MySQLTemplates; -import com.mysema.query.sql.domain.QSurvey; +import com.querydsl.sql.MySQLTemplates; +import com.querydsl.sql.domain.QSurvey; public class MySQLQueryTest { - private MySQLQuery query; + private MySQLQuery query; private QSurvey survey = new QSurvey("survey"); @Before public void setUp() { - query = new MySQLQuery(null, new MySQLTemplates() {{ - newLineToSingleSpace(); - }}); + query = new MySQLQuery(null, MySQLTemplates.builder().newLineToSingleSpace().build()); query.from(survey); query.orderBy(survey.name.asc()); - query.getMetadata().addProjection(survey.name); + query.getMetadata().setProjection(survey.name); } @Test - public void Syntax() { + public void syntax() { // SELECT // [ALL | DISTINCT | DISTINCTROW ] // [HIGH_PRIORITY] @@ -82,119 +80,111 @@ public void Syntax() { } @Test - public void ForceIndex() { - query = new MySQLQuery(null, new MySQLTemplates() {{ - newLineToSingleSpace(); - }}); + public void forceIndex() { + query = new MySQLQuery(null, MySQLTemplates.builder().newLineToSingleSpace().build()); query.from(survey); query.forceIndex("col1_index"); query.orderBy(survey.name.asc()); - query.getMetadata().addProjection(survey.name); + query.getMetadata().setProjection(survey.name); assertEquals("select survey.NAME from SURVEY survey force index (col1_index) " + "order by survey.NAME asc", toString(query)); } @Test - public void IgnoreIndex() { - query = new MySQLQuery(null, new MySQLTemplates() {{ - newLineToSingleSpace(); - }}); + public void ignoreIndex() { + query = new MySQLQuery(null, MySQLTemplates.builder().newLineToSingleSpace().build()); query.from(survey); query.ignoreIndex("col1_index"); query.orderBy(survey.name.asc()); - query.getMetadata().addProjection(survey.name); + query.getMetadata().setProjection(survey.name); assertEquals("select survey.NAME from SURVEY survey ignore index (col1_index) " + "order by survey.NAME asc", toString(query)); } @Test - public void UseIndex() { - query = new MySQLQuery(null, new MySQLTemplates() {{ - newLineToSingleSpace(); - }}); + public void useIndex() { + query = new MySQLQuery(null, MySQLTemplates.builder().newLineToSingleSpace().build()); query.from(survey); query.useIndex("col1_index"); query.orderBy(survey.name.asc()); - query.getMetadata().addProjection(survey.name); + query.getMetadata().setProjection(survey.name); assertEquals("select survey.NAME from SURVEY survey use index (col1_index) " + "order by survey.NAME asc", toString(query)); } @Test - public void UseIndex2() { - query = new MySQLQuery(null, new MySQLTemplates() {{ - newLineToSingleSpace(); - }}); + public void useIndex2() { + query = new MySQLQuery(null, MySQLTemplates.builder().newLineToSingleSpace().build()); query.from(survey); query.useIndex("col1_index","col2_index"); query.orderBy(survey.name.asc()); - query.getMetadata().addProjection(survey.name); + query.getMetadata().setProjection(survey.name); assertEquals("select survey.NAME from SURVEY survey use index (col1_index, col2_index) " + "order by survey.NAME asc", toString(query)); } @Test - public void HighPriority() { + public void highPriority() { query.highPriority(); assertEquals("select high_priority survey.NAME from SURVEY survey order by survey.NAME asc", toString(query)); } @Test - public void StraightJoin() { + public void straightJoin() { query.straightJoin(); assertEquals("select straight_join survey.NAME from SURVEY survey order by survey.NAME asc", toString(query)); } @Test - public void SmallResult() { + public void smallResult() { query.smallResult(); assertEquals("select sql_small_result survey.NAME from SURVEY survey order by survey.NAME asc", toString(query)); } @Test - public void BigResult() { + public void bigResult() { query.bigResult(); assertEquals("select sql_big_result survey.NAME from SURVEY survey order by survey.NAME asc", toString(query)); } @Test - public void BufferResult() { + public void bufferResult() { query.bufferResult(); assertEquals("select sql_buffer_result survey.NAME from SURVEY survey order by survey.NAME asc", toString(query)); } @Test - public void Cache() { + public void cache() { query.cache(); assertEquals("select sql_cache survey.NAME from SURVEY survey order by survey.NAME asc", toString(query)); } @Test - public void NoCache() { + public void noCache() { query.noCache(); assertEquals("select sql_no_cache survey.NAME from SURVEY survey order by survey.NAME asc", toString(query)); } @Test - public void CalcFoundRows() { + public void calcFoundRows() { query.calcFoundRows(); assertEquals("select sql_calc_found_rows survey.NAME from SURVEY survey order by survey.NAME asc", toString(query)); } @Test - public void WithRollup() { + public void withRollup() { query.groupBy(survey.name); query.withRollup(); assertEquals("select survey.NAME from SURVEY survey group by survey.NAME with rollup order by survey.NAME asc", @@ -202,14 +192,14 @@ public void WithRollup() { } @Test - public void ForUpdate() { + public void forUpdate() { query.forUpdate(); assertEquals("select survey.NAME from SURVEY survey order by survey.NAME asc for update", toString(query)); } @Test - public void ForUpdate_With_Limit() { + public void forUpdate_with_limit() { query.forUpdate(); query.limit(2); assertEquals("select survey.NAME from SURVEY survey order by survey.NAME asc limit ? for update", @@ -217,34 +207,34 @@ public void ForUpdate_With_Limit() { } @Test - public void IntoOutfile() { + public void intoOutfile() { query.intoOutfile(new File("target/out")); assertEquals("select survey.NAME from SURVEY survey " + "order by survey.NAME asc into outfile 'target" + File.separator + "out'", toString(query)); } @Test - public void IntoDumpfile() { + public void intoDumpfile() { query.intoDumpfile(new File("target/out")); assertEquals("select survey.NAME from SURVEY survey " + "order by survey.NAME asc into dumpfile 'target" + File.separator + "out'", toString(query)); } @Test - public void IntoString() { + public void intoString() { query.into("var1"); assertEquals("select survey.NAME from SURVEY survey " + "order by survey.NAME asc into var1", toString(query)); } @Test - public void LockInShareMode() { + public void lockInShareMode() { query.lockInShareMode(); assertEquals("select survey.NAME from SURVEY survey " + "order by survey.NAME asc lock in share mode", toString(query)); } - private String toString(MySQLQuery query) { + private String toString(MySQLQuery query) { return query.toString().replace('\n', ' '); } diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/oracle/OracleGrammarTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/oracle/OracleGrammarTest.java similarity index 86% rename from querydsl-sql/src/test/java/com/mysema/query/sql/oracle/OracleGrammarTest.java rename to querydsl-sql/src/test/java/com/querydsl/sql/oracle/OracleGrammarTest.java index 2612d3a305..ce938ff55b 100644 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/oracle/OracleGrammarTest.java +++ b/querydsl-sql/src/test/java/com/querydsl/sql/oracle/OracleGrammarTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2011, Mysema Ltd + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql.oracle; +package com.querydsl.sql.oracle; import static org.junit.Assert.assertNotNull; @@ -20,7 +20,7 @@ public class OracleGrammarTest { @Test - public void Constants() { + public void constants() { assertNotNull(OracleGrammar.level); assertNotNull(OracleGrammar.rownum); assertNotNull(OracleGrammar.sysdate); diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/oracle/OracleQueryFactoryTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/oracle/OracleQueryFactoryTest.java new file mode 100644 index 0000000000..aa560c0910 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/oracle/OracleQueryFactoryTest.java @@ -0,0 +1,68 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.oracle; + +import static org.junit.Assert.assertNotNull; + +import java.sql.Connection; +import java.util.function.Supplier; + +import org.easymock.EasyMock; +import org.junit.Before; +import org.junit.Test; + +import com.querydsl.sql.SQLTemplates; +import com.querydsl.sql.domain.QSurvey; + +public class OracleQueryFactoryTest { + + private OracleQueryFactory queryFactory; + + @Before + public void setUp() { + Supplier provider = () -> EasyMock. createNiceMock(Connection.class); + queryFactory = new OracleQueryFactory(SQLTemplates.DEFAULT, provider); + } + + @Test + public void query() { + assertNotNull(queryFactory.query()); + } + + @Test + public void from() { + assertNotNull(queryFactory.from(QSurvey.survey)); + } + + @Test + public void delete() { + assertNotNull(queryFactory.delete(QSurvey.survey)); + } + + @Test + public void insert() { + assertNotNull(queryFactory.insert(QSurvey.survey)); + } + + @Test + public void update() { + assertNotNull(queryFactory.update(QSurvey.survey)); + } + + @Test + public void merge() { + assertNotNull(queryFactory.merge(QSurvey.survey)); + } + +} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/oracle/OracleQueryTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/oracle/OracleQueryTest.java similarity index 75% rename from querydsl-sql/src/test/java/com/mysema/query/sql/oracle/OracleQueryTest.java rename to querydsl-sql/src/test/java/com/querydsl/sql/oracle/OracleQueryTest.java index 0e9d6aae25..90bb1c1d01 100644 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/oracle/OracleQueryTest.java +++ b/querydsl-sql/src/test/java/com/querydsl/sql/oracle/OracleQueryTest.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,68 +11,66 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.sql.oracle; +package com.querydsl.sql.oracle; import static org.junit.Assert.assertEquals; import org.junit.Before; import org.junit.Test; -import com.mysema.query.sql.OracleTemplates; -import com.mysema.query.sql.domain.QSurvey; +import com.querydsl.sql.OracleTemplates; +import com.querydsl.sql.domain.QSurvey; public class OracleQueryTest { - - private OracleQuery query; - + + private OracleQuery query; + private QSurvey survey = new QSurvey("survey"); - + @Before public void setUp() { - query = new OracleQuery(null, new OracleTemplates() {{ - newLineToSingleSpace(); - }}); + query = new OracleQuery(null, OracleTemplates.builder().newLineToSingleSpace().build()); query.from(survey); query.orderBy(survey.name.asc()); - } + } @Test - public void ConnectByPrior() { + public void connectByPrior() { query.connectByPrior(survey.name.isNull()); - assertEquals("from SURVEY survey connect by prior survey.NAME is null order by survey.NAME asc", + assertEquals("from SURVEY survey connect by prior survey.NAME is null order by survey.NAME asc", toString(query)); } @Test - public void ConnectBy() { + public void connectBy() { query.connectByPrior(survey.name.isNull()); assertEquals("from SURVEY survey connect by prior survey.NAME is null order by survey.NAME asc", toString(query)); } @Test - public void ConnectByNocyclePrior() { + public void connectByNocyclePrior() { query.connectByNocyclePrior(survey.name.isNull()); assertEquals("from SURVEY survey connect by nocycle prior survey.NAME is null order by survey.NAME asc", toString(query)); } @Test - public void StartWith() { + public void startWith() { query.startWith(survey.name.isNull()); - assertEquals("from SURVEY survey start with survey.NAME is null order by survey.NAME asc", + assertEquals("from SURVEY survey start with survey.NAME is null order by survey.NAME asc", toString(query)); } @Test - public void OrderSiblingsBy() { + public void orderSiblingsBy() { query.orderSiblingsBy(survey.name); - assertEquals("from SURVEY survey order siblings by survey.NAME order by survey.NAME asc", + assertEquals("from SURVEY survey order siblings by survey.NAME order by survey.NAME asc", toString(query)); } - + @Test - public void RowNum() { + public void rowNum() { query.where(OracleGrammar.rownum.lt(5)); assertEquals("from SURVEY survey where rownum < ? order by survey.NAME asc", toString(query)); } diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/postgresql/PostgreSQLQueryFactoryTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/postgresql/PostgreSQLQueryFactoryTest.java new file mode 100644 index 0000000000..1627c716c6 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/postgresql/PostgreSQLQueryFactoryTest.java @@ -0,0 +1,68 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.postgresql; + +import static org.junit.Assert.assertNotNull; + +import java.sql.Connection; +import java.util.function.Supplier; + +import org.easymock.EasyMock; +import org.junit.Before; +import org.junit.Test; + +import com.querydsl.sql.SQLTemplates; +import com.querydsl.sql.domain.QSurvey; + +public class PostgreSQLQueryFactoryTest { + + private PostgreSQLQueryFactory queryFactory; + + @Before + public void setUp() { + Supplier provider = () -> EasyMock. createNiceMock(Connection.class); + queryFactory = new PostgreSQLQueryFactory(SQLTemplates.DEFAULT, provider); + } + + @Test + public void query() { + assertNotNull(queryFactory.query()); + } + + @Test + public void from() { + assertNotNull(queryFactory.from(QSurvey.survey)); + } + + @Test + public void delete() { + assertNotNull(queryFactory.delete(QSurvey.survey)); + } + + @Test + public void insert() { + assertNotNull(queryFactory.insert(QSurvey.survey)); + } + + @Test + public void update() { + assertNotNull(queryFactory.update(QSurvey.survey)); + } + + @Test + public void merge() { + assertNotNull(queryFactory.merge(QSurvey.survey)); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/postgresql/PostgreSQLQueryTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/postgresql/PostgreSQLQueryTest.java new file mode 100644 index 0000000000..66ce6e4e5e --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/postgresql/PostgreSQLQueryTest.java @@ -0,0 +1,108 @@ +package com.querydsl.sql.postgresql; + +import static org.junit.Assert.assertEquals; + +import org.junit.Before; +import org.junit.Test; + +import com.querydsl.sql.PostgreSQLTemplates; +import com.querydsl.sql.domain.QEmployee; +import com.querydsl.sql.domain.QSurvey; + +public class PostgreSQLQueryTest { + + private PostgreSQLQuery query; + + private QSurvey survey = new QSurvey("survey"); + + private QEmployee employee = new QEmployee("employee"); + + @Before + public void setUp() { + query = new PostgreSQLQuery(null, PostgreSQLTemplates.builder().newLineToSingleSpace().build()); + } + + @Test + public void syntax() { +// [ WITH [ RECURSIVE ] with_query [, ...] ] +// SELECT [ ALL | DISTINCT [ ON ( expression [, ...] ) ] ] + query.distinctOn(survey.name); +// * | expression [ [ AS ] output_name ] [, ...] +// [ FROM from_item [, ...] ] + query.from(survey); +// [ WHERE condition ] + query.where(survey.name.isNull()); +// [ GROUP BY expression [, ...] ] + query.groupBy(survey.name); +// [ HAVING condition [, ...] ] + query.having(survey.id.isNotNull()); +// [ WINDOW window_name AS ( window_definition ) [, ...] ] + // TODO +// [ { UNION | INTERSECT | EXCEPT } [ ALL ] select ] + // TODO INTERSECT + // TODO EXCEPT +// [ ORDER BY expression [ ASC | DESC | USING operator ] [ NULLS { FIRST | LAST } ] [, ...] ] + query.orderBy(survey.name.asc()); +// [ LIMIT { count | ALL } ] + query.limit(4); +// [ OFFSET start [ ROW | ROWS ] ] + query.offset(4); +// [ FETCH { FIRST | NEXT } [ count ] { ROW | ROWS } ONLY ] +// [ FOR { UPDATE | SHARE } [ OF table_name [, ...] ] [ NOWAIT ] [...] ] + query.forUpdate(); + query.forShare(); + query.noWait(); + + query.forUpdate().of(survey); + +// where from_item can be one of: +// +// [ ONLY ] table_name [ * ] [ [ AS ] alias [ ( column_alias [, ...] ) ] ] +// ( select ) [ AS ] alias [ ( column_alias [, ...] ) ] +// with_query_name [ [ AS ] alias [ ( column_alias [, ...] ) ] ] +// function_name ( [ argument [, ...] ] ) [ AS ] alias [ ( column_alias [, ...] | column_definition [, ...] ) ] +// function_name ( [ argument [, ...] ] ) AS ( column_definition [, ...] ) +// from_item [ NATURAL ] join_type from_item [ ON join_condition | USING ( join_column [, ...] ) ] +// +// and with_query is: +// +// with_query_name [ ( column_name [, ...] ) ] AS ( select ) +// +// TABLE { [ ONLY ] table_name [ * ] | with_query_name } + } + + @Test + public void forShare() { + query.from(survey).forShare(); + assertEquals("from SURVEY survey for share", toString(query)); + } + + @Test + public void forUpDate_noWait() { + query.from(survey).forUpdate().noWait(); + assertEquals("from SURVEY survey for update nowait", toString(query)); + } + + @Test + public void forUpdate_of() { + query.from(survey).forUpdate().of(survey); + assertEquals("from SURVEY survey for update of SURVEY", toString(query)); + } + + @Test + public void distinct_on() { + query.from(employee) + .distinctOn(employee.datefield, employee.timefield) + .orderBy(employee.datefield.asc(), employee.timefield.asc(), employee.salary.asc()) + .select(employee.id); + + assertEquals( + "select distinct on(employee.DATEFIELD, employee.TIMEFIELD) employee.ID from EMPLOYEE employee order by employee.DATEFIELD asc, employee.TIMEFIELD asc, employee.SALARY asc", + toString(query)); + } + + private String toString(PostgreSQLQuery query) { + return query.toString().replace('\n', ' '); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/suites/AbstractSuite.java b/querydsl-sql/src/test/java/com/querydsl/sql/suites/AbstractSuite.java new file mode 100644 index 0000000000..5fbfcb493e --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/suites/AbstractSuite.java @@ -0,0 +1,19 @@ +package com.querydsl.sql.suites; + +import java.sql.SQLException; + +import org.junit.AfterClass; +import org.junit.experimental.runners.Enclosed; +import org.junit.runner.RunWith; + +import com.querydsl.sql.Connections; + +@RunWith(Enclosed.class) +public abstract class AbstractSuite { + + @AfterClass + public static void tearDown() throws SQLException { + Connections.close(); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/suites/CUBRIDLiteralsSuiteTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/suites/CUBRIDLiteralsSuiteTest.java new file mode 100644 index 0000000000..eb789bddce --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/suites/CUBRIDLiteralsSuiteTest.java @@ -0,0 +1,33 @@ +package com.querydsl.sql.suites; + +import org.junit.BeforeClass; +import org.junit.Ignore; +import org.junit.experimental.categories.Category; + +import com.querydsl.core.testutil.CUBRID; +import com.querydsl.sql.*; + +@Ignore +@Category(CUBRID.class) +public class CUBRIDLiteralsSuiteTest extends AbstractSuite { + + public static class BeanPopulation extends BeanPopulationBase { } + public static class Delete extends DeleteBase { } + public static class Insert extends InsertBase { } + public static class KeywordQuoting extends KeywordQuotingBase { } + public static class LikeEscape extends LikeEscapeBase { } + public static class Merge extends MergeBase { } + public static class Select extends SelectBase { } + public static class Subqueries extends SubqueriesBase { } + public static class Types extends TypesBase { } + public static class Union extends UnionBase { } + public static class Update extends UpdateBase { } + + @BeforeClass + public static void setUp() throws Exception { + Connections.initCubrid(); + Connections.initConfiguration(CUBRIDTemplates.builder().newLineToSingleSpace().build()); + Connections.getConfiguration().setUseLiterals(true); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/suites/CUBRIDSuiteTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/suites/CUBRIDSuiteTest.java new file mode 100644 index 0000000000..5539155332 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/suites/CUBRIDSuiteTest.java @@ -0,0 +1,32 @@ +package com.querydsl.sql.suites; + +import org.junit.BeforeClass; +import org.junit.Ignore; +import org.junit.experimental.categories.Category; + +import com.querydsl.core.testutil.CUBRID; +import com.querydsl.sql.*; + +@Ignore +@Category(CUBRID.class) +public class CUBRIDSuiteTest extends AbstractSuite { + + public static class BeanPopulation extends BeanPopulationBase { } + public static class Delete extends DeleteBase { } + public static class Insert extends InsertBase { } + public static class KeywordQuoting extends KeywordQuotingBase { } + public static class LikeEscape extends LikeEscapeBase { } + public static class Merge extends MergeBase { } + public static class Select extends SelectBase { } + public static class Subqueries extends SubqueriesBase { } + public static class Types extends TypesBase { } + public static class Union extends UnionBase { } + public static class Update extends UpdateBase { } + + @BeforeClass + public static void setUp() throws Exception { + Connections.initCubrid(); + Connections.initConfiguration(CUBRIDTemplates.builder().newLineToSingleSpace().build()); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/suites/DB2LiteralsSuiteTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/suites/DB2LiteralsSuiteTest.java new file mode 100644 index 0000000000..f2ab9148f2 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/suites/DB2LiteralsSuiteTest.java @@ -0,0 +1,32 @@ +package com.querydsl.sql.suites; + +import org.junit.BeforeClass; +import org.junit.experimental.categories.Category; + +import com.querydsl.core.testutil.DB2; +import com.querydsl.sql.*; + +@Category(DB2.class) +public class DB2LiteralsSuiteTest extends AbstractSuite { + + public static class BeanPopulation extends BeanPopulationBase { } + public static class Delete extends DeleteBase { } + public static class Insert extends InsertBase { } + public static class KeywordQuoting extends KeywordQuotingBase { } + public static class LikeEscape extends LikeEscapeBase { } + public static class Merge extends MergeBase { } + public static class Select extends SelectBase { } + public static class SelectWindowFunctions extends SelectWindowFunctionsBase { } + public static class Subqueries extends SubqueriesBase { } + public static class Types extends TypesBase { } + public static class Union extends UnionBase { } + public static class Update extends UpdateBase { } + + @BeforeClass + public static void setUp() throws Exception { + Connections.initDB2(); + Connections.initConfiguration(DB2Templates.builder().newLineToSingleSpace().build()); + Connections.getConfiguration().setUseLiterals(true); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/suites/DB2SuiteTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/suites/DB2SuiteTest.java new file mode 100644 index 0000000000..210aa64dc5 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/suites/DB2SuiteTest.java @@ -0,0 +1,31 @@ +package com.querydsl.sql.suites; + +import org.junit.BeforeClass; +import org.junit.experimental.categories.Category; + +import com.querydsl.core.testutil.DB2; +import com.querydsl.sql.*; + +@Category(DB2.class) +public class DB2SuiteTest extends AbstractSuite { + + public static class BeanPopulation extends BeanPopulationBase { } + public static class Delete extends DeleteBase { } + public static class Insert extends InsertBase { } + public static class KeywordQuoting extends KeywordQuotingBase { } + public static class LikeEscape extends LikeEscapeBase { } + public static class Merge extends MergeBase { } + public static class Select extends SelectBase { } + public static class SelectWindowFunctions extends SelectWindowFunctionsBase { } + public static class Subqueries extends SubqueriesBase { } + public static class Types extends TypesBase { } + public static class Union extends UnionBase { } + public static class Update extends UpdateBase { } + + @BeforeClass + public static void setUp() throws Exception { + Connections.initDB2(); + Connections.initConfiguration(DB2Templates.builder().newLineToSingleSpace().build()); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/suites/DerbyLiteralsSuiteTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/suites/DerbyLiteralsSuiteTest.java new file mode 100644 index 0000000000..848f4fc692 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/suites/DerbyLiteralsSuiteTest.java @@ -0,0 +1,31 @@ +package com.querydsl.sql.suites; + +import org.junit.BeforeClass; +import org.junit.experimental.categories.Category; + +import com.querydsl.core.testutil.Derby; +import com.querydsl.sql.*; + +@Category(Derby.class) +public class DerbyLiteralsSuiteTest extends AbstractSuite { + + public static class BeanPopulation extends BeanPopulationBase { } + public static class Delete extends DeleteBase { } + public static class Insert extends InsertBase { } + public static class KeywordQuoting extends KeywordQuotingBase { } + public static class LikeEscape extends LikeEscapeBase { } + public static class Merge extends MergeBase { } + public static class Select extends SelectBase { } + public static class Subqueries extends SubqueriesBase { } + public static class Types extends TypesBase { } + public static class Union extends UnionBase { } + public static class Update extends UpdateBase { } + + @BeforeClass + public static void setUp() throws Exception { + Connections.initDerby(); + Connections.initConfiguration(DerbyTemplates.builder().newLineToSingleSpace().build()); + Connections.getConfiguration().setUseLiterals(true); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/suites/DerbySuiteTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/suites/DerbySuiteTest.java new file mode 100644 index 0000000000..d2228478c3 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/suites/DerbySuiteTest.java @@ -0,0 +1,30 @@ +package com.querydsl.sql.suites; + +import org.junit.BeforeClass; +import org.junit.experimental.categories.Category; + +import com.querydsl.core.testutil.Derby; +import com.querydsl.sql.*; + +@Category(Derby.class) +public class DerbySuiteTest extends AbstractSuite { + + public static class BeanPopulation extends BeanPopulationBase { } + public static class Delete extends DeleteBase { } + public static class Insert extends InsertBase { } + public static class KeywordQuoting extends KeywordQuotingBase { } + public static class LikeEscape extends LikeEscapeBase { } + public static class Merge extends MergeBase { } + public static class Select extends SelectBase { } + public static class Subqueries extends SubqueriesBase { } + public static class Types extends TypesBase { } + public static class Union extends UnionBase { } + public static class Update extends UpdateBase { } + + @BeforeClass + public static void setUp() throws Exception { + Connections.initDerby(); + Connections.initConfiguration(DerbyTemplates.builder().newLineToSingleSpace().build()); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/suites/FirebirdLiteralsSuiteTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/suites/FirebirdLiteralsSuiteTest.java new file mode 100644 index 0000000000..9cf32bbb85 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/suites/FirebirdLiteralsSuiteTest.java @@ -0,0 +1,30 @@ +package com.querydsl.sql.suites; + +import org.junit.BeforeClass; +import org.junit.experimental.categories.Category; + +import com.querydsl.core.testutil.Firebird; +import com.querydsl.sql.*; + +@Category(Firebird.class) +public class FirebirdLiteralsSuiteTest extends AbstractSuite { + + public static class BeanPopulation extends BeanPopulationBase { } + public static class Delete extends DeleteBase { } + public static class Insert extends InsertBase { } + public static class KeywordQuoting extends KeywordQuotingBase { } + public static class LikeEscape extends LikeEscapeBase { } + public static class Merge extends MergeBase { } + public static class Select extends SelectBase { } + public static class Subqueries extends SubqueriesBase { } + public static class Types extends TypesBase { } + public static class Union extends UnionBase { } + public static class Update extends UpdateBase { } + + @BeforeClass + public static void setUp() throws Exception { + Connections.initFirebird(); + Connections.initConfiguration(FirebirdTemplates.builder().newLineToSingleSpace().build()); + Connections.getConfiguration().setUseLiterals(true); + } +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/suites/FirebirdSuiteTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/suites/FirebirdSuiteTest.java new file mode 100644 index 0000000000..1a1f1cd99b --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/suites/FirebirdSuiteTest.java @@ -0,0 +1,29 @@ +package com.querydsl.sql.suites; + +import org.junit.BeforeClass; +import org.junit.experimental.categories.Category; + +import com.querydsl.core.testutil.Firebird; +import com.querydsl.sql.*; + +@Category(Firebird.class) +public class FirebirdSuiteTest extends AbstractSuite { + + public static class BeanPopulation extends BeanPopulationBase { } + public static class Delete extends DeleteBase { } + public static class Insert extends InsertBase { } + public static class KeywordQuoting extends KeywordQuotingBase { } + public static class LikeEscape extends LikeEscapeBase { } + public static class Merge extends MergeBase { } + public static class Select extends SelectBase { } + public static class Subqueries extends SubqueriesBase { } + public static class Types extends TypesBase { } + public static class Union extends UnionBase { } + public static class Update extends UpdateBase { } + + @BeforeClass + public static void setUp() throws Exception { + Connections.initFirebird(); + Connections.initConfiguration(FirebirdTemplates.builder().newLineToSingleSpace().build()); + } +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/suites/H2ExceptionSuiteTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/suites/H2ExceptionSuiteTest.java new file mode 100644 index 0000000000..2d0e33dc78 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/suites/H2ExceptionSuiteTest.java @@ -0,0 +1,72 @@ +package com.querydsl.sql.suites; + +import com.querydsl.core.QueryException; +import com.querydsl.core.testutil.H2; +import com.querydsl.sql.AbstractBaseTest; +import com.querydsl.sql.Connections; +import com.querydsl.sql.DefaultSQLExceptionTranslator; +import com.querydsl.sql.H2Templates; +import com.querydsl.sql.SQLExceptionTranslator; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +import java.sql.SQLException; + +import static com.querydsl.sql.domain.QSurvey.survey; +import static org.hamcrest.Matchers.emptyArray; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.not; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThat; + +@Category(H2.class) +public class H2ExceptionSuiteTest extends AbstractBaseTest { + + private static final SQLExceptionTranslator exceptionTranslator = DefaultSQLExceptionTranslator.DEFAULT; + + @BeforeClass + public static void setUp() throws Exception { + Connections.initH2(); + Connections.initConfiguration(H2Templates.builder().build()); + + Connections.getConnection().createStatement() + .execute("ALTER TABLE SURVEY ADD CONSTRAINT UNIQUE_ID UNIQUE(ID)"); + } + + public static void tearDown() throws Exception { + Connections.getConnection().createStatement() + .execute("ALTER TABLE SURVEY DROP CONSTRAINT UNIQUE_ID"); + } + + @Test + public void sQLExceptionCreationTranslated() { + SQLException e1 = new SQLException("Exception #1", "42001", 181); + SQLException e2 = new SQLException("Exception #2", "HY000", 1030); + e1.setNextException(e2); + SQLException sqlException = new SQLException("Batch operation failed"); + sqlException.setNextException(e1); + RuntimeException result = exceptionTranslator.translate(sqlException); + inspectExceptionResult(result); + } + + @Test + public void updateBatchFailed() { + execute(insert(survey).columns(survey.name, survey.name2) + .values("New Survey", "New Survey")); + Exception result = null; + try { + execute(update(survey) + .set(survey.id, 1).addBatch() + .set(survey.id, 2).addBatch()); + } catch (QueryException e) { + result = e; + } + assertNotNull(result); + inspectExceptionResult(result); + } + + private void inspectExceptionResult(Exception result) { + assertThat(result.getSuppressed(), is(not(emptyArray()))); + } +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/suites/H2LiteralsSuiteTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/suites/H2LiteralsSuiteTest.java new file mode 100644 index 0000000000..7c5b0bc2f7 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/suites/H2LiteralsSuiteTest.java @@ -0,0 +1,31 @@ +package com.querydsl.sql.suites; + +import org.junit.BeforeClass; +import org.junit.experimental.categories.Category; + +import com.querydsl.core.testutil.H2; +import com.querydsl.sql.*; + +@Category(H2.class) +public class H2LiteralsSuiteTest extends AbstractSuite { + + public static class BeanPopulation extends BeanPopulationBase { } + public static class Delete extends DeleteBase { } + public static class Insert extends InsertBase { } + public static class KeywordQuoting extends KeywordQuotingBase { } + public static class LikeEscape extends LikeEscapeBase { } + public static class Merge extends MergeBase { } + public static class Select extends SelectBase { } + public static class Subqueries extends SubqueriesBase { } + public static class Types extends TypesBase { } + public static class Union extends UnionBase { } + public static class Update extends UpdateBase { } + + @BeforeClass + public static void setUp() throws Exception { + Connections.initH2(); + Connections.initConfiguration(H2Templates.builder().newLineToSingleSpace().build()); + Connections.getConfiguration().setUseLiterals(true); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/suites/H2SuiteTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/suites/H2SuiteTest.java new file mode 100644 index 0000000000..f6b9640116 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/suites/H2SuiteTest.java @@ -0,0 +1,30 @@ +package com.querydsl.sql.suites; + +import org.junit.BeforeClass; +import org.junit.experimental.categories.Category; + +import com.querydsl.core.testutil.H2; +import com.querydsl.sql.*; + +@Category(H2.class) +public class H2SuiteTest extends AbstractSuite { + + public static class BeanPopulation extends BeanPopulationBase { } + public static class Delete extends DeleteBase { } + public static class Insert extends InsertBase { } + public static class KeywordQuoting extends KeywordQuotingBase { } + public static class LikeEscape extends LikeEscapeBase { } + public static class Merge extends MergeBase { } + public static class Select extends SelectBase { } + public static class Subqueries extends SubqueriesBase { } + public static class Types extends TypesBase { } + public static class Union extends UnionBase { } + public static class Update extends UpdateBase { } + + @BeforeClass + public static void setUp() throws Exception { + Connections.initH2(); + Connections.initConfiguration(H2Templates.builder().newLineToSingleSpace().build()); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/suites/H2WithQuotingTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/suites/H2WithQuotingTest.java new file mode 100644 index 0000000000..11ef094dce --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/suites/H2WithQuotingTest.java @@ -0,0 +1,29 @@ +package com.querydsl.sql.suites; + +import org.junit.BeforeClass; +import org.junit.experimental.categories.Category; + +import com.querydsl.core.testutil.H2; +import com.querydsl.sql.*; + +@Category(H2.class) +public class H2WithQuotingTest extends AbstractSuite { + + public static class BeanPopulation extends BeanPopulationBase { } + public static class Delete extends DeleteBase { } + public static class Insert extends InsertBase { } + public static class KeywordQuoting extends KeywordQuotingBase { } + public static class LikeEscape extends LikeEscapeBase { } + public static class Merge extends MergeBase { } + public static class Subqueries extends SubqueriesBase { } + public static class Types extends TypesBase { } + public static class Union extends UnionBase { } + public static class Update extends UpdateBase { } + + @BeforeClass + public static void setUp() throws Exception { + Connections.initH2(); + Connections.initConfiguration(H2Templates.builder().quote().newLineToSingleSpace().build()); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/suites/H2WithSchemaTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/suites/H2WithSchemaTest.java new file mode 100644 index 0000000000..eccba6c754 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/suites/H2WithSchemaTest.java @@ -0,0 +1,30 @@ +package com.querydsl.sql.suites; + +import org.junit.BeforeClass; +import org.junit.experimental.categories.Category; + +import com.querydsl.core.testutil.H2; +import com.querydsl.sql.*; + +@Category(H2.class) +public class H2WithSchemaTest extends AbstractSuite { + + public static class BeanPopulation extends BeanPopulationBase { } + public static class Delete extends DeleteBase { } + public static class Insert extends InsertBase { } + public static class KeywordQuoting extends KeywordQuotingBase { } + public static class LikeEscape extends LikeEscapeBase { } + public static class Merge extends MergeBase { } + public static class Select extends SelectBase { } + public static class Subqueries extends SubqueriesBase { } + public static class Types extends TypesBase { } + public static class Union extends UnionBase { } + public static class Update extends UpdateBase { } + + @BeforeClass + public static void setUp() throws Exception { + Connections.initH2(); + Connections.initConfiguration(H2Templates.builder().printSchema().newLineToSingleSpace().build()); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/suites/HsqldbLiteralsSuiteTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/suites/HsqldbLiteralsSuiteTest.java new file mode 100644 index 0000000000..7cc5a06896 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/suites/HsqldbLiteralsSuiteTest.java @@ -0,0 +1,31 @@ +package com.querydsl.sql.suites; + +import org.junit.BeforeClass; +import org.junit.experimental.categories.Category; + +import com.querydsl.core.testutil.HSQLDB; +import com.querydsl.sql.*; + +@Category(HSQLDB.class) +public class HsqldbLiteralsSuiteTest extends AbstractSuite { + + public static class BeanPopulation extends BeanPopulationBase { } + public static class Delete extends DeleteBase { } + public static class Insert extends InsertBase { } + public static class KeywordQuoting extends KeywordQuotingBase { } + public static class LikeEscape extends LikeEscapeBase { } + public static class Merge extends MergeBase { } + public static class Select extends SelectBase { } + public static class Subqueries extends SubqueriesBase { } + public static class Types extends TypesBase { } + public static class Union extends UnionBase { } + public static class Update extends UpdateBase { } + + @BeforeClass + public static void setUp() throws Exception { + Connections.initHSQL(); + Connections.initConfiguration(HSQLDBTemplates.builder().newLineToSingleSpace().build()); + Connections.getConfiguration().setUseLiterals(true); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/suites/HsqldbSuiteTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/suites/HsqldbSuiteTest.java new file mode 100644 index 0000000000..6c3845b2cd --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/suites/HsqldbSuiteTest.java @@ -0,0 +1,30 @@ +package com.querydsl.sql.suites; + +import org.junit.BeforeClass; +import org.junit.experimental.categories.Category; + +import com.querydsl.core.testutil.HSQLDB; +import com.querydsl.sql.*; + +@Category(HSQLDB.class) +public class HsqldbSuiteTest extends AbstractSuite { + + public static class BeanPopulation extends BeanPopulationBase { } + public static class Delete extends DeleteBase { } + public static class Insert extends InsertBase { } + public static class KeywordQuoting extends KeywordQuotingBase { } + public static class LikeEscape extends LikeEscapeBase { } + public static class Merge extends MergeBase { } + public static class Select extends SelectBase { } + public static class Subqueries extends SubqueriesBase { } + public static class Types extends TypesBase { } + public static class Union extends UnionBase { } + public static class Update extends UpdateBase { } + + @BeforeClass + public static void setUp() throws Exception { + Connections.initHSQL(); + Connections.initConfiguration(HSQLDBTemplates.builder().newLineToSingleSpace().build()); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/suites/MSSQLLiteralsSuiteTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/suites/MSSQLLiteralsSuiteTest.java new file mode 100644 index 0000000000..351dbcab23 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/suites/MSSQLLiteralsSuiteTest.java @@ -0,0 +1,32 @@ +package com.querydsl.sql.suites; + +import org.junit.BeforeClass; +import org.junit.experimental.categories.Category; + +import com.querydsl.core.testutil.SQLServer; +import com.querydsl.sql.*; + +@Category(SQLServer.class) +public class MSSQLLiteralsSuiteTest extends AbstractSuite { + + public static class BeanPopulation extends BeanPopulationBase { } + public static class Delete extends DeleteBase { } + public static class Insert extends InsertBase { } + public static class KeywordQuoting extends KeywordQuotingBase { } + public static class LikeEscape extends LikeEscapeBase { } + public static class Merge extends MergeBase { } + public static class Select extends SelectBase { } + public static class SelectWindowFunctions extends SelectWindowFunctionsBase { } + public static class Subqueries extends SubqueriesBase { } + public static class Types extends TypesBase { } + public static class Union extends UnionBase { } + public static class Update extends UpdateBase { } + + @BeforeClass + public static void setUp() throws Exception { + Connections.initSQLServer(); + Connections.initConfiguration(SQLServer2008Templates.builder().newLineToSingleSpace().build()); + Connections.getConfiguration().setUseLiterals(true); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/suites/MSSQLSuiteTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/suites/MSSQLSuiteTest.java new file mode 100644 index 0000000000..3da1326936 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/suites/MSSQLSuiteTest.java @@ -0,0 +1,31 @@ +package com.querydsl.sql.suites; + +import org.junit.BeforeClass; +import org.junit.experimental.categories.Category; + +import com.querydsl.core.testutil.SQLServer; +import com.querydsl.sql.*; + +@Category(SQLServer.class) +public class MSSQLSuiteTest extends AbstractSuite { + + public static class BeanPopulation extends BeanPopulationBase { } + public static class Delete extends DeleteBase { } + public static class Insert extends InsertBase { } + public static class KeywordQuoting extends KeywordQuotingBase { } + public static class LikeEscape extends LikeEscapeBase { } + public static class Merge extends MergeBase { } + public static class Select extends SelectBase { } + public static class SelectWindowFunctions extends SelectWindowFunctionsBase { } + public static class Subqueries extends SubqueriesBase { } + public static class Types extends TypesBase { } + public static class Union extends UnionBase { } + public static class Update extends UpdateBase { } + + @BeforeClass + public static void setUp() throws Exception { + Connections.initSQLServer(); + Connections.initConfiguration(SQLServer2008Templates.builder().newLineToSingleSpace().build()); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/suites/MySQLLiteralsSuiteTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/suites/MySQLLiteralsSuiteTest.java new file mode 100644 index 0000000000..7f19e44a73 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/suites/MySQLLiteralsSuiteTest.java @@ -0,0 +1,32 @@ +package com.querydsl.sql.suites; + +import org.junit.BeforeClass; +import org.junit.experimental.categories.Category; + +import com.querydsl.core.testutil.MySQL; +import com.querydsl.sql.*; + +@Category(MySQL.class) +public class MySQLLiteralsSuiteTest extends AbstractSuite { + + public static class BeanPopulation extends BeanPopulationBase { } + public static class Delete extends DeleteBase { } + public static class Insert extends InsertBase { } + public static class KeywordQuoting extends KeywordQuotingBase { } + public static class LikeEscape extends LikeEscapeBase { } + public static class Merge extends MergeBase { } + public static class Select extends SelectBase { } + public static class SelectMySQL extends SelectMySQLBase { } + public static class Subqueries extends SubqueriesBase { } + public static class Types extends TypesBase { } + public static class Union extends UnionBase { } + public static class Update extends UpdateBase { } + + @BeforeClass + public static void setUp() throws Exception { + Connections.initMySQL(); + Connections.initConfiguration(MySQLTemplates.builder().newLineToSingleSpace().build()); + Connections.getConfiguration().setUseLiterals(true); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/suites/MySQLSuiteTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/suites/MySQLSuiteTest.java new file mode 100644 index 0000000000..c3b57401ce --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/suites/MySQLSuiteTest.java @@ -0,0 +1,31 @@ +package com.querydsl.sql.suites; + +import org.junit.BeforeClass; +import org.junit.experimental.categories.Category; + +import com.querydsl.core.testutil.MySQL; +import com.querydsl.sql.*; + +@Category(MySQL.class) +public class MySQLSuiteTest extends AbstractSuite { + + public static class BeanPopulation extends BeanPopulationBase { } + public static class Delete extends DeleteBase { } + public static class Insert extends InsertBase { } + public static class KeywordQuoting extends KeywordQuotingBase { } + public static class LikeEscape extends LikeEscapeBase { } + public static class Merge extends MergeBase { } + public static class Select extends SelectBase { } + public static class SelectMySQL extends SelectMySQLBase { } + public static class Subqueries extends SubqueriesBase { } + public static class Types extends TypesBase { } + public static class Union extends UnionBase { } + public static class Update extends UpdateBase { } + + @BeforeClass + public static void setUp() throws Exception { + Connections.initMySQL(); + Connections.initConfiguration(MySQLTemplates.builder().newLineToSingleSpace().build()); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/suites/MySQLWithQuotingTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/suites/MySQLWithQuotingTest.java new file mode 100644 index 0000000000..119bf80f81 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/suites/MySQLWithQuotingTest.java @@ -0,0 +1,30 @@ +package com.querydsl.sql.suites; + +import org.junit.BeforeClass; +import org.junit.experimental.categories.Category; + +import com.querydsl.core.testutil.MySQL; +import com.querydsl.sql.*; + +@Category(MySQL.class) +public class MySQLWithQuotingTest extends AbstractSuite { + + public static class BeanPopulation extends BeanPopulationBase { } + public static class Delete extends DeleteBase { } + public static class Insert extends InsertBase { } + public static class KeywordQuoting extends KeywordQuotingBase { } + public static class LikeEscape extends LikeEscapeBase { } + public static class Merge extends MergeBase { } + public static class Select extends SelectBase { } + public static class Subqueries extends SubqueriesBase { } + public static class Types extends TypesBase { } + public static class Union extends UnionBase { } + public static class Update extends UpdateBase { } + + @BeforeClass + public static void setUp() throws Exception { + Connections.initMySQL(); + Connections.initConfiguration(MySQLTemplates.builder().quote().newLineToSingleSpace().build()); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/suites/OracleLiteralsSuiteTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/suites/OracleLiteralsSuiteTest.java new file mode 100644 index 0000000000..bb8cbd85c3 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/suites/OracleLiteralsSuiteTest.java @@ -0,0 +1,33 @@ +package com.querydsl.sql.suites; + +import org.junit.BeforeClass; +import org.junit.experimental.categories.Category; + +import com.querydsl.core.testutil.Oracle; +import com.querydsl.sql.*; + +@Category(Oracle.class) +public class OracleLiteralsSuiteTest extends AbstractSuite { + + public static class BeanPopulation extends BeanPopulationBase { } + public static class Delete extends DeleteBase { } + public static class Insert extends InsertBase { } + public static class KeywordQuoting extends KeywordQuotingBase { } + public static class LikeEscape extends LikeEscapeBase { } + public static class Merge extends MergeBase { } + public static class Select extends SelectBase { } + public static class SelectOracle extends SelectOracleBase { } + public static class SelectWindowFunctions extends SelectWindowFunctionsBase { } + public static class Subqueries extends SubqueriesBase { } + public static class Types extends TypesBase { } + public static class Union extends UnionBase { } + public static class Update extends UpdateBase { } + + @BeforeClass + public static void setUp() throws Exception { + Connections.initOracle(); + Connections.initConfiguration(OracleTemplates.builder().newLineToSingleSpace().build()); + Connections.getConfiguration().setUseLiterals(true); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/suites/OracleSuiteTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/suites/OracleSuiteTest.java new file mode 100644 index 0000000000..d689315ed9 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/suites/OracleSuiteTest.java @@ -0,0 +1,32 @@ +package com.querydsl.sql.suites; + +import org.junit.BeforeClass; +import org.junit.experimental.categories.Category; + +import com.querydsl.core.testutil.Oracle; +import com.querydsl.sql.*; + +@Category(Oracle.class) +public class OracleSuiteTest extends AbstractSuite { + + public static class BeanPopulation extends BeanPopulationBase { } + public static class Delete extends DeleteBase { } + public static class Insert extends InsertBase { } + public static class KeywordQuoting extends KeywordQuotingBase { } + public static class LikeEscape extends LikeEscapeBase { } + public static class Merge extends MergeBase { } + public static class Select extends SelectBase { } + public static class SelectOracle extends SelectOracleBase { } + public static class SelectWindowFunctions extends SelectWindowFunctionsBase { } + public static class Subqueries extends SubqueriesBase { } + public static class Types extends TypesBase { } + public static class Union extends UnionBase { } + public static class Update extends UpdateBase { } + + @BeforeClass + public static void setUp() throws Exception { + Connections.initOracle(); + Connections.initConfiguration(OracleTemplates.builder().newLineToSingleSpace().build()); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/suites/OracleWithQuotingTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/suites/OracleWithQuotingTest.java new file mode 100644 index 0000000000..2d436cce07 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/suites/OracleWithQuotingTest.java @@ -0,0 +1,30 @@ +package com.querydsl.sql.suites; + +import org.junit.BeforeClass; +import org.junit.experimental.categories.Category; + +import com.querydsl.core.testutil.Oracle; +import com.querydsl.sql.*; + +@Category(Oracle.class) +public class OracleWithQuotingTest extends AbstractSuite { + + public static class BeanPopulation extends BeanPopulationBase { } + public static class Delete extends DeleteBase { } + public static class Insert extends InsertBase { } + public static class KeywordQuoting extends KeywordQuotingBase { } + public static class LikeEscape extends LikeEscapeBase { } + public static class Merge extends MergeBase { } + public static class Select extends SelectBase { } + public static class Subqueries extends SubqueriesBase { } + public static class Types extends TypesBase { } + public static class Union extends UnionBase { } + public static class Update extends UpdateBase { } + + @BeforeClass + public static void setUp() throws Exception { + Connections.initOracle(); + Connections.initConfiguration(OracleTemplates.builder().quote().newLineToSingleSpace().build()); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/suites/PostgreSQLLiteralsSuiteTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/suites/PostgreSQLLiteralsSuiteTest.java new file mode 100644 index 0000000000..2bbfc6eadf --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/suites/PostgreSQLLiteralsSuiteTest.java @@ -0,0 +1,51 @@ +package com.querydsl.sql.suites; + +import org.junit.BeforeClass; +import org.junit.experimental.categories.Category; + +import com.querydsl.core.testutil.PostgreSQL; +import com.querydsl.sql.*; + +@Category(PostgreSQL.class) +public class PostgreSQLLiteralsSuiteTest extends AbstractSuite { + + public static class BeanPopulation extends BeanPopulationBase { } + public static class Delete extends DeleteBase { } + public static class Insert extends InsertBase { } + public static class KeywordQuoting extends KeywordQuotingBase { + + private Configuration previous; + + @Override + public void setUp() throws Exception { + //NOTE: replacing the templates with a non-quoting one + previous = configuration; + configuration = new Configuration(PostgreSQLTemplates.builder().newLineToSingleSpace().build()); + super.setUp(); + } + + @Override + public void tearDown() throws Exception { + super.tearDown(); + //NOTE: restoring old templates + configuration = previous; + } + + } + public static class LikeEscape extends LikeEscapeBase { } + public static class Merge extends MergeBase { } + public static class Select extends SelectBase { } + public static class SelectWindowFunctions extends SelectWindowFunctionsBase { } + public static class Subqueries extends SubqueriesBase { } + public static class Types extends TypesBase { } + public static class Union extends UnionBase { } + public static class Update extends UpdateBase { } + + @BeforeClass + public static void setUp() throws Exception { + Connections.initPostgreSQL(); + Connections.initConfiguration(PostgreSQLTemplates.builder().quote().newLineToSingleSpace().build()); + Connections.getConfiguration().setUseLiterals(true); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/suites/PostgreSQLSuiteTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/suites/PostgreSQLSuiteTest.java new file mode 100644 index 0000000000..6e3d19edde --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/suites/PostgreSQLSuiteTest.java @@ -0,0 +1,50 @@ +package com.querydsl.sql.suites; + +import org.junit.BeforeClass; +import org.junit.experimental.categories.Category; + +import com.querydsl.core.testutil.PostgreSQL; +import com.querydsl.sql.*; + +@Category(PostgreSQL.class) +public class PostgreSQLSuiteTest extends AbstractSuite { + + public static class BeanPopulation extends BeanPopulationBase { } + public static class Delete extends DeleteBase { } + public static class Insert extends InsertBase { } + public static class KeywordQuoting extends KeywordQuotingBase { + + private Configuration previous; + + @Override + public void setUp() throws Exception { + //NOTE: replacing the templates with a non-quoting one + previous = configuration; + configuration = new Configuration(PostgreSQLTemplates.builder().newLineToSingleSpace().build()); + super.setUp(); + } + + @Override + public void tearDown() throws Exception { + super.tearDown(); + //NOTE: restoring old templates + configuration = previous; + } + + } + public static class LikeEscape extends LikeEscapeBase { } + public static class Merge extends MergeBase { } + public static class Select extends SelectBase { } + public static class SelectWindowFunctions extends SelectWindowFunctionsBase { } + public static class Subqueries extends SubqueriesBase { } + public static class Types extends TypesBase { } + public static class Union extends UnionBase { } + public static class Update extends UpdateBase { } + + @BeforeClass + public static void setUp() throws Exception { + Connections.initPostgreSQL(); + Connections.initConfiguration(PostgreSQLTemplates.builder().quote().newLineToSingleSpace().build()); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/suites/SQLiteLiteralsSuiteTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/suites/SQLiteLiteralsSuiteTest.java new file mode 100644 index 0000000000..c313009a91 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/suites/SQLiteLiteralsSuiteTest.java @@ -0,0 +1,31 @@ +package com.querydsl.sql.suites; + +import org.junit.BeforeClass; +import org.junit.experimental.categories.Category; + +import com.querydsl.core.testutil.SQLite; +import com.querydsl.sql.*; + +@Category(SQLite.class) +public class SQLiteLiteralsSuiteTest extends AbstractSuite { + + public static class BeanPopulation extends BeanPopulationBase { } + public static class Delete extends DeleteBase { } + public static class Insert extends InsertBase { } + public static class KeywordQuoting extends KeywordQuotingBase { } + public static class LikeEscape extends LikeEscapeBase { } + public static class Merge extends MergeBase { } + public static class Select extends SelectBase { } + public static class Subqueries extends SubqueriesBase { } + public static class Types extends TypesBase { } + public static class Union extends UnionBase { } + public static class Update extends UpdateBase { } + + @BeforeClass + public static void setUp() throws Exception { + Connections.initSQLite(); + Connections.initConfiguration(SQLiteTemplates.builder().newLineToSingleSpace().build()); + Connections.getConfiguration().setUseLiterals(true); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/suites/SQLiteSuiteTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/suites/SQLiteSuiteTest.java new file mode 100644 index 0000000000..66ac3a0dc1 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/suites/SQLiteSuiteTest.java @@ -0,0 +1,30 @@ +package com.querydsl.sql.suites; + +import org.junit.BeforeClass; +import org.junit.experimental.categories.Category; + +import com.querydsl.core.testutil.SQLite; +import com.querydsl.sql.*; + +@Category(SQLite.class) +public class SQLiteSuiteTest extends AbstractSuite { + + public static class BeanPopulation extends BeanPopulationBase { } + public static class Delete extends DeleteBase { } + public static class Insert extends InsertBase { } + public static class KeywordQuoting extends KeywordQuotingBase { } + public static class LikeEscape extends LikeEscapeBase { } + public static class Merge extends MergeBase { } + public static class Select extends SelectBase { } + public static class Subqueries extends SubqueriesBase { } + public static class Types extends TypesBase { } + public static class Union extends UnionBase { } + public static class Update extends UpdateBase { } + + @BeforeClass + public static void setUp() throws Exception { + Connections.initSQLite(); + Connections.initConfiguration(SQLiteTemplates.builder().newLineToSingleSpace().build()); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/teradata/SetQueryBandClauseTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/teradata/SetQueryBandClauseTest.java new file mode 100644 index 0000000000..580393c4cb --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/teradata/SetQueryBandClauseTest.java @@ -0,0 +1,56 @@ +package com.querydsl.sql.teradata; + +import static org.junit.Assert.assertEquals; + +import java.sql.Connection; + +import org.junit.Before; +import org.junit.Test; + +import com.querydsl.sql.Configuration; +import com.querydsl.sql.SQLTemplates; + +public class SetQueryBandClauseTest { + + private Configuration conf; + + private SetQueryBandClause clause; + + @Before + public void setUp() { + conf = new Configuration(SQLTemplates.DEFAULT); + conf.setUseLiterals(true); + clause = new SetQueryBandClause((Connection) null, conf); + } + + @Test + public void toString_() { + clause.set("a", "b"); + assertEquals("set query_band='a=b;' for session", clause.toString()); + } + + @Test + public void toString2() { + conf.setUseLiterals(false); + clause.set("a", "b"); + clause.forTransaction(); + assertEquals("set query_band=? for transaction", clause.toString()); + } + + @Test + public void forTransaction() { + clause.forTransaction(); + clause.set("a", "b"); + clause.set("b", "c"); + assertEquals("set query_band='a=b;b=c;' for transaction", clause.toString()); + } + + @Test + public void getSQL() { + clause.forTransaction(); + clause.set("a", "b"); + clause.set("b", "c"); + assertEquals("set query_band='a=b;b=c;' for transaction", clause.getSQL().get(0).getSQL()); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/types/ArrayTypeTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/types/ArrayTypeTest.java new file mode 100644 index 0000000000..a3cf601370 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/types/ArrayTypeTest.java @@ -0,0 +1,106 @@ +package com.querydsl.sql.types; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertSame; + +import java.sql.Array; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; + +import org.easymock.EasyMock; +import org.junit.Test; + +public class ArrayTypeTest { + + @Test + public void set_object_array() throws SQLException { + Integer[] value = new Integer[] {1, 2, 3}; + ArrayType type = new ArrayType<>(Integer[].class, "INTEGER ARRAY"); + + Array arr = EasyMock.createMock(Array.class); + Connection conn = EasyMock.createMock(Connection.class); + PreparedStatement stmt = EasyMock.createMock(PreparedStatement.class); + EasyMock.expect(stmt.getConnection()).andStubReturn(conn); + EasyMock.expect(conn.createArrayOf("INTEGER ARRAY", value)).andReturn(arr); + stmt.setArray(1, arr); + EasyMock.replay(arr, conn, stmt); + + type.setValue(stmt, 1, value); + + EasyMock.verify(arr, conn, stmt); + } + + @Test + public void set_primitive_array() throws SQLException { + int[] value = new int[] {1, 2, 3}; + Integer[] boxedValue = new Integer[] {1, 2, 3}; + ArrayType type = new ArrayType<>(int[].class, "INTEGER ARRAY"); + + Array arr = EasyMock.createMock(Array.class); + Connection conn = EasyMock.createMock(Connection.class); + PreparedStatement stmt = EasyMock.createMock(PreparedStatement.class); + EasyMock.expect(stmt.getConnection()).andStubReturn(conn); + EasyMock.expect(conn.createArrayOf("INTEGER ARRAY", boxedValue)).andReturn(arr); + stmt.setArray(1, arr); + EasyMock.replay(arr, conn, stmt); + + type.setValue(stmt, 1, value); + + EasyMock.verify(arr, conn, stmt); + } + + @Test + public void get_typed_object_array() throws SQLException { + Integer[] value = new Integer[] {1, 2, 3}; + ArrayType type = new ArrayType<>(Integer[].class, "INTEGER ARRAY"); + + ResultSet rs = EasyMock.createMock(ResultSet.class); + Array arr = EasyMock.createMock(Array.class); + EasyMock.expect(rs.getArray(1)).andReturn(arr); + EasyMock.expect(arr.getArray()).andReturn(value); + EasyMock.replay(rs, arr); + + Integer[] result = type.getValue(rs, 1); + assertSame(value, result); + + EasyMock.verify(rs, arr); + } + + @Test + public void get_generic_object_array() throws SQLException { + Object[] value = new Object[] {1, 2, 3}; + ArrayType type = new ArrayType<>(Integer[].class, "INTEGER ARRAY"); + + ResultSet rs = EasyMock.createMock(ResultSet.class); + Array arr = EasyMock.createMock(Array.class); + EasyMock.expect(rs.getArray(1)).andReturn(arr); + EasyMock.expect(arr.getArray()).andReturn(value); + EasyMock.replay(rs, arr); + + Integer[] result = type.getValue(rs, 1); + assertArrayEquals(value, result); + + EasyMock.verify(rs, arr); + } + + @Test + public void get_primitive_array() throws SQLException { + int[] value = new int[] {1, 2, 3}; + Integer[] boxedValue = new Integer[] {1, 2, 3}; + ArrayType type = new ArrayType<>(Integer[].class, "INTEGER ARRAY"); + + ResultSet rs = EasyMock.createMock(ResultSet.class); + Array arr = EasyMock.createMock(Array.class); + EasyMock.expect(rs.getArray(1)).andReturn(arr); + EasyMock.expect(arr.getArray()).andReturn(value); + EasyMock.replay(rs, arr); + + Integer[] result = type.getValue(rs, 1); + assertArrayEquals(boxedValue, result); + + EasyMock.verify(rs, arr); + } + +} diff --git a/querydsl-sql/src/test/java/com/mysema/query/sql/types/LocalDateTimeTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/types/LocalDateTimeTest.java similarity index 88% rename from querydsl-sql/src/test/java/com/mysema/query/sql/types/LocalDateTimeTest.java rename to querydsl-sql/src/test/java/com/querydsl/sql/types/LocalDateTimeTest.java index 4bdafc1d89..0834a25f15 100644 --- a/querydsl-sql/src/test/java/com/mysema/query/sql/types/LocalDateTimeTest.java +++ b/querydsl-sql/src/test/java/com/querydsl/sql/types/LocalDateTimeTest.java @@ -1,4 +1,4 @@ -package com.mysema.query.sql.types; +package com.querydsl.sql.types; import java.sql.PreparedStatement; import java.sql.SQLException; @@ -13,8 +13,6 @@ import org.junit.BeforeClass; import org.junit.Test; -import com.mysema.query.sql.types.LocalDateTimeType; - public class LocalDateTimeTest { private static final Calendar UTC = Calendar.getInstance(TimeZone.getTimeZone("UTC")); @@ -27,7 +25,7 @@ public static void setUpClass() { } @Test - public void Set() throws SQLException { + public void set() throws SQLException { LocalDateTime value = new LocalDateTime(); DateTime dt = value.toDateTime(DateTimeZone.UTC); Timestamp ts = new Timestamp(dt.getMillis()); diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/types/LocaleTypeTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/types/LocaleTypeTest.java new file mode 100644 index 0000000000..fc0e0a2834 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/types/LocaleTypeTest.java @@ -0,0 +1,29 @@ +package com.querydsl.sql.types; + +import static org.junit.Assert.assertEquals; + +import java.util.Locale; + +import org.junit.Test; + +public class LocaleTypeTest { + + @Test + public void lang() { + Locale l = new Locale("en"); + assertEquals(l, LocaleType.toLocale(l.toString())); + } + + @Test + public void lang_country() { + Locale l = new Locale("en", "US"); + assertEquals(l, LocaleType.toLocale(l.toString())); + } + + @Test + public void lang_country_variant() { + Locale l = new Locale("en", "US", "X"); + assertEquals(l, LocaleType.toLocale(l.toString())); + } + +} diff --git a/querydsl-sql/src/test/java/com/querydsl/sql/types/TypeTest.java b/querydsl-sql/src/test/java/com/querydsl/sql/types/TypeTest.java new file mode 100644 index 0000000000..10258a2b87 --- /dev/null +++ b/querydsl-sql/src/test/java/com/querydsl/sql/types/TypeTest.java @@ -0,0 +1,136 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.sql.types; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.net.MalformedURLException; +import java.net.URL; +import java.sql.*; +import java.util.*; + +import org.easymock.EasyMock; +import org.joda.time.DateTime; +import org.joda.time.LocalDate; +import org.joda.time.LocalDateTime; +import org.joda.time.LocalTime; +import org.junit.Test; + +import com.mysema.commons.lang.Pair; + +public class TypeTest implements InvocationHandler { + + public enum Gender { + MALE, FEMALE + } + + private Object value; + + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + if (method.getName().equals("wasNull")) { + return value == null; + } else if (method.getName().startsWith("get")) { + if (method.getReturnType().isPrimitive() && value == null) { + Class rt = method.getReturnType(); + if (rt == Byte.TYPE) { + return (byte) 0; + } else if (rt == Short.TYPE) { + return (short) 0; + } else if (rt == Integer.TYPE) { + return 0; + } else if (rt == Long.TYPE) { + return 0L; + } else if (rt == Float.TYPE) { + return 0.0f; + } else if (rt == Double.TYPE) { + return 0.0; + } else if (rt == Boolean.TYPE) { + return Boolean.FALSE; + } else if (rt == Character.TYPE) { + return (char) 0; + } + } + return value; + } else { + value = args[1]; + return null; + } + } + + private final ResultSet resultSet = (ResultSet) Proxy.newProxyInstance(getClass().getClassLoader(), new Class[]{ResultSet.class}, this); + + private final PreparedStatement statement = (PreparedStatement) Proxy.newProxyInstance(getClass().getClassLoader(), new Class[]{PreparedStatement.class}, this); + + @SuppressWarnings("unchecked") + @Test + public void test() throws MalformedURLException, SQLException { + List> valueAndType = new ArrayList>(); + valueAndType.add(Pair.of(new BigDecimal("1"), new BigDecimalType())); + valueAndType.add(Pair.of(new BigInteger("2"), new BigIntegerType())); + valueAndType.add(Pair.of(new BigDecimal("1.0"), new BigDecimalAsDoubleType())); + valueAndType.add(Pair.of(new BigInteger("2"), new BigIntegerAsLongType())); + //valueAndType.add(Pair.of(Boolean.TRUE, new BooleanType())); + valueAndType.add(Pair.of((byte) 1, new ByteType())); + valueAndType.add(Pair.of(new byte[0], new BytesType())); + valueAndType.add(Pair.of(Calendar.getInstance(), new CalendarType())); + valueAndType.add(Pair.of('c', new CharacterType())); + valueAndType.add(Pair.of(Currency.getInstance("EUR"), new CurrencyType())); + valueAndType.add(Pair.of(new java.sql.Date(0),new DateType())); + valueAndType.add(Pair.of(1.0, new DoubleType())); + valueAndType.add(Pair.of(1.0f, new FloatType())); + valueAndType.add(Pair.of(1, new IntegerType())); + valueAndType.add(Pair.of(true, new NumericBooleanType())); + valueAndType.add(Pair.of(1L, new LongType())); + valueAndType.add(Pair.of(new Object(), new ObjectType())); + valueAndType.add(Pair.of((short) 1, new ShortType())); + valueAndType.add(Pair.of("", new StringType())); + valueAndType.add(Pair.of(true, new TrueFalseType())); + valueAndType.add(Pair.of(true, new YesNoType())); + valueAndType.add(Pair.of(new Timestamp(0), new TimestampType())); + valueAndType.add(Pair.of(new Time(0), new TimeType())); + valueAndType.add(Pair.of(new URL("http://www.mysema.com"), new URLType())); + valueAndType.add(Pair.of(new java.util.Date(),new UtilDateType())); + + valueAndType.add(Pair.of(new DateTime(), new DateTimeType())); + valueAndType.add(Pair.of(new LocalDateTime(), new LocalDateTimeType())); + valueAndType.add(Pair.of(new LocalDate(), new LocalDateType())); + valueAndType.add(Pair.of(new LocalTime(), new LocalTimeType())); + + valueAndType.add(Pair.of(Gender.MALE, new EnumByNameType(Gender.class))); + valueAndType.add(Pair.of(Gender.MALE, new EnumByOrdinalType(Gender.class))); + + valueAndType.add(Pair.of(EasyMock.createNiceMock(Blob.class), new BlobType())); + valueAndType.add(Pair.of(EasyMock.createNiceMock(Clob.class), new ClobType())); + + valueAndType.add(Pair.of(UUID.randomUUID(), new UtilUUIDType(true))); + valueAndType.add(Pair.of(UUID.randomUUID(), new UtilUUIDType(false))); + + for (Pair pair : valueAndType) { + value = null; + Type type = (Type) pair.getSecond(); + assertNull(type.toString(), type.getValue(resultSet, 0)); + type.setValue(statement, 0, pair.getFirst()); + assertEquals(type.toString(), pair.getFirst(), type.getValue(resultSet, 0)); + } + } + + +} diff --git a/querydsl-sql/src/test/resources/log4j.properties b/querydsl-sql/src/test/resources/log4j.properties index d03c22d72e..b898adda1c 100644 --- a/querydsl-sql/src/test/resources/log4j.properties +++ b/querydsl-sql/src/test/resources/log4j.properties @@ -2,10 +2,10 @@ log4j.appender.stdout=org.apache.log4j.ConsoleAppender #log4j.appender.stdout.Target=System.out log4j.appender.stdout.layout=org.apache.log4j.PatternLayout -log4j.appender.stdout.layout.ConversionPattern=%5p [%d{yyyy-MM-dd HH:mm:ss}] (%F:%L) - %m%n +log4j.appender.stdout.layout.ConversionPattern=%5p [%d{yyyy-MM-dd HH:mm:ss}] (%F:%L) - %m %X%n ### set log levels - for more verbose logging change 'info' to 'debug' ### log4j.rootLogger=WARN, stdout -#log4j.logger.com.mysema.query.sql=DEBUG \ No newline at end of file +#log4j.logger.com.querydsl.sql=DEBUG \ No newline at end of file diff --git a/querydsl-sql/template.mf b/querydsl-sql/template.mf deleted file mode 100644 index 4236d60490..0000000000 --- a/querydsl-sql/template.mf +++ /dev/null @@ -1,17 +0,0 @@ -Bundle-SymbolicName: com.mysema.querydsl.sql -Bundle-Name: Querydsl SQL -Bundle-Vendor: Mysema -Bundle-ManifestVersion: 2 -Excluded-Imports: com.infradna.tool.bridge_method_injector, org.postgis, org.geolatte.*, oracle.*, com.vividsolutions.jts.* -Import-Template: - com.mysema.commons.lang.*;version="${mysema.lang.version}", - com.mysema.query.*;version="${project.version}", - com.mysema.util.*;version="${project.version}", - javax.annotation.*;version="0", - javax.inject.*;version="0", - javax.sql.*;version="0", - javax.validation.*;version="1.0.0", - com.google.common.*;version="${guava.version}", - org.joda.time.*;version="1.6", - org.slf4j.*;version="${slf4j.version}" - \ No newline at end of file diff --git a/release.sh b/release.sh new file mode 100755 index 0000000000..cbdd45d8f3 --- /dev/null +++ b/release.sh @@ -0,0 +1,48 @@ +#!/usr/bin/env bash +set -e + +VERSION=$2 +TAG=QUERYDSL_`sed 's/\./_/g' <<< $VERSION` + +pre() { + git checkout master + git pull + mvn -Pall,docs versions:set -DgenerateBackupPoms=false -DnewVersion=$VERSION + sed -i '' "s/4\..\../$VERSION/" querydsl-docs/src/main/docbook/en-US/Querydsl_Reference.xml + git checkout -b querydsl-$VERSION + git add . + git commit -m "Querydsl $VERSION" + git push origin querydsl-$VERSION + # TODO create PR +} + +doit() { + git checkout master + git pull --ff-only + export GPG_TTY=$(tty) + mvn clean deploy -DskipTests -Pall -Dgpg.skip=false -Dgpg.keyname=57312C37B064EE0FDAB0130490D5CE79E1DE6A2C -Denforcer.skip=true + ./dist.sh + ssh -i ~/.ssh/querydsl.com root@querydsl.com "mkdir /var/www/html/static/querydsl/$VERSION" + scp -r -i ~/.ssh/querydsl.com target/dist/* root@querydsl.com:/var/www/html/static/querydsl/$VERSION/ + ssh root@querydsl.com "cd /var/www/html/static/querydsl && unlink latest && ln -sT $VERSION latest" + git tag $TAG + git push --tags + echo -e "Don't forget \x1b[33mquerydsl-contrib\x1b[m." +} + +post() { + echo "post release stuff" + # TODO update querydsl.com + # TODO close github milestone + # TODO bump version +} + +if [ “$1” == “pre” ]; then + pre +elif [ “$1” == “doit” ]; then + doit +elif [ “$1” == “post” ]; then + post +else + echo "./release (pre|doit|post) VERSION" +fi diff --git a/querydsl-root/src/main/assembly.xml b/src/main/assembly.xml similarity index 87% rename from querydsl-root/src/main/assembly.xml rename to src/main/assembly.xml index 8fea4e7a7d..ececdf6bad 100644 --- a/querydsl-root/src/main/assembly.xml +++ b/src/main/assembly.xml @@ -8,7 +8,7 @@ - ../querydsl-root/LICENSE.txt + ../LICENSE.txt / @@ -45,7 +45,7 @@ - ../querydsl-core/target + querydsl-core/target *-sources.jar @@ -62,7 +62,5 @@ compile lib/all - diff --git a/src/main/resources/querydsl_checks_base.xml b/src/main/resources/querydsl_checks_base.xml new file mode 100644 index 0000000000..9f8d6bfe13 --- /dev/null +++ b/src/main/resources/querydsl_checks_base.xml @@ -0,0 +1,107 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/querydsl_checks_main.xml b/src/main/resources/querydsl_checks_main.xml new file mode 100644 index 0000000000..8489cbf7c8 --- /dev/null +++ b/src/main/resources/querydsl_checks_main.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file

{ + + } + +} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/Enum3Test.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Enum3Test.java similarity index 91% rename from querydsl-apt/src/test/java/com/mysema/query/domain/Enum3Test.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/Enum3Test.java index 7ce0d028a4..851cd7238b 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/Enum3Test.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Enum3Test.java @@ -1,8 +1,9 @@ -package com.mysema.query.domain; +package com.querydsl.apt.domain; + +import java.io.Serializable; import javax.persistence.Entity; import javax.persistence.Enumerated; -import java.io.Serializable; import org.junit.Test; @@ -12,7 +13,7 @@ public interface BaseInterface extends Serializable { String getFoo(); String getBar(); } - + public enum EnumImplementation implements SpecificInterface { FOO, BAR; @@ -27,49 +28,49 @@ public String getBar() { return name(); } } - + public interface SpecificInterface extends BaseInterface { EnumImplementation getValue(); } - + @Entity public static class Entity1 { - + @Enumerated(javax.persistence.EnumType.STRING) private EnumImplementation value; - + public SpecificInterface getValue() { return value; } } - + @Entity public static class Entity2 { - + private EnumImplementation value; - + @Enumerated(javax.persistence.EnumType.STRING) public SpecificInterface getValue() { return value; } } - + @Entity public static class Entity3 { - + private EnumImplementation value; - + public SpecificInterface getValue() { return value; } } - + @Test public void test() { - + } - + } diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/Enum4Test.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Enum4Test.java similarity index 90% rename from querydsl-apt/src/test/java/com/mysema/query/domain/Enum4Test.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/Enum4Test.java index 2c370f6321..74b7735ed1 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/Enum4Test.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Enum4Test.java @@ -1,4 +1,4 @@ -package com.mysema.query.domain; +package com.querydsl.apt.domain; import javax.persistence.Entity; import javax.persistence.Id; @@ -9,7 +9,7 @@ public class Enum4Test { @Entity - public static class Product{ + public static class Product { @Id long objectId; @@ -40,7 +40,7 @@ public enum ExportUnit { private final int code; private final Integer factor; // to minutes - private ExportUnit(int code, Integer factor) { + ExportUnit(int code, Integer factor) { this.code = code; this.factor = factor; } diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/EnumTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/EnumTest.java new file mode 100644 index 0000000000..8450c57692 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/EnumTest.java @@ -0,0 +1,52 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt.domain; + +import static org.junit.Assert.assertNotNull; + +import org.junit.Test; + +import com.querydsl.core.annotations.QueryEmbeddable; +import com.querydsl.core.annotations.QueryEntity; + +public class EnumTest { + + @QueryEntity + public enum Gender { + MALE, + FEMALE + } + + @QueryEmbeddable + public enum Gender2 { + MALE, + FEMALE + } + + @QueryEntity + public static class Bean { + Gender gender; + } + + @Test + public void enum_as_comparable() { + assertNotNull(QEnumTest_Gender.gender.asc()); + } + + @Test + public void enumOrdinal_as_comparable() { + assertNotNull(QEnumTest_Gender.gender.ordinal().asc()); + } + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/ExampleEntity.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/ExampleEntity.java new file mode 100644 index 0000000000..fec6002809 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/ExampleEntity.java @@ -0,0 +1,23 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt.domain; + +import com.querydsl.core.annotations.QueryEntity; + +@QueryEntity +public class ExampleEntity { + + String name; + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/Examples.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Examples.java new file mode 100644 index 0000000000..cf7646de2b --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Examples.java @@ -0,0 +1,77 @@ +package com.querydsl.apt.domain; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import com.querydsl.core.annotations.QueryEmbedded; +import com.querydsl.core.annotations.QueryEntity; +import com.querydsl.core.types.OrderSpecifier; + +public class Examples { + + public static class Supertype { + + String supertypeProperty; + } + + @QueryEntity + public static class SimpleEntity extends Supertype { + + } + + @QueryEntity + public abstract static class AbstractEntity { + + Id id; + + String first; + + } + + @QueryEntity + public static class SubEntity extends AbstractEntity { + + String second; + + } + + @QueryEntity + public static class ComplexCollections { + + @QueryEmbedded + List> list; + + @QueryEmbedded + Map> map; + + @QueryEmbedded + Map> map2; + + @QueryEmbedded + Map> map3; + + } + + public static class Complex> implements Comparable> { + + T a; + + @Override + public int compareTo(Complex arg0) { + return 0; + } + + public boolean equals(Object o) { + return o == this; + } + } + + @QueryEntity + public static class OrderBys { + + @QueryEmbedded + List> orderBy = new ArrayList>(); + } + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/ExcludedClassTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/ExcludedClassTest.java new file mode 100644 index 0000000000..c8d0874dec --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/ExcludedClassTest.java @@ -0,0 +1,41 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt.domain; + +import org.junit.Test; + +import com.querydsl.core.annotations.QueryEntity; +import com.querydsl.core.annotations.QueryExclude; + +@QueryExclude +@QueryEntity +public class ExcludedClassTest { + + @QueryExclude + @QueryEntity + public static class InnerClass { + + } + + @Test(expected = ClassNotFoundException.class) + public void outerClass() throws ClassNotFoundException { + Class.forName(getClass().getPackage().getName() + ".Q" + getClass().getSimpleName()); + } + + @Test(expected = ClassNotFoundException.class) + public void innerClass() throws ClassNotFoundException { + Class.forName(getClass().getPackage().getName() + ".QExcludedClassTest_InnerClass"); + } + +} diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/Expression.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Expression.java new file mode 100644 index 0000000000..a585866af7 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Expression.java @@ -0,0 +1,8 @@ +package com.querydsl.apt.domain; + +import javax.persistence.Entity; + +@Entity +public class Expression { + +} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/ExpressionTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/ExpressionTest.java similarity index 85% rename from querydsl-apt/src/test/java/com/mysema/query/domain/ExpressionTest.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/ExpressionTest.java index ede41b10ba..86ce0d67b1 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/ExpressionTest.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/ExpressionTest.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,22 +11,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.domain; +package com.querydsl.apt.domain; import java.lang.reflect.Field; import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.TreeSet; +import java.util.*; import org.junit.Test; -import com.mysema.query.types.ConstantImpl; -import com.mysema.query.types.Expression; -import com.mysema.query.types.expr.BooleanExpression; -import com.mysema.query.types.expr.StringExpression; +import com.querydsl.core.types.ConstantImpl; +import com.querydsl.core.types.Expression; +import com.querydsl.core.types.dsl.BooleanExpression; +import com.querydsl.core.types.dsl.StringExpression; public class ExpressionTest { @@ -61,26 +57,24 @@ public void test() throws Throwable { exprs.add(ConstantImpl.create("Hello World!")); exprs.add(ConstantImpl.create(1000)); - exprs.add(ConstantImpl.create(10l)); + exprs.add(ConstantImpl.create(10L)); exprs.add(ConstantImpl.create(true)); exprs.add(ConstantImpl.create(false)); - Set> toVisit = new HashSet>(); - // all entities - toVisit.addAll(exprs); + Set> toVisit = new HashSet>(exprs); // and all their direct properties for (Expression expr : exprs) { for (Field field : expr.getClass().getFields()) { Object rv = field.get(expr); if (rv instanceof Expression) { if (rv instanceof StringExpression) { - StringExpression str = (StringExpression)rv; + StringExpression str = (StringExpression) rv; toVisit.add(str.toLowerCase()); toVisit.add(str.charAt(0)); toVisit.add(str.isEmpty()); } else if (rv instanceof BooleanExpression) { - BooleanExpression b = (BooleanExpression)rv; + BooleanExpression b = (BooleanExpression) rv; toVisit.add(b.not()); } toVisit.add((Expression) rv); @@ -92,8 +86,12 @@ public void test() throws Throwable { for (Expression expr : toVisit) { for (Method method : expr.getClass().getMethods()) { - if (method.getName().equals("getParameter")) continue; - if (method.getName().equals("getArg")) continue; + if (method.getName().equals("getParameter")) { + continue; + } + if (method.getName().equals("getArg")) { + continue; + } if (method.getReturnType() != void.class && !method.getReturnType().isPrimitive()) { Class[] types = method.getParameterTypes(); @@ -102,7 +100,7 @@ public void test() throws Throwable { args = new Object[0]; } else if (types.length == 1) { if (types[0] == int.class) { - args = new Object[]{Integer.valueOf(1)}; + args = new Object[]{1}; } else if (types[0] == boolean.class) { args = new Object[]{Boolean.TRUE}; } else { @@ -114,14 +112,14 @@ public void test() throws Throwable { } Object rv = method.invoke(expr, args); if (method.invoke(expr, args) != rv) { - failures.add(expr.getClass().getSimpleName()+"."+method.getName()+" is unstable"); + failures.add(expr.getClass().getSimpleName() + "." + method.getName() + " is unstable"); } } } } if (failures.size() > 0) { - System.err.println("Got "+failures.size()+" failures\n"); + System.err.println("Got " + failures.size() + " failures\n"); } for (String failure : failures) { System.err.println(failure); diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/ExtendsAndSuperTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/ExtendsAndSuperTest.java similarity index 91% rename from querydsl-apt/src/test/java/com/mysema/query/domain/ExtendsAndSuperTest.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/ExtendsAndSuperTest.java index ab6416dcdd..ce998a0d13 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/ExtendsAndSuperTest.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/ExtendsAndSuperTest.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,7 +11,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.domain; +package com.querydsl.apt.domain; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; @@ -23,12 +23,12 @@ import org.junit.Test; -import com.mysema.query.annotations.QueryEntity; +import com.querydsl.core.annotations.QueryEntity; public class ExtendsAndSuperTest { @QueryEntity - public static class ExtendsAndSuper{ + public static class ExtendsAndSuper { // col Collection extendsCol; Collection extendsCol2; @@ -55,7 +55,7 @@ public static class ExtendsAndSuper{ } @Test - public void Validate() { + public void validate() { QExtendsAndSuperTest_ExtendsAndSuper var = QExtendsAndSuperTest_ExtendsAndSuper.extendsAndSuper; assertEquals(Object.class, var.extendsCol.getElementType()); assertEquals(CharSequence.class, var.extendsCol2.getElementType()); diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/ExternalEmbeddableTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/ExternalEmbeddableTest.java new file mode 100644 index 0000000000..f439330b8b --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/ExternalEmbeddableTest.java @@ -0,0 +1,34 @@ +/* + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * + * 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. + */ +package com.querydsl.apt.domain; + +import javax.persistence.Embedded; +import javax.persistence.Entity; + +import org.junit.Ignore; + +import com.querydsl.core.domain.EmbeddableWithoutQType; + +@Ignore +public class ExternalEmbeddableTest { + + @Entity + public static class EntityWithExternalEmbeddable { + + @Embedded + EmbeddableWithoutQType embeddable; + + } + +} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/ExternalEntityTest.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/ExternalEntityTest.java similarity index 76% rename from querydsl-apt/src/test/java/com/mysema/query/domain/ExternalEntityTest.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/ExternalEntityTest.java index 01b839f4d9..2c71cc8063 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/ExternalEntityTest.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/ExternalEntityTest.java @@ -1,6 +1,6 @@ /* - * Copyright 2011, Mysema Ltd - * + * Copyright 2015, The Querydsl Team (http://www.querydsl.com/team) + * * 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 @@ -11,24 +11,25 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.mysema.query.domain; +package com.querydsl.apt.domain; -import static org.junit.Assert.*; +import static org.junit.Assert.assertNotNull; import org.junit.Test; -import com.mysema.query.annotations.QueryEntity; +import com.querydsl.core.annotations.QueryEntity; +import com.querydsl.core.domain.AbstractEntity; public class ExternalEntityTest { @QueryEntity public static class MyEntity extends AbstractEntity { - + } - + @Test public void test() { assertNotNull(QExternalEntityTest_MyEntity.myEntity.id); } - + } diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/FileAttachment.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/FileAttachment.java similarity index 91% rename from querydsl-apt/src/test/java/com/mysema/query/domain/FileAttachment.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/FileAttachment.java index 66d90e7115..a06bb6e9ce 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/FileAttachment.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/FileAttachment.java @@ -1,4 +1,4 @@ -package com.mysema.query.domain; +package com.querydsl.apt.domain; import java.io.File; @@ -6,7 +6,6 @@ import javax.persistence.Transient; @Embeddable -@Deprecated public class FileAttachment { @Transient @@ -41,12 +40,10 @@ public static File getStore() { return null; } - @Deprecated public boolean exists() { return isSet(); } - @Deprecated public long length() { return get().length(); } diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/Generic10Test.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Generic10Test.java new file mode 100644 index 0000000000..d98a7abcf0 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Generic10Test.java @@ -0,0 +1,51 @@ +package com.querydsl.apt.domain; + +import static org.junit.Assert.assertNotNull; + +import javax.persistence.Entity; +import javax.persistence.MappedSuperclass; +import javax.persistence.OneToOne; + +import org.junit.Test; + +public class Generic10Test extends AbstractTest { + + public interface Tradable { } + + public interface Market { } + + @Entity + public static class FutureTrade implements Tradable { } + + @MappedSuperclass + public abstract static class AbstractTradingMarket implements Market { + + @OneToOne + private TradingMarketLedger> ledger; + } + + @Entity + public abstract static class AbstractFuturesMarket extends AbstractTradingMarket { } + + @Entity + public static class CommonFuturesMarket extends AbstractFuturesMarket { } + + @Entity + public static class TradingMarketLedger> { } + + @Test + public void test() { + assertNotNull(QGeneric10Test_FutureTrade.futureTrade); + + start(QGeneric10Test_AbstractTradingMarket.class, QGeneric10Test_AbstractTradingMarket.abstractTradingMarket); + assertPresent("ledger"); + + start(QGeneric10Test_AbstractFuturesMarket.class, QGeneric10Test_AbstractFuturesMarket.abstractFuturesMarket); + assertPresent("ledger"); + + start(QGeneric10Test_CommonFuturesMarket.class, QGeneric10Test_CommonFuturesMarket.commonFuturesMarket); + assertPresent("ledger"); + + start(QGeneric10Test_TradingMarketLedger.class, QGeneric10Test_TradingMarketLedger.tradingMarketLedger); + } +} diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/Generic11Test.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Generic11Test.java similarity index 78% rename from querydsl-apt/src/test/java/com/mysema/query/domain/Generic11Test.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/Generic11Test.java index a3ab6a2411..0c492e184f 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/Generic11Test.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Generic11Test.java @@ -1,4 +1,4 @@ -package com.mysema.query.domain; +package com.querydsl.apt.domain; import javax.persistence.Entity; import javax.persistence.MappedSuperclass; @@ -6,21 +6,21 @@ import org.junit.Test; public class Generic11Test { - - // 1 + + // 1 public interface WhatEver { } - + @Entity public static class A { } - + @Entity public static class B extends A { } // note the missing type parameter - - - // 2 + + + // 2 @MappedSuperclass - public static abstract class WhatEver2 { } - + public abstract static class WhatEver2 { } + @Entity public static class A2 { } @@ -29,7 +29,7 @@ public static class B2 extends A2 { } // note the missing type parameter @Test public void test() { - + } } diff --git a/querydsl-apt/src/test/java/com/mysema/query/domain/Generic12Test.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Generic12Test.java similarity index 75% rename from querydsl-apt/src/test/java/com/mysema/query/domain/Generic12Test.java rename to querydsl-apt/src/test/java/com/querydsl/apt/domain/Generic12Test.java index d2b1e59e7a..7f788c5a05 100644 --- a/querydsl-apt/src/test/java/com/mysema/query/domain/Generic12Test.java +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Generic12Test.java @@ -1,25 +1,20 @@ -package com.mysema.query.domain; +package com.querydsl.apt.domain; import static org.junit.Assert.assertEquals; +import java.util.ArrayList; import java.util.List; -import javax.persistence.DiscriminatorColumn; -import javax.persistence.DiscriminatorValue; -import javax.persistence.Entity; -import javax.persistence.Inheritance; -import javax.persistence.ManyToMany; +import javax.persistence.*; import org.junit.Test; -import com.google.common.collect.Lists; - public class Generic12Test { @Entity @Inheritance @DiscriminatorColumn(name = "CONTEXT") - public static abstract class Permission { + public abstract static class Permission { // some common stuff } @@ -40,10 +35,10 @@ public static class SubjectPermission extends Permission { @Entity @Inheritance @DiscriminatorColumn(name = "CONTEXT") - public static abstract class Role { + public abstract static class Role { @ManyToMany(targetEntity = Permission.class) - private final List permissions = Lists.newArrayList(); + private final List permissions = new ArrayList<>(); } diff --git a/querydsl-apt/src/test/java/com/querydsl/apt/domain/Generic13Test.java b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Generic13Test.java new file mode 100644 index 0000000000..6452e0c1c9 --- /dev/null +++ b/querydsl-apt/src/test/java/com/querydsl/apt/domain/Generic13Test.java @@ -0,0 +1,37 @@ +package com.querydsl.apt.domain; + +import org.junit.Test; + +import com.querydsl.core.annotations.QueryEntity; + +public class Generic13Test extends AbstractTest { + + @QueryEntity + public static class GenericBase { + T t; + } + + @QueryEntity + public static class GenericBaseSubclass